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();