init

Dependencies:   aconno_I2C Lis2dh12 WatchdogTimer

Revision:
34:4493c9f6d707
Parent:
33:760005331b4c
Child:
35:d9421d57d116
--- a/main.cpp	Thu Jan 03 10:09:38 2019 +0000
+++ b/main.cpp	Sun Jan 13 23:40:56 2019 +0000
@@ -5,7 +5,11 @@
 //------------------------------------------------------------------------------ 
 #define FW_VERSION 1
 
-#define DEFAULT_SLEEP_FRAME                 30000
+//MODES
+#define USE_NRF_TEMP_SENSOR                 1
+
+//DEFAULT SETTINGS
+#define DEFAULT_SLEEP_FRAME                 60000
 #define DEFAULT_LOCATION_MODE               2
 #define DEFAULT_LOCATION_ACCURACY           2  // 0 = no location, 1 = cl only, 2 = gps then cl
 #define DEFAULT_LOCATION_TX_INTERVAL_MINS   1440
@@ -31,92 +35,77 @@
 static void event_location_tx(void);
 
 //------------------------------------------------------------------------------
-//GLOBAL VARS / CLEARED ON SLEEP (IF USING SOFT REBOOT HACK)
+//GLOBAL VARS
 //------------------------------------------------------------------------------ 
 char* GLOBAL_defaultApi = "b:gps2";
 bool GLOBAL_accel_healthy = false;
-bool GLOBAL_requireSoftReset = false;
 bool GLOBAL_motionStopFlagTriggered = false;
 bool GLOBAL_debugLED = true;
-bool GLOBAL_needToConfigureLis3dh = false;
+bool GLOBAL_needToConfigureLis3dh = true;
 bool GLOBAL_registeredOnNetwork = false;
 bool GLOBAL_modemOn = false;
 bool GLOBAL_LEDSequenceinProgress = false;
-time_t GLOBAL_RTCunixtime = 0;
 time_t GLOBAL_wakeTime = 0;
-char GLOBAL_exceptionString[10];
+char GLOBAL_exceptionString[15];
+bool NRFuart_enabled = false;
+char GLOBAL_debug_buffer[200];
+
 
-//------------------------------------------------------------------------------
-//RETAINED NOINIT RAM VARS
-//------------------------------------------------------------------------------ 
-#if defined ( __CC_ARM ) /** THIS IS THE MBED ONLINE COMPILER TOOLCHAIN*/ //MUST BE STATICS
-//IDENTITY
-static long long        RET_imei                                        __attribute__((section("noinit"),zero_init));
-//SETTINGS
-static int              RET_setting_firmware                            __attribute__((section("noinit"),zero_init)); //must be int to support negative value
-static uint32_t         RET_setting_minimumupdate_hrs                   __attribute__((section("noinit"),zero_init));
-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 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));
-static time_t           RET_setting_motion_stop_seconds                 __attribute__((section("noinit"),zero_init));
-static uint16_t         RET_setting_impact_g                            __attribute__((section("noinit"),zero_init));
-static uint8_t          RET_setting_impact_alert                        __attribute__((section("noinit"),zero_init));
-static uint16_t         RET_setting_connection_timeout                  __attribute__((section("noinit"),zero_init));
-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));
+static int              RET_setting_firmware;
+static uint32_t         RET_setting_minimumupdate_hrs;
+static uint8_t          RET_setting_location_mode;
+static uint8_t          RET_setting_location_accuracy;
+static uint32_t         RET_setting_location_tx_interval_mins;
+static uint32_t         RET_setting_location_tx_failsafe_hrs;
+static uint16_t         RET_setting_location_timeout;
+static uint32_t         RET_setting_activity_tx_interval_hrs;
+static uint32_t         RET_setting_environmental_tx_interval_mins;
+static uint16_t         RET_setting_motion_g;
+static time_t           RET_setting_motion_start_seconds;
+static time_t           RET_setting_motion_stop_seconds;
+static uint16_t         RET_setting_impact_g;
+static uint8_t          RET_setting_impact_alert;
+static uint16_t         RET_setting_connection_timeout;
+static uint16_t         RET_setting_beacon_interval_seconds;
+static uint16_t         RET_setting_beacon_scan;
 //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));
-static uint8_t          RET_state_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 time_t           RET_SetupRunAt                                  __attribute__((section("noinit"),zero_init));
-static time_t           RET_SettingsGotAt                               __attribute__((section("noinit"),zero_init));
+static uint8_t          RET_coldBoot = 1;
+static bool             RET_haveSettings;
+static uint8_t          RET_state;
+static uint8_t          RET_state_prev;
+static uint8_t          RET_buttonPressCount;
+static time_t           RET_buttonPressTime;
+static time_t           RET_buttonHoldTime;
+static time_t           RET_RTCunixtime;
+static time_t           RET_SetupRunAt;
+static time_t           RET_SettingsGotAt;
 //MOTION STATE
-static bool             RET_motionTriggered                             __attribute__((section("noinit"),zero_init));
-static bool             RET_motionTriggeredInTXInterval                 __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 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 time_t           RET_motionFrameStart                            __attribute__((section("noinit"),zero_init));
-static char             RET_activityData[140]                           __attribute__((section("noinit"),zero_init));
+static bool             RET_motionTriggered;
+static bool             RET_motionTriggeredInTXInterval;
+static time_t           RET_motionStartTime;
+static time_t           RET_motionStopTime;
+static bool             RET_motionPendingOnState;
+static bool             RET_motionPendingOffState;
+static bool             RET_motionState;
+static float            RET_motionTotalActivityHours;
+static time_t           RET_motionFrameStart;
+static char             RET_activityData[140];
 //IMPACT
-static bool             RET_impactTriggered                             __attribute__((section("noinit"),zero_init));
+static bool             RET_impactTriggered;
 //EVENTS LOGGING
-static time_t           RET_eventTime_location_log                      __attribute__((section("noinit"),zero_init));
-static time_t           RET_eventTime_environmental_log                 __attribute__((section("noinit"),zero_init));
+static time_t           RET_eventTime_location_log;
+static time_t           RET_eventTime_environmental_log;
 //EVENTS TX
