Dependencies:   nRF51822

Revision:
26:a577c4b69fe0
Parent:
25:42163d650266
Child:
27:bb7247a1704e
--- a/Source/main.cpp	Mon Mar 25 15:24:15 2019 +0000
+++ b/Source/main.cpp	Mon Apr 15 18:46:57 2019 +0000
@@ -22,6 +22,7 @@
 #include "log.h"
 #include "nrf_soc.h"
 #include "mem.h"
+#include "CCITTcrc16.h"
 
 void process_state(void);
 void start_periodic_tick(uint32_t sec);
@@ -31,7 +32,7 @@
 #if TEST_ON_NRF51_DK==0
     // real board
     //int reg_mode = 1;
-    InterruptIn is_package_open(LIGHT_SENSE, PullNone); // will be pulled hi when package_is_open (only if package_open_sense_enable = 1)
+    InterruptIn is_package_open(LIGHT_SENSE, PullDown); // will be pulled hi when package_is_open (only if package_open_sense_enable = 1)
     DigitalOut package_open_sense_enable(LIGHT_SENSE_ENABLE, 0);
     
     DigitalOut cap_sense_led(CAP_SENSE_LED, 0);
@@ -85,6 +86,9 @@
     IN_USE_SETUP,
     WAIT_CAP_OFF, 
     WAIT_CAP_ON,
+    EOL_WAIT_CAP_OFF,
+    EOL_WAIT_CAP_ON,
+    EOL_WAIT_LIGHT,
     OTHER
 } state_t;
 
@@ -261,7 +265,7 @@
                 stop_periodic_tick();
                 led = 0;
                 package_open_detected = false;
-                is_package_open.mode(PullNone);
+                //is_package_open.mode(PullDown);
                 is_package_open.rise(&light_interrupt);
                 is_package_open.enable_irq();
                 state = SHIP_MODE_CHECK_CAP;
@@ -306,33 +310,84 @@
             case IN_USE_SETUP:
                 flash_led(3, .25);
                 start_periodic_tick(PERIODIC_TICK_SEC);
-                debug("In Use\n");             
+                debug("In Use\n"); 
+                if(NV_NOT_IN_USE) nv_clear(NV_NOT_IN_USE_ADDR);            
                 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();
-                debug("Cap Off \n");            
-                state = WAIT_CAP_ON;
-            }
+                if(read_clock()>((uint32_t)EOL_TIMEOUT_DAYS*24*60*60))
+                { // EOL detected due to maximum time
+                    if(!NV_NOT_EOL) nv_clear(NV_NOT_EOL_ADDR);
+                }
+                
+                if(!NV_NOT_EOL)
+                { // EOL flagged
+                    log_add(EVENT_EOL, 0, 0, 0); // log event
+                    state = EOL_WAIT_CAP_OFF;
+                }
+                else 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;
+                }
     
             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;
+                    
+                    if(log_code_count(EVENT_CAP_ON)>= EOL_MAX_USES) 
+                    { // EOL detected due to maximum uses
+                        if(!NV_NOT_EOL) nv_clear(NV_NOT_EOL_ADDR); 
+                    }
+                }
+                break;
             
-            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 EOL_WAIT_CAP_OFF: // Cap is on
+                if(is_cap_off)
+                { // cap just taken off   
+                    debug("EOL Cap Off \n");            
+                    state = EOL_WAIT_CAP_ON;
+                }
+                else if(!is_package_open)
+                { // its dark
+                    state = EOL_WAIT_LIGHT;
+                }
+                break;
+                
+            case EOL_WAIT_CAP_ON: // Cap is off
+                if(!is_cap_off)
+                { // cap just put on  
+                    debug("EOL Cap On \n");  
+                    set_radio(true);
+                    state = WAIT_CAP_OFF;
+                }
+                break;
+                
+            case EOL_WAIT_LIGHT: // EOL and its dark, save power
+                // set up and enable the Light Sense Interrupt
+                // go to lowest power state
+                start_periodic_tick(EOL_TICK_SEC);  // just tick less often?
+                debug("Going to EOL dark mode\n");
+                is_package_open.disable_irq();
+                stop_periodic_tick();
+                led = 0;
+                package_open_detected = false;
+                //is_package_open.mode(PullDown);
+                is_package_open.rise(&light_interrupt);
+                is_package_open.enable_irq();
+                state = SHIP_MODE_CHECK_CAP;
+                break;
             
             default: // illegal state
                 state = INIT;
@@ -360,11 +415,11 @@
                     BLE_UART_xmit("\n");
                     break;
                     
-                case 'x': // checksum
-                    BLE_UART_xmit("sx=");
-                    BLE_UART_xmit(0);
-                    BLE_UART_xmit("\n");
-                    break;
+                //case 'x': // checksum
+                //    BLE_UART_xmit("sx=");
+                //    BLE_UART_xmit(0);
+                //    BLE_UART_xmit("\n");
+                //    break;
                               
                 case 'c': // cap sensor analog readings
                     BLE_UART_xmit("sc=");
@@ -374,10 +429,20 @@
                     BLE_UART_xmit(off_reading);
                     BLE_UART_xmit("\n");
                     break;
+                   
+                case 'm': // CRC of Softdevice and App (Not including NV storage for logs and flags)
+                    {
+                        uint16_t crc = crc16((const unsigned char*)CRC_START_ADDR, (uint32_t)(CRC_END_ADDR - CRC_START_ADDR + 1) );
+                        BLE_UART_xmit(char2hex(crc, 4));
+                        BLE_UART_xmit("\n");
+                    }
+                    break;
                     
-                case 's': // sensors as binary, with bits '00000tcp', t=(1=TESTING REQUIRED), c=(1 is cap off), p=(1 is light sensed)
+                case 's': // sensors as binary, with bits '000eutcp', e=(0=EOL), u=(0=in use), t=(1=TESTING REQUIRED), c=(1 is cap off), p=(1 is light sensed)
                     //int val = 0;
-                    BLE_UART_xmit("ss=00000");
+                    BLE_UART_xmit("ss=000");
+                    if(NV_NOT_EOL) BLE_UART_xmit("1"); else BLE_UART_xmit("0");
+                    if(NV_NOT_IN_USE) BLE_UART_xmit("1"); else BLE_UART_xmit("0");
                     if(NV_TESTING_REQUIRED) BLE_UART_xmit("1"); else BLE_UART_xmit("0");
                     int save = package_open_sense_enable;
                     package_open_sense_enable = 1;
@@ -387,22 +452,16 @@
                     package_open_sense_enable = save;
                     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);
+                if(NV_TESTING_REQUIRED) nv_clear(NV_TESTING_REQUIRED_ADDR);
             }
-            #if 0
-            else if(tolower(cmd[1])=='e')
-            {
-                set_radio(false);
-                wait(1.0);
-                log_erase();
-            }
-            #endif
+
             break;
             
         case 't': // get time