v1.19 Release
Dependencies: nRF51822
Diff: Source/main.cpp
- Revision:
- 23:7ca590427f0e
- Child:
- 24:761c30334cf4
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/main.cpp Tue Mar 19 19:25:39 2019 +0000 @@ -0,0 +1,377 @@ +//********************************************************************** +// +// SmartCap2 Main +// +// SPG 2/22/2019 +// +// Copyright (c) 2019 Polygenesis +// +//********************************************************************** +/// @file main.cpp + +#include <events/mbed_events.h> +#include <mbed.h> +#include "main.h" +#include "hw.h" +#include "ble/BLE.h" +#include "ble/Gap.h" +#include "BLE_Stuff.h" +#include "ble/services/UARTService.h" +#include "infoService.h" +#include "log.h" +#include "nrf_soc.h" +#include "mem.h" + +void process_state(void); + +EventQueue eventQueue(/* event count */ 16 * EVENTS_EVENT_SIZE); + +#if TEST_ON_NRF51_DK==0 + // real board + //int reg_mode = 1; + InterruptIn is_package_open(LIGHT_SENSE, PullNone); // will be pulled hi when package_is_open (only if package_open_sense_enable = 1) + DigitalOut package_open_sense_enable(LIGHT_SENSE_ENABLE, 0); + + DigitalOut cap_sense_led(CAP_SENSE_LED, 0); + DigitalOut vdd_enable(VDD_ENABLE, 0); + + DigitalOut led(LED, 0); // LED for debugging purposes +#else + // simulate on nRF51-DK + DigitalIn capon(BUTTON1, PullUp); + //DigitalIn reg_mode(BUTTON3, PullUp); + InterruptIn is_package_open(BUTTON2, PullUp); // will be pulled hi when package_is_open (only if package_open_sense_enable = 1) + DigitalOut package_open_sense_enable(LED3, 0); + + DigitalOut cap_sense_led(LED2, 0); + DigitalOut vdd_enable(LED4, 0); + + DigitalOut led(LED1, 0); // LED for debugging purposes +#endif + +LowPowerTicker periodic_ticker; // this handle the RTC + + +//int dark_cnt = 0; // seconds in the dark +bool is_cap_off = false; // 0=cap on, 1=cap off +uint32_t cap_off_time; + +typedef enum { + INIT, + POST, + TEST_MODE, + SHIP_MODE_WAIT_DARK, + SHIP_MODE_WAIT_LIGHT, + SHIP_MODE_WAIT_CAP_OFF, + IN_USE_SETUP, + WAIT_CAP_OFF, + WAIT_CAP_ON, + OTHER +} state_t; + +state_t state = INIT; + +/// Light detected interrupt +void light_interrupt(void) +{ + eventQueue.call(process_state); +} + +/// Test to see if Cap is off or on +void test_cap(void) +{ +#if TEST_ON_NRF51_DK == 0 + uint16_t off_reading; + uint16_t on_reading; + + vdd_enable = 1; // enable analog power + wait(0.00075); + off_reading = adc_read(ADC_CHAN_CAP_SENSE,2); + cap_sense_led = 1; // enable led + wait(0.00075); + on_reading = adc_read(ADC_CHAN_CAP_SENSE,2); + // turn everything off + cap_sense_led = 0; + vdd_enable = 0; + + if(on_reading > off_reading+CAP_THRESHOLD) +#else + if(capon) +#endif + { + is_cap_off = 0; +#if ENABLE_LED + led = 0; +#endif + } + else + { + is_cap_off = 1; +#if ENABLE_LED + led = 1; +#endif + } + + eventQueue.call(process_state); +} + +/// this interrupt is run every PERIODIC_TICK_SEC seconds +void periodic_tick() +{ + update_rtc(PERIODIC_TICK_SEC); // keep rtc updated + + eventQueue.call(test_cap); // starts as non-interrupt task so we can use wait(); +} + +/// call here to flash the LED n times. +// n=0 to flash forever +void flash_led(int n, float sec) +{ + if(n==0) + { // flash forever + while(1) + { + led = 1; + wait(sec); + led = 0; + wait(sec); + } + } + else + { // flash n times + while(n--) + { + led = 1; + wait(sec); + led = 0; + wait(sec); + } + } +} + + +state_t last_state = OTHER; + +/// Main state machine +/// Called whenever a sensor changes +void process_state(void) +{ +#if UART_DEBUGGING==1 + if(last_state != state) + { + BLE_UART_xmit(state); + BLE_UART_xmit("\n"); + + last_state = state; + } +#endif + + switch(state) + { + case INIT: + log_add(EVENT_POWER, 0, 0, 0); // log event +#if SKIP_SHIP_MODE + state = IN_USE_SETUP; +#else + //package_open_sense_enable = 1; // turn on light sensor + state = POST; +#endif + break; + + case POST: + // check CRC ? + + // Check Misc. + + if(0) flash_led(0,0.1); // flash forever to indicate error + + + if(NV_TESTING_REQUIRED) + { + flash_led(1, 1.0); + state = TEST_MODE; + } + else + { + state = IN_USE_SETUP; + } + break; + + case TEST_MODE: + + break; + + case SHIP_MODE_WAIT_DARK: // Wait for light sensor to see darkness for at least x minutes + //if(dark_cnt>= MIN_DARK_TIME_MIN*60) + { // its been dark for a while,go into SHIP MODE + // set up and enable the Light Sense Interrupt + is_package_open.rise(&light_interrupt); + is_package_open.enable_irq(); + + // turn off dark timer + //dark_ticker.detach(); + state = SHIP_MODE; + led = 0; + } + break; + + case SHIP_MODE_WAIT_LIGHT: + if(is_package_open) + { + state = WAKE_FROM_SHIP_MODE; + periodic_ticker.detach(); + periodic_ticker.attach(&periodic_tick ,PERIODIC_TICK_SEC); + } + break; + + case SHIP_MODE_WAIT_CAP_OFF: + break; + + case IN_USE_SETUP: + periodic_ticker.detach(); + periodic_ticker.attach(&periodic_tick ,PERIODIC_TICK_SEC); +#if UART_DEBUGGING==1 + BLE_UART_xmit("Wakeup\n"); +#endif + package_open_sense_enable = 0; // turn off light sense pull-up + is_package_open.disable_irq(); // turn off light sense interrupt + + periodic_ticker.detach(); + periodic_ticker.attach(&periodic_tick ,PERIODIC_TICK_SEC); + + set_rtc(0); + //log_add(EVENT_POWER, 0, 0, 0); // log event + //set_radio(true); + + state = WAIT_CAP_OFF; + break; + + case WAIT_CAP_OFF: // cap is on, waiting for cap to be removed + if(is_cap_off) + { // cap just taken off + // save cap off time + cap_off_time = read_clock(); + +#if UART_DEBUGGING==1 + BLE_UART_xmit("Cap Off \n"); +#endif + + state = WAIT_CAP_ON; + } + + break; + + case WAIT_CAP_ON: // cap currently off, waiting for cap to be put on + + if(!is_cap_off) + { // cap just put on + // log time cap was off + uint32_t cap_off_dur = read_clock()-cap_off_time; + if(cap_off_dur>65535) cap_off_dur = 65535; + + log_add(EVENT_CAP_ON, cap_off_dur & 0xff, (cap_off_dur >> 8)&0xff, 0); // log event + + //wait(0.25); + set_radio(true); + + state = WAIT_CAP_OFF; + } + break; + + default: // illegal state + state = INIT; + break; + } +} + +int main(void) +{ + // blink LED to indicate power applied + flash_led(1,1.0); + + if(Init_BLE_Stuff()) // init and start advertising + { + flash_led(0, 0.05); // indicate a ble init error + } + + eventQueue.call(process_state); + + eventQueue.dispatch_forever(); // run all tasks in the event queue (non-interrupt routines) + return 0; +} + +//***************************************************************************** + + +// process commands sent to the SmartCap over Bluetooth UART +void process_cmd(char * cmd) +{ + switch(tolower(cmd[0])) { + case 'r': // Get records + log_show(); + //batt_voltage = read_battery_voltage(); + //updateBattValue(batt_voltage); + break; + + case 's': // status + switch(tolower(cmd[1])) { + case 0: // old, check battery voltage + batt_voltage = read_battery_voltage(); + //updateBattValue(batt_voltage); + BLE_UART_xmit("Bat="); + BLE_UART_xmit(batt_voltage); + BLE_UART_xmit("\n"); + break; + + case 'c': // checksum + BLE_UART_xmit(0); + BLE_UART_xmit("\n"); + break; + + case 'l': // light sensor analog readings + BLE_UART_xmit(0); + BLE_UART_xmit("\n"); + break; + + case ' ': // cap sensor analog readings + + case 's': // sensors as hex pair, with bit '000000xy', x=(1 is cap off), y=(1 is light sensed) + + BLE_UART_xmit(0); + BLE_UART_xmit("\n"); + break; + } + break; + + case 't': // get time + BLE_UART_xmit(read_clock()); + BLE_UART_xmit("\n"); + break; + + case 'c': // set time + { + int i = 1; + uint32_t num = 0; + + while(cmd[i]>='0' && cmd[i]<='9') { + num = num*10 + cmd[i++]-'0'; + } + + if(i>1) { + set_time_offset(num); + BLE_UART_xmit("*Time Set\n"); + } + } + break; + + case 'v': // version + BLE_UART_xmit(FW_VERSION); + BLE_UART_xmit("\n"); + break; + + default: + BLE_UART_xmit("S=Status\n"); + break; + } + cmd[0] = 0; +}