-static time_t           RET_eventTime_location_tx                       __attribute__((section("noinit"),zero_init));
-static time_t           RET_eventTime_location_failsafe_tx              __attribute__((section("noinit"),zero_init));
-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 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
+static time_t           RET_eventTime_location_tx;
+static time_t           RET_eventTime_location_failsafe_tx;
+static time_t           RET_eventTime_environmental_tx;
+static time_t           RET_eventTime_activity_tx;
+static time_t           RET_eventTime_wakeFromDormant;
 
 //------------------------------------------------------------------------------
 //GPIO
 //------------------------------------------------------------------------------ 
-InterruptIn button(PN_IN_BUTTON); //This causes wake from sleep
-DigitalOut vreg_en(PN_VREG_EN);
+InterruptIn button(PN_IN_BUTTON);
 
 //------------------------------------------------------------------------------
 //PERIPHERALS
@@ -124,11 +113,10 @@
 //BLE myble;
 WatchdogTimer watchdog(300.0); //Do not set to less than 4500ms or can cause issues with softdevice
 void watchdogKick() {watchdog.kick();}
-//SERIAL DEBUG?
-#if CONSOLE_DEBUG
-    Serial uart(PN_UART_TX, PN_UART_RX, 115200);
-#endif
-        
+SI7060 si7060(PN_I2C_SDA, PN_I2C_SCL);
+LIS3DH lis3dh(PN_SPI_MOSI, PN_SPI_MISO, PN_SPI_CS0, PN_SPI_CLK);
+Modem modem(PN_GSM_PWR_KEY, PN_VREG_EN, PN_GSM_WAKE_DISABLE);
+
 //------------------------------------------------------------------------------
 //TIMERS
 //-----------------------------------------------mi------------------------------- 
@@ -141,60 +129,194 @@
 
 //------------------------------------------------------------------------------
 // LOW LEVEL FUNCS
