diff main.c @ 20:bc48a1d17edf

near done
author Matt Johnston <matt@ucc.asn.au>
date Sun, 16 Jun 2013 13:04:09 +0800
parents 021e6e0006f4
children 83a0663c082f
line wrap: on
line diff
--- a/main.c	Thu Jun 13 23:44:59 2013 +0800
+++ b/main.c	Sun Jun 16 13:04:09 2013 +0800
@@ -19,7 +19,8 @@
 //#include "simple_ds18b20.h"
 //#include "onewire.h"
 
-LOCKBITS = (LB_MODE_3 & BLB0_MODE_4 & BLB1_MODE_4);
+// not set via bootloader
+//LOCKBITS = (LB_MODE_3 & BLB0_MODE_4 & BLB1_MODE_4);
 
 #define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
 #define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
@@ -34,8 +35,8 @@
 #define AESLEN 16
 #define KEYLEN HMACLEN
 
-#define BAUD 19200
-#define UBRR ((F_CPU)/8/(BAUD)-1)
+#define BAUD 38400
+#define UBRR ((F_CPU)/(16*(BAUD))-1)
 
 #define PORT_PI_BOOT PORTD
 #define DDR_PI_BOOT DDRD
@@ -57,7 +58,7 @@
 {
     uint32_t ticks;
     // remainder
-    uint8_t rem;
+    uint16_t rem;
 };
 
 #define WATCHDOG_LONG_MIN (60L*40) // 40 mins
@@ -109,7 +110,7 @@
 static uint8_t long_reboot_mode = 0;
 
 static uint8_t readpos;
-static char readbuf[50];
+static char readbuf[150];
 static uint8_t have_cmd;
 
 int uart_putchar(char c, FILE *stream);
@@ -117,6 +118,7 @@
 static void blink();
 static uint16_t adc_vcc();
 static uint16_t adc_5v(uint16_t vcc);
+static uint16_t adc_temp();
 static void set_pi_boot_normal(uint8_t normal);
 
 
@@ -147,12 +149,6 @@
 {
     cli();
 
-    // stop watchdog timer (might have been used to cause a reset)
-    wdt_reset();
-    MCUSR &= ~_BV(WDRF);
-    WDTCSR |= _BV(WDCE) | _BV(WDE);
-    WDTCSR = 0;
-
     // set to 8 seconds, in case sha1 is slow etc.
     wdt_enable(WDTO_8S);
 
@@ -211,8 +207,8 @@
     // systemclock/8
     TCCR1B = _BV(CS11);
 #else
-    // systemclock/64
-    TCCR1B = _BV(CS11) | _BV(CS10);
+    // systemclock/256
+    TCCR1B = _BV(CS12);
 #endif
     TCNT1 = 0;
     OCR1A = SLEEP_COMPARE;
@@ -265,8 +261,9 @@
     return (unsigned char)c;
 }
 
+static void cmd_reset() __attribute__ ((noreturn));
 static void
-cmd_reset()
+cmd_reset()  
 {
     printf_P(PSTR("reset\n"));
     _delay_ms(100);
@@ -283,7 +280,7 @@
     {
         newboot_count = newboot_limit;
     }
-    printf_P(PSTR("newboot for %d secs"), newboot_limit);
+    printf_P(PSTR("newboot for %d secs\n"), newboot_limit);
 }
 
 static void
@@ -299,9 +296,13 @@
 
 
 static void
-cmd_get_params()
+cmd_status()
 {
     uint32_t cur_watchdog_long, cur_watchdog_short, cur_newboot, cur_oneshot;
+    struct epoch_ticks t;
+
+    get_epoch_ticks(&t);
+
     ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
     {
         cur_watchdog_long = watchdog_long_count;
@@ -310,14 +311,18 @@
         cur_oneshot = oneshot_count;
     }
 
-    printf_P(PSTR("limit (count) : watchdog_long %lu (%lu) watchdog_short %lu (%lu) newboot %lu (%lu) oneshot (%lu)\n"),
-        watchdog_long_limit,
-        cur_watchdog_long,
-        watchdog_short_limit,
-        cur_watchdog_short,
-        newboot_limit,
-        cur_newboot,
-        cur_oneshot);
+    printf_P(PSTR("limit (current)\n"
+        "watchdog_long %lu (%lu) watchdog newboot mode %d\n"
+        "watchdog_short %lu (%lu)\n"
+        "newboot %lu (%lu)\n"
+        "oneshot (%lu)\n"
+        "uptime %lu rem %u\n"
+        ),
+        watchdog_long_limit, cur_watchdog_long, long_reboot_mode,
+        watchdog_short_limit, cur_watchdog_short,
+        newboot_limit, cur_newboot,
+        cur_oneshot,
+        t.ticks, t.rem);
 }
 
 static void
