diff 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
line wrap: on
line diff
--- a/main.c	Thu Jun 13 00:22:37 2013 +0800
+++ b/main.c	Thu Jun 13 20:42:54 2013 +0800
@@ -28,8 +28,7 @@
 // to be a multiple.
 
 #define TICK 1
-#define SLEEP_COMPARE (2000000/64)   // == 31250 exactly
-#define COUNTER_DIV (F_CPU / 2000000)
+#define SLEEP_COMPARE (F_CPU/256)   // == 19200 for 4915200mhz
 #define NKEYS 10
 #define HMACLEN 20
 #define AESLEN 16
@@ -61,9 +60,6 @@
     uint8_t rem;
 };
 
-// OCR1A ticks COUNTER_DIV(=4) times a second, we divide it down.
-static uint8_t counter_div = 0;
-
 #define WATCHDOG_LONG_MIN (60L*40) // 40 mins
 #define WATCHDOG_LONG_MAX (60L*60*72) // 72 hours
 #define WATCHDOG_LONG_DEFAULT (60L*60*6) // 6 hours
@@ -117,6 +113,7 @@
 static uint16_t adc_vcc();
 static void set_pi_boot_normal(uint8_t normal);
 
+
 static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL,
         _FDEV_SETUP_WRITE);
 
@@ -235,16 +232,6 @@
     UCSR0C = _BV(UCSZ01) | _BV(UCSZ00);
 }
 
-static void 
-uart_off()
-{
-    // Turn off interrupts and disable tx/rx
-    UCSR0B = 0;
-
-    // Power reduction register
-    PRR |= _BV(PRUSART0);
-}
-
 int 
 uart_putchar(char c, FILE *stream)
 {
@@ -544,7 +531,6 @@
     newboot_limit = NEWBOOT_DEFAULT;
    }
 
-   _Static_assert(NEWBOOT_MAX < WATCHDOG_LONG_MIN, "newboot max shorter than watchdog min");
 
    eeprom_read(avr_keys, avr_keys);
 }
@@ -571,6 +557,99 @@
 static void
 read_handler()
 {
+#define LOCAL_PSTR(x) const static char x ## _str[] PROGMEM = #x;
+#define LOCAL_HELP(x, d) const static char x ## _help[] PROGMEM = d;
+
+    LOCAL_PSTR(get_params);
+    LOCAL_PSTR(set_params);
+    LOCAL_PSTR(set_key);
+    LOCAL_PSTR(oneshot);
+    LOCAL_PSTR(hmac);
+    LOCAL_PSTR(decrypt);
+    LOCAL_PSTR(alive);
+    LOCAL_PSTR(vcc);
+    LOCAL_PSTR(reset);
+    LOCAL_PSTR(newboot);
+    LOCAL_PSTR(oldboot);
+    LOCAL_HELP(set_params, "<long_limit> <short_limit> <newboot_limit>");
+    LOCAL_HELP(set_key, "20_byte_hex>");
+    LOCAL_HELP(timeout, "<timeout>");
+    LOCAL_HELP(hmac, "<key_index> <20_byte_hex_data>");
+    LOCAL_HELP(decrypt, "<key_index> <20_byte_hmac|16_byte_aes_block>");
+
+    static const struct handler {
+        PGM_P name;
+        void(*cmd)(const char *param);
+        // existence of arg_help indicates if the cmd takes a parameter.
+        PGM_P arg_help;
+    } handlers[11] PROGMEM = 
+    {
+        {get_params_str, cmd_get_params, NULL},
+        {set_params_str, cmd_set_params, set_params_help},
+        {set_key_str, cmd_set_avr_key, set_key_help},
+        {oneshot_str, cmd_oneshot_reboot, timeout_help},
+        {hmac_str, cmd_hmac, hmac_help},
+        {decrypt_str, cmd_decrypt, decrypt_help},
+        {alive_str, cmd_alive, NULL},
+        {vcc_str, cmd_vcc, NULL},
+        {reset_str, cmd_reset, NULL},
+        {newboot_str, cmd_newboot, NULL},
+        {oldboot_str, cmd_oldboot, NULL},
+    };
+
+    if (readbuf[0] == '\0')
+    {
+        return;
+    }
+
+    if (strcmp_P(readbuf, PSTR("help")))
+    {
+        printf_P(PSTR("Commands:---\n"));
+        for (int i = 0; i < sizeof(handlers) / sizeof(handlers[0]); i++)
+        {
+            struct handler h;
+            memcpy_P(&h, &handlers[i], sizeof(h));
+            printf_P(h.name);
+            if (h.arg_help)
+            {
+                putchar(' ');
+                printf_P(h.arg_help);
+            }
+            putchar('\n');
+        };
+        printf_P(PSTR("---\n"));
+    }
+
+    for (int i = 0; i < sizeof(handlers) / sizeof(handlers[0]); i++)
+    {
+        struct handler h;
+        memcpy_P(&h, &handlers[i], sizeof(h));
+
+        const int h_len = strlen_P(h.name);
+        if (strncmp_P(readbuf, h.name, h_len) == 0)
+        {
+            if (h.arg_help)
+            {
+                if (readbuf[h_len] == ' ')
+                {
+                    void(*cmd)(const char*) = (void*)pgm_read_word(h.cmd);
+                    cmd(&readbuf[h_len+1]);
+                    return;
+                }
+            }
+            else 
+            {
+                if (readbuf[h_len] == '\0')
+                {
+                    void(*void_cmd)() = (void*)pgm_read_word(h.cmd);
+                    void_cmd();
+                    return;
+                }
+            }
+        }
+    }
+
+#if 0
     // TODO: make this an array, print automatic help
     if (strcmp_P(readbuf, PSTR("get_params")) == 0)
     {
@@ -617,9 +696,10 @@
         cmd_oldboot();
     }
     else
-    {
-        printf_P(PSTR("Bad command '%s'\n"), readbuf);
-    }
+
+    #endif
+
+    printf_P(PSTR("Bad command '%s'\n"), readbuf);
 }
 
 ISR(INT0_vect)
@@ -658,12 +738,6 @@
 ISR(TIMER1_COMPA_vect)
 {
     TCNT1 = 0;
-    counter_div++;
-    if (counter_div < COUNTER_DIV)
-    {
-        return;
-    }
-    counter_div = 0;
 
     clock_epoch += TICK;
 
@@ -864,7 +938,8 @@
 
 int main(void)
 {
-    _Static_assert(F_CPU % 2000000 == 0, "F_CPU is a multiple of 2mhz for counter division");
+    _Static_assert(F_CPU % 256 == 0, "clock prescaler remainder 0");
+    _Static_assert(NEWBOOT_MAX < WATCHDOG_LONG_MIN, "newboot max shorter than watchdog min");
 
     setup_chip();
     blink();