-//------------------------------------------------------------------------------ 
-void turnOffEverything() {
-    vreg_en = 0;
-    LED1off();
+//------------------------------------------------------------------------------
+void NRFuart_init_nohwfc() {
+    if(NRFuart_enabled == false) {
+        //Configure UART0 pins.
+        nrf_gpio_cfg_output(PN_UART_TX);
+        nrf_gpio_cfg_input(PN_UART_RX, NRF_GPIO_PIN_NOPULL);
+        NRF_UART0->PSELTXD = PN_UART_TX;
+        NRF_UART0->PSELRXD = PN_UART_RX;
+        NRF_UART0->CONFIG = (UART_CONFIG_PARITY_Excluded << UART_CONFIG_PARITY_Pos) | UART_CONFIG_HWFC_Disabled;
+        NRF_UART0->BAUDRATE = NRF_UART_BAUDRATE_115200;
+        NRF_UART0->ENABLE = UART_ENABLE_ENABLE_Enabled;
+        NRF_UART0->EVENTS_RXDRDY = 0;
+        NRF_UART0->EVENTS_TXDRDY = 0;
+        NRF_UART0->EVENTS_ERROR  = 0;
+        NRF_UART0->EVENTS_TXDRDY = 0;
+        NRF_UART0->TASKS_STARTRX = 1;
+        NRF_UART0->TASKS_STARTTX = 1;
+        
+        //NRF_UART0->INTENCLR = 0xffffffffUL;
+        //NRF_UART0->INTENSET = UART_INTENSET_RXDRDY_Msk;
+        /*NRF_UART0->INTENSET = (UART_INTENSET_RXDRDY_Set << UART_INTENSET_RXDRDY_Pos) |
+                              (UART_INTENSET_TXDRDY_Set << UART_INTENSET_TXDRDY_Pos) |
+                              (UART_INTENSET_ERROR_Set << UART_INTENSET_ERROR_Pos);*/    
+        //NVIC_ClearPendingIRQ(UART0_IRQn);
+        //NVIC_SetPriority(UART0_IRQn, 1); //3
+        //NVIC_EnableIRQ(UART0_IRQn);
+        //NVIC_SetVector(UART0_IRQn, (uint32_t) UART0_IRQHandler);
+    }
+    NRFuart_enabled = true;
+};
+void NRFuart_uninit() {
+    if (NRFuart_enabled) {
+        NVIC_DisableIRQ(UART0_IRQn);
+        NRF_UART0->INTENCLR = 0xffffffffUL;
+        NRF_UART0->TASKS_STOPRX = 1;
+        NRF_UART0->TASKS_STOPTX = 1;
+        NRF_UART0->ENABLE = UART_ENABLE_ENABLE_Disabled;
+        NRF_UART0->PSELTXD = 0xFFFFFFFF;
+        NRF_UART0->PSELRXD = 0xFFFFFFFF;
+        NRF_UART0->PSELRTS = 0xFFFFFFFF;
+        NRF_UART0->PSELCTS = 0xFFFFFFFF;
+        NRFuart_enabled = false;
+    }
+};
+void NRFuart_putc(char byte) {
+    if (!NRFuart_enabled) NRFuart_init_nohwfc();
+    NRF_UART0->TXD = byte;
+    uint32_t safetycounter = 0;
+    while(NRF_UART0->EVENTS_TXDRDY != 1 && safetycounter < 10000)
+    {
+        safetycounter ++; // Wait for the current TXD data to be sent.
+    }
+    NRF_UART0->EVENTS_TXDRDY = 0;
+};
+void NRFuart_puts(char* bytes) {
+    if (!NRFuart_enabled) NRFuart_init_nohwfc();
+    for(int i = 0; bytes[i] != '\0'; i++) {
+        NRFuart_putc(bytes[i]);
+    }
+};
+void NRFuart_puts_debug(char* bytes) {
+    if (!NRFuart_enabled) NRFuart_init_nohwfc();
+    for(int i = 0; bytes[i] != '\0'; i++) {
+        NRFuart_putc(bytes[i]);
+    }
+    NRFuart_putc('\n');
+};
+void debug_prep(){
+    memset(GLOBAL_debug_buffer, '\0', sizeof(GLOBAL_debug_buffer));   
 }
-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();
+void debug_exe(){
+    NRFuart_puts_debug(GLOBAL_debug_buffer);
+}
+char NRFuart_getc() {
+    if (!NRFuart_enabled) NRFuart_init_nohwfc();
+    uint32_t safetycounter = 0;
+    while(NRF_UART0->EVENTS_RXDRDY != 1 && safetycounter < 10000){
+        safetycounter ++;
+    }
+    NRF_UART0->EVENTS_RXDRDY = 0;
+    return (uint8_t)NRF_UART0->RXD;
+};
+char* NRFuart_gets(char terminator) {
+    if (!NRFuart_enabled) NRFuart_init_nohwfc();
+    static char buffer[200];
+    int charindex = 0;
+    memset(buffer,'\0',sizeof(buffer));
+    while(1) {
+        if (NRF_UART0->EVENTS_RXDRDY == 0) {
+            //Nothing available from the UART.
+            continue;
+        } else {
+            char inbyte = NRFuart_getc();
+            if (inbyte == terminator) {
+                break;
+            } else {
+                buffer[charindex] = inbyte;
+                charindex++;
+            }
+        }
     }
-    mainthread.wait(sleep_milliseconds);
-    */
+    buffer[charindex] = '\n'; //make sure we end with whitespace lf
+    return buffer;
+};
+void NRFuart_flush() {
+    if (!NRFuart_enabled) NRFuart_init_nohwfc();
+    //THIS HASNT BEEN TESTED
+    char char1 = 0;
+    while (NRFuart_readable()) {
+        char1 = NRFuart_getc();
+    }
+};
+bool NRFuart_readable() {
+    if (!NRFuart_enabled) NRFuart_init_nohwfc();
+    return (NRF_UART0->EVENTS_RXDRDY == 1);
+};
+#define CONSOLE_DEBUG 0
+#if CONSOLE_DEBUG
+#define DEBUG(str, ... ) do{\
+    /*int n;\
+    char buffer[200];\
+    memset(buffer, '\0', sizeof(buffer));\
+    n = snprintf(buffer, sizeof(buffer), str,  __VA_ARGS__);\
+    buffer[sizeof(buffer)-1] = 0x00;\
+    if(n < 0) { }\
+    else if(n >= sizeof(buffer)) { }\
+    else\
+    {\
+        NRFuart_puts_debug(buffer);\
+    }\
+}while(0)*/
+#else
+#define DEBUG(...)
+#endif
+
+void nrf_configureGPIOForSleep(){
+    nrf_gpio_cfg_input(PN_SPI_MOSI, NRF_GPIO_PIN_NOPULL);
+    nrf_gpio_cfg_input(PN_SPI_MISO, NRF_GPIO_PIN_NOPULL);
 }
 void setState(uint8_t state) {
     RET_state_prev = RET_state;
     RET_state = state;
-    //DEBUG("STATEREADBACK %d\n",RET_state)
-}
-bool memoryIntegrityCheck() {
-    bool pass = true;
-    //check memory is init correct
-    if (RET_memTest != 12345) { pass = false; DEBUG("Mem fail 1\n"); }
-    //Check clocks match
-    if (RET_RTCunixtime != RET_RTCunixtime_bu) { pass = false; DEBUG("Mem fail 2\n"); }
-    //Check clocks are in range (only if we have settings)
-    if (RET_haveSettings && RET_RTCunixtime < 1545412457) { pass = false; DEBUG("Mem fail 3\n"); }
-    return pass;
 }
-void dumpSettings() {
-    DEBUG("RET_memTest:%d \n",RET_memTest);
-    DEBUG("RET_RTCunixtime:%u \n",RET_RTCunixtime);
-    DEBUG("RET_RTCunixtime_bu:%u \n",RET_RTCunixtime_bu);
-    DEBUG("RET_setting_firmware:%d \n",RET_setting_firmware);
-    DEBUG("RET_setting_minimumupdate_hrs:%d \n",RET_setting_minimumupdate_hrs);
-    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 dumpSettings() {    
+    if(DEBUG_ON){
+        debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RET_RTCunixtime:%u", RET_RTCunixtime);debug_exe();
+        debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RET_setting_firmware:%d", RET_setting_firmware);debug_exe();
+        debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RET_setting_minimumupdate_hrs:%d", RET_setting_minimumupdate_hrs);debug_exe();
+        debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RET_state:%d", RET_state);debug_exe();
+        debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RET_setting_location_mode:%d", RET_setting_location_mode);debug_exe();
+        debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RET_setting_location_accuracy:%d", RET_setting_location_accuracy);debug_exe();
+        debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RET_setting_location_tx_interval_mins:%d", RET_setting_location_tx_interval_mins);debug_exe();
+        debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RET_setting_location_tx_failsafe_hrs:%d", RET_setting_location_tx_failsafe_hrs);debug_exe();
+        debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RET_setting_location_timeout:%d", RET_setting_location_timeout);debug_exe();
+        debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RET_setting_activity_tx_interval_hrs:%d", RET_setting_activity_tx_interval_hrs);debug_exe();
+        debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RET_setting_environmental_tx_interval_mins:%d", RET_setting_environmental_tx_interval_mins);debug_exe();
+        debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RET_setting_motion_g:%d", RET_setting_motion_g);debug_exe();
+        debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RET_setting_motion_start_seconds:%d", RET_setting_motion_start_seconds);debug_exe();
+        debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RET_setting_motion_stop_seconds:%d", RET_setting_motion_stop_seconds);debug_exe();
+        debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RET_setting_impact_g:%d", RET_setting_impact_g);debug_exe();
+        debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RET_setting_impact_alert:%d", RET_setting_impact_alert);debug_exe();
+        debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RET_setting_connection_timeout:%d", RET_setting_connection_timeout);debug_exe();
+        debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RET_setting_beacon_interval_seconds:%d", RET_setting_beacon_interval_seconds);debug_exe();
+        debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RET_setting_beacon_scan:%d", RET_setting_beacon_scan);debug_exe();
+    }
+    
+    DEBUG("RET_RTCunixtime:%u",RET_RTCunixtime);
+    DEBUG("RET_setting_firmware:%d",RET_setting_firmware);
+    DEBUG("RET_setting_minimumupdate_hrs:%d",RET_setting_minimumupdate_hrs);
+    DEBUG("RET_state:%d",RET_state);
+    DEBUG("RET_setting_location_mode:%d",RET_setting_location_mode);
+    DEBUG("RET_setting_location_accuracy:%d",RET_setting_location_accuracy);
+    DEBUG("RET_setting_location_tx_interval_mins:%d",RET_setting_location_tx_interval_mins);
+    DEBUG("RET_setting_location_tx_failsafe_hrs:%d",RET_setting_location_tx_failsafe_hrs);
+    DEBUG("RET_setting_location_timeout:%d",RET_setting_location_timeout);
+    DEBUG("RET_setting_activity_tx_interval_hrs:%d",RET_setting_activity_tx_interval_hrs);
+    DEBUG("RET_setting_environmental_tx_interval_mins:%d",RET_setting_environmental_tx_interval_mins);
+    DEBUG("RET_setting_motion_g:%d",RET_setting_motion_g);
+    DEBUG("RET_setting_motion_start_seconds:%d",RET_setting_motion_start_seconds);
+    DEBUG("RET_setting_motion_stop_seconds:%d",RET_setting_motion_stop_seconds);
+    DEBUG("RET_setting_impact_g:%d",RET_setting_impact_g);
+    DEBUG("RET_setting_impact_alert:%d",RET_setting_impact_alert);
+    DEBUG("RET_setting_connection_timeout:%d",RET_setting_connection_timeout);
+    DEBUG("RET_setting_beacon_interval_seconds:%d",RET_setting_beacon_interval_seconds);
+    DEBUG("RET_setting_beacon_scan:%d",RET_setting_beacon_scan);
 }
-float getBatteryV() { //this creates an extra 400ua of power usage!!!
+float getBatteryV() {
     NRF52_SAADC batteryIn;
     batteryIn.addChannel(9); // vdd for battery
     batteryIn.calibrate();
@@ -206,9 +328,20 @@
     return voltage;
 }
 float getTemperature() {
-    SI7060 si7060(PN_I2C_SDA, PN_I2C_SCL);
-    float temperature = si7060.getTemperature();
-    //DEBUG("Temperature:%.2f\n",temperature);
+    float temperature;
+    
+    if (USE_NRF_TEMP_SENSOR) {
+        //INTERNAL NRF52 TEMP SENSOR
+        uint32_t safetycounter = 0;
+        NRF_TEMP->TASKS_START=1;
+        while (NRF_TEMP->EVENTS_DATARDY==0 && safetycounter < 10000);
+        NRF_TEMP->EVENTS_DATARDY=0;
+        temperature = nrf_temp_read()/4.0;
+        NRF_TEMP->TASKS_STOP=1;
+    } else {
+        temperature = si7060.getTemperature(); //currently disabled because its causing a high current 450ua sleep, most likely due to sensor not sleeping correctly, or i2c sleep issue
+    }
+    
     return temperature;  
 }
 void addToExceptionString(char* value) {
@@ -230,8 +363,6 @@
 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_RTCunixtime_bu = RET_RTCunixtime;
-    GLOBAL_RTCunixtime = RET_RTCunixtime;
     
     //button logic - check for hold
     if (RET_buttonHoldTime > 4) {
@@ -270,82 +401,22 @@
     }
     //SETUP STATE VISUALISE
     if (!GLOBAL_LEDSequenceinProgress && RET_state == STATE_SETUP) {
-        led1 = !led1;
+        led1 = !led1; 
     }
 }
+void resetGlobals() {
+    GLOBAL_accel_healthy = false;
+    GLOBAL_motionStopFlagTriggered = false;
+    memset(GLOBAL_exceptionString,0x00,sizeof(GLOBAL_exceptionString));
+    if (DEBUG_ON) {memset(GLOBAL_debug_buffer,0x00,sizeof(GLOBAL_debug_buffer));}
+}
 
-void factoryReset() {
-    //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_bu = 0;
-    RET_SetupRunAt = 0;
-    RET_SettingsGotAt = 0;
-    //SETTINGS
-    RET_setting_firmware = 0;
-    RET_setting_minimumupdate_hrs = 0;
-    RET_setting_location_mode = DEFAULT_LOCATION_MODE;
-    RET_setting_location_accuracy = DEFAULT_LOCATION_ACCURACY;
-    RET_setting_location_tx_interval_mins = DEFAULT_LOCATION_TX_INTERVAL_MINS;
-    RET_setting_location_tx_failsafe_hrs = DEFAULT_LOCATION_TX_FAILSAFE_HRS;
-    RET_setting_location_timeout = DEFAULT_LOCATION_TIMEOUT;
-    RET_setting_activity_tx_interval_hrs = 0;
-    RET_setting_environmental_tx_interval_mins = 0;
-    RET_setting_motion_g = DEFAULT_MOTION_G;
-    RET_setting_motion_start_seconds = DEFAULT_MOTION_START_SECONDS;
-    RET_setting_motion_stop_seconds = DEFAULT_MOTION_STOP_SECONDS;
-    RET_setting_impact_g = 0;
-    RET_setting_impact_alert = 0;
-    RET_setting_connection_timeout = DEFAULT_CONNECTION_TIMEOUT;
-    RET_setting_beacon_interval_seconds = DEFAULT_BEACON_INTERVAL_SECONDS;
-    RET_setting_beacon_scan = 0;
-    //RET_RTCmillis = 0;
-    RET_buttonPressCount = 0;
-    RET_buttonPressTime = 0;
-    RET_buttonReleaseTime = 0;
-    RET_buttonHoldTime = 0;
-    //MOTION STATE
-    RET_motionTriggered = 0;
-    RET_motionTriggeredInTXInterval = 0;
-    RET_motionStartTime = 0;
-    RET_motionStopTime = 0;
-    RET_motionPendingOnState = 0;
-    RET_motionPendingOffState = 0;
-    RET_motionState = 0;
-    RET_motionTotalActivityHours = 0.0;
-    RET_motionFrameStart = 0;
-    memset(RET_activityData,0,sizeof(RET_activityData));
-    //IMPACT
-    RET_impactTriggered = 0;
-    //EVENT HANDLING
-    RET_eventTime_location_log = 0;
-    RET_eventTime_location_tx = 0;
-    RET_eventTime_location_failsafe_tx = 0;
-    RET_eventTime_environmental_log = 0;
-    RET_eventTime_environmental_tx = 0;
-    RET_eventTime_activity_tx = 0;
-    RET_eventTime_wakeFromDormant = 0;
-    //OTHER LOCAL GLOBALS   
-    GLOBAL_requireSoftReset = false;   
-    
-    //PERIPHERAL RESET
-    lis3dh_configureForSleep(DEFAULT_MOTION_G,DEFAULT_IMPACT_G);
-}
 bool selfTest() {
     int test_count = 0;
     int test_pass = 0;
     
     //Accelerometer
     test_count ++;
-    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 (lis3dh_id == 51) {
@@ -356,9 +427,18 @@
     
     //Temperature
     test_count ++;
-    SI7060 si7060(PN_I2C_SDA, PN_I2C_SCL);
     float temperature;
-    temperature = si7060.getTemperature();
+    if (USE_NRF_TEMP_SENSOR) {
+        //INTERNAL NRF52 TEMP SENSOR
+        uint32_t safetycounter = 0;
+        NRF_TEMP->TASKS_START=1;
+        while (NRF_TEMP->EVENTS_DATARDY==0 && safetycounter < 10000);
+        NRF_TEMP->EVENTS_DATARDY=0;
+        temperature = nrf_temp_read()/4.0;
+        NRF_TEMP->TASKS_STOP=1;
+    } else {
+        temperature = si7060.getTemperature();
+    }
     if (temperature > -40 && temperature < 60) {
         test_pass ++;
     } else {
@@ -441,20 +521,23 @@
         DEBUG("FROMSERVER: a:%d,b:%u,c:%d,d:%d,e:%d,f:%d,g:%d,h:%d,i:%d,j:%d,k:%d,l:%d,m:%d,n:%d,o:%d,p:%d,q:%d,r:%d,s:%d\n",
         TEMP_a,TEMP_b,TEMP_c,TEMP_d,TEMP_e,TEMP_f,TEMP_g,TEMP_h,TEMP_i,TEMP_j,TEMP_k,TEMP_l,TEMP_m,TEMP_n,TEMP_o,TEMP_p,TEMP_q,TEMP_r,TEMP_s);
         
+        if(DEBUG_ON){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "FROMSERVER: a:%d,b:%u,c:%d,d:%d,e:%d,f:%d,g:%d,h:%d,i:%d,j:%d,k:%d,l:%d,m:%d,n:%d,o:%d,p:%d,q:%d,r:%d,s:%d\n",
+        TEMP_a,TEMP_b,TEMP_c,TEMP_d,TEMP_e,TEMP_f,TEMP_g,TEMP_h,TEMP_i,TEMP_j,TEMP_k,TEMP_l,TEMP_m,TEMP_n,TEMP_o,TEMP_p,TEMP_q,TEMP_r,TEMP_s);debug_exe();}
+        
         //FAILUREMODE need to be checking these against checksums
         char changed;
         
         if(TEMP_a != -1) { RET_setting_minimumupdate_hrs = TEMP_a;                 changed = 'Y'; } else { changed = 'N'; }; DEBUG("RET_setting_minimumupdate_hrs:%u..%c\n",RET_setting_minimumupdate_hrs,changed);
-        if(TEMP_b != 0) { RET_RTCunixtime = TEMP_b; RET_RTCunixtime_bu = TEMP_b;   changed = 'Y'; } else { changed = 'N'; critical_fail_count++; }; DEBUG("RET_RTCunixtime:%u..%c\n",RET_RTCunixtime,changed);
+        if(TEMP_b != 0)  { RET_RTCunixtime = TEMP_b; changed = 'Y';                               } else { changed = 'N'; critical_fail_count++; }; DEBUG("RET_RTCunixtime:%u..%c\n",RET_RTCunixtime,changed);
         if(TEMP_c != -1) { RET_setting_firmware = TEMP_c;                          changed = 'Y'; } else { changed = 'N'; RET_setting_firmware = -1;}; DEBUG("RET_setting_firmware:%d..%c\n",RET_setting_firmware,changed);
         if(TEMP_d != -1) { setState(TEMP_d);                                       changed = 'Y'; } else { changed = 'N'; critical_fail_count++; }; DEBUG("RET_state:%d..%c\n",RET_state,changed);
         if(TEMP_e != -1) { RET_setting_location_mode = TEMP_e;                     changed = 'Y'; } else { changed = 'N'; }; DEBUG("RET_setting_location_mode:%d..%c\n",RET_setting_location_mode,changed);
-            if(RET_setting_location_mode < 0 || RET_setting_location_mode > 3) {RET_setting_location_mode = DEFAULT_LOCATION_MODE;}
+            if(RET_setting_location_mode > 3) {RET_setting_location_mode = DEFAULT_LOCATION_MODE;}
         if(TEMP_f != -1) { RET_setting_location_accuracy = TEMP_f;                 changed = 'Y'; } else { changed = 'N'; }; DEBUG("RET_setting_location_accuracy:%d..%c\n",RET_setting_location_accuracy,changed);
-            if(RET_setting_location_accuracy < 0 || RET_setting_location_accuracy > 3) {RET_setting_location_accuracy = DEFAULT_LOCATION_ACCURACY;}
+            if(RET_setting_location_accuracy > 3) {RET_setting_location_accuracy = DEFAULT_LOCATION_ACCURACY;}
         if(TEMP_g != -1) { RET_setting_location_tx_interval_mins = TEMP_g;         changed = 'Y'; } else { changed = 'N'; }; DEBUG("RET_setting_location_tx_interval_mins:%d..%c\n",RET_setting_location_tx_interval_mins,changed);
         if(TEMP_h != -1) { RET_setting_location_tx_failsafe_hrs = TEMP_h;          changed = 'Y'; } else { changed = 'N'; }; DEBUG("RET_setting_location_tx_failsafe_hrs:%d..%c\n",RET_setting_location_tx_failsafe_hrs,changed);
-            if(RET_setting_location_tx_failsafe_hrs < 0 || RET_setting_location_tx_failsafe_hrs > 504) {RET_setting_location_tx_failsafe_hrs = DEFAULT_LOCATION_TX_FAILSAFE_HRS;}
+            if(RET_setting_location_tx_failsafe_hrs > 504) {RET_setting_location_tx_failsafe_hrs = DEFAULT_LOCATION_TX_FAILSAFE_HRS;}
         if(TEMP_i != -1) { RET_setting_location_timeout = TEMP_i;                  changed = 'Y'; } else { changed = 'N'; }; DEBUG("RET_setting_location_timeout:%d..%c\n",RET_setting_location_timeout,changed);
             if(RET_setting_location_timeout < 60 || RET_setting_location_timeout > 300) {RET_setting_location_timeout = DEFAULT_LOCATION_TIMEOUT;}
         if(TEMP_j != -1) { RET_setting_activity_tx_interval_hrs = TEMP_j;          changed = 'Y'; } else { changed = 'N'; }; DEBUG("RET_setting_activity_tx_interval_hrs:%d..%c\n",RET_setting_activity_tx_interval_hrs,changed);
@@ -471,13 +554,18 @@
         if(TEMP_s != -1) { RET_setting_beacon_scan = TEMP_s;                       changed = 'Y'; } else { changed = 'N'; }; DEBUG("RET_setting_beacon_scan:%d..%c\n",RET_setting_beacon_scan,changed);
         
         if (critical_fail_count == 0) { 
-            DEBUG("GOT SETTINGS OK\n"); 
+            if(DEBUG_ON){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "GOT SETTINGS OK");debug_exe();}
+            DEBUG("GOT SETTINGS OK",false);
+            dumpSettings(); 
             saveEventTimes();
             RET_haveSettings = true;
+            GLOBAL_needToConfigureLis3dh = true;
             RET_SettingsGotAt = RET_RTCunixtime;
             return true;
         } else {
-            DEBUG("CRITICAL FAILS:%d\n",critical_fail_count);
+            if(DEBUG_ON){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "CRITICAL FAILS:%d",critical_fail_count);debug_exe();}
+            DEBUG("CRITICAL FAILS:%d",critical_fail_count);
+            dumpSettings();
             RET_haveSettings = false; 
             return false;
         }
@@ -491,21 +579,25 @@
     //SET EVENT TIMES
     if(RET_setting_location_tx_interval_mins > 0) { 
         RET_eventTime_location_tx = (RET_RTCunixtime + (RET_setting_location_tx_interval_mins * 60));
+        if(DEBUG_ON){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "EVENTSET - LOCATION TX at %u, MODE %d\n",RET_eventTime_location_tx, RET_setting_location_mode);debug_exe();}
         DEBUG("EVENTSET - LOCATION TX at %u, MODE %d\n",RET_eventTime_location_tx, RET_setting_location_mode);
     }
     if(RET_setting_location_tx_failsafe_hrs > 0) { 
         RET_eventTime_location_failsafe_tx = (RET_RTCunixtime + (RET_setting_location_tx_failsafe_hrs * 3600));
+        if(DEBUG_ON){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "EVENTSET - LOCATION FAILSAFE TX at %u\n",RET_eventTime_location_failsafe_tx);debug_exe();}
         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));
