v1.19 Release

Dependencies:   nRF51822

Revision:
24:761c30334cf4
Parent:
23:7ca590427f0e
Child:
25:42163d650266
diff -r 7ca590427f0e -r 761c30334cf4 Source/main.cpp
--- a/Source/main.cpp	Tue Mar 19 19:25:39 2019 +0000
+++ b/Source/main.cpp	Thu Mar 21 19:28:22 2019 +0000
@@ -11,6 +11,7 @@
 
 #include <events/mbed_events.h>
 #include <mbed.h>
+#include <ctype.h>
 #include "main.h"
 #include "hw.h"
 #include "ble/BLE.h"
@@ -23,6 +24,7 @@
 #include "mem.h"
 
 void process_state(void);
+void start_periodic_tick(uint32_t sec);
 
 EventQueue eventQueue(/* event count */ 16 * EVENTS_EVENT_SIZE);
 
@@ -36,32 +38,49 @@
     DigitalOut vdd_enable(VDD_ENABLE, 0);
     
     DigitalOut led(LED, 0); // LED for debugging purposes
+    
+    #if UART_DEBUGGING
+        #define debug(STR) BLE_UART_xmit(STR); BLE_UART_xmit("\n");
+    #else
+        #define debug(...) 
+    #endif
 #else
     // simulate on nRF51-DK
     DigitalIn capon(BUTTON1, PullUp);
     //DigitalIn reg_mode(BUTTON3, PullUp);
-    InterruptIn is_package_open(BUTTON2, PullUp); // will be pulled hi when package_is_open (only if package_open_sense_enable = 1)
+    InterruptIn is_package_open(BUTTON2, PullUp); // will be pulled hi when package_is_open
     DigitalOut package_open_sense_enable(LED3, 0);
     
     DigitalOut cap_sense_led(LED2, 0);
     DigitalOut vdd_enable(LED4, 0);
     
     DigitalOut led(LED1, 0); // LED for debugging purposes
+    #if UART_DEBUGGING
+        Serial pc(USBTX, USBRX); // tx, rx
+        #define debug(STR) pc.printf(STR)
+    #else
+        #define debug(...) 
+    #endif
 #endif
 
 LowPowerTicker periodic_ticker; // this handle the RTC
 
+float tick_rate = FAST_TICK_SEC;
 
-//int dark_cnt = 0; // seconds in the dark
+bool package_open_detected = false;
 bool is_cap_off = false; // 0=cap on, 1=cap off
 uint32_t cap_off_time;
 
