Mercurial > templog
comparison main.c @ 16:5075d8c428bd
untested, add comms timeout code
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Mon, 21 May 2012 07:52:51 +0800 |
parents | 54b0fda9cba7 |
children | a5e3b363675d |
comparison
equal
deleted
inserted
replaced
15:54b0fda9cba7 | 16:5075d8c428bd |
---|---|
33 | 33 |
34 #define VALUE_NOSENSOR -9000 | 34 #define VALUE_NOSENSOR -9000 |
35 #define VALUE_BROKEN -8000 | 35 #define VALUE_BROKEN -8000 |
36 | 36 |
37 #define COMMS_WAKE 3600 | 37 #define COMMS_WAKE 3600 |
38 #define WAKE_SECS 30 | |
38 | 39 |
39 #define BAUD 19200 | 40 #define BAUD 19200 |
40 #define UBRR ((F_CPU)/8/(BAUD)-1) | 41 #define UBRR ((F_CPU)/8/(BAUD)-1) |
41 | 42 |
42 #define PORT_LED PORTC | 43 #define PORT_LED PORTC |
64 static int16_t measurements[NUM_MEASUREMENTS][MAX_SENSORS]; | 65 static int16_t measurements[NUM_MEASUREMENTS][MAX_SENSORS]; |
65 | 66 |
66 // boolean flags | 67 // boolean flags |
67 static uint8_t need_measurement = 0; | 68 static uint8_t need_measurement = 0; |
68 static uint8_t need_comms = 0; | 69 static uint8_t need_comms = 0; |
69 static uint8_t comms_done = 0; | 70 |
71 // counts down from WAKE_SECS to 0, goes to deep sleep when hits 0 | |
72 static uint8_t comms_timeout = 0; | |
70 | 73 |
71 static uint8_t readpos = 0; | 74 static uint8_t readpos = 0; |
72 static char readbuf[30]; | 75 static char readbuf[30]; |
73 | 76 |
74 static uint8_t measure_count = 0; | 77 static uint8_t measure_count = 0; |
90 | 93 |
91 #define DEBUG(str) printf_P(PSTR(str)) | 94 #define DEBUG(str) printf_P(PSTR(str)) |
92 | 95 |
93 static void deep_sleep(); | 96 static void deep_sleep(); |
94 | 97 |
98 // Very first setup | |
99 static void | |
100 setup_chip() | |
101 { | |
102 // Set clock to 2mhz | |
103 cli(); | |
104 CLKPR = _BV(CLKPCE); | |
105 // divide by 4 | |
106 CLKPR = _BV(CLKPS1); | |
107 sei(); | |
108 | |
109 DDR_LED |= _BV(PIN_LED); | |
110 DDR_SHDN |= _BV(PIN_SHDN); | |
111 } | |
112 | |
113 static void | |
114 set_aux_power(uint8_t on) | |
115 { | |
116 if (on) | |
117 { | |
118 PORT_SHDN &= ~_BV(PIN_SHDN); | |
119 } | |
120 else | |
121 { | |
122 PORT_SHDN |= _BV(PIN_SHDN); | |
123 } | |
124 } | |
125 | |
126 static void | |
127 setup_tick_counter() | |
128 { | |
129 // set up counter2. | |
130 // COM21 COM20 Set OC2 on Compare Match (p116) | |
131 // WGM21 Clear counter on compare | |
132 //TCCR2A = _BV(COM2A1) | _BV(COM2A0) | _BV(WGM21); | |
133 // toggle on match | |
134 TCCR2A = _BV(COM2A0); | |
135 // CS22 CS21 CS20 clk/1024 | |
136 TCCR2B = _BV(CS22) | _BV(CS21) | _BV(CS20); | |
137 // set async mode | |
138 ASSR |= _BV(AS2); | |
139 TCNT2 = 0; | |
140 OCR2A = SLEEP_COMPARE; | |
141 // interrupt | |
142 TIMSK2 = _BV(OCIE2A); | |
143 } | |
144 | |
95 static void | 145 static void |
96 uart_on() | 146 uart_on() |
97 { | 147 { |
98 // Power reduction register | 148 // Power reduction register |
99 //PRR &= ~_BV(PRUSART0); | 149 //PRR &= ~_BV(PRUSART0); |
100 | 150 |
151 // All of this needs to be done each time after turning off the PRR | |
101 // baud rate | 152 // baud rate |
102 UBRR0H = (unsigned char)(UBRR >> 8); | 153 UBRR0H = (unsigned char)(UBRR >> 8); |
103 UBRR0L = (unsigned char)UBRR; | 154 UBRR0L = (unsigned char)UBRR; |
104 // set 2x clock, improves accuracy of UBRR | 155 // set 2x clock, improves accuracy of UBRR |
105 UCSR0A |= _BV(U2X0); | 156 UCSR0A |= _BV(U2X0); |
181 static void | 232 static void |
182 cmd_btoff() | 233 cmd_btoff() |
183 { | 234 { |
184 printf_P(PSTR("Turning off\n")); | 235 printf_P(PSTR("Turning off\n")); |
185 _delay_ms(50); | 236 _delay_ms(50); |
186 PORTD |= _BV(PIN_SHDN); | 237 comms_timeout = 0; |
187 comms_done = 1; | |
188 } | 238 } |
189 | 239 |
190 static void | 240 static void |
191 cmd_measure() | 241 cmd_measure() |
192 { | 242 { |
201 printf_P(PSTR("All sensors, ret %d, waiting...\n"), ret); | 251 printf_P(PSTR("All sensors, ret %d, waiting...\n"), ret); |
202 long_delay(DS18B20_TCONV_12BIT); | 252 long_delay(DS18B20_TCONV_12BIT); |
203 simple_ds18b20_read_all(); | 253 simple_ds18b20_read_all(); |
204 } | 254 } |
205 | 255 |
256 #if 0 | |
206 // 0 on success | 257 // 0 on success |
207 static uint8_t | 258 static uint8_t |
208 get_hex_string(const char *hex, uint8_t *out, uint8_t size) | 259 get_hex_string(const char *hex, uint8_t *out, uint8_t size) |
209 { | 260 { |
210 uint8_t upper; | 261 uint8_t upper; |
254 printf_P(PSTR("Short hex\n")); | 305 printf_P(PSTR("Short hex\n")); |
255 return 1; | 306 return 1; |
256 } | 307 } |
257 return 0; | 308 return 0; |
258 } | 309 } |
310 #endif | |
259 | 311 |
260 static void | 312 static void |
261 add_sensor(uint8_t *id) | 313 add_sensor(uint8_t *id) |
262 { | 314 { |
263 uint8_t n; | 315 uint8_t n; |
300 add_sensor(id); | 352 add_sensor(id); |
301 } | 353 } |
302 } | 354 } |
303 | 355 |
304 static void | 356 static void |
305 cmd_add_sensor(const char* hex_addr) | |
306 { | |
307 uint8_t id[ID_LEN]; | |
308 uint8_t ret = get_hex_string(hex_addr, id, ID_LEN); | |
309 if (ret) | |
310 { | |
311 return; | |
312 } | |
313 add_sensor(id); | |
314 | |
315 } | |
316 | |
317 static void | |
318 cmd_init() | 357 cmd_init() |
319 { | 358 { |
320 printf_P(PSTR("Resetting sensor list\n")); | 359 printf_P(PSTR("Resetting sensor list\n")); |
321 uint8_t zero = 0; | 360 uint8_t zero = 0; |
322 cli(); | 361 cli(); |
331 uint16_t magic; | 370 uint16_t magic; |
332 eeprom_read(magic, magic); | 371 eeprom_read(magic, magic); |
333 if (magic != EXPECT_MAGIC) | 372 if (magic != EXPECT_MAGIC) |
334 { | 373 { |
335 printf_P(PSTR("First boot, looking for sensors...\n")); | 374 printf_P(PSTR("First boot, looking for sensors...\n")); |
375 // in case of power fumbles don't want to reset during eeprom write, | |
376 long_delay(2); | |
336 cmd_init(); | 377 cmd_init(); |
337 cmd_add_all(); | 378 cmd_add_all(); |
338 cli(); | 379 cli(); |
339 magic = EXPECT_MAGIC; | 380 magic = EXPECT_MAGIC; |
340 eeprom_write(magic, magic); | 381 eeprom_write(magic, magic); |
341 sei(); | 382 sei(); |
342 } | 383 } |
343 } | 384 } |
344 | 385 |
345 static void | 386 static void |
346 cmd_toggle() | |
347 { | |
348 PORT_SHDN ^= _BV(PIN_SHDN); | |
349 printf_P(PSTR("toggling power 3.3v %d\n"), PORT_SHDN & _BV(PIN_SHDN)); | |
350 } | |
351 | |
352 static void | |
353 read_handler() | 387 read_handler() |
354 { | 388 { |
355 if (strcmp_P(readbuf, PSTR("fetch")) == 0) | 389 if (strcmp_P(readbuf, PSTR("fetch")) == 0) |
356 { | 390 { |
357 cmd_fetch(); | 391 cmd_fetch(); |
369 cmd_measure(); | 403 cmd_measure(); |
370 } | 404 } |
371 else if (strcmp_P(readbuf, PSTR("sensors")) == 0) | 405 else if (strcmp_P(readbuf, PSTR("sensors")) == 0) |
372 { | 406 { |
373 cmd_sensors(); | 407 cmd_sensors(); |
374 } | |
375 else if (strcmp_P(readbuf, PSTR("toggle")) == 0) | |
376 { | |
377 cmd_toggle(); | |
378 } | |
379 else if (strncmp_P(readbuf, PSTR("adds "), strlen("adds ")) == 0) | |
380 { | |
381 cmd_add_sensor(readbuf + strlen("adds ")); | |
382 } | 408 } |
383 else if (strcmp_P(readbuf, PSTR("addall"))== 0) | 409 else if (strcmp_P(readbuf, PSTR("addall"))== 0) |
384 { | 410 { |
385 cmd_add_all(); | 411 cmd_add_all(); |
386 } | 412 } |
418 ISR(TIMER2_COMPA_vect) | 444 ISR(TIMER2_COMPA_vect) |
419 { | 445 { |
420 TCNT2 = 0; | 446 TCNT2 = 0; |
421 measure_count ++; | 447 measure_count ++; |
422 comms_count ++; | 448 comms_count ++; |
423 printf("measure_count %d\n", measure_count); | 449 |
450 if (comms_timeout != 0) | |
451 { | |
452 comms_timeout--; | |
453 } | |
454 | |
424 if (measure_count >= MEASURE_WAKE) | 455 if (measure_count >= MEASURE_WAKE) |
425 { | 456 { |
426 measure_count = 0; | 457 measure_count = 0; |
427 printf("need_measurement = 1\n"); | |
428 need_measurement = 1; | 458 need_measurement = 1; |
429 } | 459 } |
430 | 460 |
431 if (comms_count == COMMS_WAKE) | 461 if (comms_count >= COMMS_WAKE) |
432 { | 462 { |
433 comms_count = 0; | 463 comms_count = 0; |
434 need_comms = 1; | 464 need_comms = 1; |
435 } | 465 } |
466 | |
436 } | 467 } |
437 | 468 |
438 DWORD get_fattime (void) | 469 DWORD get_fattime (void) |
439 { | 470 { |
440 return 0; | 471 return 0; |
559 } | 590 } |
560 | 591 |
561 static void | 592 static void |
562 do_comms() | 593 do_comms() |
563 { | 594 { |
564 need_comms = 0; | |
565 | |
566 // turn on bluetooth | 595 // turn on bluetooth |
567 uart_on(); | 596 uart_on(); |
568 | 597 |
569 // write sd card here? same 3.3v regulator... | 598 // write sd card here? same 3.3v regulator... |
570 | 599 |
571 printf("ready> \n"); | 600 printf("ready> \n"); |
572 | 601 |
573 comms_done = 0; | 602 for (comms_timeout = WAKE_SECS; comms_timeout > 0; ) |
574 for (;;) | |
575 { | 603 { |
576 if (comms_done) | |
577 { | |
578 break; | |
579 } | |
580 | |
581 if (need_measurement) | 604 if (need_measurement) |
582 { | 605 { |
583 need_measurement = 0; | 606 need_measurement = 0; |
584 printf("measure from do_comms\n"); | 607 printf("measure from do_comms\n"); |
585 do_measurement(); | 608 do_measurement(); |
586 } | 609 } |
587 | 610 |
611 // wait for commands from the master | |
588 idle_sleep(); | 612 idle_sleep(); |
589 } | 613 } |
590 | 614 |
591 uart_off(); | 615 uart_off(); |
592 | 616 set_aux_power(0); |
593 // turn off bluetooth | |
594 } | 617 } |
595 | 618 |
596 static void | 619 static void |
597 blink() | 620 blink() |
598 { | 621 { |
616 { | 639 { |
617 //uart_on(); | 640 //uart_on(); |
618 printf_P(PSTR("Bad interrupt\n")); | 641 printf_P(PSTR("Bad interrupt\n")); |
619 } | 642 } |
620 | 643 |
621 static void | |
622 set_2mhz() | |
623 { | |
624 cli(); | |
625 CLKPR = _BV(CLKPCE); | |
626 // divide by 4 | |
627 CLKPR = _BV(CLKPS1); | |
628 sei(); | |
629 } | |
630 | 644 |
631 int main(void) | 645 int main(void) |
632 { | 646 { |
633 set_2mhz(); | 647 setup_chip(); |
634 | |
635 DDR_LED |= _BV(PIN_LED); | |
636 DDR_SHDN |= _BV(PIN_SHDN); | |
637 blink(); | 648 blink(); |
649 | |
650 set_aux_power(0); | |
638 | 651 |
639 stdout = &mystdout; | 652 stdout = &mystdout; |
640 uart_on(); | 653 uart_on(); |
641 | 654 |
642 fprintf_P(&mystdout, PSTR("hello %d\n"), 12); | 655 printf(PSTR("Started.\n")); |
643 | 656 |
644 check_first_startup(); | 657 check_first_startup(); |
645 | 658 |
646 uart_off(); | 659 uart_off(); |
647 | 660 |
649 //PRR = _BV(PRTWI) | _BV(PRTIM0) | _BV(PRTIM1) | _BV(PRSPI) | _BV(PRUSART0) | _BV(PRADC); | 662 //PRR = _BV(PRTWI) | _BV(PRTIM0) | _BV(PRTIM1) | _BV(PRSPI) | _BV(PRUSART0) | _BV(PRADC); |
650 | 663 |
651 // for testing | 664 // for testing |
652 uart_on(); | 665 uart_on(); |
653 | 666 |
667 setup_tick_counter(); | |
668 | |
654 sei(); | 669 sei(); |
655 | 670 |
656 // set up counter2. | 671 #if 0 |
657 // COM21 COM20 Set OC2 on Compare Match (p116) | |
658 // WGM21 Clear counter on compare | |
659 //TCCR2A = _BV(COM2A1) | _BV(COM2A0) | _BV(WGM21); | |
660 // toggle on match | |
661 TCCR2A = _BV(COM2A0); | |
662 // CS22 CS21 CS20 clk/1024 | |
663 TCCR2B = _BV(CS22) | _BV(CS21) | _BV(CS20); | |
664 // set async mode | |
665 ASSR |= _BV(AS2); | |
666 TCNT2 = 0; | |
667 OCR2A = SLEEP_COMPARE; | |
668 // interrupt | |
669 TIMSK2 = _BV(OCIE2A); | |
670 | |
671 for (;;) | 672 for (;;) |
672 { | 673 { |
673 do_comms(); | 674 do_comms(); |
674 } | 675 } |
675 | 676 #endif |
676 for(;;){ | 677 |
677 /* insert your main loop code here */ | 678 for(;;) |
679 { | |
678 if (need_measurement) | 680 if (need_measurement) |
679 { | 681 { |
680 need_measurement = 0; | 682 need_measurement = 0; |
681 do_measurement(); | 683 do_measurement(); |
682 // testing | |
683 cmd_fetch(); | |
684 continue; | 684 continue; |
685 } | 685 } |
686 | 686 |
687 if (need_comms) | 687 if (need_comms) |
688 { | 688 { |
689 need_comms = 0; | |
689 do_comms(); | 690 do_comms(); |
690 continue; | 691 continue; |
691 } | 692 } |
692 | 693 |
693 deep_sleep(); | 694 deep_sleep(); |