init
Dependencies: aconno_I2C Lis2dh12 WatchdogTimer
main.cpp
- Committer:
- pathfindr
- Date:
- 2018-11-12
- Revision:
- 5:8f8951127724
- Parent:
- 4:8d8e9bfa82e4
- Child:
- 6:388d3c7efdd9
File content as of revision 5:8f8951127724:
#include "main.h"
#include "board.h"
#include "modes.h"
//include "nrf_soc.h"
//#include "ATCommand.h"
//LowPowerTicker ticker; //no impact on power consumption
//------------------------------------------------------------------------------
//Function declarations- Local
//------------------------------------------------------------------------------
static void mainStateEngine(void);
static void mode_mtu(void);
static void selftest(void);
static void LEDon(void);
static void LEDoff(void);
//------------------------------------------------------------------------------
//Var declarations- Local
//------------------------------------------------------------------------------
bool accel_healthy = false;
bool firstBoot = false;
bool requireSoftReset = false;
//------------------------------------------------------------------------------
//Var declarations- RETAINED NOINIT RAM
//------------------------------------------------------------------------------
#if defined ( __CC_ARM )
/** THIS IS THE MBED ONLINE COMPILER TOOLCHAIN*/
static uint8_t RET_mode __attribute__((section("noinit"),zero_init));
static uint32_t RET_unixtime __attribute__((section("noinit"),zero_init));
#elif defined ( __GNUC__ )
#elif defined ( __ICCARM__ )
#endif
char RET_pf_identifier[9]; //includes null byte at end
int RET_interval_setting = 720;
int RET_interval_hours_failsafe = 24;
int RET_motioncheck_interval_seconds = 60;
int RET_gps_timeout = 180;
int RET_gsm_timeout = 120;
bool RET_gsmtimedout = false;
int RET_beacon_scan = 0;
int RET_accel_awake_thr = 11;
int RET_accel_awake_triggercount = 0;
int RET_accel_alarm_thr = 127;
unsigned long RET_unixtime_configrun = 0;
unsigned long RET_unixtime_lastpost = 0;
unsigned long RET_unixtime_nextpost = 0;
unsigned long RET_unixtime_nextpost_failsafe = 0;
unsigned long RET_unixtime_framestart = 0;
unsigned long RET_motionstarttime = 0;
unsigned long RET_motionstoptime = 0;
int RET_gsm_failcount = 0;
int RET_serverresponse_failcount = 0;
int RET_motionconsecutive = 0;
int RET_no_motionconsecutive = 0;
bool RET_wethinkinmotion = false;
bool RET_wethinkhasmoved = false;
bool RET_haveservertime = false;
float RET_operationTimeHours = 0;
float RET_operationFrameTimeHours = 0;
int RET_operationCount = 0;
char RET_operationTimeString[100];
//------------------------------------------------------------------------------
//Pin states
//------------------------------------------------------------------------------
DigitalOut led1(p11);
DigitalOut vreg_en(p29);
DigitalOut gsm_pwkey(p28);
DigitalOut lis3dh_cs(p22);
//------------------------------------------------------------------------------
//Peripherals
//------------------------------------------------------------------------------
//BLE myble;
#if NEED_CONSOLE_OUTPUT
Serial uart(p6, p8, 115200);
#endif
//ATSerial atserial(p6,p8,115200);
WatchdogTimer watchdog(65.0); //Do not set to less than 4500ms or can cause issues with softdevice
void gotoSleep(long sleep_milliseconds) {
//accelerometer.configureForSleep();
if (requireSoftReset) { //dont need to clear this var as reset changes it back to false
RET_unixtime = time(NULL); //save unixtime for reset
//NVIC_SystemReset();
system_reset();
}
ThisThread::sleep_for(sleep_milliseconds);
}
void LED1on(long flash_milliseconds = 0) {
led1 = 0;
if (flash_milliseconds > 0) {
ThisThread::sleep_for(flash_milliseconds);
led1 = 1;
}
}
void LED1off() {
led1 = 1;
}
void resetState() {
firstBoot = true;
RET_mode = 0;
RET_unixtime = 0;
set_time(RET_unixtime);
}
int main() {
led1 = 1;
//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\n",NRF_POWER->RESETREAS);
resetState();
break;
case 0x00000002 :
DEBUG("reset_reason: 0x%08x. - Watchdog\n",NRF_POWER->RESETREAS);
set_time(RET_unixtime);
break;
case 0x00000004 :
DEBUG("reset_reason: 0x%08x. - Soft reset\n",NRF_POWER->RESETREAS);
set_time(RET_unixtime);
break;
}
NRF_POWER->RESETREAS = 0xffffffff;
}
while(true) {
//GOTO TO SLEEP
if (!firstBoot) gotoSleep(60000);
LED1on(20);
watchdog.kick();
//MAIN STATE ENGINE
mainStateEngine();
}
}
bool GSMon() {
//power on GSM
vreg_en = 1;
ThisThread::sleep_for(500);
gsm_pwkey = 0;
ThisThread::sleep_for(1500);
gsm_pwkey = 1;
LED1on(1000);
}
void mainStateEngine() {
//TEST AREA
LIS3DH accelerometer(p23, p19, p24, p22, LIS3DH_DR_NR_LP_25HZ, LIS3DH_FS_8G);
requireSoftReset = true;
if (!accelerometer.selfTest()) {
LED1on(100);
}
accelerometer.configureForSleep();
//ThisThread::sleep_for(10000);
bool accel_awake;
RET_mode = MODE_SETUP;
switch(RET_mode) {
case MODE_SETUP :
//selftest();
break;
case MODE_INTERVAL :
break;
case MODE_INTELLIGENT :
break;
case MODE_MTU :
//mode_mtu();
break;
case MODE_DORMANT :
break;
default :
RET_mode = MODE_SETUP;
}
}
/*
void initMotion() {
//CHECK FOR ANY MOTION
if (!accelerometer.selfTest()) {
if (exceptions.find("A.") < 0) {
exceptions += "A.";
}
DEBUG("Couldnt start accelerometer");
} else {
accel_healthy = true;
}
}
void mode_mtu() {
bool accel_awake = accelerometer.getINT2();
//CHECK FOR MOTION
if (accel_awake == true) {
LED1on(50);
RET_motionconsecutive ++;
RET_no_motionconsecutive = 0;
//this is needed to ensure accel_awake_triggercount is 1 or higher for mode 2
if (RET_accel_awake_triggercount == 0) {
RET_accel_awake_triggercount = 1;
}
if (RET_motionconsecutive == RET_accel_awake_triggercount && RET_wethinkinmotion == false) {
RET_wethinkinmotion = true;
RET_motionstarttime = (time(NULL) - ((RET_accel_awake_triggercount+1) * RET_motioncheck_interval_seconds));
long eventEpoch = RET_motionstarttime;
long epochoffsetminutes = ((eventEpoch - RET_unixtime_framestart) / 60);
char buf[20];
sprintf(buf,"1.%i!", epochoffsetminutes);
strcat(RET_operationTimeString, buf);
RET_operationCount ++;
DEBUG("%s", RET_operationTimeString);
LEDon(100);
LEDon(100);
LEDon(100);
LEDon(100);
}
} else if (accel_awake == false) {
RET_no_motionconsecutive ++;
RET_motionconsecutive = 0;
if (RET_no_motionconsecutive == RET_accel_awake_triggercount && RET_wethinkinmotion == true) {
RET_wethinkinmotion = false;
// log engine stop
RET_motionstoptime = (time(NULL) - ((RET_accel_awake_triggercount+1) * RET_motioncheck_interval_seconds));
long eventEpoch = RET_motionstoptime;
long epochoffsetminutes = ((eventEpoch - RET_unixtime_framestart) / 60);
char buf[20];
sprintf(buf,"0.%i!", epochoffsetminutes);
strcat(RET_operationTimeString, buf);
RET_operationFrameTimeHours = (float(RET_motionstoptime - RET_motionstarttime) / 3600.0);
RET_operationTimeHours += RET_operationFrameTimeHours;
//test by posting on every stop event
//doOperationTimePost = true;
DEBUG("%i", RET_operationTimeHours);
LEDon(500);
}
}
// Check time interval for location run
if (time(NULL) > RET_unixtime_nextpost_failsafe) {
//setfailsafetime(); //these must be before gpsPost, incase gpsPost fails, then stuck in broadcast loop
//gpsPost();
}
//Check for operatingTime post time or if data buffer is full for force post
if (RET_operationFrameTimeHours > 0.0) {
if (time(NULL) > RET_unixtime_nextpost || strlen(RET_operationTimeString) > 60) {
//only bother if we actual have data to post
//setwaketime(); //these must be before gpsPost, incase gpsPost fails, then stuck in broadcast loop
//uploadOperationTimeData();
}
}
}
*/
/*
int selftest() {
int result = 0;
int tests = 0;
int testscore = 0;
led1 = 0;
string failures;
//Accelerometer
tests ++;
if (accelerometer.read_id() == 51){
testscore ++;
} else {
//Accelerometer Fail
failures += 'Ac,';
};
return result;
}
*/
/*
void readRegs(uint8_t addr, uint8_t * data, int len) {
lis3dh_cs = 0;
for (int i = 0 ; i < len ; i++ ) {
spi.write((addr+i)|0x80) ; // specify address to read
data[i] = spi.write((addr+i)|0x80) ;
}
spi.write(0x00) ; // to terminate read mode
lis3dh_cs = 1;
}
uint8_t read_reg(uint8_t addr)
{
uint8_t data[1] ;
readRegs(addr, data, 1) ;
return( data[0] ) ;
}
*/
/*
//OPTION 1
// Switch on both RAM banks when in System OFF mode.
NRF_POWER->RAMON |= (POWER_RAMON_OFFRAM0_RAM0On << POWER_RAMON_OFFRAM0_Pos) |
(POWER_RAMON_OFFRAM1_RAM1On << POWER_RAMON_OFFRAM1_Pos);
// Enter System OFF and wait for wake up from GPIO detect signal.
NRF_POWER->SYSTEMOFF = 0x1;
//spi.close();
//delete spi;
//spi_disable();
//spi_free(spi);
//nrf_drv_spi_uninit(spi);
//nordic_nrf5_spi_initialized[instance] = false;
//HFCLKSTOP = 0x1;
NRF_SPI0->ENABLE = 0;
NRF_SPI1->ENABLE = 0;
NRF_SPI2->ENABLE = 0;
NRF_TWI0->ENABLE = 0;
NRF_TWI1->ENABLE = 0;
sd_clock_hfclk_release();
NRF_POWER->SYSTEMOFF=1;
//NRF_SPI0->POWER = 0;
//OPTION 3
*(volatile uint32_t *)0x40003FFC = 0;
*(volatile uint32_t *)0x40003FFC;
*(volatile uint32_t *)0x40003FFC = 1;
NRF_SPI0->ENABLE = (SPI_ENABLE_ENABLE_Disabled << SPI_ENABLE_ENABLE_Pos);
NRF_SPI1->ENABLE = (SPI_ENABLE_ENABLE_Disabled << SPI_ENABLE_ENABLE_Pos);
if (sleep_manager_can_deep_sleep()) {
ThisThread::sleep_for(10000);
} else {
led1 = 0;
wait(50.0);
}
//system_reset();
*/
//time_t unixtime = time(NULL);
//DEBUG("got: %i, %d, %d \n", RET_mode, RET_unixtime, unixtime);