+uint16_t off_reading;
+uint16_t on_reading;
+
 typedef  enum {
     INIT,
     POST, 
     TEST_MODE, 
     SHIP_MODE_WAIT_DARK,
     SHIP_MODE_WAIT_LIGHT,
+    SHIP_MODE_CHECK_CAP,
     SHIP_MODE_WAIT_CAP_OFF,
     IN_USE_SETUP,
     WAIT_CAP_OFF, 
@@ -73,17 +92,15 @@
 
 /// Light detected interrupt
 void light_interrupt(void)
-{
-    eventQueue.call(process_state);
+{ // dark to light transition
+    package_open_detected = true;
+    start_periodic_tick(PERIODIC_TICK_SEC);
 }
     
 /// Test to see if Cap is off or on
 void test_cap(void)
 {
-#if TEST_ON_NRF51_DK == 0
-    uint16_t off_reading;
-    uint16_t on_reading;
-    
+#if TEST_ON_NRF51_DK == 0   
     vdd_enable = 1; // enable analog power
     wait(0.00075);
     off_reading = adc_read(ADC_CHAN_CAP_SENSE,2);
@@ -100,27 +117,42 @@
 #endif 
     {
         is_cap_off = 0;
-#if ENABLE_LED        
-        led = 0;
-#endif        
+        #if ENABLE_LED        
+            led = 0;
+        #endif        
     }
     else
     {
         is_cap_off = 1;
-#if ENABLE_LED        
-        led = 1;
-#endif        
+        #if ENABLE_LED        
+            led = 1;
+        #endif        
     }
-    
-    eventQueue.call(process_state);
+}
+
+void periodic_tick_task(void)
+{
+    test_cap();
+    process_state();
 }
 
 /// this interrupt is run every PERIODIC_TICK_SEC seconds
 void periodic_tick()
 {
-    update_rtc(PERIODIC_TICK_SEC); // keep rtc updated
-    
-    eventQueue.call(test_cap); // starts as non-interrupt task so we can use wait();
+    update_rtc(tick_rate); // keep rtc updated
+    eventQueue.call(periodic_tick_task); // starts as non-interrupt task so we can use wait();
+}
+
+void start_periodic_tick(uint32_t sec)
+{
+    tick_rate = sec;
+    periodic_ticker.detach();
+    periodic_ticker.attach(&periodic_tick ,sec);
+}
+
+void stop_periodic_tick(void)
+{
+    periodic_ticker.detach();
 }
 
 /// call here to flash the LED n times.
@@ -156,132 +188,151 @@
 /// Called whenever a sensor changes
 void process_state(void)
 {
-#if UART_DEBUGGING==1    
-    if(last_state != state)
+    do
     {
-        BLE_UART_xmit(state);
-        BLE_UART_xmit("\n");
-
+        #if UART_DEBUGGING==1    
+            if(last_state != state)
+            {
+                debug(uli2a(state));
+                debug("\n");    
+            }
+        #endif
         last_state = state;
-    }
-#endif
         
-    switch(state)
-    {
-        case INIT:
-            log_add(EVENT_POWER, 0, 0, 0); // log event 
-#if SKIP_SHIP_MODE
-            state = IN_USE_SETUP;
-#else
-            //package_open_sense_enable = 1; // turn on light sensor
-            state = POST;
-#endif
+        switch(state)
+        {
+            case INIT:
+                log_add(EVENT_POWER, 0, 0, 0); // log event 
+                set_radio(true);
+                start_periodic_tick(PERIODIC_TICK_SEC);
+                #if SKIP_SHIP_MODE
+                    state = IN_USE_SETUP;
+                #else
+                    state = POST;
+                #endif
+                break;
+                
+            case POST:
+                // check CRC ?
+                
+                // Check Misc.
+                
+                //if(error) flash_led(0,0.1); // flash forever to indicate error
+                
+                if(NV_TESTING_REQUIRED) 
+                {
+                    flash_led(1, 1.0);
+                    package_open_sense_enable = 1;
+                    state = TEST_MODE;
+                }
+                else 
+                {
+                    state = IN_USE_SETUP;
+                }
+                break;
+                
+            case TEST_MODE: // allow 
+                start_periodic_tick(FAST_TICK_SEC);
+                test_cap();
+                led = is_cap_off;
+                if(NV_TESTING_REQUIRED == 0 && is_package_open == true)
+                { // testing passed
+                    set_radio(false); // already done when NV_TESTING_REQUIRED was cleared.
+                    led = 0;
+                    //package_open_sense_enable = 1;
+                    state = SHIP_MODE_WAIT_DARK;
+                }
+                break;
+                
+            case SHIP_MODE_WAIT_DARK: // Wait for light sensor to see darkness
+                if(is_package_open == 0)
+                { // its dark
+                    state = SHIP_MODE_WAIT_LIGHT;
+                }
+            break;           
+            
+            case SHIP_MODE_WAIT_LIGHT: 
+                // set up and enable the Light Sense Interrupt
+                // go to lowest power state
+                debug("Going SHIP MODE\n");
+                is_package_open.disable_irq();
+                stop_periodic_tick();
+                led = 0;
+                package_open_detected = false;
+                is_package_open.rise(&light_interrupt);
+                is_package_open.enable_irq();
+                state = SHIP_MODE_CHECK_CAP;
+
             break;
             
-        case POST:
-            // check CRC ?
-            
-            // Check Misc.
-            
-            if(0) flash_led(0,0.1); // flash forever to indicate error
-            
+            case SHIP_MODE_CHECK_CAP:
+                if(package_open_detected)
+                {
+                    debug("Awake\n");
+                    test_cap();
+                    if(is_cap_off)
+                    {
+                        state = SHIP_MODE_WAIT_DARK;
+                    }
+                    else
+                    {
+                        state = SHIP_MODE_WAIT_CAP_OFF;
+                    }
+                }
+                break;
+                
+            case SHIP_MODE_WAIT_CAP_OFF:
+                if(is_package_open == 0) 
+                {
+                    state = SHIP_MODE_WAIT_LIGHT;
+                }
+                else
+                { 
+                    test_cap();
+                    if(is_cap_off)
+                    {
+                        package_open_sense_enable = 0;
+                        log_add(EVENT_WAKE_FROM_SHIP, 0, 0, 0);
+                        state = IN_USE_SETUP;
+                    }
+                }
+                break;
+                
+            case IN_USE_SETUP:
+                start_periodic_tick(PERIODIC_TICK_SEC);
+                debug("In Use\n");             
+                state = WAIT_CAP_OFF;
+            break;
             
-            if(NV_TESTING_REQUIRED) 
-            {
-                flash_led(1, 1.0);
-                state = TEST_MODE;
+            case WAIT_CAP_OFF: // cap is on, waiting for cap to be removed
+            if(is_cap_off)
+            { // cap just taken off   
+                // save cap off time
+                cap_off_time = read_clock();
+                debug("Cap Off \n");            
+                state = WAIT_CAP_ON;
             }
-            else 
-            {
-                state = IN_USE_SETUP;
+    
+            break;
+            
+            case WAIT_CAP_ON: // cap currently off, waiting for cap to be put on
+            
+            if(!is_cap_off)
+            { // cap just put on  
+                // log time cap was off
+                uint32_t cap_off_dur = read_clock()-cap_off_time;
+                if(cap_off_dur>65535) cap_off_dur = 65535;
+                log_add(EVENT_CAP_ON, cap_off_dur & 0xff, (cap_off_dur >> 8)&0xff, 0); // log event
+                set_radio(true);
+                state = WAIT_CAP_OFF;
             }
             break;
             
-        case TEST_MODE:
-            
-            break;
-            
-        case SHIP_MODE_WAIT_DARK: // Wait for light sensor to see darkness for at least x minutes
-            //if(dark_cnt>= MIN_DARK_TIME_MIN*60)
-            { // its been dark for a while,go into SHIP MODE
-                // set up and enable the Light Sense Interrupt
-                is_package_open.rise(&light_interrupt);
-                is_package_open.enable_irq();
-                
-                // turn off dark timer
-                //dark_ticker.detach();
-                state = SHIP_MODE;
-                led = 0;
-            }
-        break;
-        
-        case SHIP_MODE_WAIT_LIGHT: 
-            if(is_package_open)
-            {
-                state = WAKE_FROM_SHIP_MODE;
-                periodic_ticker.detach();
-                periodic_ticker.attach(&periodic_tick ,PERIODIC_TICK_SEC);
-            }
-        break;
-        
-        case SHIP_MODE_WAIT_CAP_OFF:
+            default: // illegal state
+                state = INIT;
             break;
-            
-        case IN_USE_SETUP:
-            periodic_ticker.detach();
-            periodic_ticker.attach(&periodic_tick ,PERIODIC_TICK_SEC);
-#if UART_DEBUGGING==1
-            BLE_UART_xmit("Wakeup\n");
-#endif
-            package_open_sense_enable = 0; // turn off light sense pull-up
-            is_package_open.disable_irq();  // turn off light sense interrupt
-            
-            periodic_ticker.detach();
-            periodic_ticker.attach(&periodic_tick ,PERIODIC_TICK_SEC);
-            
-            set_rtc(0);
-            //log_add(EVENT_POWER, 0, 0, 0); // log event
-            //set_radio(true);
-            
-            state = WAIT_CAP_OFF;
-        break;
-        
-        case WAIT_CAP_OFF: // cap is on, waiting for cap to be removed
-        if(is_cap_off)
-        { // cap just taken off   
-            // save cap off time
-            cap_off_time = read_clock();
-
-#if UART_DEBUGGING==1
-            BLE_UART_xmit("Cap Off \n");
-#endif            
-
-            state = WAIT_CAP_ON;
         }
-
-        break;
-        
-        case WAIT_CAP_ON: // cap currently off, waiting for cap to be put on
-        
-        if(!is_cap_off)
-        { // cap just put on  
-            // log time cap was off
-            uint32_t cap_off_dur = read_clock()-cap_off_time;
-            if(cap_off_dur>65535) cap_off_dur = 65535;
-
-            log_add(EVENT_CAP_ON, cap_off_dur & 0xff, (cap_off_dur >> 8)&0xff, 0); // log event
-            
-            //wait(0.25);
-            set_radio(true);
-           
-            state = WAIT_CAP_OFF;
-        }
-        break;
-        
-        default: // illegal state
-            state = INIT;
-        break;
-    }
+    } while(state != last_state);
 }
 
 int main(void)
@@ -303,7 +354,7 @@
 //*****************************************************************************
 
 
-// process commands sent to the SmartCap over Bluetooth UART
+/// process commands sent to the SmartCap over Bluetooth UART
 void process_cmd(char * cmd)
 {
     switch(tolower(cmd[0])) {
@@ -317,32 +368,58 @@
             switch(tolower(cmd[1])) {
                 case 0: // old, check battery voltage
                     batt_voltage = read_battery_voltage();
-                    //updateBattValue(batt_voltage);
                     BLE_UART_xmit("Bat=");
                     BLE_UART_xmit(batt_voltage);
                     BLE_UART_xmit("\n");
                     break;
                     
-                case 'c': // checksum
+                case 'x': // checksum
+                    BLE_UART_xmit("sx=");
                     BLE_UART_xmit(0);
                     BLE_UART_xmit("\n");
                     break;
+                
+                #if 0
+                case 'l': // light sensor analog readings
+                    BLE_UART_xmit("sl=");
+                    package_open_sense_enable = 1;
+                    wait(0.001);
+                    BLE_UART_xmit(adc_read(ADC_CHAN_LIGHT_SENSE, 2));
+                    package_open_sense_enable = 0;
+                    BLE_UART_xmit("\n");
+                    break;
+                #endif
+                
+                case 'c': // cap sensor analog readings
+                    BLE_UART_xmit("sc=");
+                    test_cap();
+                    BLE_UART_xmit(on_reading);
+                    BLE_UART_xmit(",");
+                    BLE_UART_xmit(off_reading);
+                    BLE_UART_xmit("\n");
+                    break;
                     
-                case 'l': // light sensor analog readings
-                    BLE_UART_xmit(0);
-                    BLE_UART_xmit("\n");
-                    break;
-                    
-                case ' ': // cap sensor analog readings
-                    
-                case 's': // sensors as hex pair, with bit '000000xy', x=(1 is cap off), y=(1 is light sensed)
-                    
-                    BLE_UART_xmit(0);
+                case 's': // sensors as int, with bits '000000xy', x=(1 is cap off), y=(1 is light sensed)
+                    int val = 0;
+                    BLE_UART_xmit("ss=");
+                    package_open_sense_enable = 1;
+                    test_cap();
+                    if(is_cap_off) val |= 2;
+                    if(is_package_open) val |= 1;
+                    package_open_sense_enable = 0;
+                    BLE_UART_xmit(val);
                     BLE_UART_xmit("\n");
                     break;
             }
             break;
-
+        case 'p': // test passed
+            if(tolower(cmd[1])=='z')
+            {
+                log_add(EVENT_TEST_PASS, 0, 0, 0);
+                nv_clear(NV_TESTING_REQUIRED_ADDR);
+            }
+            break;
+            
         case 't': // get time
             BLE_UART_xmit(read_clock());
             BLE_UART_xmit("\n");
@@ -365,6 +442,7 @@
             break;
              
         case 'v': // version
+            BLE_UART_xmit("v=");
             BLE_UART_xmit(FW_VERSION);
             BLE_UART_xmit("\n");
             break;