# HG changeset patch # User Matt Johnston # Date 1371359049 -28800 # Node ID bc48a1d17edff5b377426086dd39538be505c102 # Parent 021e6e0006f4daa2f37b22430c9f121f49256241 near done diff -r 021e6e0006f4 -r bc48a1d17edf Makefile --- a/Makefile Thu Jun 13 23:44:59 2013 +0800 +++ b/Makefile Sun Jun 16 13:04:09 2013 +0800 @@ -6,7 +6,7 @@ # This is a prototype Makefile. Modify it according to your needs. # You should at least check the settings for # DEVICE ....... The AVR device you compile for -# CLOCK ........ Target AVR clock rate in Hertz +# CLOCK ........ Target AVR CLOCK rate in Hertz # OBJECTS ...... The object files created from your source files. This list is # usually the same as the list of source files with suffix ".o". # PROGRAMMER ... Options to avrdude which define the hardware you use for @@ -19,7 +19,7 @@ DEVICE = atmega328 PROGDEVICE = atmega328p -CLOCK = 4915200 +CLOCK = 4915200L PROGRAMMER = #-c stk500v2 -P avrdoper PROGRAMMER = -c stk500 -P ~/dev/stk500 -p $(PROGDEVICE) -B 2 SOURCE_1WIRE = onewire.c simple_ds18b20.c crc8.c @@ -82,7 +82,7 @@ $(COMPILE) -S $< -o $@ flash: all - $(AVRDUDE) -U flash:w:main.hex:i + $(AVRDUDE) -D -U flash:w:main.hex:i checkprog: $(AVRDUDE) -v diff -r 021e6e0006f4 -r bc48a1d17edf main.c --- 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, " "); LOCAL_HELP(set_key, "20_byte_hex>"); LOCAL_HELP(oneshot, ""); @@ -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 matt@ucc.asn.au")); + long_delay(500); + printf_P(PSTR("Pi Watchdog\nMatt Johnston matt@ucc.asn.au\n")); set_pi_boot_normal(0);