init

Dependencies:   aconno_I2C Lis2dh12 WatchdogTimer

Revision:
9:b0a1535b8ef2
Parent:
8:7351f8c4cd60
Child:
10:c8798fd9773b
--- a/main.cpp	Tue Dec 11 22:38:25 2018 +0000
+++ b/main.cpp	Sat Dec 15 13:45:28 2018 +0000
@@ -10,23 +10,26 @@
 static void buttonRelease(void);
 
 //------------------------------------------------------------------------------
-//GLOBAL VARS
+//GLOBAL VARS / CLEARED ON SLEEP (IF USING SOFT REBOOT HACK)
 //------------------------------------------------------------------------------ 
 bool accel_healthy = false;
-bool firstBoot = false;
 bool requireSoftReset = false;
 bool motionFlagTriggered = false;
+bool debugLED = false;
 
 //------------------------------------------------------------------------------
 //RETAINED NOINIT RAM VARS
 //------------------------------------------------------------------------------ 
 #if defined ( __CC_ARM ) /** THIS IS THE MBED ONLINE COMPILER TOOLCHAIN*/
+static uint8_t          RET_coldBoot                    __attribute__((section("noinit"),zero_init));
 static uint8_t          RET_mode                    __attribute__((section("noinit"),zero_init));
-
-static uint8_t          RET_buttonReleaseCount      __attribute__((section("noinit"),zero_init));
-static uint32_t         RET_buttonPressTime         __attribute__((section("noinit"),zero_init));
-static uint32_t         RET_buttonReleaseTime       __attribute__((section("noinit"),zero_init));
-static uint32_t         RET_unixtime_backup         __attribute__((section("noinit"),zero_init));
+static uint8_t          RET_mode_prev                    __attribute__((section("noinit"),zero_init));
+static uint8_t          RET_buttonPressCount      __attribute__((section("noinit"),zero_init));
+static time_t           RET_buttonPressTime         __attribute__((section("noinit"),zero_init));
+static time_t           RET_buttonReleaseTime       __attribute__((section("noinit"),zero_init));
+static time_t           RET_buttonHoldTime       __attribute__((section("noinit"),zero_init));
+static time_t           RET_RTCunixtime         __attribute__((section("noinit"),zero_init));
+static long             RET_RTCmicros         __attribute__((section("noinit"),zero_init));
 static bool             RET_requireImpactFlag       __attribute__((section("noinit"),zero_init));
 static char             RET_buffer[64]              __attribute__((section("noinit"),zero_init));
 
@@ -34,62 +37,117 @@
 static bool             RET_motionTriggered              __attribute__((section("noinit"),zero_init));
 static time_t           RET_motionStartTime              __attribute__((section("noinit"),zero_init));
 static time_t           RET_motionStopTime              __attribute__((section("noinit"),zero_init));
-static uint32_t         RET_motionStartThreshold_seconds    __attribute__((section("noinit"),zero_init));
-static uint32_t         RET_motionStopThreshold_seconds     __attribute__((section("noinit"),zero_init));
+static time_t           RET_motionStartThreshold_seconds    __attribute__((section("noinit"),zero_init));
+static time_t           RET_motionStopThreshold_seconds     __attribute__((section("noinit"),zero_init));
 static bool             RET_motionPendingOnState              __attribute__((section("noinit"),zero_init));
 static bool             RET_motionPendingOffState              __attribute__((section("noinit"),zero_init));
 static bool             RET_motionState              __attribute__((section("noinit"),zero_init));
+static float            RET_motionTotalActivityHours     __attribute__((section("noinit"),zero_init));
+static char             RET_motionData[100]              __attribute__((section("noinit"),zero_init));
 
 //EVENT HANDLING
