comparison main.c @ 17:21717153e0f1

change clock to 4915200 improve argument parser
author Matt Johnston <matt@ucc.asn.au>
date Thu, 13 Jun 2013 20:42:54 +0800
parents 8b1aeff120e9
children 021e6e0006f4
comparison
equal deleted inserted replaced
16:8b1aeff120e9 17:21717153e0f1
26 26
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 (F_CPU/256) // == 19200 for 4915200mhz
32 #define COUNTER_DIV (F_CPU / 2000000)
33 #define NKEYS 10 32 #define NKEYS 10
34 #define HMACLEN 20 33 #define HMACLEN 20
35 #define AESLEN 16 34 #define AESLEN 16
36 #define KEYLEN HMACLEN 35 #define KEYLEN HMACLEN
37 36
58 { 57 {
59 uint32_t ticks; 58 uint32_t ticks;
60 // remainder 59 // remainder
61 uint8_t rem; 60 uint8_t rem;
62 }; 61 };
63
64 // OCR1A ticks COUNTER_DIV(=4) times a second, we divide it down.
65 static uint8_t counter_div = 0;
66 62
67 #define WATCHDOG_LONG_MIN (60L*40) // 40 mins 63 #define WATCHDOG_LONG_MIN (60L*40) // 40 mins
68 #define WATCHDOG_LONG_MAX (60L*60*72) // 72 hours 64 #define WATCHDOG_LONG_MAX (60L*60*72) // 72 hours
69 #define WATCHDOG_LONG_DEFAULT (60L*60*6) // 6 hours 65 #define WATCHDOG_LONG_DEFAULT (60L*60*6) // 6 hours
70 66
114 int uart_putchar(char c, FILE *stream); 110 int uart_putchar(char c, FILE *stream);
115 static void long_delay(int ms); 111 static void long_delay(int ms);
116 static void blink(); 112 static void blink();
117 static uint16_t adc_vcc(); 113 static uint16_t adc_vcc();
118 static void set_pi_boot_normal(uint8_t normal); 114 static void set_pi_boot_normal(uint8_t normal);
115
119 116
120 static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, 117 static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL,
121 _FDEV_SETUP_WRITE); 118 _FDEV_SETUP_WRITE);
122 119
123 // thanks to http://projectgus.com/2010/07/eeprom-access-with-arduino/ 120 // thanks to http://projectgus.com/2010/07/eeprom-access-with-arduino/
233 UCSR0B = _BV(RXCIE0) | _BV(RXEN0) | _BV(TXEN0); 230 UCSR0B = _BV(RXCIE0) | _BV(RXEN0) | _BV(TXEN0);
234 //8N1 231 //8N1
235 UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); 232 UCSR0C = _BV(UCSZ01) | _BV(UCSZ00);
236 } 233 }
237 234
238 static void
239 uart_off()
240 {
241 // Turn off interrupts and disable tx/rx
242 UCSR0B = 0;
243
244 // Power reduction register
245 PRR |= _BV(PRUSART0);
246 }
247
248 int 235 int
249 uart_putchar(char c, FILE *stream) 236 uart_putchar(char c, FILE *stream)
250 { 237 {
251 // XXX could perhaps sleep in the loop for power. 238 // XXX could perhaps sleep in the loop for power.
252 if (c == '\n') 239 if (c == '\n')
542 if (newboot_limit < NEWBOOT_MIN || newboot_limit > NEWBOOT_MAX) 529 if (newboot_limit < NEWBOOT_MIN || newboot_limit > NEWBOOT_MAX)
543 { 530 {
544 newboot_limit = NEWBOOT_DEFAULT; 531 newboot_limit = NEWBOOT_DEFAULT;
545 } 532 }
546 533
547 _Static_assert(NEWBOOT_MAX < WATCHDOG_LONG_MIN, "newboot max shorter than watchdog min");
548 534
549 eeprom_read(avr_keys, avr_keys); 535 eeprom_read(avr_keys, avr_keys);
550 } 536 }
551 537
552 static void 538 static void
569 } 555 }
570 556
571 static void 557 static void
572 read_handler() 558 read_handler()
573 { 559 {
560 #define LOCAL_PSTR(x) const static char x ## _str[] PROGMEM = #x;
561 #define LOCAL_HELP(x, d) const static char x ## _help[] PROGMEM = d;
562
563 LOCAL_PSTR(get_params);
564 LOCAL_PSTR(set_params);
565 LOCAL_PSTR(set_key);
566 LOCAL_PSTR(oneshot);
567 LOCAL_PSTR(hmac);
568 LOCAL_PSTR(decrypt);
569 LOCAL_PSTR(alive);
570 LOCAL_PSTR(vcc);
571 LOCAL_PSTR(reset);
572 LOCAL_PSTR(newboot);
573 LOCAL_PSTR(oldboot);
574 LOCAL_HELP(set_params, "<long_limit> <short_limit> <newboot_limit>");
575 LOCAL_HELP(set_key, "20_byte_hex>");
576 LOCAL_HELP(timeout, "<timeout>");
577 LOCAL_HELP(hmac, "<key_index> <20_byte_hex_data>");
578 LOCAL_HELP(decrypt, "<key_index> <20_byte_hmac|16_byte_aes_block>");
579
580 static const struct handler {
581 PGM_P name;
582 void(*cmd)(const char *param);
583 // existence of arg_help indicates if the cmd takes a parameter.
584 PGM_P arg_help;
585 } handlers[11] PROGMEM =
586 {
587 {get_params_str, cmd_get_params, NULL},
588 {set_params_str, cmd_set_params, set_params_help},
589 {set_key_str, cmd_set_avr_key, set_key_help},
590 {oneshot_str, cmd_oneshot_reboot, timeout_help},
591 {hmac_str, cmd_hmac, hmac_help},
592 {decrypt_str, cmd_decrypt, decrypt_help},
593 {alive_str, cmd_alive, NULL},
594 {vcc_str, cmd_vcc, NULL},
595 {reset_str, cmd_reset, NULL},
596 {newboot_str, cmd_newboot, NULL},
597 {oldboot_str, cmd_oldboot, NULL},
598 };
599
600 if (readbuf[0] == '\0')
601 {
602 return;
603 }
604
605 if (strcmp_P(readbuf, PSTR("help")))
606 {
607 printf_P(PSTR("Commands:---\n"));
608 for (int i = 0; i < sizeof(handlers) / sizeof(handlers[0]); i++)
609 {
610 struct handler h;
611 memcpy_P(&h, &handlers[i], sizeof(h));
612 printf_P(h.name);
613 if (h.arg_help)
614 {
615 putchar(' ');
616 printf_P(h.arg_help);
617 }
618 putchar('\n');
619 };
620 printf_P(PSTR("---\n"));
621 }
622
623 for (int i = 0; i < sizeof(handlers) / sizeof(handlers[0]); i++)
624 {
625 struct handler h;
626 memcpy_P(&h, &handlers[i], sizeof(h));
627
628 const int h_len = strlen_P(h.name);
629 if (strncmp_P(readbuf, h.name, h_len) == 0)
630 {
631 if (h.arg_help)
632 {
633 if (readbuf[h_len] == ' ')
634 {
635 void(*cmd)(const char*) = (void*)pgm_read_word(h.cmd);
636 cmd(&readbuf[h_len+1]);
637 return;
638 }
639 }
640 else
641 {
642 if (readbuf[h_len] == '\0')
643 {
644 void(*void_cmd)() = (void*)pgm_read_word(h.cmd);
645 void_cmd();
646 return;
647 }
648 }
649 }
650 }
651
652 #if 0
574 // TODO: make this an array, print automatic help 653 // TODO: make this an array, print automatic help
575 if (strcmp_P(readbuf, PSTR("get_params")) == 0) 654 if (strcmp_P(readbuf, PSTR("get_params")) == 0)
576 { 655 {
577 cmd_get_params(); 656 cmd_get_params();
578 } 657 }
615 else if (strcmp_P(readbuf, PSTR("oldboot")) == 0) 694 else if (strcmp_P(readbuf, PSTR("oldboot")) == 0)
616 { 695 {
617 cmd_oldboot(); 696 cmd_oldboot();
618 } 697 }
619 else 698 else
620 { 699
621 printf_P(PSTR("Bad command '%s'\n"), readbuf); 700 #endif
622 } 701
702 printf_P(PSTR("Bad command '%s'\n"), readbuf);
623 } 703 }
624 704
625 ISR(INT0_vect) 705 ISR(INT0_vect)
626 { 706 {
627 blink(); 707 blink();
656 } 736 }
657 737
658 ISR(TIMER1_COMPA_vect) 738 ISR(TIMER1_COMPA_vect)
659 { 739 {
660 TCNT1 = 0; 740 TCNT1 = 0;
661 counter_div++;
662 if (counter_div < COUNTER_DIV)
663 {
664 return;
665 }
666 counter_div = 0;
667 741
668 clock_epoch += TICK; 742 clock_epoch += TICK;
669 743
670 // watchdogs count up, continuous 744 // watchdogs count up, continuous
671 if (watchdog_long_limit > 0) { 745 if (watchdog_long_limit > 0) {
862 printf_P(PSTR("Bad interrupt\n")); 936 printf_P(PSTR("Bad interrupt\n"));
863 } 937 }
864 938
865 int main(void) 939 int main(void)
866 { 940 {
867 _Static_assert(F_CPU % 2000000 == 0, "F_CPU is a multiple of 2mhz for counter division"); 941 _Static_assert(F_CPU % 256 == 0, "clock prescaler remainder 0");
942 _Static_assert(NEWBOOT_MAX < WATCHDOG_LONG_MIN, "newboot max shorter than watchdog min");
868 943
869 setup_chip(); 944 setup_chip();
870 blink(); 945 blink();
871 946
872 stdout = &mystdout; 947 stdout = &mystdout;