Mercurial > pihelp
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; |