-static uint32_t         RET_eventTime_location      __attribute__((section("noinit"),zero_init));
-static uint32_t         RET_eventTime_environmental __attribute__((section("noinit"),zero_init));
-static uint32_t         RET_eventTime_activity      __attribute__((section("noinit"),zero_init));
+static time_t           RET_eventTime_location_log      __attribute__((section("noinit"),zero_init));
+static time_t           RET_eventTime_location_bc      __attribute__((section("noinit"),zero_init));
+static time_t           RET_eventTime_environmental_log __attribute__((section("noinit"),zero_init));
+static time_t           RET_eventTime_environmental_bc __attribute__((section("noinit"),zero_init));
+static time_t           RET_eventTime_activity_bc      __attribute__((section("noinit"),zero_init));
+static time_t           RET_eventTime_wakeFromDormant      __attribute__((section("noinit"),zero_init));
 #elif defined ( __GNUC__ )
 #elif defined ( __ICCARM__ )
 #endif
 
 //------------------------------------------------------------------------------
+//GPIO
+//------------------------------------------------------------------------------ 
+InterruptIn button(PN_IN_BUTTON); //This causes wake from sleep
+
+//------------------------------------------------------------------------------
 //PERIPHERALS
 //------------------------------------------------------------------------------ 
 //BLE myble;
 WatchdogTimer watchdog(65.0); //Do not set to less than 4500ms or can cause issues with softdevice
-InterruptIn button(PN_IN_BUTTON); //This causes wake from sleep
 #if NEED_CONSOLE_OUTPUT
 Serial uart(PN_UART_TX, PN_UART_RX, 115200);
 #endif
 
 //------------------------------------------------------------------------------
+//TIMERS
+//------------------------------------------------------------------------------ 
+LowPowerTicker RTCticker; //no impact on power consumption
+
+//------------------------------------------------------------------------------
+//THREAD SEMAPHORES
+//------------------------------------------------------------------------------ 
+Semaphore mainthread;
+
+//------------------------------------------------------------------------------
 //SINGLETONS
 //------------------------------------------------------------------------------
 //NVStore &nvstore = NVStore::get_instance();
 
-
 //------------------------------------------------------------------------------
-// LOW LEVEL CRITICAL FUNCS
+// LOW LEVEL FUNCS
 //------------------------------------------------------------------------------ 
+void turnOffEverything() {
+    //vreg_en = 0;
+    LED1off();
+}
 void gotoSleep(long sleep_milliseconds) {
-    
+    turnOffEverything();
+    watchdog.kick();
     if (requireSoftReset) { //dont need to clear this var as reset changes it back to false
-        RET_unixtime_backup = time(NULL); //save unixtime for reset
         system_reset();
     }
-    
-    //button.fall(&buttonPress);
-    //button.rise(&buttonRelease);
-    
-    ThisThread::sleep_for(sleep_milliseconds);   
+    mainthread.wait(sleep_milliseconds);
 }