+        if(DEBUG_ON){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "EVENTSET - ACTIVITY TX at %u\n",RET_eventTime_activity_tx);debug_exe();}
         DEBUG("EVENTSET - ACTIVITY TX at %u\n",RET_eventTime_activity_tx);
     }
     if(RET_eventTime_environmental_tx > 0) { 
         RET_eventTime_environmental_tx = (RET_RTCunixtime + (RET_setting_environmental_tx_interval_mins * 60));
+        if(DEBUG_ON){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "EVENTSET - ENVIRONMENTAL TX at %u\n",RET_eventTime_environmental_tx);debug_exe();}
         DEBUG("EVENTSET - ENVIRONMENTAL TX at %u\n",RET_eventTime_environmental_tx);
-    }   
+    }
 }
 
 //------------------------------------------------------------------------------
@@ -513,11 +605,10 @@
 //------------------------------------------------------------------------------ 
 bool setup() {
     bool pass = true;
+    float temperature = getTemperature();
     float voltage = getBatteryV();
-    float temperature = getTemperature();
     bool selftestresult = selfTest();
     if (selftestresult == false) { LED1errorCode(4,20); } //ERROR 4
-    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()) {
         //RET_imei = modem.getIMEI();
         //DEBUG("imei: %lld \n",RET_imei);
@@ -528,28 +619,34 @@
             int timetaken = (RET_RTCunixtime - GLOBAL_wakeTime) + 10; //add 10 for ussd response time.
             char bytestosend[160];
             snprintf(bytestosend,sizeof(bytestosend),"(%s,a:setup,f:%d,v:%.2f,t:%.1f,e:%d,z:SETUP-%s,c:1,s:1%s)\0",GLOBAL_defaultApi,FW_VERSION,voltage,temperature,timetaken,GLOBAL_exceptionString,locString);
-            char result[180];
+            char result[200];
             snprintf(result,sizeof(result),"%s",modem.USSDmessage(bytestosend, true, 2, GLOBAL_defaultApi));
-            if (result != "err") {
+            if (strcmp(result, "err") != 0) {
                 //DEBUG("\nfromserver: %s \n",result);
-                if (!saveSettings(result)) { 
+                if (!saveSettings(result)) {
                     //something went critically wrong getting settings 
                     pass = false;
-                    LED1errorCode(5,20); //ERROR 5
+                    modem.off(false);
+                    if(GLOBAL_debugLED) LED1errorCode(5,10); //ERROR 5
                 }              
+            } else {
+                //Response error
             }
         } else {
             //FAILUREMODE modem failed to register on network
-            DEBUG("NET REGISTER FAIL");
-            LED1errorCode(3,20); //ERROR 3
+            DEBUG("NET REGISTER FAIL",false);
+            modem.off(false);
+            if(GLOBAL_debugLED) LED1errorCode(3,10); //ERROR 3
             pass = false;
         }
     } else {
         //FAILUREMODE Modem failed to turn on  
-        DEBUG("MODEM ON FAIL");
-        LED1errorCode(2,20); //ERROR 2
+        DEBUG("MODEM ON FAIL",false);
+        modem.off(false);
+        if(GLOBAL_debugLED) LED1errorCode(2,10); //ERROR 2
         pass = false;
     }
+    modem.off(false);
     
     //LOG RUN TIME - THIS MUST GO AT END AFTER WE HAVE GOT SERVER TIMESTAMP
     RET_SetupRunAt = RET_RTCunixtime;
@@ -562,11 +659,10 @@
 // EVENTS
 //------------------------------------------------------------------------------ 
 void event_connectiontest_tx(int location_accuracy) {
-    DEBUG("TEST EVENT\n");
-    float voltage = getBatteryV();  
+    DEBUG("TEST EVENT\n",false);
     float temperature = getTemperature();
+    float voltage = getBatteryV();  
     int selftestresult = selfTest();
-    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()) {
         char locString[70];
         memcpy(locString, modem.getLocation(location_accuracy, RET_setting_location_timeout), 70);
@@ -581,26 +677,28 @@
                 //DEBUG("\nfromserver: %s \n",result);
                 if (getSettings) {
                     saveSettings(result);
-                    LED1blink(5,250);
+                    if(GLOBAL_debugLED) LED1blink(5,250);
                 }
             }
         } else {
-            LED1errorCode(3,20); //ERROR 3   
+            modem.off(false);
+            if(GLOBAL_debugLED) LED1errorCode(3,20); //ERROR 3   
         }
     } else {
-        LED1errorCode(2,20); //ERROR 2
+        modem.off(false);
+        if(GLOBAL_debugLED) LED1errorCode(2,20); //ERROR 2
     }
