# HG changeset patch # User Matt Johnston # Date 1337693572 -28800 # Node ID b05c9fd7c0986dca9ee0afd245bbe996f793773a # Parent 5181ea55ea77d814034f875555afd74b3d954927# Parent e3664732f11f731beac7207a4428ed767be3b84e Merge diff -r e3664732f11f -r b05c9fd7c098 main.c --- a/main.c Tue May 22 21:27:50 2012 +0800 +++ b/main.c Tue May 22 21:32:52 2012 +0800 @@ -35,6 +35,7 @@ #define VALUE_BROKEN -8000 #define COMMS_WAKE 3600 +#define WAKE_SECS 30 #define BAUD 19200 #define UBRR ((F_CPU)/8/(BAUD)-1) @@ -59,20 +60,24 @@ static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE); -static uint16_t n_measurements = 0; +static uint16_t n_measurements; // stored as decidegrees static int16_t measurements[NUM_MEASUREMENTS][MAX_SENSORS]; // boolean flags -static uint8_t need_measurement = 0; -static uint8_t need_comms = 0; -static uint8_t comms_done = 0; +static uint8_t need_measurement; +static uint8_t need_comms; -static uint8_t readpos = 0; +// counts down from WAKE_SECS to 0, goes to deep sleep when hits 0 +static uint8_t comms_timeout; + +static uint8_t readpos; static char readbuf[30]; -static uint8_t measure_count = 0; -static uint16_t comms_count = 0; +static uint8_t measure_count; +static uint16_t comms_count; + +static uint32_t clock_epoch; // thanks to http://projectgus.com/2010/07/eeprom-access-with-arduino/ #define eeprom_read_to(dst_p, eeprom_field, dst_size) eeprom_read_block((dst_p), (void *)offsetof(struct __eeprom_data, eeprom_field), (dst_size)) @@ -92,15 +97,58 @@ static void deep_sleep(); +// Very first setup static void -chip_setup() +setup_chip() { + // Set clock to 2mhz + cli(); + CLKPR = _BV(CLKPCE); + // divide by 4 + CLKPR = _BV(CLKPS1); + sei(); + + // 3.3v power for bluetooth and SD + DDR_LED |= _BV(PIN_LED); + DDR_SHDN |= _BV(PIN_SHDN); + // INT0 setup EIMSK = _BV(INT0); // set pullup PORTD |= _BV(PD2); } +static void +set_aux_power(uint8_t on) +{ + if (on) + { + PORT_SHDN &= ~_BV(PIN_SHDN); + } + else + { + PORT_SHDN |= _BV(PIN_SHDN); + } +} + +static void +setup_tick_counter() +{ + // set up counter2. + // COM21 COM20 Set OC2 on Compare Match (p116) + // WGM21 Clear counter on compare + //TCCR2A = _BV(COM2A1) | _BV(COM2A0) | _BV(WGM21); + // toggle on match + TCCR2A = _BV(COM2A0); + // CS22 CS21 CS20 clk/1024 + TCCR2B = _BV(CS22) | _BV(CS21) | _BV(CS20); + // set async mode + ASSR |= _BV(AS2); + TCNT2 = 0; + OCR2A = SLEEP_COMPARE; + // interrupt + TIMSK2 = _BV(OCIE2A); +} static void uart_on() @@ -108,6 +156,7 @@ // Power reduction register //PRR &= ~_BV(PRUSART0); + // All of this needs to be done each time after turning off the PRR // baud rate UBRR0H = (unsigned char)(UBRR >> 8); UBRR0L = (unsigned char)UBRR; @@ -148,12 +197,23 @@ } static void +update_crc(uint16_t *crc, const void *data, uint8_t len) +{ + for (uint8_t i = 0; i < len; i++) + { + *crc = _crc_ccitt_update(*crc, ((const uint8_t*)data)[i]); + } +} + +static void cmd_fetch() { uint16_t crc = 0; uint8_t n_sensors; eeprom_read(n_sensors, n_sensors); + printf_P(PSTR("Time %lu\n"), clock_epoch); + update_crc(&crc, &clock_epoch, sizeof(clock_epoch)); printf_P(PSTR("%d sensors\n"), n_measurements); for (uint8_t s = 0; s < n_sensors; s++) { @@ -162,10 +222,7 @@ eeprom_read_to(id, sensor_id[s], ID_LEN); printhex(id, ID_LEN); putchar('\n'); - for (uint8_t i = 0; i < ID_LEN; i++) - { - crc = _crc_ccitt_update(crc, id[i]); - } + update_crc(&crc, id, ID_LEN); } printf_P(PSTR("%d measurements\n"), n_measurements); for (uint16_t n = 0; n < n_measurements; n++) @@ -174,7 +231,7 @@ for (uint8_t s = 0; s < n_sensors; s++) { printf_P(PSTR(" %6d"), measurements[n][s]); - crc = _crc_ccitt_update(crc, measurements[n][s]); + update_crc(&crc, &measurements[n][s], sizeof(measurements[n][s])); } putchar('\n'); } @@ -193,8 +250,7 @@ { printf_P(PSTR("Turning off\n")); _delay_ms(50); - PORTD |= _BV(PIN_SHDN); - comms_done = 1; + comms_timeout = 0; } static void @@ -213,6 +269,7 @@ simple_ds18b20_read_all(); } +#if 0 // 0 on success static uint8_t get_hex_string(const char *hex, uint8_t *out, uint8_t size) @@ -266,6 +323,7 @@ } return 0; } +#endif static void add_sensor(uint8_t *id) @@ -312,19 +370,6 @@ } static void -cmd_add_sensor(const char* hex_addr) -{ - uint8_t id[ID_LEN]; - uint8_t ret = get_hex_string(hex_addr, id, ID_LEN); - if (ret) - { - return; - } - add_sensor(id); - -} - -static void cmd_init() { printf_P(PSTR("Resetting sensor list\n")); @@ -336,6 +381,13 @@ } static void +cmd_settime(const char *str) +{ + clock_epoch = strtoul(str, NULL, 10); + printf_P(PSTR("Time set to %lu\n"), clock_epoch); +} + +static void check_first_startup() { uint16_t magic; @@ -343,6 +395,8 @@ if (magic != EXPECT_MAGIC) { printf_P(PSTR("First boot, looking for sensors...\n")); + // in case of power fumbles don't want to reset during eeprom write, + long_delay(2); cmd_init(); cmd_add_all(); cli(); @@ -353,13 +407,6 @@ } static void -cmd_toggle() -{ - PORT_SHDN ^= _BV(PIN_SHDN); - printf_P(PSTR("toggling power 3.3v %d\n"), PORT_SHDN & _BV(PIN_SHDN)); -} - -static void read_handler() { if (strcmp_P(readbuf, PSTR("fetch")) == 0) @@ -382,18 +429,15 @@ { cmd_sensors(); } - else if (strcmp_P(readbuf, PSTR("toggle")) == 0) - { - cmd_toggle(); - } - else if (strncmp_P(readbuf, PSTR("adds "), strlen("adds ")) == 0) - { - cmd_add_sensor(readbuf + strlen("adds ")); - } else if (strcmp_P(readbuf, PSTR("addall"))== 0) { cmd_add_all(); } + else if (strncmp_P(readbuf, PSTR("settime "), + strlen("settime ") == 0)) + { + cmd_settime(&readbuf[strlen("settime ")]); + } else if (strcmp_P(readbuf, PSTR("init")) == 0) { cmd_init(); @@ -436,19 +480,26 @@ TCNT2 = 0; measure_count ++; comms_count ++; - printf("measure_count %d\n", measure_count); + + clock_epoch ++; + + if (comms_timeout != 0) + { + comms_timeout--; + } + if (measure_count >= MEASURE_WAKE) { measure_count = 0; - printf("need_measurement = 1\n"); need_measurement = 1; } - if (comms_count == COMMS_WAKE) + if (comms_count >= COMMS_WAKE) { comms_count = 0; need_comms = 1; } + } DWORD get_fattime (void) @@ -577,8 +628,6 @@ static void do_comms() { - need_comms = 0; - // turn on bluetooth uart_on(); @@ -586,14 +635,8 @@ printf("ready> \n"); - comms_done = 0; - for (;;) + for (comms_timeout = WAKE_SECS; comms_timeout > 0; ) { - if (comms_done) - { - break; - } - if (need_measurement) { need_measurement = 0; @@ -601,12 +644,12 @@ do_measurement(); } + // wait for commands from the master idle_sleep(); } uart_off(); - - // turn off bluetooth + set_aux_power(0); } static void @@ -634,28 +677,18 @@ printf_P(PSTR("Bad interrupt\n")); } -static void -set_2mhz() -{ - cli(); - CLKPR = _BV(CLKPCE); - // divide by 4 - CLKPR = _BV(CLKPS1); - sei(); -} int main(void) { - set_2mhz(); + setup_chip(); + blink(); - DDR_LED |= _BV(PIN_LED); - DDR_SHDN |= _BV(PIN_SHDN); - blink(); + set_aux_power(0); stdout = &mystdout; uart_on(); - fprintf_P(&mystdout, PSTR("hello %d\n"), 12); + printf(PSTR("Started.\n")); check_first_startup(); @@ -667,41 +700,29 @@ // for testing uart_on(); + setup_tick_counter(); + sei(); - // set up counter2. - // COM21 COM20 Set OC2 on Compare Match (p116) - // WGM21 Clear counter on compare - //TCCR2A = _BV(COM2A1) | _BV(COM2A0) | _BV(WGM21); - // toggle on match - TCCR2A = _BV(COM2A0); - // CS22 CS21 CS20 clk/1024 - TCCR2B = _BV(CS22) | _BV(CS21) | _BV(CS20); - // set async mode - ASSR |= _BV(AS2); - TCNT2 = 0; - OCR2A = SLEEP_COMPARE; - // interrupt - TIMSK2 = _BV(OCIE2A); - +#if 0 for (;;) { do_comms(); } +#endif - for(;;){ - /* insert your main loop code here */ + for(;;) + { if (need_measurement) { need_measurement = 0; do_measurement(); - // testing - cmd_fetch(); continue; } if (need_comms) { + need_comms = 0; do_comms(); continue; }