comparison main.c @ 26:292cd17de2a4

merge
author Matt Johnston <matt@ucc.asn.au>
date Wed, 26 Jun 2013 22:00:08 +0800
parents 534009795508 a55d7c2440fd
children ce5097eacf2f
comparison
equal deleted inserted replaced
25:534009795508 26:292cd17de2a4
23 #include "sd_raw_config.h" 23 #include "sd_raw_config.h"
24 24
25 //#include "simple_ds18b20.h" 25 //#include "simple_ds18b20.h"
26 //#include "onewire.h" 26 //#include "onewire.h"
27 27
28 LOCKBITS = (LB_MODE_3 & BLB0_MODE_4 & BLB1_MODE_4); 28 // not set via bootloader
29 //LOCKBITS = (LB_MODE_3 & BLB0_MODE_4 & BLB1_MODE_4);
29 30
30 #define MIN(X,Y) ((X) < (Y) ? (X) : (Y)) 31 #define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
31 #define MAX(X,Y) ((X) > (Y) ? (X) : (Y)) 32 #define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
32 33
33 // TICK should be 8 or less (8 untested). all timers need 34 // TICK should be 8 or less (8 untested). all timers need
38 #define NKEYS 10 39 #define NKEYS 10
39 #define HMACLEN 20 40 #define HMACLEN 20
40 #define AESLEN 16 41 #define AESLEN 16
41 #define KEYLEN HMACLEN 42 #define KEYLEN HMACLEN
42 43
43 #define BAUD 19200 44 #define BAUD 38400
44 #define UBRR ((F_CPU)/8/(BAUD)-1) 45 #define UBRR ((F_CPU)/(16*(BAUD))-1)
45 46
46 #define PORT_PI_BOOT PORTD 47 #define PORT_PI_BOOT PORTD
47 #define DDR_PI_BOOT DDRD 48 #define DDR_PI_BOOT DDRD
48 #define PIN_PI_BOOT PD5 49 #define PIN_PI_BOOT PD5
49 50
61 // for 1/32 second accuracy 62 // for 1/32 second accuracy
62 struct epoch_ticks 63 struct epoch_ticks
63 { 64 {
64 uint32_t ticks; 65 uint32_t ticks;
65 // remainder 66 // remainder
66 uint8_t rem; 67 uint16_t rem;
67 }; 68 };
68 69
69 #define WATCHDOG_LONG_MIN (60L*40) // 40 mins 70 #define WATCHDOG_LONG_MIN (60L*40) // 40 mins
70 #define WATCHDOG_LONG_MAX (60L*60*72) // 72 hours 71 #define WATCHDOG_LONG_MAX (60L*60*72) // 72 hours
71 #define WATCHDOG_LONG_DEFAULT (60L*60*6) // 6 hours 72 #define WATCHDOG_LONG_DEFAULT (60L*60*6) // 6 hours
107 static uint8_t watchdog_short_hit; 108 static uint8_t watchdog_short_hit;
108 static uint8_t newboot_hit; 109 static uint8_t newboot_hit;
109 static uint8_t oneshot_hit; 110 static uint8_t oneshot_hit;
110 static uint8_t reboot_hit; 111 static uint8_t reboot_hit;
111 112
113 // informational for status messages
114 static uint8_t boot_normal_status;
115
112 // flips between 0 and 1 each watchdog_long_hit, so eventually a 116 // flips between 0 and 1 each watchdog_long_hit, so eventually a
113 // working firmware should boot. set back to 0 for each 'alive' 117 // working firmware should boot. set back to 0 for each 'alive'
114 // command 118 // command
115 static uint8_t long_reboot_mode = 0; 119 static uint8_t long_reboot_mode = 0;
116 120
117 static uint8_t readpos; 121 static uint8_t readpos;
118 static char readbuf[50]; 122 static char readbuf[150];
119 static uint8_t have_cmd; 123 static uint8_t have_cmd;
120 124
121 int uart_putchar(char c, FILE *stream); 125 int uart_putchar(char c, FILE *stream);
122 static void long_delay(int ms); 126 static void long_delay(uint16_t ms);
123 static void blink(); 127 static void blink();
124 static uint16_t adc_vcc(); 128 static uint16_t adc_vcc();
125 static uint16_t adc_5v(uint16_t vcc); 129 static uint16_t adc_5v(uint16_t vcc);
130 static uint16_t adc_temp();
126 static void set_pi_boot_normal(uint8_t normal); 131 static void set_pi_boot_normal(uint8_t normal);
127 132
128 133
129 static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, 134 static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL,
130 _FDEV_SETUP_WRITE); 135 _FDEV_SETUP_WRITE);
150 // Very first setup 155 // Very first setup
151 static void 156 static void
152 setup_chip() 157 setup_chip()
153 { 158 {
154 cli(); 159 cli();
155
156 // stop watchdog timer (might have been used to cause a reset)
157 wdt_reset();
158 MCUSR &= ~_BV(WDRF);
159 WDTCSR |= _BV(WDCE) | _BV(WDE);
160 WDTCSR = 0;
161 160
162 // set to 8 seconds, in case sha1 is slow etc. 161 // set to 8 seconds, in case sha1 is slow etc.
163 wdt_enable(WDTO_8S); 162 wdt_enable(WDTO_8S);
164 163
165 // Set scaler to /1, -> clock to 8mhz 164 // Set scaler to /1, -> clock to 8mhz
215 TCCR1A = _BV(COM1A0); 214 TCCR1A = _BV(COM1A0);
216 #ifdef SIM_DEBUG 215 #ifdef SIM_DEBUG
217 // systemclock/8 216 // systemclock/8
218 TCCR1B = _BV(CS11); 217 TCCR1B = _BV(CS11);
219 #else 218 #else
220 // systemclock/64 219 // systemclock/256
221 TCCR1B = _BV(CS11) | _BV(CS10); 220 TCCR1B = _BV(CS12);
222 #endif 221 #endif
223 TCNT1 = 0; 222 TCNT1 = 0;
224 OCR1A = SLEEP_COMPARE; 223 OCR1A = SLEEP_COMPARE;
225 // interrupt 224 // interrupt
226 TIMSK1 = _BV(OCIE1A); 225 TIMSK1 = _BV(OCIE1A);
319 c ^= buf[0]; 318 c ^= buf[0];
320 } 319 }
321 printf("total %d\n", c); 320 printf("total %d\n", c);
322 } 321 }
323 322
324 static void 323 static void cmd_reset() __attribute__ ((noreturn));
325 cmd_reset() 324 static void
325 cmd_reset()
326 { 326 {
327 printf_P(PSTR("reset\n")); 327 printf_P(PSTR("reset\n"));
328 _delay_ms(100); 328 _delay_ms(100);
329 cli(); // disable interrupts 329 cli(); // disable interrupts
330 wdt_enable(WDTO_15MS); // enable watchdog 330 wdt_enable(WDTO_15MS); // enable watchdog
337 set_pi_boot_normal(1); 337 set_pi_boot_normal(1);
338 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) 338 ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
339 { 339 {
340 newboot_count = newboot_limit; 340 newboot_count = newboot_limit;
341 } 341 }
342 printf_P(PSTR("newboot for %d secs"), newboot_limit); 342 printf_P(PSTR("newboot for %d secs\n"), newboot_limit);
343 } 343 }
344 344
345 static void 345 static void
346 cmd_oldboot() 346 cmd_oldboot()
347 { 347 {
353 printf_P(PSTR("back to old boot\n")); 353 printf_P(PSTR("back to old boot\n"));
354 } 354 }
355 355
356 356
357 static void 357 static void
358 cmd_get_params() 358 cmd_status()
359 { 359 {
360 uint32_t cur_watchdog_long, cur_watchdog_short, cur_newboot, cur_oneshot; 360 uint32_t cur_watchdog_long, cur_watchdog_short, cur_newboot, cur_oneshot;
361 struct epoch_ticks t;
362
363 get_epoch_ticks(&t);
364
361 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) 365 ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
362 { 366 {
363 cur_watchdog_long = watchdog_long_count; 367 cur_watchdog_long = watchdog_long_count;
364 cur_watchdog_short = watchdog_short_count; 368 cur_watchdog_short = watchdog_short_count;
365 cur_newboot = newboot_count; 369 cur_newboot = newboot_count;
366 cur_oneshot = oneshot_count; 370 cur_oneshot = oneshot_count;
367 } 371 }
368 372
369 printf_P(PSTR("limit (count) : watchdog_long %lu (%lu) watchdog_short %lu (%lu) newboot %lu (%lu) oneshot (%lu)\n"), 373 printf_P(PSTR("limit (current)\n"
370 watchdog_long_limit, 374 "watchdog_long %lu (%lu) watchdog newboot mode %d\n"
371 cur_watchdog_long, 375 "watchdog_short %lu (%lu)\n"
372 watchdog_short_limit, 376 "newboot %lu (%lu)\n"
373 cur_watchdog_short, 377 "oneshot (%lu)\n"
374 newboot_limit, 378 "uptime %lu rem %u\n"
375 cur_newboot, 379 "boot normal %hhu\n"
376 cur_oneshot); 380 ),
381 watchdog_long_limit, cur_watchdog_long, long_reboot_mode,
382 watchdog_short_limit, cur_watchdog_short,
383 newboot_limit, cur_newboot,
384 cur_oneshot,
385 t.ticks, t.rem,
386 boot_normal_status);
377 } 387 }
378 388
379 static void 389 static void
380 cmd_set_params(const char *params) 390 cmd_set_params(const char *params)
381 { 391 {
457 parse_key(const char *params, uint8_t *key_index, uint8_t *bytes, 467 parse_key(const char *params, uint8_t *key_index, uint8_t *bytes,
458 uint8_t bytes_len) 468 uint8_t bytes_len)
459 { 469 {
460 // "N HEXKEY" 470 // "N HEXKEY"
461 if (strlen(params) != bytes_len*2 + 2) { 471 if (strlen(params) != bytes_len*2 + 2) {
462 printf_P(PSTR("Wrong length key\n")); 472 printf_P(PSTR("Wrong length key. wanted %d, got %d, '%s'\n"),
473 bytes_len*2+2, strlen(params), params);
463 return -1; 474 return -1;
464 } 475 }
465 476
466 if (params[1] != ' ') 477 if (params[1] != ' ')
467 { 478 {
494 } 505 }
495 memcpy(avr_keys[key_index], new_key, sizeof(new_key)); 506 memcpy(avr_keys[key_index], new_key, sizeof(new_key));
496 #ifndef SIM_DEBUG 507 #ifndef SIM_DEBUG
497 eeprom_write(avr_keys, avr_keys); 508 eeprom_write(avr_keys, avr_keys);
498 #endif 509 #endif
510 printf_P(PSTR("Set key %d: "), key_index);
511 printhex(new_key, sizeof(new_key), stdout);
512 putchar('\n');
499 } 513 }
500 514
501 static void 515 static void
502 cmd_hmac(const char *params) 516 cmd_hmac(const char *params)
503 { 517 {
515 #endif 529 #endif
516 530
517 hmac_sha1(outdata, avr_keys[key_index], KEYLEN*8, indata, sizeof(indata)*8); 531 hmac_sha1(outdata, avr_keys[key_index], KEYLEN*8, indata, sizeof(indata)*8);
518 printf_P(PSTR("HMAC: ")); 532 printf_P(PSTR("HMAC: "));
519 printhex(outdata, HMACLEN, stdout); 533 printhex(outdata, HMACLEN, stdout);
520 fputc('\n', stdout); 534 putchar('\n');
521 } 535 }
522 536
523 static void 537 static void
524 cmd_decrypt(const char *params) 538 cmd_decrypt(const char *params)
525 { 539 {
550 //aesInit(avr_keys[key_index], tmpbuf); 564 //aesInit(avr_keys[key_index], tmpbuf);
551 //aesDecrypt(&indata[HMACLEN], NULL); 565 //aesDecrypt(&indata[HMACLEN], NULL);
552 566
553 printf_P(PSTR("DECRYPTED: ")); 567 printf_P(PSTR("DECRYPTED: "));
554 printhex(output, AESLEN, stdout); 568 printhex(output, AESLEN, stdout);
555 fputc('\n', stdout); 569 putchar('\n');
556 } 570 }
557 571
558 static void 572 static void
559 cmd_oneshot_reboot(const char *params) 573 cmd_oneshot_reboot(const char *params)
560 { 574 {
620 cmd_vcc() 634 cmd_vcc()
621 { 635 {
622 uint16_t vcc = adc_vcc(); 636 uint16_t vcc = adc_vcc();
623 uint16_t v5 = adc_5v(vcc); 637 uint16_t v5 = adc_5v(vcc);
624 uint16_t r = adc_random(); 638 uint16_t r = adc_random();
625 printf_P(PSTR("vcc: %u mV\n5v: %u mV random %u\n"), vcc, v5, r); 639 uint16_t temp = adc_temp();
626 } 640 // roughly?
641 uint16_t temp_deg = temp - 290;
642 printf_P(PSTR("vcc: %u mV\n"
643 "5v: %u mV\n"
644 "temp: %u mV (%dÂșC)\n"
645 "random: %u\n"
646 ),
647 vcc, v5, temp, temp_deg, r);
648 }
649
650 void(*bootloader)() __attribute__ ((noreturn)) = (void*)0x7e00;
651
652 #if 0
653 #ifndef PROG_PASSWORD
654 #define PROG_PASSWORD "Y2vvjxO5"
655 #endif
656
657 static void
658 cmd_prog(const char* arg)
659 {
660 if (strcmp(arg, PROG_PASSWORD) != 0)
661 {
662 printf_P(PSTR("Bad prog password\n"));
663 return;
664 }
665
666 // disable wdt
667 wdt_disable();
668
669 // disable interrupts
670 TIMSK0 = 0;
671 TIMSK1 = 0;
672 TIMSK2 = 0;
673 EIMSK = 0;
674 PCMSK0 = 0;
675 PCMSK1 = 0;
676 PCMSK2 = 0;
677 ACSR &= ~_BV(ACIE);
678 ADCSRA &= ~_BV(ADIE);
679 UCSR0B &= ~_BV(RXCIE0);
680 UCSR0B &= _BV(TXCIE0);
681 // doesn't do TWI, other uart, probably others
682
683 _delay_ms(20);
684
685 bootloader();
686 }
687 #endif
627 688
628 static void 689 static void
629 read_handler() 690 read_handler()
630 { 691 {
631 #define LOCAL_PSTR(x) const static char x ## _str[] PROGMEM = #x; 692 #define LOCAL_PSTR(x) const static char x ## _str[] PROGMEM = #x;
632 #define LOCAL_HELP(x, d) const static char x ## _help[] PROGMEM = d; 693 #define LOCAL_HELP(x, d) const static char x ## _help[] PROGMEM = d;
633 694
634 LOCAL_PSTR(get_params);
635 LOCAL_PSTR(set_params); 695 LOCAL_PSTR(set_params);
636 LOCAL_PSTR(set_key); 696 LOCAL_PSTR(set_key);
637 LOCAL_PSTR(oneshot); 697 LOCAL_PSTR(oneshot);
638 LOCAL_PSTR(hmac); 698 LOCAL_PSTR(hmac);
639 LOCAL_PSTR(decrypt); 699 LOCAL_PSTR(decrypt);
640 LOCAL_PSTR(alive); 700 LOCAL_PSTR(alive);
641 LOCAL_PSTR(vcc); 701 LOCAL_PSTR(vcc);
642 LOCAL_PSTR(reset); 702 LOCAL_PSTR(reset);
643 LOCAL_PSTR(newboot); 703 LOCAL_PSTR(newboot);
644 LOCAL_PSTR(oldboot); 704 LOCAL_PSTR(oldboot);
705 LOCAL_PSTR(status);
645 LOCAL_HELP(set_params, "<long_limit> <short_limit> <newboot_limit>"); 706 LOCAL_HELP(set_params, "<long_limit> <short_limit> <newboot_limit>");
646 LOCAL_HELP(set_key, "20_byte_hex>"); 707 LOCAL_HELP(set_key, "20_byte_hex>");
647 LOCAL_HELP(oneshot, "<timeout>"); 708 LOCAL_HELP(oneshot, "<timeout>");
648 LOCAL_HELP(hmac, "<key_index> <20_byte_hex_data>"); 709 LOCAL_HELP(hmac, "<key_index> <20_byte_hex_data>");
649 LOCAL_HELP(decrypt, "<key_index> <20_byte_hmac|16_byte_aes_block>"); 710 LOCAL_HELP(decrypt, "<key_index> <20_byte_hmac|16_byte_aes_block>");
651 static const struct handler { 712 static const struct handler {
652 PGM_P name; 713 PGM_P name;
653 void(*cmd)(const char *param); 714 void(*cmd)(const char *param);
654 // existence of arg_help indicates if the cmd takes a parameter. 715 // existence of arg_help indicates if the cmd takes a parameter.
655 PGM_P arg_help; 716 PGM_P arg_help;
656 } handlers[11] PROGMEM = 717 } handlers[] PROGMEM =
657 { 718 {
658 {get_params_str, cmd_get_params, NULL}, 719 {alive_str, cmd_alive, NULL},
720 {newboot_str, cmd_newboot, NULL},
721 {oldboot_str, cmd_oldboot, NULL},
722 {oneshot_str, cmd_oneshot_reboot, oneshot_help},
723 {status_str, cmd_status, NULL},
724 {hmac_str, cmd_hmac, hmac_help},
725 {decrypt_str, cmd_decrypt, decrypt_help},
659 {set_params_str, cmd_set_params, set_params_help}, 726 {set_params_str, cmd_set_params, set_params_help},
660 {set_key_str, cmd_set_avr_key, set_key_help}, 727 {set_key_str, cmd_set_avr_key, set_key_help},
661 {oneshot_str, cmd_oneshot_reboot, oneshot_help},
662 {hmac_str, cmd_hmac, hmac_help},
663 {decrypt_str, cmd_decrypt, decrypt_help},
664 {alive_str, cmd_alive, NULL},
665 {vcc_str, cmd_vcc, NULL}, 728 {vcc_str, cmd_vcc, NULL},
666 {reset_str, cmd_reset, NULL}, 729 {reset_str, cmd_reset, NULL},
667 {newboot_str, cmd_newboot, NULL},
668 {oldboot_str, cmd_oldboot, NULL},
669 }; 730 };
670 731
671 if (readbuf[0] == '\0') 732 if (readbuf[0] == '\0')
672 { 733 {
673 return; 734 return;
818 { 879 {
819 set_sleep_mode(SLEEP_MODE_IDLE); 880 set_sleep_mode(SLEEP_MODE_IDLE);
820 sleep_mode(); 881 sleep_mode();
821 } 882 }
822 883
823 static uint16_t 884 static void
824 adc_vcc() 885 adc_generic(uint8_t admux, uint8_t *ret_num, uint16_t *ret_sum)
825 { 886 {
826 PRR &= ~_BV(PRADC); 887 PRR &= ~_BV(PRADC);
827 888
828 // /16 prescaler 889 // /16 prescaler
829 ADCSRA = _BV(ADEN) | _BV(ADPS2); 890 ADCSRA = _BV(ADEN) | _BV(ADPS2);
830 891
831 // set to measure 1.1 reference 892 // set to measure 1.1 reference
832 ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); 893 ADMUX = admux;
894
895 // delay after setting reference etc, allow settling
896 long_delay(300);
833 // average a number of samples 897 // average a number of samples
834 uint16_t sum = 0; 898 uint16_t sum = 0;
835 uint8_t num = 0; 899 uint8_t num = 0;
836 for (uint8_t n = 0; n < 20; n++) 900 for (uint8_t n = 0; n < 20; n++)
837 { 901 {
849 } 913 }
850 } 914 }
851 ADCSRA = 0; 915 ADCSRA = 0;
852 PRR |= _BV(PRADC); 916 PRR |= _BV(PRADC);
853 917
918 *ret_num = num;
919 *ret_sum = sum;
920 }
921
922 static uint16_t
923 adc_vcc()
924 {
925 const uint8_t mux = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
926 uint16_t sum;
927 uint8_t num;
928
929 adc_generic(mux, &num, &sum);
930
854 //float res_volts = 1.1 * 1024 * num / sum; 931 //float res_volts = 1.1 * 1024 * num / sum;
855 //return 1000 * res_volts; 932 //return 1000 * res_volts;
856 return ((uint32_t)1100*1024*num) / sum; 933 return ((uint32_t)1100*1024*num) / sum;
857 } 934 }
858 935
859 #define SCALER_5V 2 936 #define SCALER_5V 2
860 937
861 static uint16_t 938 static uint16_t
862 adc_5v(uint16_t vcc) 939 adc_5v(uint16_t vcc)
863 { 940 {
864 PRR &= ~_BV(PRADC); 941 // set to measure ADC4 against AVCC
942 const uint8_t mux = _BV(REFS0) | _BV(MUX2);
943 uint16_t sum;
944 uint8_t num;
865 945
866 // /16 prescaler 946 adc_generic(mux, &num, &sum);
867 ADCSRA = _BV(ADEN) | _BV(ADPS2); 947
868 948 return ((uint32_t)vcc*sum*SCALER_5V/(num*1024));
869 // set to measure ADC4 against AVCC 949 }
870 ADMUX = _BV(REFS0) | _BV(MUX2); 950
871 // average a number of samples 951 static uint16_t
872 uint16_t sum = 0; 952 adc_temp()
873 uint8_t num = 0; 953 {
874 for (uint8_t n = 0; n < 20; n++) 954 // set to measure temperature against 1.1v reference.
875 { 955 const uint8_t mux = _BV(REFS0) | _BV(REFS1) | _BV(MUX3);
876 ADCSRA |= _BV(ADSC); 956 uint16_t sum;
877 loop_until_bit_is_clear(ADCSRA, ADSC); 957 uint8_t num;
878 958
879 uint8_t low_11 = ADCL; 959 adc_generic(mux, &num, &sum);
880 uint8_t high_11 = ADCH; 960
881 uint16_t val = low_11 + (high_11 << 8); 961 // return the voltage
882 962
883 if (n >= 4) 963 return ((uint32_t)1100*sum) / (num*1024);
884 {
885 sum += val;
886 num++;
887 }
888 }
889 ADCSRA = 0;
890 PRR |= _BV(PRADC);
891
892 return ((uint32_t)vcc*sum*SCALER_5V/(num*1024));;
893 } 964 }
894 965
895 static void 966 static void
896 reboot_pi() 967 reboot_pi()
897 { 968 {
919 } 990 }
920 991
921 static void 992 static void
922 set_pi_boot_normal(uint8_t normal) 993 set_pi_boot_normal(uint8_t normal)
923 { 994 {
995 boot_normal_status = normal;
924 PORT_PI_BOOT &= ~_BV(PIN_PI_BOOT); 996 PORT_PI_BOOT &= ~_BV(PIN_PI_BOOT);
925 if (normal) 997 if (normal)
926 { 998 {
927 // tristate 999 // tristate
928 DDR_PI_BOOT &= ~_BV(PIN_PI_BOOT); 1000 DDR_PI_BOOT &= ~_BV(PIN_PI_BOOT);
1014 PORT_LED |= _BV(PIN_LED); 1086 PORT_LED |= _BV(PIN_LED);
1015 #endif 1087 #endif
1016 } 1088 }
1017 1089
1018 static void 1090 static void
1019 long_delay(int ms) 1091 long_delay(uint16_t ms)
1020 { 1092 {
1021 int iter = ms / 100; 1093 uint16_t iter = ms / 10;
1022 1094
1023 for (int i = 0; i < iter; i++) 1095 for (uint16_t i = 0; i < iter; i++)
1024 { 1096 {
1025 _delay_ms(100); 1097 _delay_ms(10);
1026 } 1098 }
1027 } 1099 }
1028 1100
1029 ISR(BADISR_vect) 1101 ISR(BADISR_vect)
1030 { 1102 {
1031 //uart_on(); 1103 //uart_on();
1032 printf_P(PSTR("Bad interrupt\n")); 1104 printf_P(PSTR("Bad interrupt\n"));
1033 } 1105 }
1034 1106
1107 // disable watchdog on boot
1108 void wdt_init(void) __attribute__((naked)) __attribute__((section(".init3")));
1109 void wdt_init(void)
1110 {
1111 MCUSR = 0;
1112 wdt_disable();
1113 }
1114
1035 int main(void) 1115 int main(void)
1036 { 1116 {
1037 _Static_assert(F_CPU % 256 == 0, "clock prescaler remainder 0"); 1117 _Static_assert(F_CPU % 256 == 0, "clock prescaler remainder 0");
1038 _Static_assert(NEWBOOT_MAX < WATCHDOG_LONG_MIN, "newboot max shorter than watchdog min"); 1118 _Static_assert(NEWBOOT_MAX < WATCHDOG_LONG_MIN, "newboot max shorter than watchdog min");
1119 _Static_assert((F_CPU)%(16*(BAUD)) == 0, "baud rate good multiple");
1039 1120
1040 setup_chip(); 1121 setup_chip();
1041 blink(); 1122 blink();
1042 1123
1043 stdout = &mystdout; 1124 stdout = &mystdout;
1044 uart_on(); 1125 uart_on();
1045 1126
1046 printf_P(PSTR("Pi Watchdog\nMatt Johnston [email protected]")); 1127 long_delay(500);
1128 printf_P(PSTR("Pi Watchdog\nMatt Johnston [email protected]\n"));
1047 1129
1048 set_pi_boot_normal(0); 1130 set_pi_boot_normal(0);
1049 1131
1050 load_params(); 1132 load_params();
1051 1133