+    modem.off(false);
     //RESETS
     RET_motionTriggeredInTXInterval = 0;
     saveEventTimes();
 }
 
 void event_location_tx() {
-    DEBUG("LOCATION TX\n");
-    float voltage = getBatteryV();
+    DEBUG("LOCATION TX\n",false);
     float temperature = getTemperature();
+    float voltage = getBatteryV();
     int selfTestResult = selfTest();
-    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()) {
         char locString[70];
         memcpy(locString, modem.getLocation(RET_setting_location_accuracy, RET_setting_location_timeout), 70);
@@ -624,20 +722,22 @@
                 }
             }
         } else {
-            LED1errorCode(3,20); //ERROR 3   
+            modem.off(false);
+            if(GLOBAL_debugLED) LED1errorCode(3,20); //ERROR 3   
         }
     } else {
-        LED1errorCode(2,20); //ERROR 2
+        modem.off(false);
+        if(GLOBAL_debugLED) LED1errorCode(2,20); //ERROR 2
     }
+    modem.off(false);
     //RESETS
     RET_motionTriggeredInTXInterval = 0;
     saveEventTimes();
 }
 
 void event_activity_tx() {
-    DEBUG("ACTIVITY TX\n");
+    DEBUG("ACTIVITY TX\n",false);
     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(DEFAULT_CONNECTION_ATTEMPTS,(RET_setting_connection_timeout*1000))) {
@@ -652,11 +752,14 @@
                 if (RET_haveSettings) { RET_motionFrameStart = RET_RTCunixtime; }
             }
         } else {
-            LED1errorCode(3,20); //ERROR 3
+            modem.off(false);
+            if(GLOBAL_debugLED) LED1errorCode(3,20); //ERROR 3
         }
     } else {
-        LED1errorCode(2,20); //ERROR 3
+        modem.off(false);
+        if(GLOBAL_debugLED) LED1errorCode(2,20); //ERROR 3
     }
