Mercurial > pihelp
comparison main.c @ 2:0a6cbbb8c2b7
mostly there
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Mon, 03 Jun 2013 23:29:13 +0800 |
parents | e23c1b6f6080 |
children | fd28c7358ce8 |
comparison
equal
deleted
inserted
replaced
1:e23c1b6f6080 | 2:0a6cbbb8c2b7 |
---|---|
11 #include <avr/eeprom.h> | 11 #include <avr/eeprom.h> |
12 #include <avr/wdt.h> | 12 #include <avr/wdt.h> |
13 #include <util/atomic.h> | 13 #include <util/atomic.h> |
14 #include <util/crc16.h> | 14 #include <util/crc16.h> |
15 | 15 |
16 #include "hmac-sha1.h" | |
17 | |
16 //#include "simple_ds18b20.h" | 18 //#include "simple_ds18b20.h" |
17 //#include "onewire.h" | 19 //#include "onewire.h" |
18 | 20 |
19 #define MIN(X,Y) ((X) < (Y) ? (X) : (Y)) | 21 #define MIN(X,Y) ((X) < (Y) ? (X) : (Y)) |
20 #define MAX(X,Y) ((X) > (Y) ? (X) : (Y)) | 22 #define MAX(X,Y) ((X) > (Y) ? (X) : (Y)) |
21 | 23 |
22 // TICK should be 8 or less (8 untested). all timers need | 24 // TICK should be 8 or less (8 untested). all timers need |
23 // to be a multiple. | 25 // to be a multiple. |
24 | 26 |
25 #define TICK 1 | 27 #define TICK 1 |
26 // we have 1024 prescaler, 32768 crystal. | 28 #define SLEEP_COMPARE (2000000/64) // == 31250 exactly |
27 #define SLEEP_COMPARE (32*TICK-1) | 29 #define NKEYS 6 |
28 | |
29 #define KEYLEN 20 | 30 #define KEYLEN 20 |
30 | |
31 #define VALUE_NOSENSOR 0x07D0 // 125 degrees | |
32 #define VALUE_BROKEN 0x07D1 // 125.0625 | |
33 | |
34 #define OVERSHOOT_MAX_DIV 1800.0 // 30 mins | |
35 #define WORT_INVALID_TIME 900 // 15 mins | |
36 // fridge min/max are only used if the wort sensor is invalid | |
37 #define FRIDGE_AIR_MIN_RANGE 40 // 4º | |
38 #define FRIDGE_AIR_MAX_RANGE 40 // 4º | |
39 | 31 |
40 #define BAUD 19200 | 32 #define BAUD 19200 |
41 #define UBRR ((F_CPU)/8/(BAUD)-1) | 33 #define UBRR ((F_CPU)/8/(BAUD)-1) |
34 | |
35 // XXX | |
36 #define PORT_PI_BOOT PORTD | |
37 #define DDR_PI_BOOT DDRD | |
38 #define PIN_PI_BOOT PD7 | |
39 | |
40 // XXX | |
41 #define PORT_PI_RESET PORTD | |
42 #define DDR_PI_RESET DDRD | |
43 #define PIN_PI_RESET PD6 | |
44 | |
42 | 45 |
43 #define PORT_LED PORTC | 46 #define PORT_LED PORTC |
44 #define DDR_LED DDRC | 47 #define DDR_LED DDRC |
45 #define PIN_LED PC4 | 48 #define PIN_LED PC4 |
46 | |
47 #define PORT_SHDN PORTD | |
48 #define DDR_SHDN DDRD | |
49 #define PIN_SHDN PD7 | |
50 | |
51 #define PORT_FRIDGE PORTD | |
52 #define DDR_FRIDGE DDRD | |
53 #define PIN_FRIDGE PD6 | |
54 | |
55 // total amount of 16bit values available for measurements. | |
56 // adjust emperically, be sure to allow enough stack space too | |
57 #define TOTAL_MEASUREMENTS 800 | |
58 | |
59 // each sensor slot uses 8 bytes | |
60 #define MAX_SENSORS 6 | |
61 | |
62 // fixed at 8, have a shorter name | |
63 #define ID_LEN OW_ROMCODE_SIZE | |
64 | 49 |
65 // #define HAVE_UART_ECHO | 50 // #define HAVE_UART_ECHO |
66 | 51 |
67 // stores a value of clock_epoch combined with the remainder of TCNT2, | 52 // stores a value of clock_epoch combined with the remainder of TCNT2, |
68 // for 1/32 second accuracy | 53 // for 1/32 second accuracy |
73 uint8_t rem; | 58 uint8_t rem; |
74 }; | 59 }; |
75 | 60 |
76 // eeprom-settable parameters, default values defined here. | 61 // eeprom-settable parameters, default values defined here. |
77 // all timeouts should be a multiple of TICK | 62 // all timeouts should be a multiple of TICK |
78 static uint32_t watchdog_long_limit = 60*60*24; | 63 static uint32_t watchdog_long_limit = (60L*60*24); |
79 static uint32_t watchdog_short_limit = 0; | 64 static uint32_t watchdog_short_limit = 0; |
80 static uint32_t newboot_limit = 60*10; | 65 static uint32_t newboot_limit = 60*10; |
81 | 66 |
82 // avr proves itself | 67 // avr proves itself |
83 static uint8_t avr_keys[NKEYS][KEYLEN] = {0}; | 68 static uint8_t avr_keys[NKEYS][KEYLEN] = {{0}}; |
84 | |
85 | 69 |
86 // ---- Atomic guards required accessing these variables | 70 // ---- Atomic guards required accessing these variables |
87 // clock_epoch in seconds | 71 // clock_epoch in seconds |
88 static uint32_t clock_epoch; | 72 static uint32_t clock_epoch; |
89 // watchdog counts up | 73 // watchdog counts up |
90 static uint32_t watchdog_long_count; | 74 static uint32_t watchdog_long_count; |
91 static uint32_t watchdog_short_count; | 75 static uint32_t watchdog_short_count; |
92 // newboot counts down - it's a one-shot | 76 // newboot counts down |
93 static uint32_t newboot_count; | 77 static uint32_t newboot_count; |
78 // oneshot counts down | |
79 static uint32_t oneshot_count; | |
80 | |
94 // ---- End atomic guards required | 81 // ---- End atomic guards required |
95 | 82 |
96 // boolean flags | 83 // boolean flags |
97 static uint8_t watchdog_long_hit; | 84 static uint8_t watchdog_long_hit; |
98 static uint8_t watchdog_short_hit; | 85 static uint8_t watchdog_short_hit; |
99 static uint8_t newboot_hit; | 86 static uint8_t newboot_hit; |
87 static uint8_t oneshot_hit; | |
100 | 88 |
101 static uint8_t readpos; | 89 static uint8_t readpos; |
102 static char readbuf[50]; | 90 static char readbuf[50]; |
103 static uint8_t have_cmd; | 91 static uint8_t have_cmd; |
104 | 92 |
105 int uart_putchar(char c, FILE *stream); | 93 int uart_putchar(char c, FILE *stream); |
106 static void long_delay(int ms); | 94 static void long_delay(int ms); |
107 static void blink(); | 95 static void blink(); |
108 static uint16_t adc_vcc(); | 96 static uint16_t adc_vcc(); |
97 static void set_pi_boot_normal(uint8_t normal); | |
109 | 98 |
110 static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, | 99 static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, |
111 _FDEV_SETUP_WRITE); | 100 _FDEV_SETUP_WRITE); |
112 | 101 |
113 // thanks to http://projectgus.com/2010/07/eeprom-access-with-arduino/ | 102 // thanks to http://projectgus.com/2010/07/eeprom-access-with-arduino/ |
121 struct __attribute__ ((__packed__)) __eeprom_data { | 110 struct __attribute__ ((__packed__)) __eeprom_data { |
122 uint32_t watchdog_long_limit; | 111 uint32_t watchdog_long_limit; |
123 uint32_t watchdog_short_limit; | 112 uint32_t watchdog_short_limit; |
124 uint32_t newboot_limit; | 113 uint32_t newboot_limit; |
125 | 114 |
126 uint8_t avr_key[NKEYS][KEYLEN]; | 115 uint8_t avr_keys[NKEYS][KEYLEN]; |
127 | 116 |
128 uint16_t magic; | 117 uint16_t magic; |
129 }; | 118 }; |
130 | |
131 static void deep_sleep(); | |
132 | 119 |
133 // Very first setup | 120 // Very first setup |
134 static void | 121 static void |
135 setup_chip() | 122 setup_chip() |
136 { | 123 { |
145 // set to 8S, in case sha1 is slow etc. | 132 // set to 8S, in case sha1 is slow etc. |
146 wdt_enable(WDTO_8S); | 133 wdt_enable(WDTO_8S); |
147 | 134 |
148 // Set clock to 2mhz | 135 // Set clock to 2mhz |
149 CLKPR = _BV(CLKPCE); | 136 CLKPR = _BV(CLKPCE); |
150 // divide by 4 | |
151 CLKPR = _BV(CLKPS1); | 137 CLKPR = _BV(CLKPS1); |
152 | 138 |
153 // enable pullups | 139 // enable pullups |
154 // XXX matt pihelp | 140 // XXX matt pihelp |
155 PORTB = 0xff; // XXX change when using SPI | 141 PORTB = 0xff; // XXX change when using SPI |
186 } | 172 } |
187 | 173 |
188 static void | 174 static void |
189 setup_tick_counter() | 175 setup_tick_counter() |
190 { | 176 { |
177 // set up counter1 | |
178 | |
191 // set up counter2. | 179 // set up counter2. |
192 // COM21 COM20 Set OC2 on Compare Match (p116) | 180 // COM21 COM20 Set OC2 on Compare Match (p116) |
193 // WGM21 Clear counter on compare | 181 // WGM21 Clear counter on compare |
194 //TCCR2A = _BV(COM2A1) | _BV(COM2A0) | _BV(WGM21); | 182 //TCCR2A = _BV(COM2A1) | _BV(COM2A0) | _BV(WGM21); |
195 // toggle on match | 183 // toggle on match |
196 TCCR2A = _BV(COM2A0); | 184 TCCR1A = _BV(COM1A0); |
197 // CS22 CS21 CS20 clk/1024 | 185 // systemclock/1024 |
198 TCCR2B = _BV(CS22) | _BV(CS21) | _BV(CS20); | 186 TCCR1B = _BV(CS12) | _BV(CS10); |
199 // set async mode | 187 TCNT1 = 0; |
200 ASSR |= _BV(AS2); | 188 OCR1A = SLEEP_COMPARE; |
201 TCNT2 = 0; | |
202 OCR2A = SLEEP_COMPARE; | |
203 // interrupt | 189 // interrupt |
204 TIMSK2 = _BV(OCIE2A); | 190 TIMSK1 = _BV(OCIE1A); |
205 } | 191 } |
206 | 192 |
207 static void | 193 static void |
208 uart_on() | 194 uart_on() |
209 { | 195 { |
217 // set 2x clock, improves accuracy of UBRR | 203 // set 2x clock, improves accuracy of UBRR |
218 UCSR0A |= _BV(U2X0); | 204 UCSR0A |= _BV(U2X0); |
219 UCSR0B = _BV(RXCIE0) | _BV(RXEN0) | _BV(TXEN0); | 205 UCSR0B = _BV(RXCIE0) | _BV(RXEN0) | _BV(TXEN0); |
220 //8N1 | 206 //8N1 |
221 UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); | 207 UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); |
222 uart_enabled = 1; | |
223 } | 208 } |
224 | 209 |
225 static void | 210 static void |
226 uart_off() | 211 uart_off() |
227 { | 212 { |
228 // Turn off interrupts and disable tx/rx | 213 // Turn off interrupts and disable tx/rx |
229 UCSR0B = 0; | 214 UCSR0B = 0; |
230 uart_enabled = 0; | |
231 | 215 |
232 // Power reduction register | 216 // Power reduction register |
233 PRR |= _BV(PRUSART0); | 217 PRR |= _BV(PRUSART0); |
234 } | 218 } |
235 | 219 |
236 int | 220 int |
237 uart_putchar(char c, FILE *stream) | 221 uart_putchar(char c, FILE *stream) |
238 { | 222 { |
239 if (!uart_enabled) | |
240 { | |
241 return EOF; | |
242 } | |
243 // XXX could perhaps sleep in the loop for power. | 223 // XXX could perhaps sleep in the loop for power. |
244 if (c == '\n') | 224 if (c == '\n') |
245 { | 225 { |
246 loop_until_bit_is_set(UCSR0A, UDRE0); | 226 loop_until_bit_is_set(UCSR0A, UDRE0); |
247 UDR0 = '\r'; | 227 UDR0 = '\r'; |
248 } | 228 } |
249 loop_until_bit_is_set(UCSR0A, UDRE0); | 229 loop_until_bit_is_set(UCSR0A, UDRE0); |
250 UDR0 = c; | 230 UDR0 = c; |
251 if (stream == crc_stdout) | |
252 { | |
253 crc_out = _crc_ccitt_update(crc_out, c); | |
254 } | |
255 if (c == '\r') | 231 if (c == '\r') |
256 { | 232 { |
257 loop_until_bit_is_set(UCSR0A, UDRE0); | 233 loop_until_bit_is_set(UCSR0A, UDRE0); |
258 UDR0 = '\n'; | 234 UDR0 = '\n'; |
259 if (stream == crc_stdout) | |
260 { | |
261 crc_out = _crc_ccitt_update(crc_out, '\n'); | |
262 } | |
263 } | 235 } |
264 return (unsigned char)c; | 236 return (unsigned char)c; |
265 } | 237 } |
266 | 238 |
267 static void | 239 static void |
272 cli(); // disable interrupts | 244 cli(); // disable interrupts |
273 wdt_enable(WDTO_15MS); // enable watchdog | 245 wdt_enable(WDTO_15MS); // enable watchdog |
274 while(1); // wait for watchdog to reset processor | 246 while(1); // wait for watchdog to reset processor |
275 } | 247 } |
276 | 248 |
249 static void | |
250 cmd_newboot() | |
251 { | |
252 set_pi_boot_normal(1); | |
253 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) | |
254 { | |
255 newboot_count = newboot_limit; | |
256 } | |
257 printf_P(PSTR("newboot for %d secs"), newboot_limit); | |
258 } | |
259 | |
277 | 260 |
278 | 261 |
279 static void | 262 static void |
280 cmd_get_params() | 263 cmd_get_params() |
281 { | 264 { |
282 uint32_t cur_watchdog_long, cur_watchdog_short, cur_newboot; | 265 uint32_t cur_watchdog_long, cur_watchdog_short, cur_newboot, cur_oneshot; |
283 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) | 266 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) |
284 { | 267 { |
285 cur_watchdog_long = watchdot_long_count; | 268 cur_watchdog_long = watchdog_long_count; |
286 cur_watchdog_short = watchdot_short_count; | 269 cur_watchdog_short = watchdog_short_count; |
287 cur_newboot = newboot_limit_count; | 270 cur_newboot = newboot_count; |
288 } | 271 cur_oneshot = oneshot_count; |
289 | 272 } |
290 printf_P(PSTR("limit (count) : watchdog_long %lu (%lu) watchdog_short %lu (%lu) newboot %lu (%lu)\n"), | 273 |
274 printf_P(PSTR("limit (count) : watchdog_long %lu (%lu) watchdog_short %lu (%lu) newboot %lu (%lu) oneshot (%lu)\n"), | |
291 watchdog_long_limit, | 275 watchdog_long_limit, |
292 watchdog_long_count, | 276 cur_watchdog_long, |
293 watchdog_short_limit, | 277 watchdog_short_limit, |
294 watchdog_short_count, | 278 cur_watchdog_short, |
295 newboot_limit, | 279 newboot_limit, |
296 newboot_count); | 280 cur_newboot, |
281 cur_oneshot); | |
297 } | 282 } |
298 | 283 |
299 static void | 284 static void |
300 cmd_set_params(const char *params) | 285 cmd_set_params(const char *params) |
301 { | 286 { |
344 return c-'A' + 0xa; | 329 return c-'A' + 0xa; |
345 } | 330 } |
346 return 0; | 331 return 0; |
347 } | 332 } |
348 | 333 |
334 static void | |
335 printhex_nibble(const unsigned char b, FILE *stream) | |
336 { | |
337 unsigned char c = b & 0x0f; | |
338 if ( c > 9 ) { | |
339 c += 'A'-10; | |
340 } | |
341 else { | |
342 c += '0'; | |
343 } | |
344 fputc(c, stream); | |
345 } | |
346 | |
347 void | |
348 printhex_byte(const unsigned char b, FILE *stream) | |
349 { | |
350 printhex_nibble( b >> 4, stream); | |
351 printhex_nibble( b, stream); | |
352 } | |
353 | |
354 void | |
355 printhex(uint8_t *id, uint8_t n, FILE *stream) | |
356 { | |
357 for (uint8_t i = 0; i < n; i++) | |
358 { | |
359 if (i > 0) | |
360 { | |
361 fputc(' ', stream); | |
362 } | |
363 printhex_byte(id[i], stream); | |
364 } | |
365 } | |
366 | |
367 static int8_t | |
368 parse_key(const char *params, uint8_t *key_index, uint8_t bytes[KEYLEN]) | |
369 { | |
370 // "N HEXKEY" | |
371 if (strlen(params) != KEYLEN*2+2) { | |
372 printf_P(PSTR("Wrong length key\n")); | |
373 return -1; | |
374 } | |
375 | |
376 if (params[1] != ' ') | |
377 { | |
378 printf_P(PSTR("Missing space\n")); | |
379 return -1; | |
380 } | |
381 | |
382 *key_index = from_hex(params[0]); | |
383 if (*key_index >= NKEYS) | |
384 { | |
385 printf_P(PSTR("Bad key index %d, max %d\n"), *key_index, NKEYS); | |
386 return -1; | |
387 } | |
388 | |
389 for (int i = 0, p = 0; i < KEYLEN; i++, p += 2) | |
390 { | |
391 bytes[i] = (from_hex(params[p+2]) << 4) | from_hex(params[p+3]); | |
392 } | |
393 return 0; | |
394 } | |
395 | |
349 static void | 396 static void |
350 cmd_set_avr_key(const char *params) | 397 cmd_set_avr_key(const char *params) |
351 { | 398 { |
352 // "N HEXKEY" | 399 uint8_t new_key[KEYLEN]; |
353 if (strlen(params)) != KEYLEN*2+2) { | 400 uint8_t key_index; |
354 printf_P(PSTR("Wrong length key\n")); | 401 if (parse_key(params, &key_index, new_key) != 0) |
402 { | |
355 return; | 403 return; |
356 } | 404 } |
357 | 405 memcpy(avr_keys[key_index], new_key, sizeof(new_key)); |
358 uint8_t new_key[KEYLEN]; | 406 eeprom_write(avr_keys, avr_keys); |
359 for (int i = 0, p = 0; i < KEYLEN; i++, p += 2) | 407 } |
360 { | 408 |
361 new_key[i] = (fromhex(params[p]) << 4) | fromhex(params[p+1]); | 409 static void |
362 } | 410 cmd_hmac(const char *params) |
411 { | |
412 uint8_t data[KEYLEN]; | |
413 uint8_t key_index; | |
414 if (parse_key(params, &key_index, data) != 0) | |
415 { | |
416 printf_P(PSTR("FAIL: Bad input\n")); | |
417 } | |
418 | |
419 hmac_sha1_ctx_t ctx; | |
420 hmac_sha1_init(&ctx, avr_keys[key_index], KEYLEN); | |
421 hmac_sha1_lastBlock(&ctx, data, KEYLEN); | |
422 hmac_sha1_final(data, &ctx); | |
423 | |
424 printf_P(PSTR("HMAC: ")); | |
425 printhex(data, KEYLEN, stdout); | |
426 fputc('\n', stdout); | |
427 } | |
428 | |
429 static void | |
430 cmd_oneshot_reboot(const char *params) | |
431 { | |
432 uint32_t new_delay = strtoul(params, NULL, 10); | |
433 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) | |
434 { | |
435 oneshot_count = new_delay; | |
436 } | |
437 printf_P(PSTR("oneshot delay %lu\n"), new_delay); | |
363 } | 438 } |
364 | 439 |
365 static void | 440 static void |
366 load_params() | 441 load_params() |
367 { | 442 { |
369 eeprom_read(magic, magic); | 444 eeprom_read(magic, magic); |
370 if (magic == EXPECT_MAGIC) | 445 if (magic == EXPECT_MAGIC) |
371 { | 446 { |
372 eeprom_read(watchdog_long_limit, watchdog_long_limit); | 447 eeprom_read(watchdog_long_limit, watchdog_long_limit); |
373 eeprom_read(watchdog_short_limit, watchdog_short_limit); | 448 eeprom_read(watchdog_short_limit, watchdog_short_limit); |
374 eeprom_read(netboot_limit); | 449 eeprom_read(newboot_limit, newboot_limit); |
375 eeprom_read(avr_key); | |
376 } | 450 } |
377 } | 451 |
378 | 452 eeprom_read(avr_keys, avr_keys); |
379 // returns true if eeprom was written | 453 } |
380 static bool | 454 |
381 set_initial_eeprom() | 455 static void |
382 { | 456 cmd_vcc() |
383 uint16_t magic; | 457 { |
384 eeprom_read(magic, magic); | 458 uint16_t vcc = adc_vcc(); |
385 if (magic == EXPECT_MAGIC) | 459 printf_P("vcc: %u mV\n", vcc); |
386 { | |
387 return false; | |
388 } | |
389 | |
390 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) | |
391 { | |
392 eeprom_write(measure_wake, measure_wake); | |
393 eeprom_write(comms_wake, comms_wake); | |
394 eeprom_write(wake_secs, wake_secs); | |
395 eeprom_write(fridge_setpoint, fridge_setpoint); | |
396 eeprom_write(fridge_difference, fridge_difference); | |
397 eeprom_write(fridge_delay, fridge_delay); | |
398 eeprom_write(overshoot_delay, overshoot_delay); | |
399 eeprom_write(overshoot_factor, overshoot_factor); | |
400 magic = EXPECT_MAGIC; | |
401 eeprom_write(magic, magic); | |
402 } | |
403 | |
404 return true; | |
405 } | 460 } |
406 | 461 |
407 static void | 462 static void |
408 read_handler() | 463 read_handler() |
409 { | 464 { |
410 if (strcmp_P(readbuf, PSTR("fetch")) == 0) | 465 if (strcmp_P(readbuf, PSTR("get_params")) == 0) |
411 { | |
412 cmd_fetch(); | |
413 } | |
414 else if (strcmp_P(readbuf, PSTR("clear")) == 0) | |
415 { | |
416 cmd_clear(); | |
417 } | |
418 else if (strcmp_P(readbuf, PSTR("btoff")) == 0) | |
419 { | |
420 cmd_btoff(); | |
421 } | |
422 else if (strcmp_P(readbuf, PSTR("measure")) == 0) | |
423 { | |
424 cmd_measure(); | |
425 } | |
426 else if (strcmp_P(readbuf, PSTR("sensors")) == 0) | |
427 { | |
428 cmd_sensors(); | |
429 } | |
430 else if (strcmp_P(readbuf, PSTR("get_params")) == 0) | |
431 { | 466 { |
432 cmd_get_params(); | 467 cmd_get_params(); |
433 } | 468 } |
434 else if (strncmp_P(readbuf, PSTR("set_params "), 11) == 0) | 469 else if (strncmp_P(readbuf, PSTR("set_params "), 11) == 0) |
435 { | 470 { |
436 cmd_set_params(&readbuf[11]); | 471 cmd_set_params(&readbuf[11]); |
437 } | 472 } |
438 else if (strcmp_P(readbuf, PSTR("awake")) == 0) | 473 else if (strncmp_P(readbuf, PSTR("set_key "), 8) == 0) |
439 { | 474 { |
440 cmd_awake(); | 475 cmd_set_avr_key(&readbuf[8]); |
441 } | 476 } |
442 else if (strncmp_P(readbuf, PSTR("fridge_setpoint "), 16) == 0) | 477 else if (strncmp_P(readbuf, PSTR("oneshot "), 8) == 0) |
443 { | 478 { |
444 cmd_set_fridge_setpoint(&readbuf[16]); | 479 cmd_oneshot_reboot(&readbuf[8]); |
445 } | 480 } |
446 else if (strncmp_P(readbuf, PSTR("fridge_diff "), 12) == 0) | 481 else if (strncmp_P(readbuf, PSTR("hmac "), 5) == 0) |
447 { | 482 { |
448 cmd_set_fridge_difference(&readbuf[12]); | 483 cmd_hmac(&readbuf[5]); |
449 } | 484 } |
450 else if (strncmp_P(readbuf, PSTR("fridge_delay "), 13) == 0) | 485 else if (strcmp_P(readbuf, PSTR("vcc")) == 0) |
451 { | 486 { |
452 cmd_set_fridge_delay(&readbuf[13]); | 487 cmd_vcc(); |
453 } | |
454 else if (strncmp_P(readbuf, PSTR("overshoot_delay "), 16) == 0) | |
455 { | |
456 cmd_set_overshoot_delay(&readbuf[16]); | |
457 } | |
458 else if (strncmp_P(readbuf, PSTR("overshoot_factor "), 17) == 0) | |
459 { | |
460 cmd_set_overshoot_factor(&readbuf[17]); | |
461 } | 488 } |
462 else if (strcmp_P(readbuf, PSTR("reset")) == 0) | 489 else if (strcmp_P(readbuf, PSTR("reset")) == 0) |
463 { | 490 { |
464 cmd_reset(); | 491 cmd_reset(); |
465 } | 492 } |
469 } | 496 } |
470 } | 497 } |
471 | 498 |
472 ISR(INT0_vect) | 499 ISR(INT0_vect) |
473 { | 500 { |
474 button_pressed = 1; | |
475 blink(); | 501 blink(); |
476 _delay_ms(100); | 502 _delay_ms(100); |
477 blink(); | 503 blink(); |
478 } | 504 } |
479 | 505 |
502 readpos = 0; | 528 readpos = 0; |
503 } | 529 } |
504 } | 530 } |
505 } | 531 } |
506 | 532 |
507 ISR(TIMER2_COMPA_vect) | 533 ISR(TIMER1_COMPA_vect) |
508 { | 534 { |
509 TCNT2 = 0; | 535 TCNT1 = 0; |
510 | 536 |
511 clock_epoch += TICK; | 537 clock_epoch += TICK; |
512 | 538 |
513 // watchdogs count up, continuous | 539 // watchdogs count up, continuous |
514 if (watchdog_long_limit > 0) { | 540 if (watchdog_long_limit > 0) { |
515 watchdog_count += TICK; | 541 watchdog_long_count += TICK; |
516 if (watchdog_long_count >= watchdog_long_limit) | 542 if (watchdog_long_count >= watchdog_long_limit) |
517 { | 543 { |
518 watchdog_long_count = 0; | 544 watchdog_long_count = 0; |
519 watchdog_long_hit = 1; | 545 watchdog_long_hit = 1; |
520 } | 546 } |
521 } | 547 } |
522 | 548 |
523 if (watchdog_short_limit > 0) { | 549 if (watchdog_short_limit > 0) { |
524 watchdog_count += TICK; | 550 watchdog_short_count += TICK; |
525 if (watchdog_short_count >= watchdog_short_limit) | 551 if (watchdog_short_count >= watchdog_short_limit) |
526 { | 552 { |
527 watchdog_short_count = 0; | 553 watchdog_short_count = 0; |
528 watchdog_short_hit = 1; | 554 watchdog_short_hit = 1; |
529 } | 555 } |
530 } | 556 } |
531 | 557 |
532 // newboot counts down, oneshot. | 558 // newboot counts down |
533 if (newboot_count > 0) | 559 if (newboot_count > 0) |
534 { | 560 { |
535 newboot_count--; | 561 newboot_count-=TICK; |
536 if (newboot_count == 0) | 562 if (newboot_count <= 0) |
537 { | 563 { |
538 newboot_hit = 1; | 564 newboot_hit = 1; |
539 } | 565 newboot_count = 0; |
540 } | 566 } |
541 | 567 } |
542 } | 568 |
543 | 569 if (oneshot_count > 0) |
544 static void | 570 { |
545 deep_sleep() | 571 oneshot_count-=TICK; |
546 { | 572 if (oneshot_count <= 0) |
547 // p119 of manual | 573 { |
548 OCR2A = SLEEP_COMPARE; | 574 oneshot_hit = 1; |
549 loop_until_bit_is_clear(ASSR, OCR2AUB); | 575 oneshot_count = 0; |
550 | 576 } |
551 set_sleep_mode(SLEEP_MODE_PWR_SAVE); | 577 } |
552 sleep_mode(); | 578 |
579 | |
553 } | 580 } |
554 | 581 |
555 static void | 582 static void |
556 idle_sleep() | 583 idle_sleep() |
557 { | 584 { |
594 //return 1000 * res_volts; | 621 //return 1000 * res_volts; |
595 return ((uint32_t)1100*1024*num) / sum; | 622 return ((uint32_t)1100*1024*num) / sum; |
596 } | 623 } |
597 | 624 |
598 static void | 625 static void |
626 reboot_pi() | |
627 { | |
628 // pull it low for 30ms | |
629 PORT_PI_RESET &= ~_BV(PIN_PI_RESET); | |
630 DDR_PI_RESET |= _BV(PIN_PI_RESET); | |
631 _delay_ms(30); | |
632 DDR_PI_RESET &= ~_BV(PIN_PI_RESET); | |
633 } | |
634 | |
635 static void | |
636 set_pi_boot_normal(uint8_t normal) | |
637 { | |
638 PORT_PI_BOOT &= ~_BV(PIN_PI_BOOT); | |
639 if (normal) | |
640 { | |
641 // tristate | |
642 DDR_PI_BOOT &= ~_BV(PIN_PI_BOOT); | |
643 } | |
644 else | |
645 { | |
646 // pull it low | |
647 DDR_PI_RESET |= _BV(PIN_PI_BOOT); | |
648 | |
649 } | |
650 } | |
651 | |
652 static void | |
653 check_flags() | |
654 { | |
655 if (watchdog_long_hit | |
656 || watchdog_short_hit | |
657 || oneshot_hit) | |
658 { | |
659 reboot_pi(); | |
660 } | |
661 | |
662 if (newboot_hit) { | |
663 set_pi_boot_normal(0); | |
664 } | |
665 | |
666 watchdog_long_hit = 0; | |
667 watchdog_short_hit = 0; | |
668 newboot_hit = 0; | |
669 oneshot_hit = 0; | |
670 } | |
671 | |
672 static void | |
599 do_comms() | 673 do_comms() |
600 { | 674 { |
601 // avoid receiving rubbish, perhaps | 675 // avoid receiving rubbish, perhaps |
602 uart_on(); | 676 uart_on(); |
603 | 677 |
604 // write sd card here? same 3.3v regulator... | 678 // write sd card here? same 3.3v regulator... |
605 | 679 |
606 while (1) | 680 while (1) |
607 { | 681 { |
608 wdt_reset(); | 682 wdt_reset(); |
683 | |
684 check_flags(); | |
685 | |
609 if (have_cmd) | 686 if (have_cmd) |
610 { | 687 { |
611 have_cmd = 0; | 688 have_cmd = 0; |
612 read_handler(); | 689 read_handler(); |
613 continue; | 690 continue; |
651 stdout = &mystdout; | 728 stdout = &mystdout; |
652 uart_on(); | 729 uart_on(); |
653 | 730 |
654 printf(PSTR("Started.\n")); | 731 printf(PSTR("Started.\n")); |
655 | 732 |
733 set_pi_boot_normal(0); | |
734 | |
656 load_params(); | 735 load_params(); |
657 | 736 |
658 setup_tick_counter(); | 737 setup_tick_counter(); |
659 | 738 |
660 sei(); | 739 sei(); |