Mercurial > pihelp
comparison main.c @ 15:915be6f0ff13
fix for 8mhz, add flip/flop long watchdog
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Thu, 13 Jun 2013 00:14:20 +0800 |
parents | aec45c673a60 |
children | 8b1aeff120e9 |
comparison
equal
deleted
inserted
replaced
14:c17f2e4a7a8b | 15:915be6f0ff13 |
---|---|
27 // TICK should be 8 or less (8 untested). all timers need | 27 // TICK should be 8 or less (8 untested). all timers need |
28 // to be a multiple. | 28 // to be a multiple. |
29 | 29 |
30 #define TICK 1 | 30 #define TICK 1 |
31 #define SLEEP_COMPARE (2000000/64) // == 31250 exactly | 31 #define SLEEP_COMPARE (2000000/64) // == 31250 exactly |
32 #define COUNTER_DIV (F_CPU / 2000000) | |
32 #define NKEYS 10 | 33 #define NKEYS 10 |
33 #define HMACLEN 20 | 34 #define HMACLEN 20 |
34 #define AESLEN 16 | 35 #define AESLEN 16 |
35 #define KEYLEN HMACLEN | 36 #define KEYLEN HMACLEN |
36 | 37 |
37 #define BAUD 19200 | 38 #define BAUD 38400 |
38 #define UBRR ((F_CPU)/8/(BAUD)-1) | 39 #define UBRR ((F_CPU)/8/(BAUD)-1) |
39 | 40 |
40 #define PORT_PI_BOOT PORTD | 41 #define PORT_PI_BOOT PORTD |
41 #define DDR_PI_BOOT DDRD | 42 #define DDR_PI_BOOT DDRD |
42 #define PIN_PI_BOOT PD5 | 43 #define PIN_PI_BOOT PD5 |
58 uint32_t ticks; | 59 uint32_t ticks; |
59 // remainder | 60 // remainder |
60 uint8_t rem; | 61 uint8_t rem; |
61 }; | 62 }; |
62 | 63 |
64 // OCR1A ticks COUNTER_DIV(=4) times a second, we divide it down. | |
65 static uint8_t counter_div = 0; | |
66 | |
63 // eeprom-settable parameters, default values defined here. | 67 // eeprom-settable parameters, default values defined here. |
64 // all timeouts should be a multiple of TICK | 68 // all timeouts should be a multiple of TICK |
65 static uint32_t watchdog_long_limit = (60L*60*24); | 69 static uint32_t watchdog_long_limit = (60L*60*24); // 6 hours |
66 static uint32_t watchdog_short_limit = 0; | 70 static uint32_t watchdog_short_limit = 0; |
67 static uint32_t newboot_limit = 60*10; | 71 static uint32_t newboot_limit = 60*10; // 10 minutes |
68 | 72 |
69 // avr proves itself | 73 // avr proves itself |
70 static uint8_t avr_keys[NKEYS][KEYLEN] = {{0}}; | 74 static uint8_t avr_keys[NKEYS][KEYLEN] = {{0}}; |
71 | 75 |
72 // ---- Atomic guards required accessing these variables | 76 // ---- Atomic guards required accessing these variables |
86 static uint8_t watchdog_long_hit; | 90 static uint8_t watchdog_long_hit; |
87 static uint8_t watchdog_short_hit; | 91 static uint8_t watchdog_short_hit; |
88 static uint8_t newboot_hit; | 92 static uint8_t newboot_hit; |
89 static uint8_t oneshot_hit; | 93 static uint8_t oneshot_hit; |
90 | 94 |
95 // flips between 0 and 1 each watchdog_long_hit, so eventually a | |
96 // working firmware should boot. set back to 0 for each 'alive' | |
97 // command | |
98 static uint8_t long_reboot_mode = 0; | |
99 | |
91 static uint8_t readpos; | 100 static uint8_t readpos; |
92 static char readbuf[50]; | 101 static char readbuf[50]; |
93 static uint8_t have_cmd; | 102 static uint8_t have_cmd; |
94 | 103 |
95 int uart_putchar(char c, FILE *stream); | 104 int uart_putchar(char c, FILE *stream); |
129 wdt_reset(); | 138 wdt_reset(); |
130 MCUSR &= ~_BV(WDRF); | 139 MCUSR &= ~_BV(WDRF); |
131 WDTCSR |= _BV(WDCE) | _BV(WDE); | 140 WDTCSR |= _BV(WDCE) | _BV(WDE); |
132 WDTCSR = 0; | 141 WDTCSR = 0; |
133 | 142 |
134 // set to 8S, in case sha1 is slow etc. | 143 // set to 8 seconds, in case sha1 is slow etc. |
135 wdt_enable(WDTO_8S); | 144 wdt_enable(WDTO_8S); |
136 | 145 |
137 // Set clock to 2mhz | 146 // Set scaler to /1, -> clock to 8mhz |
138 CLKPR = _BV(CLKPCE); | 147 CLKPR = _BV(CLKPCE); |
139 CLKPR = _BV(CLKPS1); | 148 CLKPR = 0; |
140 | 149 |
141 // enable pullups | 150 // enable pullups |
142 // XXX matt pihelp | 151 // XXX matt pihelp |
143 //PORTB = 0xff; // XXX change when using SPI | 152 //PORTB = 0xff; // XXX change when using SPI |
144 //PORTD = 0xff; | 153 //PORTD = 0xff; |
145 //PORTC = 0xff; | 154 //PORTC = 0xff; |
146 | 155 |
147 // 3.3v power for bluetooth and SD | 156 // 3.3v power for bluetooth and SD |
148 DDR_LED |= _BV(PIN_LED); | 157 //DDR_LED |= _BV(PIN_LED); |
149 | 158 |
150 #if 0 | 159 #if 0 |
151 // set pullup | 160 // set pullup |
152 PORTD |= _BV(PD2); | 161 PORTD |= _BV(PD2); |
153 // INT0 setup | 162 // INT0 setup |
264 newboot_count = newboot_limit; | 273 newboot_count = newboot_limit; |
265 } | 274 } |
266 printf_P(PSTR("newboot for %d secs"), newboot_limit); | 275 printf_P(PSTR("newboot for %d secs"), newboot_limit); |
267 } | 276 } |
268 | 277 |
278 static void | |
279 cmd_oldboot() | |
280 { | |
281 set_pi_boot_normal(0); | |
282 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) | |
283 { | |
284 newboot_count = 0; | |
285 } | |
286 printf_P(PSTR("back to old boot\n")); | |
287 } | |
269 | 288 |
270 | 289 |
271 static void | 290 static void |
272 cmd_get_params() | 291 cmd_get_params() |
273 { | 292 { |
481 uint32_t new_delay = strtoul(params, NULL, 10); | 500 uint32_t new_delay = strtoul(params, NULL, 10); |
482 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) | 501 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) |
483 { | 502 { |
484 oneshot_count = new_delay; | 503 oneshot_count = new_delay; |
485 } | 504 } |
486 printf_P(PSTR("oneshot delay %lu\n"), new_delay); | 505 printf_P(PSTR("oneshot new delay %lu\n"), new_delay); |
487 } | 506 } |
488 | 507 |
489 static void | 508 static void |
490 load_params() | 509 load_params() |
491 { | 510 { |
500 | 519 |
501 eeprom_read(avr_keys, avr_keys); | 520 eeprom_read(avr_keys, avr_keys); |
502 } | 521 } |
503 | 522 |
504 static void | 523 static void |
524 cmd_alive() | |
525 { | |
526 printf_P(PSTR("Ah, good.\n")); | |
527 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) | |
528 { | |
529 watchdog_long_count = 0; | |
530 watchdog_short_count = 0; | |
531 } | |
532 long_reboot_mode = 0; | |
533 } | |
534 | |
535 static void | |
505 cmd_vcc() | 536 cmd_vcc() |
506 { | 537 { |
507 uint16_t vcc = adc_vcc(); | 538 uint16_t vcc = adc_vcc(); |
508 printf_P(PSTR("vcc: %u mV\n"), vcc); | 539 printf_P(PSTR("vcc: %u mV\n"), vcc); |
509 } | 540 } |
510 | 541 |
511 static void | 542 static void |
512 read_handler() | 543 read_handler() |
513 { | 544 { |
545 // TODO: make this an array, print automatic help | |
514 if (strcmp_P(readbuf, PSTR("get_params")) == 0) | 546 if (strcmp_P(readbuf, PSTR("get_params")) == 0) |
515 { | 547 { |
516 cmd_get_params(); | 548 cmd_get_params(); |
517 } | 549 } |
518 else if (strncmp_P(readbuf, PSTR("set_params "), 11) == 0) | 550 else if (strncmp_P(readbuf, PSTR("set_params "), 11) == 0) |
533 } | 565 } |
534 else if (strncmp_P(readbuf, PSTR("decrypt "), 8) == 0) | 566 else if (strncmp_P(readbuf, PSTR("decrypt "), 8) == 0) |
535 { | 567 { |
536 cmd_decrypt(&readbuf[8]); | 568 cmd_decrypt(&readbuf[8]); |
537 } | 569 } |
570 else if (strcmp_P(readbuf, PSTR("alive")) == 0) | |
571 { | |
572 cmd_alive(); | |
573 } | |
538 else if (strcmp_P(readbuf, PSTR("vcc")) == 0) | 574 else if (strcmp_P(readbuf, PSTR("vcc")) == 0) |
539 { | 575 { |
540 cmd_vcc(); | 576 cmd_vcc(); |
541 } | 577 } |
542 else if (strcmp_P(readbuf, PSTR("reset")) == 0) | 578 else if (strcmp_P(readbuf, PSTR("reset")) == 0) |
544 cmd_reset(); | 580 cmd_reset(); |
545 } | 581 } |
546 else if (strcmp_P(readbuf, PSTR("newboot")) == 0) | 582 else if (strcmp_P(readbuf, PSTR("newboot")) == 0) |
547 { | 583 { |
548 cmd_newboot(); | 584 cmd_newboot(); |
585 } | |
586 else if (strcmp_P(readbuf, PSTR("oldboot")) == 0) | |
587 { | |
588 cmd_oldboot(); | |
549 } | 589 } |
550 else | 590 else |
551 { | 591 { |
552 printf_P(PSTR("Bad command '%s'\n"), readbuf); | 592 printf_P(PSTR("Bad command '%s'\n"), readbuf); |
553 } | 593 } |
587 } | 627 } |
588 | 628 |
589 ISR(TIMER1_COMPA_vect) | 629 ISR(TIMER1_COMPA_vect) |
590 { | 630 { |
591 TCNT1 = 0; | 631 TCNT1 = 0; |
632 counter_div++; | |
633 if (counter_div < COUNTER_DIV) | |
634 { | |
635 return; | |
636 } | |
637 counter_div = 0; | |
592 | 638 |
593 clock_epoch += TICK; | 639 clock_epoch += TICK; |
594 | 640 |
595 // watchdogs count up, continuous | 641 // watchdogs count up, continuous |
596 if (watchdog_long_limit > 0) { | 642 if (watchdog_long_limit > 0) { |
704 } | 750 } |
705 | 751 |
706 static void | 752 static void |
707 check_flags() | 753 check_flags() |
708 { | 754 { |
755 if (watchdog_long_hit) | |
756 { | |
757 // alternate between booting normal and emergency | |
758 if (long_reboot_mode) | |
759 { | |
760 cmd_newboot(); | |
761 } | |
762 long_reboot_mode ^= 1; | |
763 } | |
764 | |
709 if (watchdog_long_hit | 765 if (watchdog_long_hit |
710 || watchdog_short_hit | 766 || watchdog_short_hit |
711 || oneshot_hit) | 767 || oneshot_hit) |
712 { | 768 { |
713 printf_P(PSTR("Rebooting! long %d, short %d, oneshot %d\n"), | 769 printf_P(PSTR("Rebooting! long %d, short %d, oneshot %d\n"), |
777 printf_P(PSTR("Bad interrupt\n")); | 833 printf_P(PSTR("Bad interrupt\n")); |
778 } | 834 } |
779 | 835 |
780 int main(void) | 836 int main(void) |
781 { | 837 { |
838 _Static_assert(F_CPU % 2000000 == 0, "F_CPU is a multiple of 2mhz for counter division"); | |
839 | |
782 setup_chip(); | 840 setup_chip(); |
783 blink(); | 841 blink(); |
784 | 842 |
785 stdout = &mystdout; | 843 stdout = &mystdout; |
786 uart_on(); | 844 uart_on(); |