-
+void RTCtick() {
+    //RET_unixtime ++;
+    RET_RTCmicros += 100;
+    RET_RTCunixtime = (RET_RTCmicros / 1000);
+    //button logic - check for hold
+    if (RET_buttonHoldTime > 4000) {
+        RET_buttonHoldTime = 0;
+        RET_buttonPressCount = 0;
+        RET_mode_prev = RET_mode;
+        RET_mode = MODE_BUTTONHOLD;
+        mainthread.release();
+    } else {
+        if((RET_RTCmicros - RET_buttonPressTime) > 500) {
+            switch (RET_buttonPressCount) {   
+                case 1 :
+                    RET_mode_prev = RET_mode;
+                    RET_mode = MODE_BUTTONPRESS1;
+                    mainthread.release();
+                    break;
+                case 2 :
+                    RET_mode_prev = RET_mode;
+                    RET_mode = MODE_BUTTONPRESS2;
+                    mainthread.release();
+                    break;
+                default :
+                    //do nothing
+                    break;
+            }
+            RET_buttonPressCount = 0;
+        }
+    }
+}
 void factoryReset() {
-    firstBoot = true;
+    //firstBoot = true;
+    requireSoftReset = false;
     
-    //RESET VARS
-    RET_mode = 0;
-    RET_unixtime_backup = 0;
-    RET_buttonReleaseCount = 0;
-    RET_eventTime_location = 0;
-    RET_eventTime_environmental = 0;
-    RET_eventTime_activity = 0;
+    //RESET RETAINED VARS
+    RET_coldBoot = 1;
+    RET_mode = MODE_NORMAL;
+    RET_mode_prev = RET_mode;
+    RET_RTCunixtime = 0;
+    RET_RTCmicros = 0;
+    RET_eventTime_location_log = 0;
+    RET_eventTime_location_bc = 0;
+    RET_eventTime_environmental_log = 0;
+    RET_eventTime_environmental_bc = 0;
+    RET_eventTime_activity_bc = 0;
+    RET_eventTime_wakeFromDormant = 0;
     RET_motionPendingOffState = 0;
     RET_motionPendingOnState = 0;
     RET_motionState = 0;
@@ -97,127 +155,133 @@
     RET_motionStopTime = 0;
     RET_motionStartThreshold_seconds = 60;
     RET_motionStopThreshold_seconds = 60;
-    set_time(RET_unixtime_backup);
+    RET_motionTotalActivityHours = 0.0;
+    RET_buttonPressTime = 0;
+    RET_buttonPressCount = 0;
+    RET_buttonHoldTime = 0;
     
     //SET IDENTIFIER
     //uint32_t nv_value = 12345678;
     //int rc = nvstore.set(NV_IDENTIFIER, sizeof(nv_value), &nv_value);
 }
