init
Dependencies: aconno_I2C Lis2dh12 WatchdogTimer
Diff: main.cpp
- Revision:
- 24:c161db07557f
- Parent:
- 23:a3b0ccf75ca5
- Child:
- 25:7adeb1a53360
--- a/main.cpp Sun Dec 23 01:37:00 2018 +0000 +++ b/main.cpp Sun Dec 23 17:24:42 2018 +0000 @@ -1,9 +1,10 @@ #include "main.h" //------------------------------------------------------------------------------ -//FUNCTION PROTOTYPES +//DEFINES //------------------------------------------------------------------------------ #define FW_VERSION 1 +#define SLEEP_FRAME 30000 //------------------------------------------------------------------------------ //FUNCTION PROTOTYPES @@ -12,6 +13,7 @@ static void selftest(void); static void buttonPress(void); static void buttonRelease(void); +static void dumpSettings(void); static void saveEventTimes(void); static void event_location_tx(void); @@ -22,7 +24,7 @@ bool GLOBAL_accel_healthy = false; bool GLOBAL_requireSoftReset = false; bool GLOBAL_motionStopFlagTriggered = false; -bool GLOBAL_debugLED = false; +bool GLOBAL_debugLED = true; bool GLOBAL_needToConfigureLis3dh = false; bool GLOBAL_registeredOnNetwork = false; bool GLOBAL_modemOn = false; @@ -38,14 +40,13 @@ //IDENTITY static long long RET_imei __attribute__((section("noinit"),zero_init)); //SETTINGS -static int RET_setting_firmware __attribute__((section("noinit"),zero_init)); +static int RET_setting_firmware __attribute__((section("noinit"),zero_init)); //must be int to support negative value static uint8_t RET_setting_location_mode __attribute__((section("noinit"),zero_init)); static uint8_t RET_setting_location_accuracy __attribute__((section("noinit"),zero_init)); static uint32_t RET_setting_location_tx_interval_mins __attribute__((section("noinit"),zero_init)); static uint32_t RET_setting_location_tx_failsafe_hrs __attribute__((section("noinit"),zero_init)); static uint16_t RET_setting_location_timeout __attribute__((section("noinit"),zero_init)); -static uint8_t RET_setting_activity_mode __attribute__((section("noinit"),zero_init)); -static uint32_t RET_setting_activity_tx_interval_hrs __attribute__((section("noinit"),zero_init)); +static uint32_t RET_setting_activity_tx_interval_hrs __attribute__((section("noinit"),zero_init)); static uint32_t RET_setting_environmental_tx_interval_mins __attribute__((section("noinit"),zero_init)); static uint16_t RET_setting_motion_g __attribute__((section("noinit"),zero_init)); static time_t RET_setting_motion_start_seconds __attribute__((section("noinit"),zero_init)); @@ -56,6 +57,7 @@ static uint16_t RET_setting_beacon_interval_seconds __attribute__((section("noinit"),zero_init)); static uint16_t RET_setting_beacon_scan __attribute__((section("noinit"),zero_init)); //STATE +static uint16_t RET_sleepToggle __attribute__((section("noinit"),zero_init)); static uint8_t RET_coldBoot __attribute__((section("noinit"),zero_init)); static bool RET_haveSettings __attribute__((section("noinit"),zero_init)); static uint8_t RET_state __attribute__((section("noinit"),zero_init)); @@ -75,7 +77,8 @@ 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_activityData[130] __attribute__((section("noinit"),zero_init)); +static time_t RET_motionFrameStart __attribute__((section("noinit"),zero_init)); +static char RET_activityData[140] __attribute__((section("noinit"),zero_init)); //IMPACT static bool RET_impactTriggered __attribute__((section("noinit"),zero_init)); //EVENTS LOGGING @@ -87,8 +90,9 @@ static time_t RET_eventTime_environmental_tx __attribute__((section("noinit"),zero_init)); static time_t RET_eventTime_activity_tx __attribute__((section("noinit"),zero_init)); static time_t RET_eventTime_wakeFromDormant __attribute__((section("noinit"),zero_init)); -//DUPLICATES -static time_t RET_RTCunixtime2 __attribute__((section("noinit"),zero_init)); +//DUPLICATES MEM INIT CHECK +static time_t RET_RTCunixtime_bu __attribute__((section("noinit"),zero_init)); +static uint32_t RET_memTest __attribute__((section("noinit"),zero_init)); #elif defined ( __GNUC__ ) #elif defined ( __ICCARM__ ) #endif @@ -128,12 +132,14 @@ LED1off(); } void gotoSleep(long sleep_milliseconds) { + /* turnOffEverything(); watchdogKick(); if (GLOBAL_requireSoftReset) { //dont need to clear this var as reset changes it back to false system_reset(); } mainthread.wait(sleep_milliseconds); + */ } void setState(uint8_t state) { RET_state_prev = RET_state; @@ -141,15 +147,38 @@ DEBUG("STATEREADBACK %d\n",RET_state) } bool memoryIntegrityCheck() { + bool pass = true; + //check memory is init correct + if (RET_memTest != 12345) { + pass = false; + } //Check clocks match and are in range - if (RET_RTCunixtime != RET_RTCunixtime && RET_RTCunixtime > 1545412457) { - RET_coldBoot = 1; - return false; - } else { - return true; - } + if (RET_RTCunixtime != RET_RTCunixtime || RET_RTCunixtime < 1545412457) { + pass = false; + } + return pass; } -void getBatteryV() { +void dumpSettings() { + DEBUG("RET_RTCunixtime:%u \n",RET_RTCunixtime); + DEBUG("RET_setting_firmware:%d \n",RET_setting_firmware); + DEBUG("RET_state:%d \n",RET_state); + DEBUG("RET_setting_location_mode:%d \n",RET_setting_location_mode); + DEBUG("RET_setting_location_accuracy:%d \n",RET_setting_location_accuracy); + DEBUG("RET_setting_location_tx_interval_mins:%d \n",RET_setting_location_tx_interval_mins); + DEBUG("RET_setting_location_tx_failsafe_hrs:%d \n",RET_setting_location_tx_failsafe_hrs); + DEBUG("RET_setting_location_timeout:%d \n",RET_setting_location_timeout); + DEBUG("RET_setting_activity_tx_interval_hrs:%d \n",RET_setting_activity_tx_interval_hrs); + DEBUG("RET_setting_environmental_tx_interval_mins:%d \n",RET_setting_environmental_tx_interval_mins); + DEBUG("RET_setting_motion_g:%d \n",RET_setting_motion_g); + DEBUG("RET_setting_motion_start_seconds:%d \n",RET_setting_motion_start_seconds); + DEBUG("RET_setting_motion_stop_seconds:%d \n",RET_setting_motion_stop_seconds); + DEBUG("RET_setting_impact_g:%d \n",RET_setting_impact_g); + DEBUG("RET_setting_impact_alert:%d \n",RET_setting_impact_alert); + DEBUG("RET_setting_connection_timeout:%d \n",RET_setting_connection_timeout); + DEBUG("RET_setting_beacon_interval_seconds:%d \n",RET_setting_beacon_interval_seconds); + DEBUG("RET_setting_beacon_scan:%d \n",RET_setting_beacon_scan); +} +void getBatteryV() { //this creates an extra 400ua of power usage!!! NRF52_SAADC batteryIn; batteryIn.addChannel(9); // vdd for battery batteryIn.calibrate(); @@ -181,7 +210,7 @@ void RTCtick() { //YOU MUST NOT CALL ANY OTHER FUNCTIONS OR DEBUG FROM INSIDE HERE!!! OR IT LOCKS UP THE DEVICE, just change vars RET_RTCunixtime += 1; - RET_RTCunixtime2 += 1; + RET_RTCunixtime_bu += 1; GLOBAL_RTCunixtime = RET_RTCunixtime; @@ -219,18 +248,20 @@ led1 = !led1; } } + void factoryReset() { - DEBUG("Factory Reset \n"); - Thread::wait(200); //wait to ensure that devices are turned off + //MEM CHECK + RET_memTest = 12345; //IDENTITY RET_imei = 0; //STATE + RET_sleepToggle = 0; RET_coldBoot = 1; RET_haveSettings = 0; RET_state = STATE_SETUP; RET_state_prev = RET_state; RET_RTCunixtime = 0; - RET_RTCunixtime = 2; + RET_RTCunixtime_bu = 0; RET_SetupRunAt = 0; //SETTINGS RET_setting_firmware = 0; @@ -263,6 +294,7 @@ RET_motionPendingOffState = 0; RET_motionState = 0; RET_motionTotalActivityHours = 0.0; + RET_motionFrameStart = 0; memset(RET_activityData,0,sizeof(RET_activityData)); //IMPACT RET_impactTriggered = 0; @@ -276,6 +308,7 @@ RET_eventTime_wakeFromDormant = 0; //OTHER LOCAL GLOBALS GLOBAL_requireSoftReset = false; + //PERIPHERAL RESET lis3dh_configureForSleep(10,127); } @@ -313,7 +346,7 @@ //------------------------------------------------------------------------------ void checkMotion() { if (lis3dh_int2) { - if (GLOBAL_debugLED) LED1blink(2,100); + if (GLOBAL_debugLED) LED1blink(1,100); RET_motionTriggered = true; GLOBAL_needToConfigureLis3dh = true; //interrupt has fire so need to clear it if (!RET_motionPendingOnState) { @@ -323,7 +356,6 @@ RET_motionStartTime = RET_RTCunixtime; } } else { - if (GLOBAL_debugLED) LED1blink(2,500); RET_motionTriggered = false; RET_motionPendingOnState = false; if (!RET_motionPendingOffState) { @@ -335,25 +367,28 @@ //calculate motion state if (RET_motionPendingOnState) { //check if above threshold - time_t inMotionForSeconds = (RET_RTCunixtime - RET_motionStartTime); - if (inMotionForSeconds >= RET_setting_motion_start_seconds) { + time_t inMotionForSeconds = (RET_RTCunixtime - RET_motionStartTime) + 2; //Plus 2 to account for rounding and non exact clocks + if (inMotionForSeconds >= RET_setting_motion_start_seconds && RET_motionState == false) { RET_motionState = true; RET_motionTriggeredInTXInterval = true; if (GLOBAL_debugLED) LED1blink(10,100); - if (RET_setting_activity_mode == 1) { - //RET_activityData + if (RET_setting_location_tx_failsafe_hrs > 0) { + time_t epochOffsetMins = ((RET_RTCunixtime - RET_motionFrameStart) / 60); + sprintf(RET_activityData+strlen(RET_activityData),"1.%u!",epochOffsetMins); } } } if (RET_motionPendingOffState) { - time_t noMotionForSeconds = (RET_RTCunixtime - RET_motionStopTime); - if (noMotionForSeconds >= RET_setting_motion_stop_seconds) { + time_t noMotionForSeconds = (RET_RTCunixtime - RET_motionStopTime) + 2; //Plus 2 to account for rounding and non exact clocks + if (noMotionForSeconds >= RET_setting_motion_stop_seconds && RET_motionState == true) { + RET_motionPendingOffState = false; RET_motionState = false; GLOBAL_motionStopFlagTriggered = true; RET_motionTotalActivityHours += (float(RET_motionStopTime - RET_motionStartTime) / 3600.0); if (GLOBAL_debugLED) LED1blink(5,500); - if (RET_setting_activity_mode == 1) { - + if (RET_setting_location_tx_failsafe_hrs > 0) { + time_t epochOffsetMins = ((RET_RTCunixtime - RET_motionFrameStart) / 60); + sprintf(RET_activityData+strlen(RET_activityData),"0.%u!",epochOffsetMins); } } } @@ -410,26 +445,7 @@ return false; } } -bool dumpSettings() { - DEBUG("RET_RTCunixtime:%u \n",RET_RTCunixtime); - DEBUG("RET_setting_firmware:%d \n",RET_setting_firmware); - DEBUG("RET_state:%d \n",RET_state); - DEBUG("RET_setting_location_mode:%d \n",RET_setting_location_mode); - DEBUG("RET_setting_location_accuracy:%d \n",RET_setting_location_accuracy); - DEBUG("RET_setting_location_tx_interval_mins:%d \n",RET_setting_location_tx_interval_mins); - DEBUG("RET_setting_location_tx_failsafe_hrs:%d \n",RET_setting_location_tx_failsafe_hrs); - DEBUG("RET_setting_location_timeout:%d \n",RET_setting_location_timeout); - DEBUG("RET_setting_activity_tx_interval_hrs:%d \n",RET_setting_activity_tx_interval_hrs); - DEBUG("RET_setting_environmental_tx_interval_mins:%d \n",RET_setting_environmental_tx_interval_mins); - DEBUG("RET_setting_motion_g:%d \n",RET_setting_motion_g); - DEBUG("RET_setting_motion_start_seconds:%d \n",RET_setting_motion_start_seconds); - DEBUG("RET_setting_motion_stop_seconds:%d \n",RET_setting_motion_stop_seconds); - DEBUG("RET_setting_impact_g:%d \n",RET_setting_impact_g); - DEBUG("RET_setting_impact_alert:%d \n",RET_setting_impact_alert); - DEBUG("RET_setting_connection_timeout:%d \n",RET_setting_connection_timeout); - DEBUG("RET_setting_beacon_interval_seconds:%d \n",RET_setting_beacon_interval_seconds); - DEBUG("RET_setting_beacon_scan:%d \n",RET_setting_beacon_scan); -} + void saveEventTimes() { //SET EVENT TIMES if(RET_setting_location_tx_interval_mins > 0) { @@ -441,6 +457,7 @@ DEBUG("EVENTSET - LOCATION FAILSAFE TX at %u\n",RET_eventTime_location_failsafe_tx); } if(RET_setting_activity_tx_interval_hrs > 0) { + RET_motionFrameStart = RET_RTCunixtime; //SET START FRAME INITAL RET_eventTime_activity_tx = (RET_RTCunixtime + (RET_setting_activity_tx_interval_hrs * 3600)); DEBUG("EVENTSET - ACTIVITY TX at %u\n",RET_eventTime_activity_tx); } @@ -464,7 +481,7 @@ if (modem.registerOnNetwork(2,180000)) { int timetaken = (RET_RTCunixtime - GLOBAL_wakeTime); char bytestosend[160]; - snprintf(bytestosend,sizeof(bytestosend),"(%s,im:%lld,f:%d,v:%.2f,e:%d,fr:1,z:SETUP,c:1)\0",GLOBAL_defaultApi,GLOBAL_imei,FW_VERSION,GLOBAL_voltage,timetaken); + snprintf(bytestosend,sizeof(bytestosend),"(%s,im:%lld,a:loc,f:%d,v:%.2f,e:%d,z:SETUP,c:1)\0",GLOBAL_defaultApi,GLOBAL_imei,FW_VERSION,GLOBAL_voltage,timetaken); char result[180]; snprintf(result,sizeof(result),"%s",modem.USSDmessage(bytestosend, true, 2, GLOBAL_defaultApi)); if (result != "err") { @@ -503,7 +520,7 @@ if (modem.registerOnNetwork(2,180000)) { int timetaken = (RET_RTCunixtime - GLOBAL_wakeTime); char bytestosend[160]; - snprintf(bytestosend,sizeof(bytestosend),"(%s,f:%d,t:%.2f,v:%.2f,z:SHAKERTEST-%d,e:%d,c:1)\0",GLOBAL_defaultApi,FW_VERSION,temperature,GLOBAL_voltage,selftestresult,timetaken); + snprintf(bytestosend,sizeof(bytestosend),"(%s,a:loc,f:%d,t:%.2f,v:%.2f,z:SHAKERTEST-%d,e:%d,c:1)\0",GLOBAL_defaultApi,FW_VERSION,temperature,GLOBAL_voltage,selftestresult,timetaken); char result[180]; bool getSettings = true; snprintf(result,sizeof(result),"%s",modem.USSDmessage(bytestosend, getSettings, 2, GLOBAL_defaultApi)); @@ -535,7 +552,7 @@ if (modem.registerOnNetwork(2,180000)) { int timetaken = (RET_RTCunixtime - GLOBAL_wakeTime); char bytesToSend[160]; - snprintf(bytesToSend,sizeof(bytesToSend),"(%s,f:%d,t:%.2f,v:%.2f,z:OK,e:%d,c:1%s)\0",GLOBAL_defaultApi,FW_VERSION,temperature,GLOBAL_voltage,timetaken,locString); + snprintf(bytesToSend,sizeof(bytesToSend),"(%s,a:loc,f:%d,t:%.2f,v:%.2f,z:OK,e:%d,c:1%s)\0",GLOBAL_defaultApi,FW_VERSION,temperature,GLOBAL_voltage,timetaken,locString); char result[180]; bool getSettings = true; snprintf(result,sizeof(result),"%s",modem.USSDmessage(bytesToSend, getSettings, 2, GLOBAL_defaultApi)); @@ -551,6 +568,32 @@ RET_motionTriggeredInTXInterval = 0; saveEventTimes(); } + +void event_activity_tx() { + DEBUG("ACTIVITY TX\n"); + getBatteryV(); + float temperature = getTemperature(); + Modem modem(PN_UART_TX, PN_UART_RX, PN_UART_CTS, PN_UART_RTS, PN_GSM_PWR_KEY, PN_VREG_EN, PN_GSM_WAKE_DISABLE); + if (modem.on()) { + //SEND DATA + if (modem.registerOnNetwork(2,180000)) { + char bytesToSend[160]; + snprintf(bytesToSend,sizeof(bytesToSend),"(%s,a:act,e:%s,t:%u,r:%.2f,c:1)\0",GLOBAL_defaultApi,RET_activityData,RET_motionFrameStart,RET_motionTotalActivityHours); + char result[180]; + bool getResponse = false; + snprintf(result,sizeof(result),"%s",modem.USSDmessage(bytesToSend, getResponse, 2, GLOBAL_defaultApi)); + if (result != "err") { + //RESET ACTIVITY FRAME + memset(RET_activityData,0,sizeof(RET_activityData)); + if (RET_haveSettings) {RET_motionFrameStart = RET_RTCunixtime;} + } + } + } + //RESETS + RET_motionTriggeredInTXInterval = 0; + saveEventTimes(); +} + //------------------------------------------------------------------------------ // STATE ENGINE //------------------------------------------------------------------------------ @@ -573,24 +616,24 @@ //check and log motion checkMotion(); - //EVENTS - //LOCATION + //LOCATION EVENT bool run_location_tx = false; - if(RET_RTCunixtime >= RET_eventTime_location_tx && RET_eventTime_location_tx > 0) { - DEBUG("INTERVAL LOC TX...\n"); - run_location_tx = true; - } + if(RET_RTCunixtime >= RET_eventTime_location_tx && RET_eventTime_location_tx > 0) { DEBUG("INTERVAL LOC TX...\n"); run_location_tx = true; } //Location Failsafe timer catchall if(RET_RTCunixtime >= RET_eventTime_location_failsafe_tx && RET_eventTime_location_failsafe_tx > 0) { run_location_tx = true; } if (run_location_tx) { event_location_tx(); } - //ACTIVITY TX - if(RET_RTCunixtime >= RET_eventTime_activity_tx && RET_eventTime_activity_tx > 0) { - //event_activity_tx(); - event_shakertest_tx(); + //ACTIVITY EVENT + bool run_activity_tx = false; + if(RET_RTCunixtime >= RET_eventTime_activity_tx && RET_eventTime_activity_tx > 0) { + run_activity_tx = true; + //event_shakertest_tx(); } + if (strlen(RET_activityData) > 130) { run_activity_tx = true; } + if (run_activity_tx) {event_activity_tx();} + break; case STATE_DORMANT : if (RET_RTCunixtime >= RET_eventTime_wakeFromDormant) { @@ -643,49 +686,61 @@ // MAIN //------------------------------------------------------------------------------ int main() { + //INIT turnOffEverything(); - memoryIntegrityCheck(); + if (!memoryIntegrityCheck()) { RET_coldBoot = 1;} + RTCticker.attach(&RTCtick, 1.0); + button.fall(&buttonPress); //does this affect power? + button.rise(&buttonRelease); + copyRETtoGLOBAL(); //CHECK IF THIS IS RESET //0x00000004 == soft reset //0x00000002 == watchdog //0x00000001 == button/hardreset if (NRF_POWER->RESETREAS != 0xffffffff) { switch(NRF_POWER->RESETREAS) { case 0x00000001 : - DEBUG("reset_reason: 0x%08x. - Hard Reset - CSTATE:%d\n",NRF_POWER->RESETREAS, RET_state); + DEBUG("reset_reason: 0x%08x. Hard Reset STATE:%d\n",NRF_POWER->RESETREAS, RET_state); RET_coldBoot = 1; break; case 0x00000002 : - DEBUG("reset_reason: 0x%08x. - Watchdog - CSTATE:%d\n",NRF_POWER->RESETREAS, RET_state); + DEBUG("Watchdog reset STATE:%d\n",RET_state); break; case 0x00000004 : - DEBUG("reset_reason: 0x%08x. - Soft reset - CSTATE:%d\n",NRF_POWER->RESETREAS, RET_state); + DEBUG("Soft reset STATE:%d SLEEP:%d\n",RET_state, RET_sleepToggle); break; } NRF_POWER->RESETREAS = 0xffffffff; } - //DEBUG + dumpSettings(); //CHECK FOR FIRST BOOT - if (RET_coldBoot == 1) { factoryReset(); } + if (RET_coldBoot == 1) { factoryReset(); dumpSettings(); } - //INIT - RTCticker.attach(&RTCtick, 1.0); - button.fall(&buttonPress); //does this affect power? - button.rise(&buttonRelease); - copyRETtoGLOBAL(); + //SHALL WE SLEEP + if (RET_sleepToggle == 1) { + RET_sleepToggle = 0; + NRF_UART0->TASKS_SUSPEND = 1; + NRF_UART0->ENABLE = 0; //NO MORE SERIAL OR DEBUG OUTPUTS AFTER THIS + mainthread.wait(SLEEP_FRAME); + system_reset(); + } while(true) { - memoryIntegrityCheck(); + if (!memoryIntegrityCheck()) { RET_coldBoot = 1;} watchdogKick(); - //LOG START TIME GLOBAL_wakeTime = RET_RTCunixtime; //MAIN LOGIC - DEBUG("STATE:%d, HAVESETTINGS:%d, RTC:%u, BOOTAT:%u, LOC:%u, LOCFS:%u, ACT:%u \n", RET_state, RET_haveSettings, RET_RTCunixtime,RET_SetupRunAt,RET_eventTime_location_tx,RET_eventTime_location_failsafe_tx,RET_eventTime_activity_tx); + DEBUG("STATE:%d, HAVESETTINGS:%d, MOTION: %d, RTC:%u, BOOTAT:%u, LOC:%u, LOCFS:%u, ACT:%u \n", RET_state, RET_haveSettings, RET_motionState, RET_RTCunixtime,RET_SetupRunAt,RET_eventTime_location_tx,RET_eventTime_location_failsafe_tx,RET_eventTime_activity_tx); + DEBUG("ACTIVITY:%s\n",RET_activityData); mainStateEngine(); + //sprintf(RET_activityData+strlen(RET_activityData),"test"); + //int result = strlen(RET_activityData); + //DEBUG("size:%d\n",result) + //PRE-SLEEP ACTIONS if (GLOBAL_needToConfigureLis3dh) { lis3dh_configureForSleep(10,127); } if (GLOBAL_modemOn) { @@ -695,10 +750,13 @@ } RET_coldBoot = 0; - //SLEEP DIFFERENT FOR THIS SHAKER TEST VERSION - AS IS WILL GIVE 450ua sleep + //SLEEP DIFFERENT FOR THIS SHAKER TEST VERSION - AS IS WILL GIVE 450ua sleep if in motion + /* NRF_UART0->TASKS_SUSPEND = 1; NRF_UART0->ENABLE = 0; //NO MORE SERIAL OR DEBUG OUTPUTS AFTER THIS - mainthread.wait(30000); + mainthread.wait(SLEEP_FRAME); + */ + RET_sleepToggle = 1; system_reset(); } } \ No newline at end of file