+    modem.off(false);
     //RESETS
     RET_motionTriggeredInTXInterval = 0;
     saveEventTimes();
@@ -666,21 +769,24 @@
 // STATE ENGINE
 //------------------------------------------------------------------------------ 
 void mainStateEngine() {
+    
     switch(RET_state) {
         case STATE_SETUP :
-            DEBUG("STATE:SETUP\n");
-            factoryReset();
+        { //need the curlies to avoid "transfer of control bypass init error warning"
+            DEBUG("STATE:SETUP\n",false);
             if (setup()) {
                 // All good
             } else {
-                //LED1blink(200,50);   
                 RET_eventTime_wakeFromDormant = (RET_RTCunixtime + (24*3600)); //24hrs
                 setState(STATE_DORMANT);
                 DEBUG("SETUP FAILED:DORMANT until %u\n",RET_eventTime_wakeFromDormant);
             }
             break;
+        }
         case STATE_NORMAL :
-            DEBUG("STATE:NORMAL\n");
+        {
+            DEBUG("STATE:NORMAL\n",false);
+            
             //check and log motion
             checkMotion();
             
@@ -698,7 +804,7 @@
                     break;
             }
             if(RET_RTCunixtime >= RET_eventTime_location_failsafe_tx && RET_eventTime_location_failsafe_tx > 0) { run_location_tx = true; }
-            if (run_location_tx) { DEBUG("INTERVAL LOC TX...\n"); event_location_tx(); }
+            if (run_location_tx) { DEBUG("INTERVAL LOC TX...\n",false); event_location_tx(); }
             
             //if(RET_RTCunixtime >= RET_eventTime_location_tx && RET_eventTime_location_tx > 0) { run_location_tx = true; }
             //Location Failsafe timer catchall
@@ -711,46 +817,57 @@
                 run_activity_tx = true;
             }
             if (strlen(RET_activityData) > 130) { run_activity_tx = true; }
-            if (run_activity_tx) { DEBUG("ACTIVITY TX...\n"); event_activity_tx();}
+            if (run_activity_tx) { DEBUG("ACTIVITY TX...\n",false); event_activity_tx();}
+            
             break;
+        }
         case STATE_DORMANT :
