# HG changeset patch # User Matt Johnston # Date 1340633163 -28800 # Node ID d5b269352ba0ca4943fc98e3fd36a649a510f1a2 # Parent 5100e0bdadad1d4a22016ba3f6f58a045e6d015a - add some atomic guards - get rid of avrtemp diff -r 5100e0bdadad -r d5b269352ba0 main.c --- a/main.c Mon Jun 25 01:23:34 2012 +0800 +++ b/main.c Mon Jun 25 22:06:03 2012 +0800 @@ -8,6 +8,7 @@ #include #include #include +#include #include // for DWORD of get_fattime() @@ -61,7 +62,7 @@ int uart_putchar(char c, FILE *stream); static void long_delay(int ms); static void blink(); -static void adc_internal(uint16_t *millivolt_vcc, uint16_t *int_temp); +static uint16_t adc_vcc(); static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE); @@ -72,7 +73,14 @@ // convenience static FILE *crc_stdout = &_crc_stdout; +// ---- Atomic guards required accessing these variables +static uint32_t clock_epoch; +static uint16_t comms_count; +static uint16_t measure_count; +// ---- End atomic guards required + static uint16_t n_measurements; + // stored as decidegrees static int16_t measurements[NUM_MEASUREMENTS][MAX_SENSORS]; static uint32_t first_measurement_clock; @@ -80,6 +88,8 @@ // samples static uint32_t last_measurement_clock; +static uint32_t last_comms_clock; + // boolean flags static uint8_t need_measurement; static uint8_t need_comms; @@ -92,10 +102,6 @@ static char readbuf[30]; static uint8_t have_cmd; -static uint16_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)) @@ -256,23 +262,28 @@ uint8_t n_sensors; eeprom_read(n_sensors, n_sensors); - uint16_t millivolt_vcc, int_temp; + uint16_t millivolt_vcc = adc_vcc(); - adc_internal(&millivolt_vcc, &int_temp); + uint32_t epoch_copy; + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) + { + epoch_copy = clock_epoch; + } fprintf_P(crc_stdout, PSTR("START\n")); fprintf_P(crc_stdout, PSTR("now=%lu\n" "time_step=%hu\n" "first_time=%lu\n" "last_time=%lu\n" + "comms_time=%lu\n" "voltage=%hu\n" "avrtemp=%hu\n"), - clock_epoch, + epoch_copy, (uint16_t)MEASURE_WAKE, first_measurement_clock, last_measurement_clock, - millivolt_vcc, - int_temp + last_comms_clock, + millivolt_vcc ); fprintf_P(crc_stdout, PSTR("sensors=%u\n"), n_sensors); for (uint8_t s = 0; s < n_sensors; s++) @@ -307,7 +318,10 @@ static void cmd_btoff() { - comms_count = 0; + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) + { + comms_count = 0; + } printf_P(PSTR("off:%hu\n"), COMMS_WAKE); _delay_ms(100); comms_timeout = 0; @@ -581,7 +595,6 @@ comms_count = 0; need_comms = 1; } - } DWORD get_fattime (void) @@ -607,8 +620,8 @@ sleep_mode(); } -static void -adc_internal(uint16_t *millivolt_vcc, uint16_t *int_temp) +static uint16_t +adc_vcc() { PRR &= ~_BV(PRADC); @@ -620,28 +633,23 @@ // set to measure 1.1 reference ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); - ADCSRA |= _BV(ADSC); - loop_until_bit_is_clear(ADCSRA, ADSC); + _delay_ms(30); + // try a few times so it can stabilise + for (uint16_t n = 0; n < 20; n++) + { + ADCSRA |= _BV(ADSC); + loop_until_bit_is_clear(ADCSRA, ADSC); + } uint8_t low_11 = ADCL; uint8_t high_11 = ADCH; uint16_t f_11 = low_11 + (high_11 << 8); float res_volts = 1.1 * 1024 / f_11; - *millivolt_vcc = 1000 * res_volts; - - // measure AVR internal temperature against 1.1 ref. - ADMUX = _BV(MUX3) | _BV(REFS1) | _BV(REFS0); - ADCSRA |= _BV(ADSC); - loop_until_bit_is_clear(ADCSRA, ADSC); - uint8_t low_temp = ADCL; - uint8_t high_temp = ADCH; - uint16_t res_internal = low_temp + (high_temp << 8); - float internal_volts = res_internal * (1.1 / 1024.0); - // millivolts - *int_temp = internal_volts * 1000; PRR |= _BV(PRADC); ADCSRA = 0; + + return 1000 * res_volts; } #if 0 @@ -709,7 +717,9 @@ eeprom_read(n_sensors, n_sensors); simple_ds18b20_start_meas(NULL); - _delay_ms(DS18B20_TCONV_12BIT); + // sleep rather than using a long delay + deep_sleep(); + //_delay_ms(DS18B20_TCONV_12BIT); if (n_measurements == NUM_MEASUREMENTS) { @@ -737,11 +747,14 @@ measurements[n_measurements][s] = decicelsius; } - if (n_measurements == 0) + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { - first_measurement_clock = clock_epoch; + if (n_measurements == 0) + { + first_measurement_clock = clock_epoch; + } + last_measurement_clock = clock_epoch; } - last_measurement_clock = clock_epoch; n_measurements++; //do_adc_335(); @@ -751,6 +764,10 @@ do_comms() { // turn on bluetooth + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) + { + last_comms_clock = clock_epoch; + } set_aux_power(1); uart_on();