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