-
-void turnOffEverything() {
-    //vreg_en = 0;
-    led1 = 1;
-}
-
-//------------------------------------------------------------------------------
-// USER BUTTON
-//------------------------------------------------------------------------------ 
-void buttonPress() {
-    led1 = 0;
-    
-    //while(RET_buttonReleaseCount < 1){
-        //wait   
-    //}
-    
-    //led1 = 1;
-    /*
-    //RET_buttonPressTime = time(NULL);
-    RET_buttonReleaseCount ++;
-    led1 = 0;
-    for (int i = 0; i < RET_buttonReleaseCount; i++) {
-        led1 = 0;
-        wait_ms(100);
-        led1 = 1;
-        wait_ms(100);
-    */
-}
-void buttonRelease() {
-    led1 = 1;
-    //RET_buttonReleaseCount ++;
-    /*RET_buttonReleaseCount ++;
-    led1 = 0;
-    for (int i = 0; i < RET_buttonReleaseCount; i++) {
-        led1 = 0;
-        wait_ms(100);
-        led1 = 1;
-        wait_ms(100);
-    }*/
-}
-
-bool selfTest() {
+void selfTest() {
     //Accelerometer
     LIS3DH lis3dh(PN_SPI_MOSI, PN_SPI_MISO, PN_SPI_CS0, PN_SPI_CLK);
     uint8_t lis3dh_id; 
     lis3dh.LIS3DH_GetWHO_AM_I(&lis3dh_id);
-    if (asdf == 51) {
-        LED1blink(10,100);
-    }   
+    if (lis3dh_id == 51) {
+        LED1blink(10,50);
+    }
+}
+
+//------------------------------------------------------------------------------
+// USER BUTTON HANDLING
+//------------------------------------------------------------------------------ 
+void buttonPress() {
+    RET_buttonPressTime = RET_RTCmicros;
+}
+void buttonRelease() {
+    RET_buttonHoldTime = (RET_RTCmicros - RET_buttonPressTime);
+    //debounce catch
+    if((RET_RTCmicros - RET_buttonPressTime) >= 100) {
+        RET_buttonPressCount ++;
+    }
+}
+
+//------------------------------------------------------------------------------
+// MOTION FUNCS
+//------------------------------------------------------------------------------ 
+void checkMotion() {
+    if (lis3dh_int2) {
+        if (debugLED) LED1blink(2,100);
+        RET_motionTriggered = true;
+        if (!RET_motionPendingOnState) {
+            RET_motionPendingOnState = true;
+            RET_motionPendingOffState = false;
+            // Log start motion time
+            RET_motionStartTime = time(NULL);
+        }
+    } else {
+        if (debugLED) LED1blink(2,500);
+        RET_motionTriggered = false;
+        RET_motionPendingOnState = false;
+        if (!RET_motionPendingOffState) {
+            RET_motionPendingOffState = true;
+            //log stop motion time
+            RET_motionStopTime = time(NULL);
+        }
+    }
+    //calculate motion state
+    if (RET_motionPendingOnState) {
+        //check if above threshold
+        time_t inMotionForSeconds = (time(NULL) - RET_motionStartTime);
+        if (inMotionForSeconds >= RET_motionStartThreshold_seconds) {
+            RET_motionState = true;
+            if (debugLED) LED1blink(10,100);
+        }
+    }
+    if (RET_motionPendingOffState) {
+        time_t noMotionForSeconds = (time(NULL) - RET_motionStopTime);
+        if (noMotionForSeconds >= RET_motionStartThreshold_seconds) {
+            RET_motionState = false;
+            RET_motionTotalActivityHours += (float(RET_motionStopTime - RET_motionStartTime) / 3600.0); 
+            if (debugLED) LED1blink(5,500);
+        }
+    }
 }
 
 //------------------------------------------------------------------------------
 // STATE ENGINE
 //------------------------------------------------------------------------------ 
-
 void mainStateEngine() {
-    
-    RET_mode = MODE_NORMAL;
-    
     switch(RET_mode) {
         case MODE_SETUP :
             factoryReset();
             //selftest();
             break;
-            
         case MODE_NORMAL :
             //check and log motion
-            if (lis3dh_int1) {
-                LED1blink(2,100);
-                RET_motionTriggered = true;
-                if (!RET_motionPendingOnState) {
-                    RET_motionPendingOnState = true;
-                    RET_motionPendingOffState = false;
-                    // Log start motion time
-                    RET_motionStartTime = time(NULL);
-                    RET_motionStopTime = 0;                
-                }
-            } else {
-                LED1blink(2,500);
-                RET_motionTriggered = false;
-                RET_motionPendingOnState = false;
-                if (!RET_motionPendingOffState) {
-                    RET_motionPendingOffState = true;
-                    //log stop motion time
-                    RET_motionStopTime = time(NULL);
-                    RET_motionStartTime = 0;
-                }
+            checkMotion();
+            
+            //EVENTS
+            //Location
+            if(time(NULL) > RET_eventTime_location_log && RET_eventTime_location_log > 0) {
+                //getdata_environmental();
+                //event_location_log();
+            }
+            if(time(NULL) > RET_eventTime_location_bc && RET_eventTime_location_bc > 0) {
+                //getdata_battery();
+                //event_location_broadcast();
+            }
+            //Environmental
+            if(time(NULL) > RET_eventTime_environmental_log && RET_eventTime_environmental_log > 0) {
+                //event_environmental_log();
+            }
+            if(time(NULL) > RET_eventTime_environmental_bc && RET_eventTime_environmental_bc > 0) {
+                //event_environmental_bc();
             }
-            //calculate motion state
-            if (RET_motionPendingOnState) {
-                //check if above threshold
-                time_t inMotionForSeconds = (time(NULL) - RET_motionStartTime);
-                if (inMotionForSeconds >= RET_motionStartThreshold_seconds) {
-                    RET_motionState = true;
-                    LED1blink(10,100);
-                }
+            //Activity
+            if(time(NULL) > RET_eventTime_activity_bc && RET_eventTime_activity_bc > 0) {
+                //event_activity_bc();
+            }
+            break;
+        case MODE_DORMANT :
+            if (time(NULL) > RET_eventTime_wakeFromDormant) {
+                RET_mode = MODE_NORMAL;
             }
-            if (RET_motionPendingOffState) {
-                time_t noMotionForSeconds = (time(NULL) - RET_motionStopTime);
-                if (noMotionForSeconds >= RET_motionStartThreshold_seconds) {
-                    RET_motionState = false;
-                    LED1blink(5,500);
-                }
-            }
-            
+            break;  
+        case MODE_BUTTONPRESS1 :
+            LED1blink(2,300);
+            RET_mode = RET_mode_prev;
+            break; 
+        case MODE_BUTTONPRESS2 :
+            LED1blink(4,300);
+            RET_mode = RET_mode_prev;
+            break;  
+        case MODE_BUTTONHOLD :
+            LED1blink(10,300);
+            RET_mode = RET_mode_prev;
             break;
-            
-        case MODE_DORMANT :
-            //LIS3DH lis3dh(PN_SPI_MOSI, PN_SPI_MISO, PN_SPI_CS0, PN_SPI_CLK);
-            break;
-            
-        case MODE_OFF_48HRS :
-           
-            break;
-      
         default :
             RET_mode = MODE_SETUP;
     }
@@ -229,7 +293,12 @@
 //------------------------------------------------------------------------------ 
 
 int main() {
+    RTCticker.attach(&RTCtick, 0.1);
+    turnOffEverything();
     
+    button.fall(&buttonPress); //does this affect power?
+    button.rise(&buttonRelease);
+
     //CHECK IF THIS IS RESET
     //0x00000004 == soft reset  //0x00000002 == watchdog  //0x00000001 == button/hardreset 
     if (NRF_POWER->RESETREAS != 0xffffffff) {
@@ -240,30 +309,41 @@
             break;
             case 0x00000002  :
                 DEBUG("reset_reason: 0x%08x. - Watchdog\n",NRF_POWER->RESETREAS);
-                set_time(RET_unixtime_backup);
             break;
             case 0x00000004  :
                 DEBUG("reset_reason: 0x%08x. - Soft reset\n",NRF_POWER->RESETREAS);
-                set_time(RET_unixtime_backup);
             break;
         }
         NRF_POWER->RESETREAS = 0xffffffff;
     }
-        
+    //CHECK FOR FIRST BOOT
+    if (RET_coldBoot != 0) factoryReset();
+    
     while(true) {
-        turnOffEverything();
+        //SLEEP
+        if (RET_coldBoot != 1) gotoSleep(30000); //THIS HAS TO BE THE FIRST ITEM IN THE MAIN LOOP
         watchdog.kick();
+        
+        //MAIN LOGIC
+        DEBUG("mode: %i  time: %i, %i, %i, %i \n", RET_mode, RET_RTCmicros, RET_RTCunixtime, RET_buttonHoldTime, RET_buttonPressCount);
+        mainStateEngine();
+        
+        //PRE-SLEEP ACTIONS
+        lis3dh_configureForSleep(10,127);
+        RET_coldBoot = 0;
+        
+        
+        /*
         firstBoot = false; //temp
         if (!firstBoot) gotoSleep(10000);
         
         //INIT
-        Modem modem(PN_UART_TX, PN_UART_RX, PN_UART_CTS, PN_UART_RTS, PN_GSM_PWR_KEY, PN_VREG_EN);
+        //Modem modem(PN_UART_TX, PN_UART_RX, PN_UART_CTS, PN_UART_RTS, PN_GSM_PWR_KEY, PN_VREG_EN);
         
         //MAIN STATE ENGINE
-        //LED1blink(1,100);
-        mainStateEngine();
         
         //Configure for sleep
-        lis3dh_configureForSleep(10);
+        lis3dh_configureForSleep(10,127);
+        */
     }
 }
\ No newline at end of file