00001
00121 #include "avr_compiler.h"
00122 #include "usart.h"
00123 #include "init.h"
00124 #include "touch_api.h"
00125
00126 #define ADC_NUM_OVERSAMPLING 16
00127
00128 #define ASCII_BACKSPACE 8
00129 #define ASCII_CR 13
00130 #define ASCII_SPACE 32
00131 #define MAX_CMD_BUFFER_LEN 32
00132
00133 #define CMD_PROMPT "\r\nMEGA-1284P Xplained>"
00134
00135 #define FLASHCOUNT 100
00136
00137 #define IDLE 0x01 //!< Idle SMCR setting
00138 #define POWER_DOWN 0x05 //!< Power-Down SMCR setting
00139 #define POWER_SAVE 0x07 //!< Power-Save SMCR setting
00140 #define STANDBY 0x0D //!< Standby SMCR setting
00141 #define EXTENDED_STANDBY 0x0F //!< Extended standby SMCR setting
00142
00143 #define NUM_COMMANDS 12
00144
00145
00146 static void print_help (void);
00147 static void flash_leds_cmd (void);
00148 static void read_ntc (void);
00149 static void read_light_sensor (void);
00150 static void light_sensor_demo (void);
00151 static void crystal_start_cmd (void);
00152 static void crystal_stop_cmd (void);
00153 static void idle_mode_cmd (void);
00154 static void power_save_cmd (void);
00155 static void power_down_cmd (void);
00156 static void standby_cmd (void);
00157 static void ext_standby_cmd (void);
00158
00160 struct {
00161 char cmd[20];
00162 char help[70];
00163 void (* func)(void);
00164 } commands[NUM_COMMANDS] = {
00165 { "help", "Print this help", print_help },
00166 { "flash leds", "Toggles leds connected to PORTB0:3", flash_leds_cmd },
00167 { "read ntc", "Returns NTC ADC code (ADC7)", read_ntc },
00168 { "read light sensor", "Returns Light Sensor ADC code (ADC6)", read_light_sensor },
00169 { "light sensor demo", "LED3:0 are dimmed according to the light sensor value", light_sensor_demo },
00170 { "start 32khz crystal", "Starts the 32.768kHz crystal", crystal_start_cmd },
00171 { "stop 32khz crystal", "Stops the 32.768kHz crystal", crystal_stop_cmd },
00172 { "idle", "MCU in idle mode. Wake up by pressing SW0", idle_mode_cmd },
00173 { "power-save", "MCU in Power-Save mode. Wake up by pressing SW0", power_save_cmd },
00174 { "power-down", "MCU in Power-Down mode. Wake up by pressing SW0", power_down_cmd },
00175 { "standby", "MCU in Standby mode. Wake up by pressing SW0", standby_cmd },
00176 { "extended standby", "MCU in Extended Standby mode. Wake up by pressing SW0", ext_standby_cmd },
00177 };
00178
00180 static volatile bool light_sensor_demo_mode = false;
00181
00183 #define QT_KEY_DETECT() \
00184 (qt_measure_data.qt_touch_status.sensor_states[0] & 0x01)
00185
00187 #define NUMBER_OF_PORTS 1
00188
00190 uint16_t qt_measurement_period_msec = 25;
00191
00193 static volatile bool time_to_measure_touch = false;
00194
00196 static volatile uint16_t current_time_ms_touch = 0;
00197
00198 #if defined( __GNUC__ )
00199
00202 FILE usart1_str = FDEV_SETUP_STREAM((int(*)(char, FILE *))usart1_putchar, NULL, _FDEV_SETUP_WRITE);
00203 #endif
00204
00206 enum adc_sources {
00207 FILTER_OUTPUT = 0x05,
00208 LIGHT_SENSOR = 0x06,
00209 NTC = 0x07
00210 };
00211
00215 ISR(PCINT1_vect)
00216 {
00217 return;
00218 }
00219
00230 ISR(TIMER1_OVF_vect)
00231 {
00232
00233 PORTB |= (1 << PORTB3) | (1 << PORTB2) | (1 << PORTB1) | (1 << PORTB0);
00234
00235 DDRB &= ~(1 << DDB0);
00236
00238 asm("nop");
00239
00240 if (!(PINB & (1 << PINB0))) {
00241 light_sensor_demo_mode = false;
00242 }
00243 }
00244
00255 ISR(TIMER1_COMPB_vect)
00256 {
00257
00258 DDRB |= (1 << DDB0);
00259 PORTB &= ~((1 << PORTB3) | (1 << PORTB2) | (1 << PORTB1) | (1 << PORTB0));
00260 }
00261
00268 ISR(TIMER1_COMPA_vect)
00269 {
00270
00271 time_to_measure_touch = true;
00272
00273
00274 current_time_ms_touch += qt_measurement_period_msec;
00275 }
00276
00282 ISR(TIMER2_OVF_vect)
00283 {
00284
00285 PINB |= (1 << PINB3) | (1 << PINB2) | (1 << PINB1) | (1 << PINB0);
00286 }
00287
00293 static void flash_leds(uint8_t flashcount)
00294 {
00295 uint8_t i;
00296
00297 for (i = 0; i < flashcount; i++) {
00298
00299 PINB |= (1 << PINB3) | (1 << PINB2) | (1 << PINB1) | (1 << PINB0);
00300
00301 delay_us(20000);
00302 }
00303
00304 PORTB |= (1 << PORTB3) | (1 << PORTB2) | (1 << PORTB1) | (1 << PORTB0);
00305 }
00306
00317 static uint16_t read_adc(enum adc_sources source)
00318 {
00319 uint16_t adc_data = 0;
00320
00321
00322 ADMUX &= 0xE0;
00323 ADMUX |= source;
00324
00325 for (int i = 0 ; i < ADC_NUM_OVERSAMPLING ; i++) {
00326
00327 ADCSRA |= (1<<ADSC);
00328
00329
00330 while(!(ADCSRA & (1<<ADIF)));
00331
00332
00333 adc_data += ADC;
00334 }
00335
00336 adc_data = adc_data/ADC_NUM_OVERSAMPLING;
00337
00338 return adc_data;
00339 }
00340
00345 static void read_ntc(void)
00346 {
00347 uint16_t ntc_data;
00348
00349
00350 ntc_data = read_adc(NTC);
00351
00352
00353 printf("NTC ADC value: %4d\r\n", ntc_data);
00354 }
00355
00359 static void read_light_sensor(void)
00360 {
00361 uint16_t light_sensor_data;
00362
00363 light_sensor_data = read_adc(LIGHT_SENSOR);
00364
00365
00366 printf("LIGHT SENSOR ADC value: %4d\r\n", light_sensor_data);
00367 }
00368
00372 static void start32crystal(void)
00373 {
00374
00375 PRR0 &= ~(1 << PRTIM2);
00376
00377
00378 TCCR2B = (0 << WGM22) | (0 << CS22) | (1 << CS21) | (0 << CS20);
00379
00380
00381 ASSR = (1 << AS2);
00382 }
00383
00387 static void stop32crystal(void)
00388 {
00389
00390 ASSR = (0 << AS2);
00391
00392
00393 TCCR2B = (0 << WGM22) | (0 << CS22) | (0 << CS21) | (0 << CS20);
00394
00395
00396 PRR0 |= (1 << PRTIM2);
00397 }
00398
00404 static void enter_sleep(uint8_t sleepmode)
00405 {
00406 uint8_t temp_timsk1;
00407 uint8_t temp_timsk2;
00408 uint8_t temp_portb;
00409 uint8_t temp_ddrb;
00410 uint8_t temp_prr0;
00411
00412
00413 temp_timsk1 = TIMSK1;
00414 temp_timsk2 = TIMSK2;
00415 temp_portb = PORTB;
00416 temp_ddrb = DDRB;
00417 TIMSK1 = 0x00;
00418 TIMSK2 = 0x00;
00419 temp_prr0 = PRR0;
00420
00421
00422 PORTB |= (1 << PORTB0);
00423 DDRB &= ~(1 << DDB0);
00424
00425
00426 PCIFR = (1 << PCIF1);
00427
00428
00429 PCICR = (1 << PCIE1);
00430 PCMSK1 = (1 << PCINT10) | (1 << PCINT9) |(1 << PCINT8);
00431
00432
00433 SMCR = sleepmode;
00434
00435
00436 power_reduction_enable();
00437
00438
00439 sleep_enter();
00440
00441
00442 SMCR = 0x00;
00443
00444
00445 PRR0 = temp_prr0;
00446
00447
00448 TIFR1 =(1 << OCF1B) | (1 << OCF1A) | (1 << TOV1);
00449 TIFR2 = (1 << TOV2);
00450
00451
00452 TIMSK1 = temp_timsk1;
00453 TIMSK2 = temp_timsk2;
00454 PORTB = temp_portb;
00455 DDRB = temp_ddrb;
00456 }
00457
00461 static void flash_leds_cmd (void)
00462 {
00463 flash_leds(FLASHCOUNT);
00464 }
00465
00469 static void light_sensor_demo (void)
00470 {
00471 timer1_lightdemo_init();
00472 adc_init();
00473 light_sensor_demo_mode = true;
00474 printf("Light sensor demo mode enabled.\r\n");
00475 printf("Push SW0 to exit light sensor demo.\r\n");
00476
00477
00478
00479
00480
00481 while(light_sensor_demo_mode) {
00482
00483 OCR1B = read_adc(LIGHT_SENSOR);
00484 }
00485 stop_timer1_lightdemo();
00486 printf("Light sensor demo mode stopped.\r\n");
00487 }
00488
00492 static void crystal_start_cmd (void)
00493 {
00494 start32crystal();
00495
00496 TIMSK2 |= (1<<TOIE2);
00497 printf("32.768kHz crystal started.\r\n");
00498 }
00499
00503 static void crystal_stop_cmd (void)
00504 {
00505 stop32crystal();
00506
00507 TIMSK2 &= ~(1<<TOIE2);
00508
00509 PORTB |= (1 << PORTB3) | (1 << PORTB2) | (1 << PORTB1) | (1 << PORTB0);
00510 printf("32.768kHz crystal stopped.\r\n");
00511 }
00512
00516 static void idle_mode_cmd (void)
00517 {
00518 printf("Entering idle mode. Push SW0 to wake-up.\r\n");
00519 while (!(UCSR1A & (1 << TXC1)));
00520 enter_sleep(IDLE);
00521 printf("Woke up from idle mode.\r\n");
00522 }
00523
00527 static void power_save_cmd (void)
00528 {
00529 printf("Entering power-save mode. Push SW0 to wake-up.\r\n");
00530 while (!(UCSR1A & (1 << TXC1)));
00531 enter_sleep(POWER_SAVE);
00532 printf("Woke up from power-save mode.\r\n");
00533 }
00534
00538 static void power_down_cmd (void)
00539 {
00540 printf("Entering power-down mode. Push SW0 to wake-up.\r\n");
00541 while (!(UCSR1A & (1 << TXC1)));
00542 enter_sleep(POWER_DOWN);
00543 printf("Woke up from power-down mode.\r\n");
00544 }
00545
00549 static void standby_cmd (void)
00550 {
00551 printf("Entering standby mode. Push SW0 to wake-up.\r\n");
00552 while (!(UCSR1A & (1 << TXC1)));
00553 enter_sleep(STANDBY);
00554 printf("Woke up from standby mode.\r\n");
00555 }
00556
00560 static void ext_standby_cmd (void)
00561 {
00562 printf("Entering extended standby mode.\r\n");
00563 printf("Push SW0 to wake-up.\r\n");
00564 while (!(UCSR1A & (1 << TXC1)));
00565 enter_sleep(EXTENDED_STANDBY);
00566 printf("Woke up from extended standby mode.\r\n");
00567 }
00568
00572 static void print_help()
00573 {
00574 uint8_t cnt;
00575
00576 printf("\r\n------------------------------------------------------------------------------\r\n");
00577 printf("# COMMAND: DESCRIPTION:\r\n");
00578 printf("------------------------------------------------------------------------------\r\n");
00579 for (cnt = 0; cnt < NUM_COMMANDS; cnt++) {
00580 printf("%-2d %-20s %s\r\n", cnt+1, commands[cnt].cmd, commands[cnt].help);
00581 }
00582 printf("------------------------------------------------------------------------------\r\n");
00583 printf("To perform a command, enter command number or command string\r\n");
00584 }
00585
00586
00591 static void process_command(const char *command)
00592 {
00593 uint8_t cnt;
00594 uint8_t num_cmd = atoi(command);
00595
00596 for (cnt = 0; cnt < NUM_COMMANDS; cnt++) {
00597 if ((strcmp(command, commands[cnt].cmd) == 0) || (num_cmd == cnt+1)) {
00598 commands[cnt].func();
00599 return;
00600 }
00601 }
00602 printf("Invalid command. Type 'help' for a list of available commands.\r\n");
00603 }
00604
00615 static void execute_demo_mode(void)
00616 {
00617
00618 uint16_t status_flag = 0;
00619 uint16_t burst_flag = 0;
00620
00621 io_init_demo_mode();
00622 touch_init();
00623 sei();
00624
00625 while (1) {
00626 if (time_to_measure_touch) {
00627
00628 time_to_measure_touch = false;
00629 MCUCR |= (1 << PUD);
00630
00631 do {
00632
00633 status_flag = qt_measure_sensors(current_time_ms_touch);
00634 burst_flag = status_flag & QTLIB_BURST_AGAIN;
00635 if (QT_KEY_DETECT()) {
00636 PORTB &= ~(1 << PORTB3);
00637 }
00638 else {
00639 PORTB |= (1 << PORTB3);
00640 }
00641
00642 } while (burst_flag);
00643 MCUCR &= ~(1 << PUD);
00644 }
00645
00646 if (!(PINB & (1 << PINB0))) {
00647
00648 DDRB |= (1 << DDB3) | (1 << DDB0);
00649 DDRB &= ~((1 << DDB2) | (1 << DDB1));
00650 PORTB &= ~(1 << PORTB0);
00651 PORTB |= (1 << PORTB2) | (1 << PORTB1);
00652 }
00653
00654 if (!(PINB & (1 << PINB1))){
00655
00656 DDRB |= (1 << DDB3) | (1 << DDB1);
00657 DDRB &= ~((1 << DDB2) | (1 << DDB0));
00658 PORTB &= ~(1 << PORTB1);
00659 PORTB |= (1 << PORTB2) | (1 << PORTB0);
00660
00661
00662
00663
00664
00665 start32crystal();
00666 enter_sleep(POWER_SAVE);
00667 stop32crystal();
00668 }
00669
00670 if (!(PINB & (1 << PINB2))) {
00671
00672 DDRB |= (1 << DDB3) | (1 << DDB2);
00673 DDRB &= ~(1 << DDB1) & ~(1 << DDB0);
00674 PORTB &= ~(1 << PORTB2);
00675 PORTB |= (1 << PORTB1) | (1 << PORTB0);
00676 enter_sleep(POWER_DOWN);
00677 }
00678
00679 if (!(PINB & (1 << PINB6))) {
00680
00681 PCICR = (0 << PCIE1);
00682
00683 adc_init();
00684 timer1_lightdemo_init();
00685
00686
00687 DDRB |= (1 << DDB3) | (1 << DDB2) | (1 << DDB1) | (1 << DDB0);
00688
00689
00690 while (!(PINB & (1 << PINB6))) {
00691
00692
00693
00694
00695
00696 OCR1B = read_adc(LIGHT_SENSOR);
00697 }
00698
00699 stop_timer1_lightdemo();
00700
00701
00702 DDRB &= ~(1 << DDB2) & ~(1 << DDB1) & ~(1 << DDB0);
00703
00704 touch_init();
00705
00706
00707 PCIFR = (1 << PCIF1);
00708
00709 PCICR = (1 << PCIE1);
00710 }
00711 }
00712 }
00713
00721 static void execute_terminal_mode(void)
00722 {
00723
00724 uint8_t data = 0;
00725
00726 uint8_t cmd_buf_ptr = 0;
00727
00728 char cmd_buffer[MAX_CMD_BUFFER_LEN];
00729
00730
00731 io_init_terminal_mode();
00732 usart1_init();
00733 adc_init();
00734
00735 sei();
00736
00737 flash_leds(20);
00738 print_help();
00739 printf(CMD_PROMPT);
00740
00741 while (1) {
00742
00743
00744 data = usart1_getchar();
00745 switch (data) {
00746
00747 case ASCII_CR:
00748 if (cmd_buf_ptr > 0) {
00749 usart1_putchar('\n');
00750 cmd_buffer[cmd_buf_ptr] = '\0';
00751 process_command(cmd_buffer);
00752 cmd_buf_ptr = 0;
00753 }
00754 printf(CMD_PROMPT);
00755 break;
00756
00757 case ASCII_BACKSPACE:
00758 if (cmd_buf_ptr == 0) {
00759 break;
00760 }
00761 printf("\b \b");
00762 cmd_buf_ptr--;
00763 break;
00764
00765 default:
00766 if (cmd_buf_ptr >= MAX_CMD_BUFFER_LEN || data < ASCII_SPACE ) {
00767
00768 break;
00769 }
00770 cmd_buffer[cmd_buf_ptr++] = data;
00771 usart1_putchar(data);
00772 break;
00773 }
00774 }
00775 }
00776
00788 int main(void)
00789 {
00790 #if defined( __GNUC__ )
00791
00792
00793
00794 stdout = &usart1_str;
00795 #endif
00796
00797
00798 power_reduction_enable();
00799
00800
00801 if (!(PINB & (1 << PORTB1))) {
00802 execute_terminal_mode();
00803 } else {
00804 execute_demo_mode();
00805 }
00806 }
00807