init
Dependencies: aconno_I2C Lis2dh12 WatchdogTimer
Diff: main.cpp
- 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