changeset 325:b05c9fd7c098

Merge
author Matt Johnston <matt@ucc.asn.au>
date Tue, 22 May 2012 21:32:52 +0800
parents 5181ea55ea77 (diff) e3664732f11f (current diff)
children f6b5941b4c34
files main.c
diffstat 1 files changed, 111 insertions(+), 90 deletions(-) [+]
line wrap: on
line diff
--- 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;
         }