comparison main.c @ 30:320c8cc7df5a

merge
author Matt Johnston <matt@ucc.asn.au>
date Thu, 27 Jun 2013 00:12:01 +0800
parents ce5097eacf2f
children 5d6a841eef82
comparison
equal deleted inserted replaced
29:22badb6239e0 30:320c8cc7df5a
14 #include <util/crc16.h> 14 #include <util/crc16.h>
15 15
16 #include "hmac-sha1.h" 16 #include "hmac-sha1.h"
17 #include "aes.h" 17 #include "aes.h"
18 18
19 #include "fat.h"
20 #include "fat_config.h"
21 #include "partition.h"
22 #include "sd_raw.h"
23 #include "sd_raw_config.h"
24
19 //#include "simple_ds18b20.h" 25 //#include "simple_ds18b20.h"
20 //#include "onewire.h" 26 //#include "onewire.h"
21 27
22 // not set via bootloader 28 // not set via bootloader
23 //LOCKBITS = (LB_MODE_3 & BLB0_MODE_4 & BLB1_MODE_4); 29 //LOCKBITS = (LB_MODE_3 & BLB0_MODE_4 & BLB1_MODE_4);
33 #define NKEYS 10 39 #define NKEYS 10
34 #define HMACLEN 20 40 #define HMACLEN 20
35 #define AESLEN 16 41 #define AESLEN 16
36 #define KEYLEN HMACLEN 42 #define KEYLEN HMACLEN
37 43
38 #define BAUD 38400 44 #define BAUD 115200
39 #define UBRR ((F_CPU)/(16*(BAUD))-1) 45 #define UBRR ((F_CPU)/(16*(BAUD))-1)
40 46
41 #define PORT_PI_BOOT PORTD 47 #define PORT_PI_BOOT PORTD
42 #define DDR_PI_BOOT DDRD 48 #define DDR_PI_BOOT DDRD
43 #define PIN_PI_BOOT PD5 49 #define PIN_PI_BOOT PD5
92 static uint32_t newboot_count; 98 static uint32_t newboot_count;
93 // oneshot counts down 99 // oneshot counts down
94 static uint32_t oneshot_count; 100 static uint32_t oneshot_count;
95 // countdown after the warning. 101 // countdown after the warning.
96 static uint8_t reboot_count; 102 static uint8_t reboot_count;
103 // set by adc completion interrupt
104 static uint8_t adc_done;
97 105
98 // ---- End atomic guards required 106 // ---- End atomic guards required
99 107
100 // boolean flags 108 // boolean flags
101 static uint8_t watchdog_long_hit; 109 static uint8_t watchdog_long_hit;
262 UDR0 = '\n'; 270 UDR0 = '\n';
263 } 271 }
264 return (unsigned char)c; 272 return (unsigned char)c;
265 } 273 }
266 274
275 uint8_t find_file_in_dir(struct fat_fs_struct* fs, struct fat_dir_struct* dd, const char* name, struct fat_dir_entry_struct* dir_entry)
276 {
277 while(fat_read_dir(dd, dir_entry))
278 {
279 if(strcmp(dir_entry->long_name, name) == 0)
280 {
281 fat_reset_dir(dd);
282 return 1;
283 }
284 }
285
286 return 0;
287 }
288
289 struct fat_file_struct*
290 open_file_in_dir(struct fat_fs_struct* fs, struct fat_dir_struct* dd, const char* name)
291 {
292 struct fat_dir_entry_struct file_entry;
293 if(!find_file_in_dir(fs, dd, name, &file_entry))
294 return 0;
295
296 return fat_open_file(fs, &file_entry);
297 }
298
299 static void
300 hmac_file(const char* fn)
301 {
302 sd_raw_init();
303 struct partition_struct* partition = partition_open(sd_raw_read, sd_raw_read_interval, 0, 0, 0);
304 struct fat_fs_struct* fs = fat_open(partition);
305 struct fat_dir_entry_struct directory;
306 fat_get_dir_entry_of_path(fs, "/", &directory);
307
308 struct sd_raw_info disk_info;
309 sd_raw_get_info(&disk_info);
310 printf("diskinfo size %d", disk_info.capacity);
311
312 struct fat_dir_struct* dd = fat_open_dir(fs, &directory);
313 struct fat_file_struct* fd = open_file_in_dir(fs, dd, "fn");
314
315 char c = 0;
316 char buf[512];
317 for (int i = 0; i < 10; i++)
318 {
319 fat_read_file(fd, buf, sizeof(buf));
320 c ^= buf[0];
321 }
322 printf("total %d\n", c);
323 }
324
267 static void cmd_reset() __attribute__ ((noreturn)); 325 static void cmd_reset() __attribute__ ((noreturn));
268 static void 326 static void
269 cmd_reset() 327 cmd_reset()
270 { 328 {
271 printf_P(PSTR("reset\n")); 329 printf_P(PSTR("reset\n"));
582 uint16_t temp = adc_temp(); 640 uint16_t temp = adc_temp();
583 // roughly? 641 // roughly?
584 uint16_t temp_deg = temp - 290; 642 uint16_t temp_deg = temp - 290;
585 printf_P(PSTR("vcc: %u mV\n" 643 printf_P(PSTR("vcc: %u mV\n"
586 "5v: %u mV\n" 644 "5v: %u mV\n"
587 "temp: %u mV (%dºC)\n"), 645 "temp: %u mV (%dºC)\n"
646 ),
588 vcc, v5, temp, temp_deg); 647 vcc, v5, temp, temp_deg);
589 } 648 }
590 649
591 void(*bootloader)() __attribute__ ((noreturn)) = (void*)0x7e00; 650
592 651 void(*bootloader)() __attribute__ ((noreturn)) = (void*)0x7800;
593 #if 0 652
594 #ifndef PROG_PASSWORD 653 #ifndef PROG_PASSWORD
595 #define PROG_PASSWORD "Y2vvjxO5" 654 #define PROG_PASSWORD "Y2vvjxO5"
596 #endif 655 #endif
597 656
598 static void 657 static void
623 682
624 _delay_ms(20); 683 _delay_ms(20);
625 684
626 bootloader(); 685 bootloader();
627 } 686 }
628 #endif 687
688
689 static void
690 adc_sleep()
691 {
692 set_sleep_mode(SLEEP_MODE_IDLE);
693 sleep_mode();
694 }
695
696 #define BITSET(v, n) (((v) >> (n)) & 1)
697
698 static inline uint8_t
699 popcnt(uint8_t v)
700 {
701 return BITSET(v, 0)
702 + BITSET(v, 1)
703 + BITSET(v, 2)
704 + BITSET(v, 3)
705 + BITSET(v, 4)
706 + BITSET(v, 5)
707 + BITSET(v, 6)
708 + BITSET(v, 7);
709 }
710
711 static uint8_t
712 adc_bit()
713 {
714 ADCSRA |= _BV(ADSC);
715 loop_until_bit_is_clear(ADCSRA, ADSC);
716 uint8_t low = ADCL;
717 uint8_t high = ADCH;
718 return (popcnt(low)&1) ^ (popcnt(high)&1);
719 }
720
721 static void
722 adc_random(uint8_t admux,
723 uint8_t *out, uint16_t num, uint32_t *tries)
724 {
725 uint8_t ret = 0;
726 uint8_t count = 0;
727
728 PRR &= ~_BV(PRADC);
729 // /16 prescaler for 691mhz, no interrupt
730 ADCSRA = _BV(ADEN) | _BV(ADPS2);
731
732 *tries = 0;
733 for (int i = 0; i < num; i++)
734 {
735 while (count <= 7)
736 {
737 (*tries)++;
738
739 // Von Neumann extractor
740 uint8_t one = adc_bit();
741 uint8_t two = adc_bit();
742 if (one == two)
743 {
744 continue;
745 }
746 ret |= one << count;
747 count++;
748 }
749 out[i] = ret;
750 }
751 ADCSRA = 0;
752 PRR |= _BV(PRADC);
753 }
754
755 ISR(ADC_vect)
756 {
757 adc_done = 1;
758 }
759
760 static void
761 adc_generic(uint8_t admux, uint8_t *ret_num, uint16_t *ret_sum)
762 {
763 PRR &= ~_BV(PRADC);
764
765 // /64 prescaler, interrupt
766 ADCSRA = _BV(ADEN) | _BV(ADPS2) | _BV(ADPS1) | _BV(ADIE);
767
768 // set to measure 1.1 reference
769 ADMUX = admux;
770
771 // delay after setting reference etc, allow settling
772 long_delay(300);
773 // average a number of samples
774 uint16_t sum = 0;
775 uint8_t num = 0;
776 for (uint8_t n = 0; n < 20; n++)
777 {
778 while (1)
779 {
780 adc_done = 0;
781 ADCSRA |= _BV(ADSC);
782 adc_sleep();
783
784 uint8_t done;
785 ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
786 {
787 done = adc_done;
788 }
789 if (done)
790 {
791 break;
792 }
793 }
794
795 uint8_t low_11 = ADCL;
796 uint8_t high_11 = ADCH;
797 uint16_t val = low_11 + (high_11 << 8);
798
799 if (n >= 4)
800 {
801 sum += val;
802 num++;
803 }
804 }
805 ADCSRA = 0;
806 PRR |= _BV(PRADC);
807
808 *ret_num = num;
809 *ret_sum = sum;
810 }
811
812 static uint16_t
813 adc_vcc()
814 {
815 const uint8_t mux = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
816 uint16_t sum;
817 uint8_t num;
818
819 adc_generic(mux, &num, &sum);
820
821 //float res_volts = 1.1 * 1024 * num / sum;
822 //return 1000 * res_volts;
823 return ((uint32_t)1100*1024*num) / sum;
824 }
825
826 #define SCALER_5V 2
827
828 static uint16_t
829 adc_5v(uint16_t vcc)
830 {
831 // set to measure ADC4 against AVCC
832 const uint8_t mux = _BV(REFS0) | _BV(MUX2);
833 uint16_t sum;
834 uint8_t num;
835
836 adc_generic(mux, &num, &sum);
837
838 return ((uint32_t)vcc*sum*SCALER_5V/(num*1024));
839 }
840
841 static uint16_t
842 adc_temp()
843 {
844 // set to measure temperature against 1.1v reference.
845 const uint8_t mux = _BV(REFS0) | _BV(REFS1) | _BV(MUX3);
846 uint16_t sum;
847 uint8_t num;
848
849 adc_generic(mux, &num, &sum);
850
851 // return the voltage
852
853 return ((uint32_t)1100*sum) / (num*1024);
854 }
855
856 static void
857 cmd_random(const char* params)
858 {
859 uint8_t admux;
860 uint16_t num;
861 uint8_t buf[100];
862
863 int ret = sscanf_P(params, PSTR("%hhu %u"),
864 &admux, &num);
865 if (!ret)
866 {
867 printf_P(PSTR("Bad arguments\n"));
868 return;
869 }
870 uint32_t tries = 0;
871 printf_P(PSTR("output: "));
872 for (int i = 0; i < num; i+= sizeof(buf))
873 {
874 uint32_t t;
875 uint16_t nr = MIN(num-i, sizeof(buf));
876 adc_random(admux, buf, nr, &t);
877 printhex(buf, nr, stdout);
878 tries += t;
879 }
880 putchar('\n');
881 printf_P(PSTR("%ld tries\n"), tries);
882 }
883
884
629 885
630 static void 886 static void
631 read_handler() 887 read_handler()
632 { 888 {
633 #define LOCAL_PSTR(x) const static char x ## _str[] PROGMEM = #x; 889 #define LOCAL_PSTR(x) const static char x ## _str[] PROGMEM = #x;
642 LOCAL_PSTR(vcc); 898 LOCAL_PSTR(vcc);
643 LOCAL_PSTR(reset); 899 LOCAL_PSTR(reset);
644 LOCAL_PSTR(newboot); 900 LOCAL_PSTR(newboot);
645 LOCAL_PSTR(oldboot); 901 LOCAL_PSTR(oldboot);
646 LOCAL_PSTR(status); 902 LOCAL_PSTR(status);
903 LOCAL_PSTR(random);
904 LOCAL_PSTR(prog);
647 LOCAL_HELP(set_params, "<long_limit> <short_limit> <newboot_limit>"); 905 LOCAL_HELP(set_params, "<long_limit> <short_limit> <newboot_limit>");
648 LOCAL_HELP(set_key, "20_byte_hex>"); 906 LOCAL_HELP(set_key, "20_byte_hex>");
649 LOCAL_HELP(oneshot, "<timeout>"); 907 LOCAL_HELP(oneshot, "<timeout>");
908 LOCAL_HELP(prog, "<password>");
909 LOCAL_HELP(random, "<admux> <nbytes>");
650 LOCAL_HELP(hmac, "<key_index> <20_byte_hex_data>"); 910 LOCAL_HELP(hmac, "<key_index> <20_byte_hex_data>");
651 LOCAL_HELP(decrypt, "<key_index> <20_byte_hmac|16_byte_aes_block>"); 911 LOCAL_HELP(decrypt, "<key_index> <20_byte_hmac|16_byte_aes_block>");
652 912
653 static const struct handler { 913 static const struct handler {
654 PGM_P name; 914 PGM_P name;
664 {status_str, cmd_status, NULL}, 924 {status_str, cmd_status, NULL},
665 {hmac_str, cmd_hmac, hmac_help}, 925 {hmac_str, cmd_hmac, hmac_help},
666 {decrypt_str, cmd_decrypt, decrypt_help}, 926 {decrypt_str, cmd_decrypt, decrypt_help},
667 {set_params_str, cmd_set_params, set_params_help}, 927 {set_params_str, cmd_set_params, set_params_help},
668 {set_key_str, cmd_set_avr_key, set_key_help}, 928 {set_key_str, cmd_set_avr_key, set_key_help},
929 {random_str, cmd_random, random_help},
669 {vcc_str, cmd_vcc, NULL}, 930 {vcc_str, cmd_vcc, NULL},
670 {reset_str, cmd_reset, NULL}, 931 {reset_str, cmd_reset, NULL},
932 {prog_str, cmd_prog, prog_help},
671 }; 933 };
672 934
673 if (readbuf[0] == '\0') 935 if (readbuf[0] == '\0')
674 { 936 {
675 return; 937 return;
821 set_sleep_mode(SLEEP_MODE_IDLE); 1083 set_sleep_mode(SLEEP_MODE_IDLE);
822 sleep_mode(); 1084 sleep_mode();
823 } 1085 }
824 1086
825 static void 1087 static void
826 adc_generic(uint8_t admux, uint8_t *ret_num, uint16_t *ret_sum)
827 {
828 PRR &= ~_BV(PRADC);
829
830 // /16 prescaler
831 ADCSRA = _BV(ADEN) | _BV(ADPS2);
832
833 // set to measure 1.1 reference
834 ADMUX = admux;
835
836 // delay after setting reference etc, allow settling
837 long_delay(300);
838 // average a number of samples
839 uint16_t sum = 0;
840 uint8_t num = 0;
841 for (uint8_t n = 0; n < 20; n++)
842 {
843 ADCSRA |= _BV(ADSC);
844 loop_until_bit_is_clear(ADCSRA, ADSC);
845
846 uint8_t low_11 = ADCL;
847 uint8_t high_11 = ADCH;
848 uint16_t val = low_11 + (high_11 << 8);
849
850 if (n >= 4)
851 {
852 sum += val;
853 num++;
854 }
855 }
856 ADCSRA = 0;
857 PRR |= _BV(PRADC);
858
859 *ret_num = num;
860 *ret_sum = sum;
861 }
862
863 static uint16_t
864 adc_vcc()
865 {
866 const uint8_t mux = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
867 uint16_t sum;
868 uint8_t num;
869
870 adc_generic(mux, &num, &sum);
871
872 //float res_volts = 1.1 * 1024 * num / sum;
873 //return 1000 * res_volts;
874 return ((uint32_t)1100*1024*num) / sum;
875 }
876
877 #define SCALER_5V 2
878
879 static uint16_t
880 adc_5v(uint16_t vcc)
881 {
882 // set to measure ADC4 against AVCC
883 const uint8_t mux = _BV(REFS0) | _BV(MUX2);
884 uint16_t sum;
885 uint8_t num;
886
887 adc_generic(mux, &num, &sum);
888
889 return ((uint32_t)vcc*sum*SCALER_5V/(num*1024));
890 }
891
892 static uint16_t
893 adc_temp()
894 {
895 // set to measure temperature against 1.1v reference.
896 const uint8_t mux = _BV(REFS0) | _BV(REFS1) | _BV(MUX3);
897 uint16_t sum;
898 uint8_t num;
899
900 adc_generic(mux, &num, &sum);
901
902 // return the voltage
903
904 return ((uint32_t)1100*sum) / (num*1024);
905 }
906
907 static void
908 reboot_pi() 1088 reboot_pi()
909 { 1089 {
910 printf_P(PSTR("Real reboot now\n")); 1090 printf_P(PSTR("Real reboot now\n"));
911 // pull it low for 200ms 1091 // pull it low for 200ms
912 PORT_PI_RESET &= ~_BV(PIN_PI_RESET); 1092 PORT_PI_RESET &= ~_BV(PIN_PI_RESET);