@@ -403,7 +408,8 @@
 {
     // "N HEXKEY"
     if (strlen(params) != bytes_len*2 + 2) {
-        printf_P(PSTR("Wrong length key\n"));
+        printf_P(PSTR("Wrong length key. wanted %d, got %d, '%s'\n"),
+            bytes_len*2+2, strlen(params), params);
         return -1;
     }
 
@@ -440,6 +446,9 @@
 #ifndef SIM_DEBUG
     eeprom_write(avr_keys, avr_keys);
 #endif
+    printf_P(PSTR("Set key %d: "), key_index);
+    printhex(new_key, sizeof(new_key), stdout);
+    putchar('\n');
 }
 
 static void
@@ -461,7 +470,7 @@
     hmac_sha1(outdata, avr_keys[key_index], KEYLEN*8, indata, sizeof(indata)*8);
     printf_P(PSTR("HMAC: "));
     printhex(outdata, HMACLEN, stdout);
-    fputc('\n', stdout);
+    putchar('\n');
 }
 
 static void
@@ -496,7 +505,7 @@
 
     printf_P(PSTR("DECRYPTED: "));
     printhex(output, AESLEN, stdout);
-    fputc('\n', stdout);
+    putchar('\n');
 }
 
 static void
@@ -568,13 +577,51 @@
     printf_P(PSTR("vcc: %u mV\n5v: %u mV\n"), vcc, v5);
 }
 
+void(*bootloader)() __attribute__ ((noreturn)) = (void*)0x7e00;
+
+#if 0
+#ifndef PROG_PASSWORD
+#define PROG_PASSWORD "Y2vvjxO5"
+#endif
+
+static void
+cmd_prog(const char* arg)
+{
+    if (strcmp(arg, PROG_PASSWORD) != 0)
+    {
+        printf_P(PSTR("Bad prog password\n"));
+        return;
+    }
+
+    // disable wdt
+    wdt_disable();
+
+    // disable interrupts
+    TIMSK0 = 0;
+    TIMSK1 = 0;
+    TIMSK2 = 0;
+    EIMSK = 0;
+    PCMSK0 = 0;
+    PCMSK1 = 0;
+    PCMSK2 = 0;
+    ACSR &= ~_BV(ACIE);
+    ADCSRA &= ~_BV(ADIE);
+    UCSR0B &= ~_BV(RXCIE0);
+    UCSR0B &= _BV(TXCIE0);
+    // doesn't do TWI, other uart, probably others
+
+    _delay_ms(20);
+
+    bootloader();
+}
+#endif
+
 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);
@@ -585,6 +632,7 @@
     LOCAL_PSTR(reset);
     LOCAL_PSTR(newboot);
     LOCAL_PSTR(oldboot);
+    LOCAL_PSTR(status);
     LOCAL_HELP(set_params, "<long_limit> <short_limit> <newboot_limit>");
     LOCAL_HELP(set_key, "20_byte_hex>");
     LOCAL_HELP(oneshot, "<timeout>");
@@ -596,19 +644,19 @@
         void(*cmd)(const char *param);
         // existence of arg_help indicates if the cmd takes a parameter.
         PGM_P arg_help;
-    } handlers[11] PROGMEM = 
+    } handlers[] PROGMEM = 
     {
-        {get_params_str, cmd_get_params, NULL},
+        {alive_str, cmd_alive, NULL},
+        {newboot_str, cmd_newboot, NULL},
+        {oldboot_str, cmd_oldboot, NULL},
+        {oneshot_str, cmd_oneshot_reboot, oneshot_help},
+        {status_str, cmd_status, NULL},
+        {hmac_str, cmd_hmac, hmac_help},
+        {decrypt_str, cmd_decrypt, decrypt_help},
         {set_params_str, cmd_set_params, set_params_help},
         {set_key_str, cmd_set_avr_key, set_key_help},
-        {oneshot_str, cmd_oneshot_reboot, oneshot_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')
@@ -973,10 +1021,19 @@
     printf_P(PSTR("Bad interrupt\n"));
 }
 
+// disable watchdog on boot
+void wdt_init(void) __attribute__((naked)) __attribute__((section(".init3")));
+void wdt_init(void)
+{
+    MCUSR = 0;
+    wdt_disable();
+}
+
 int main(void)
 {
     _Static_assert(F_CPU % 256 == 0, "clock prescaler remainder 0");
     _Static_assert(NEWBOOT_MAX < WATCHDOG_LONG_MIN, "newboot max shorter than watchdog min");
+    _Static_assert((F_CPU)%(16*(BAUD)) == 0, "baud rate good multiple");
 
     setup_chip();
     blink();
@@ -984,7 +1041,8 @@
     stdout = &mystdout;
     uart_on();
 
-    printf_P(PSTR("Pi Watchdog\nMatt Johnston [email protected]"));
+    long_delay(500);
+    printf_P(PSTR("Pi Watchdog\nMatt Johnston [email protected]\n"));
 
     set_pi_boot_normal(0);