+        {
             if (RET_RTCunixtime >= RET_eventTime_wakeFromDormant) {
                 if (RET_haveSettings) {
                     setState(STATE_NORMAL); 
                 } else {
                     setState(STATE_SETUP); 
                 }
-                DEBUG("WAKING UP FROM DORMANT\n");
+                DEBUG("WAKING UP FROM DORMANT\n",false);
             }
             DEBUG("STATE:DORMANT until %u\n",RET_eventTime_wakeFromDormant);
             break;
+        }
         case STATE_BUTTONPRESS1 :
+        {
             setState(STATE_NORMAL);
-            DEBUG("STATE:BUTTONPRESS1\n");
+            DEBUG("STATE:BUTTONPRESS1\n",false);
             LED1blink(1,300);
-            break; 
+            break;
+        }
         case STATE_BUTTONPRESS2 :
+        {
             setState(STATE_NORMAL);
-            DEBUG("STATE:BUTTONPRESS2\n");
+            DEBUG("STATE:BUTTONPRESS2\n",false);
             LED1blink(2,300);
             LED1on(0);
             event_connectiontest_tx(1);
             LED1off();
             break;
+        }
         case STATE_BUTTONPRESS3 :
+        {
             setState(STATE_NORMAL);
-            DEBUG("STATE:BUTTONPRESS3\n");
+            DEBUG("STATE:BUTTONPRESS3\n",false);
             LED1blink(3,300);
             LED1on(0);
             event_connectiontest_tx(2);
             LED1off();
             break;  
+        }
         case STATE_BUTTONHOLD :
-            DEBUG("STATE:BUTTONHOLD\n");
+        {
+            DEBUG("STATE:BUTTONHOLD\n",false);
             if (RET_state_prev == STATE_NORMAL) {
                 setState(STATE_DORMANT);
                 RET_eventTime_wakeFromDormant = (RET_RTCunixtime + (48*3600)); //48hrs
-                DEBUG("TURNING OFF\n");
+                DEBUG("TURNING OFF\n",false);
                 DEBUG("STATE:DORMANT until %u\n",RET_eventTime_wakeFromDormant);
                 LED1on(5000);
             } else {
@@ -759,27 +876,32 @@
                 } else {
                     setState(STATE_SETUP);
                 }
-                DEBUG("TURNING ON\n");
+                DEBUG("TURNING ON\n",false);
                 LED1blink(20,100);
             }
             break;
+        }
         default :
+        {
             setState(STATE_SETUP);
-            DEBUG("DEFAULT STATE\n");
+            DEBUG("DEFAULT STATE\n",false);
+        }
     }
 }
 
-
 //------------------------------------------------------------------------------
 // MAIN
 //------------------------------------------------------------------------------ 
 int main() {
+    LED1on(500);
+    
     //INIT
-    turnOffEverything();
-    if (!memoryIntegrityCheck()) { RET_coldBoot = 1;}
+    LED1off();
     RTCticker.attach(&RTCtick, 1.0);
-    button.fall(&buttonPress); //does this affect power?
+    button.fall(&buttonPress);
     button.rise(&buttonRelease);
+
+    dumpSettings();
     
     //CHECK IF THIS IS RESET
     //0x00000004 == soft reset  //0x00000002 == watchdog  //0x00000001 == button/hardreset 
@@ -789,53 +911,65 @@
                 DEBUG("0x%08x. Hard Reset ST:%d\n",NRF_POWER->RESETREAS, RET_state);
                 RET_coldBoot = 1;
                 dumpSettings();
+                NRF_POWER->RESETREAS = 0xffffffff;
             break;
             case 0x00000002  :
                 DEBUG("Watchdog ST:%d\n",RET_state);
+                NRF_POWER->RESETREAS = 0xffffffff;
             break;
             case 0x00000004  :
-                DEBUG("Soft ST:%d SLP:%d\n",RET_state, RET_sleepToggle);
+                DEBUG("Soft ST:%d\n",RET_state);
             break;
         }
-        NRF_POWER->RESETREAS = 0xffffffff;
     }
     
-    
     //CHECK FOR FIRST BOOT
-    if (RET_coldBoot == 1) { factoryReset(); dumpSettings(); LED1errorCode(6,3); }
-    
-    //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(DEFAULT_SLEEP_FRAME);
-        system_reset();
+    if (RET_coldBoot == 1) { 
+        LED1errorCode(6,2); 
     }
     
-    //while(true) {
-        watchdogKick();
-        //LOG START TIME
+    //MAIN LOOP
+    while(true) {
+        //WATCHDOG
+        watchdogKick(); //only need this if we're in while loop
+        
+        //INIT
+        resetGlobals(); // could move this into state engine switches to save actions on each loop
         GLOBAL_wakeTime = RET_RTCunixtime;
         
         //MAIN LOGIC
         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();
+                
+        //LOG FIRST RUN - BOOTLOADER COMMS
+        if (RET_coldBoot) {
+            read_app_data_from_flash(&app_data);
+            bool write_app_data_to_flash_execute = false;
+            if(get_flag(&app_data, app_execution_flag) == true) {
+                clr_flag(&app_data, app_execution_flag);
+                write_app_data_to_flash_execute = true;
+            }
+            if(app_data.current_firmware_version != FW_VERSION) {
+                app_data.current_firmware_version = FW_VERSION;
+                app_data.target_firmware_version = FW_VERSION;
+                write_app_data_to_flash_execute = true;
+            }
+            if (write_app_data_to_flash_execute) {
+                write_app_data_to_flash(&app_data);
+            }
+            RET_coldBoot = 0;
+        }
         
         //PRE-SLEEP ACTIONS
-        if (GLOBAL_needToConfigureLis3dh) { lis3dh_configureForSleep(10,127); }
-        turnOffEverything();
+        LED1off();
+        if (GLOBAL_needToConfigureLis3dh) { lis3dh_configureForSleep(RET_setting_motion_g,RET_setting_impact_g); }
+        modem.off(false);
+        NRFuart_uninit();
+        nrf_configureGPIOForSleep();
+        watchdogKick();
         
-        //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
+        //SLEEP
         mainthread.wait(DEFAULT_SLEEP_FRAME);
-        */
-        
-        RET_coldBoot = 0;
-        RET_sleepToggle = 1;
-        system_reset();
-    //}
+    }
 }
\ No newline at end of file