Merck / Mbed OS SmartCap_OS5

Dependencies:   nRF51822

Committer:
fdelahan
Date:
Thu Dec 19 19:17:51 2019 +0000
Revision:
39:93d6d459c76c
Parent:
38:4b06a103c044
Child:
40:adabdb1c5abe
Brought back the battery level command for the UART, i.e., "sb"; Set settling time for ambient sensor at 200 ms when reading level, i.e., "sl"

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sgetz7908 23:7ca590427f0e 1 //**********************************************************************
sgetz7908 23:7ca590427f0e 2 //
sgetz7908 23:7ca590427f0e 3 // SmartCap2 Main
sgetz7908 23:7ca590427f0e 4 //
sgetz7908 23:7ca590427f0e 5 // SPG 2/22/2019
sgetz7908 23:7ca590427f0e 6 //
sgetz7908 23:7ca590427f0e 7 // Copyright (c) 2019 Polygenesis
sgetz7908 23:7ca590427f0e 8 //
sgetz7908 23:7ca590427f0e 9 //**********************************************************************
sgetz7908 23:7ca590427f0e 10 /// @file main.cpp
sgetz7908 23:7ca590427f0e 11
sgetz7908 23:7ca590427f0e 12 #include <events/mbed_events.h>
sgetz7908 23:7ca590427f0e 13 #include <mbed.h>
sgetz7908 24:761c30334cf4 14 #include <ctype.h>
sgetz7908 23:7ca590427f0e 15 #include "main.h"
sgetz7908 23:7ca590427f0e 16 #include "hw.h"
sgetz7908 23:7ca590427f0e 17 #include "ble/BLE.h"
sgetz7908 23:7ca590427f0e 18 #include "ble/Gap.h"
sgetz7908 23:7ca590427f0e 19 #include "BLE_Stuff.h"
sgetz7908 23:7ca590427f0e 20 #include "ble/services/UARTService.h"
sgetz7908 23:7ca590427f0e 21 #include "infoService.h"
sgetz7908 23:7ca590427f0e 22 #include "log.h"
sgetz7908 23:7ca590427f0e 23 #include "nrf_soc.h"
sgetz7908 23:7ca590427f0e 24 #include "mem.h"
sgetz7908 26:a577c4b69fe0 25 #include "CCITTcrc16.h"
sgetz7908 23:7ca590427f0e 26
sgetz7908 23:7ca590427f0e 27 void process_state(void);
sgetz7908 24:761c30334cf4 28 void start_periodic_tick(uint32_t sec);
sgetz7908 23:7ca590427f0e 29
sgetz7908 23:7ca590427f0e 30 EventQueue eventQueue(/* event count */ 16 * EVENTS_EVENT_SIZE);
sgetz7908 23:7ca590427f0e 31
sgetz7908 23:7ca590427f0e 32 #if TEST_ON_NRF51_DK==0
sgetz7908 23:7ca590427f0e 33 // real board
sgetz7908 23:7ca590427f0e 34 //int reg_mode = 1;
sgetz7908 27:bb7247a1704e 35 InterruptIn is_package_open(LIGHT_SENSE, PullNone); // will be pulled hi when package_is_open (only if package_open_sense_enable = 1)
sgetz7908 23:7ca590427f0e 36 DigitalOut package_open_sense_enable(LIGHT_SENSE_ENABLE, 0);
sgetz7908 23:7ca590427f0e 37
sgetz7908 23:7ca590427f0e 38 DigitalOut cap_sense_led(CAP_SENSE_LED, 0);
sgetz7908 23:7ca590427f0e 39 DigitalOut vdd_enable(VDD_ENABLE, 0);
sgetz7908 23:7ca590427f0e 40
sgetz7908 23:7ca590427f0e 41 DigitalOut led(LED, 0); // LED for debugging purposes
sgetz7908 24:761c30334cf4 42
sgetz7908 24:761c30334cf4 43 #if UART_DEBUGGING
sgetz7908 24:761c30334cf4 44 #define debug(STR) BLE_UART_xmit(STR); BLE_UART_xmit("\n");
sgetz7908 24:761c30334cf4 45 #else
sgetz7908 24:761c30334cf4 46 #define debug(...)
sgetz7908 24:761c30334cf4 47 #endif
sgetz7908 23:7ca590427f0e 48 #else
sgetz7908 23:7ca590427f0e 49 // simulate on nRF51-DK
sgetz7908 23:7ca590427f0e 50 DigitalIn capon(BUTTON1, PullUp);
sgetz7908 23:7ca590427f0e 51 //DigitalIn reg_mode(BUTTON3, PullUp);
sgetz7908 24:761c30334cf4 52 InterruptIn is_package_open(BUTTON2, PullUp); // will be pulled hi when package_is_open
sgetz7908 23:7ca590427f0e 53 DigitalOut package_open_sense_enable(LED3, 0);
sgetz7908 23:7ca590427f0e 54
sgetz7908 23:7ca590427f0e 55 DigitalOut cap_sense_led(LED2, 0);
sgetz7908 23:7ca590427f0e 56 DigitalOut vdd_enable(LED4, 0);
sgetz7908 23:7ca590427f0e 57
sgetz7908 23:7ca590427f0e 58 DigitalOut led(LED1, 0); // LED for debugging purposes
sgetz7908 24:761c30334cf4 59 #if UART_DEBUGGING
sgetz7908 24:761c30334cf4 60 Serial pc(USBTX, USBRX); // tx, rx
sgetz7908 24:761c30334cf4 61 #define debug(STR) pc.printf(STR)
sgetz7908 24:761c30334cf4 62 #else
sgetz7908 24:761c30334cf4 63 #define debug(...)
sgetz7908 24:761c30334cf4 64 #endif
sgetz7908 23:7ca590427f0e 65 #endif
sgetz7908 23:7ca590427f0e 66
sgetz7908 23:7ca590427f0e 67 LowPowerTicker periodic_ticker; // this handle the RTC
sgetz7908 23:7ca590427f0e 68
sgetz7908 24:761c30334cf4 69 float tick_rate = FAST_TICK_SEC;
sgetz7908 23:7ca590427f0e 70
sgetz7908 24:761c30334cf4 71 bool package_open_detected = false;
sgetz7908 23:7ca590427f0e 72 bool is_cap_off = false; // 0=cap on, 1=cap off
sgetz7908 23:7ca590427f0e 73 uint32_t cap_off_time;
sgetz7908 23:7ca590427f0e 74
sgetz7908 24:761c30334cf4 75 uint16_t off_reading;
sgetz7908 24:761c30334cf4 76 uint16_t on_reading;
sgetz7908 24:761c30334cf4 77
sgetz7908 23:7ca590427f0e 78 typedef enum {
sgetz7908 23:7ca590427f0e 79 INIT,
sgetz7908 23:7ca590427f0e 80 POST,
sgetz7908 23:7ca590427f0e 81 TEST_MODE,
sgetz7908 23:7ca590427f0e 82 SHIP_MODE_WAIT_DARK,
sgetz7908 23:7ca590427f0e 83 SHIP_MODE_WAIT_LIGHT,
sgetz7908 24:761c30334cf4 84 SHIP_MODE_CHECK_CAP,
sgetz7908 23:7ca590427f0e 85 SHIP_MODE_WAIT_CAP_OFF,
sgetz7908 23:7ca590427f0e 86 IN_USE_SETUP,
sgetz7908 23:7ca590427f0e 87 WAIT_CAP_OFF,
sgetz7908 23:7ca590427f0e 88 WAIT_CAP_ON,
sgetz7908 26:a577c4b69fe0 89 EOL_WAIT_CAP_OFF,
sgetz7908 26:a577c4b69fe0 90 EOL_WAIT_CAP_ON,
sgetz7908 26:a577c4b69fe0 91 EOL_WAIT_LIGHT,
sgetz7908 23:7ca590427f0e 92 OTHER
sgetz7908 23:7ca590427f0e 93 } state_t;
sgetz7908 23:7ca590427f0e 94
sgetz7908 23:7ca590427f0e 95 state_t state = INIT;
sgetz7908 23:7ca590427f0e 96
sgetz7908 23:7ca590427f0e 97 /// Light detected interrupt
sgetz7908 23:7ca590427f0e 98 void light_interrupt(void)
sgetz7908 24:761c30334cf4 99 { // dark to light transition
sgetz7908 24:761c30334cf4 100 package_open_detected = true;
sgetz7908 25:42163d650266 101 start_periodic_tick(FAST_TICK_SEC);
sgetz7908 23:7ca590427f0e 102 }
sgetz7908 23:7ca590427f0e 103
sgetz7908 23:7ca590427f0e 104 /// Test to see if Cap is off or on
sgetz7908 23:7ca590427f0e 105 void test_cap(void)
sgetz7908 23:7ca590427f0e 106 {
sgetz7908 24:761c30334cf4 107 #if TEST_ON_NRF51_DK == 0
sgetz7908 23:7ca590427f0e 108 vdd_enable = 1; // enable analog power
fdelahan 37:0cb0a0b22b99 109 //wait(0.00075);
fdelahan 37:0cb0a0b22b99 110 wait(0.0035); // increase wait time to allow full settling - FTD 11/21/2019
sgetz7908 23:7ca590427f0e 111 off_reading = adc_read(ADC_CHAN_CAP_SENSE,2);
sgetz7908 23:7ca590427f0e 112 cap_sense_led = 1; // enable led
sgetz7908 23:7ca590427f0e 113 wait(0.00075);
fdelahan 37:0cb0a0b22b99 114 //wait(0.001); // increase wait time to allow full settling - FTD 11/21/2019
sgetz7908 23:7ca590427f0e 115 on_reading = adc_read(ADC_CHAN_CAP_SENSE,2);
sgetz7908 23:7ca590427f0e 116 // turn everything off
sgetz7908 23:7ca590427f0e 117 cap_sense_led = 0;
sgetz7908 23:7ca590427f0e 118 vdd_enable = 0;
sgetz7908 23:7ca590427f0e 119
sgetz7908 23:7ca590427f0e 120 if(on_reading > off_reading+CAP_THRESHOLD)
sgetz7908 23:7ca590427f0e 121 #else
sgetz7908 23:7ca590427f0e 122 if(capon)
sgetz7908 23:7ca590427f0e 123 #endif
sgetz7908 23:7ca590427f0e 124 {
sgetz7908 23:7ca590427f0e 125 is_cap_off = 0;
sgetz7908 24:761c30334cf4 126 #if ENABLE_LED
sgetz7908 24:761c30334cf4 127 led = 0;
sgetz7908 24:761c30334cf4 128 #endif
sgetz7908 23:7ca590427f0e 129 }
sgetz7908 23:7ca590427f0e 130 else
sgetz7908 23:7ca590427f0e 131 {
sgetz7908 23:7ca590427f0e 132 is_cap_off = 1;
sgetz7908 24:761c30334cf4 133 #if ENABLE_LED
sgetz7908 24:761c30334cf4 134 led = 1;
sgetz7908 24:761c30334cf4 135 #endif
sgetz7908 23:7ca590427f0e 136 }
sgetz7908 24:761c30334cf4 137 }
sgetz7908 24:761c30334cf4 138
sgetz7908 24:761c30334cf4 139 void periodic_tick_task(void)
sgetz7908 24:761c30334cf4 140 {
sgetz7908 24:761c30334cf4 141 test_cap();
sgetz7908 24:761c30334cf4 142 process_state();
sgetz7908 23:7ca590427f0e 143 }
sgetz7908 23:7ca590427f0e 144
sgetz7908 23:7ca590427f0e 145 /// this interrupt is run every PERIODIC_TICK_SEC seconds
sgetz7908 23:7ca590427f0e 146 void periodic_tick()
sgetz7908 23:7ca590427f0e 147 {
sgetz7908 24:761c30334cf4 148 update_rtc(tick_rate); // keep rtc updated
sgetz7908 24:761c30334cf4 149 eventQueue.call(periodic_tick_task); // starts as non-interrupt task so we can use wait();
sgetz7908 24:761c30334cf4 150 }
sgetz7908 24:761c30334cf4 151
sgetz7908 24:761c30334cf4 152 void start_periodic_tick(uint32_t sec)
sgetz7908 24:761c30334cf4 153 {
sgetz7908 24:761c30334cf4 154 tick_rate = sec;
sgetz7908 24:761c30334cf4 155 periodic_ticker.detach();
sgetz7908 24:761c30334cf4 156 periodic_ticker.attach(&periodic_tick ,sec);
sgetz7908 24:761c30334cf4 157 }
sgetz7908 24:761c30334cf4 158
sgetz7908 24:761c30334cf4 159 void stop_periodic_tick(void)
sgetz7908 24:761c30334cf4 160 {
sgetz7908 24:761c30334cf4 161 periodic_ticker.detach();
sgetz7908 23:7ca590427f0e 162 }
sgetz7908 23:7ca590427f0e 163
sgetz7908 23:7ca590427f0e 164 /// call here to flash the LED n times.
sgetz7908 23:7ca590427f0e 165 // n=0 to flash forever
sgetz7908 23:7ca590427f0e 166 void flash_led(int n, float sec)
sgetz7908 23:7ca590427f0e 167 {
sgetz7908 23:7ca590427f0e 168 if(n==0)
sgetz7908 23:7ca590427f0e 169 { // flash forever
sgetz7908 23:7ca590427f0e 170 while(1)
sgetz7908 23:7ca590427f0e 171 {
sgetz7908 23:7ca590427f0e 172 led = 1;
sgetz7908 23:7ca590427f0e 173 wait(sec);
sgetz7908 23:7ca590427f0e 174 led = 0;
sgetz7908 23:7ca590427f0e 175 wait(sec);
sgetz7908 23:7ca590427f0e 176 }
sgetz7908 23:7ca590427f0e 177 }
sgetz7908 23:7ca590427f0e 178 else
sgetz7908 23:7ca590427f0e 179 { // flash n times
sgetz7908 23:7ca590427f0e 180 while(n--)
sgetz7908 23:7ca590427f0e 181 {
sgetz7908 23:7ca590427f0e 182 led = 1;
sgetz7908 23:7ca590427f0e 183 wait(sec);
sgetz7908 23:7ca590427f0e 184 led = 0;
sgetz7908 23:7ca590427f0e 185 wait(sec);
sgetz7908 23:7ca590427f0e 186 }
sgetz7908 23:7ca590427f0e 187 }
sgetz7908 23:7ca590427f0e 188 }
sgetz7908 23:7ca590427f0e 189
sgetz7908 23:7ca590427f0e 190
sgetz7908 23:7ca590427f0e 191 state_t last_state = OTHER;
sgetz7908 27:bb7247a1704e 192 int last_cap;
sgetz7908 23:7ca590427f0e 193
sgetz7908 23:7ca590427f0e 194 /// Main state machine
sgetz7908 23:7ca590427f0e 195 /// Called whenever a sensor changes
sgetz7908 23:7ca590427f0e 196 void process_state(void)
sgetz7908 23:7ca590427f0e 197 {
sgetz7908 24:761c30334cf4 198 do
sgetz7908 23:7ca590427f0e 199 {
sgetz7908 24:761c30334cf4 200 #if UART_DEBUGGING==1
sgetz7908 24:761c30334cf4 201 if(last_state != state)
sgetz7908 24:761c30334cf4 202 {
sgetz7908 24:761c30334cf4 203 debug(uli2a(state));
sgetz7908 24:761c30334cf4 204 debug("\n");
sgetz7908 24:761c30334cf4 205 }
sgetz7908 24:761c30334cf4 206 #endif
sgetz7908 23:7ca590427f0e 207 last_state = state;
sgetz7908 23:7ca590427f0e 208
sgetz7908 24:761c30334cf4 209 switch(state)
sgetz7908 24:761c30334cf4 210 {
sgetz7908 24:761c30334cf4 211 case INIT:
sgetz7908 24:761c30334cf4 212 log_add(EVENT_POWER, 0, 0, 0); // log event
sgetz7908 34:c122d842ad9a 213
sgetz7908 25:42163d650266 214 start_periodic_tick(FAST_TICK_SEC);
sgetz7908 24:761c30334cf4 215 #if SKIP_SHIP_MODE
sgetz7908 24:761c30334cf4 216 state = IN_USE_SETUP;
sgetz7908 24:761c30334cf4 217 #else
sgetz7908 24:761c30334cf4 218 state = POST;
sgetz7908 24:761c30334cf4 219 #endif
sgetz7908 24:761c30334cf4 220 break;
sgetz7908 24:761c30334cf4 221
sgetz7908 24:761c30334cf4 222 case POST:
sgetz7908 24:761c30334cf4 223 // check CRC ?
sgetz7908 24:761c30334cf4 224
sgetz7908 24:761c30334cf4 225 // Check Misc.
sgetz7908 24:761c30334cf4 226
sgetz7908 24:761c30334cf4 227 //if(error) flash_led(0,0.1); // flash forever to indicate error
sgetz7908 25:42163d650266 228
sgetz7908 24:761c30334cf4 229 if(NV_TESTING_REQUIRED)
sgetz7908 24:761c30334cf4 230 {
sgetz7908 24:761c30334cf4 231 flash_led(1, 1.0);
sgetz7908 24:761c30334cf4 232 package_open_sense_enable = 1;
sgetz7908 25:42163d650266 233 start_periodic_tick(FAST_TICK_SEC);
sgetz7908 27:bb7247a1704e 234 last_cap = 99;
sgetz7908 34:c122d842ad9a 235 set_radio(true, 0); // advertise forever until stopped
sgetz7908 24:761c30334cf4 236 state = TEST_MODE;
sgetz7908 24:761c30334cf4 237 }
sgetz7908 24:761c30334cf4 238 else
sgetz7908 24:761c30334cf4 239 {
sgetz7908 24:761c30334cf4 240 state = IN_USE_SETUP;
sgetz7908 24:761c30334cf4 241 }
sgetz7908 25:42163d650266 242
sgetz7908 24:761c30334cf4 243 break;
sgetz7908 24:761c30334cf4 244
sgetz7908 25:42163d650266 245 case TEST_MODE:
sgetz7908 24:761c30334cf4 246 test_cap();
sgetz7908 24:761c30334cf4 247 led = is_cap_off;
sgetz7908 27:bb7247a1704e 248 if(last_cap != is_cap_off)
sgetz7908 27:bb7247a1704e 249 {
sgetz7908 27:bb7247a1704e 250 last_cap = is_cap_off;
sgetz7908 27:bb7247a1704e 251 BLE_UART_xmit("*Cap ");
sgetz7908 27:bb7247a1704e 252 if(last_cap) BLE_UART_xmit("Off"); else BLE_UART_xmit("On");
sgetz7908 27:bb7247a1704e 253 BLE_UART_xmit("\n");
sgetz7908 27:bb7247a1704e 254 }
sgetz7908 25:42163d650266 255 if(!NV_TESTING_REQUIRED && is_package_open)
sgetz7908 24:761c30334cf4 256 { // testing passed
sgetz7908 24:761c30334cf4 257 set_radio(false); // already done when NV_TESTING_REQUIRED was cleared.
sgetz7908 24:761c30334cf4 258 led = 0;
sgetz7908 24:761c30334cf4 259 state = SHIP_MODE_WAIT_DARK;
sgetz7908 24:761c30334cf4 260 }
sgetz7908 24:761c30334cf4 261 break;
sgetz7908 24:761c30334cf4 262
sgetz7908 24:761c30334cf4 263 case SHIP_MODE_WAIT_DARK: // Wait for light sensor to see darkness
sgetz7908 27:bb7247a1704e 264 //flash_led(1,0.1);
sgetz7908 25:42163d650266 265 if(!is_package_open)
sgetz7908 24:761c30334cf4 266 { // its dark
sgetz7908 24:761c30334cf4 267 state = SHIP_MODE_WAIT_LIGHT;
sgetz7908 24:761c30334cf4 268 }
sgetz7908 24:761c30334cf4 269 break;
sgetz7908 24:761c30334cf4 270
sgetz7908 24:761c30334cf4 271 case SHIP_MODE_WAIT_LIGHT:
sgetz7908 24:761c30334cf4 272 // set up and enable the Light Sense Interrupt
sgetz7908 24:761c30334cf4 273 // go to lowest power state
sgetz7908 25:42163d650266 274
sgetz7908 24:761c30334cf4 275 debug("Going SHIP MODE\n");
sgetz7908 24:761c30334cf4 276 is_package_open.disable_irq();
sgetz7908 24:761c30334cf4 277 stop_periodic_tick();
sgetz7908 24:761c30334cf4 278 led = 0;
sgetz7908 24:761c30334cf4 279 package_open_detected = false;
sgetz7908 26:a577c4b69fe0 280 //is_package_open.mode(PullDown);
sgetz7908 24:761c30334cf4 281 is_package_open.rise(&light_interrupt);
sgetz7908 24:761c30334cf4 282 is_package_open.enable_irq();
sgetz7908 24:761c30334cf4 283 state = SHIP_MODE_CHECK_CAP;
sgetz7908 24:761c30334cf4 284
sgetz7908 23:7ca590427f0e 285 break;
sgetz7908 23:7ca590427f0e 286
sgetz7908 24:761c30334cf4 287 case SHIP_MODE_CHECK_CAP:
sgetz7908 25:42163d650266 288
sgetz7908 24:761c30334cf4 289 if(package_open_detected)
sgetz7908 24:761c30334cf4 290 {
sgetz7908 24:761c30334cf4 291 debug("Awake\n");
sgetz7908 27:bb7247a1704e 292 //flash_led(3,0.25);
sgetz7908 24:761c30334cf4 293 test_cap();
sgetz7908 24:761c30334cf4 294 if(is_cap_off)
sgetz7908 24:761c30334cf4 295 {
sgetz7908 24:761c30334cf4 296 state = SHIP_MODE_WAIT_DARK;
sgetz7908 24:761c30334cf4 297 }
sgetz7908 24:761c30334cf4 298 else
sgetz7908 24:761c30334cf4 299 {
sgetz7908 24:761c30334cf4 300 state = SHIP_MODE_WAIT_CAP_OFF;
sgetz7908 24:761c30334cf4 301 }
sgetz7908 24:761c30334cf4 302 }
sgetz7908 24:761c30334cf4 303 break;
sgetz7908 24:761c30334cf4 304
sgetz7908 24:761c30334cf4 305 case SHIP_MODE_WAIT_CAP_OFF:
sgetz7908 25:42163d650266 306 if(!is_package_open)
sgetz7908 24:761c30334cf4 307 {
sgetz7908 24:761c30334cf4 308 state = SHIP_MODE_WAIT_LIGHT;
sgetz7908 24:761c30334cf4 309 }
sgetz7908 24:761c30334cf4 310 else
sgetz7908 24:761c30334cf4 311 {
sgetz7908 24:761c30334cf4 312 test_cap();
sgetz7908 24:761c30334cf4 313 if(is_cap_off)
sgetz7908 24:761c30334cf4 314 {
sgetz7908 24:761c30334cf4 315 package_open_sense_enable = 0;
sgetz7908 35:e8fa201fe147 316 set_rtc(0);
sgetz7908 24:761c30334cf4 317 log_add(EVENT_WAKE_FROM_SHIP, 0, 0, 0);
sgetz7908 24:761c30334cf4 318 state = IN_USE_SETUP;
sgetz7908 24:761c30334cf4 319 }
sgetz7908 24:761c30334cf4 320 }
sgetz7908 24:761c30334cf4 321 break;
sgetz7908 24:761c30334cf4 322
sgetz7908 24:761c30334cf4 323 case IN_USE_SETUP:
sgetz7908 25:42163d650266 324 flash_led(3, .25);
sgetz7908 24:761c30334cf4 325 start_periodic_tick(PERIODIC_TICK_SEC);
sgetz7908 26:a577c4b69fe0 326 debug("In Use\n");
sgetz7908 26:a577c4b69fe0 327 if(NV_NOT_IN_USE) nv_clear(NV_NOT_IN_USE_ADDR);
sgetz7908 24:761c30334cf4 328 state = WAIT_CAP_OFF;
sgetz7908 24:761c30334cf4 329 break;
sgetz7908 23:7ca590427f0e 330
sgetz7908 24:761c30334cf4 331 case WAIT_CAP_OFF: // cap is on, waiting for cap to be removed
sgetz7908 26:a577c4b69fe0 332 if(read_clock()>((uint32_t)EOL_TIMEOUT_DAYS*24*60*60))
sgetz7908 26:a577c4b69fe0 333 { // EOL detected due to maximum time
sgetz7908 27:bb7247a1704e 334 if(NV_NOT_EOL) nv_clear(NV_NOT_EOL_ADDR);
sgetz7908 26:a577c4b69fe0 335 }
sgetz7908 26:a577c4b69fe0 336
sgetz7908 26:a577c4b69fe0 337 if(!NV_NOT_EOL)
sgetz7908 26:a577c4b69fe0 338 { // EOL flagged
sgetz7908 27:bb7247a1704e 339 if(log_code_count(EVENT_EOL)==0) log_add(EVENT_EOL, 0, 0, 0); // log event
sgetz7908 27:bb7247a1704e 340 start_periodic_tick(EOL_TICK_SEC); // just tick less often
sgetz7908 26:a577c4b69fe0 341 state = EOL_WAIT_CAP_OFF;
sgetz7908 26:a577c4b69fe0 342 }
sgetz7908 26:a577c4b69fe0 343 else if(is_cap_off)
sgetz7908 26:a577c4b69fe0 344 { // cap just taken off
sgetz7908 26:a577c4b69fe0 345 // save cap off time
sgetz7908 26:a577c4b69fe0 346 cap_off_time = read_clock();
sgetz7908 26:a577c4b69fe0 347 debug("Cap Off \n");
sgetz7908 26:a577c4b69fe0 348 state = WAIT_CAP_ON;
sgetz7908 26:a577c4b69fe0 349 }
sgetz7908 24:761c30334cf4 350
sgetz7908 24:761c30334cf4 351 break;
sgetz7908 24:761c30334cf4 352
sgetz7908 24:761c30334cf4 353 case WAIT_CAP_ON: // cap currently off, waiting for cap to be put on
sgetz7908 26:a577c4b69fe0 354 if(!is_cap_off)
sgetz7908 26:a577c4b69fe0 355 { // cap just put on
sgetz7908 26:a577c4b69fe0 356 // log time cap was off
sgetz7908 26:a577c4b69fe0 357 uint32_t cap_off_dur = read_clock()-cap_off_time;
sgetz7908 26:a577c4b69fe0 358 if(cap_off_dur>65535) cap_off_dur = 65535;
sgetz7908 26:a577c4b69fe0 359 log_add(EVENT_CAP_ON, cap_off_dur & 0xff, (cap_off_dur >> 8)&0xff, 0); // log event
sgetz7908 26:a577c4b69fe0 360
sgetz7908 26:a577c4b69fe0 361 if(log_code_count(EVENT_CAP_ON)>= EOL_MAX_USES)
sgetz7908 26:a577c4b69fe0 362 { // EOL detected due to maximum uses
sgetz7908 27:bb7247a1704e 363 if(NV_NOT_EOL) nv_clear(NV_NOT_EOL_ADDR);
sgetz7908 26:a577c4b69fe0 364 }
sgetz7908 27:bb7247a1704e 365
sgetz7908 27:bb7247a1704e 366 set_radio(true);
sgetz7908 27:bb7247a1704e 367 state = WAIT_CAP_OFF;
sgetz7908 26:a577c4b69fe0 368 }
sgetz7908 26:a577c4b69fe0 369 break;
sgetz7908 24:761c30334cf4 370
sgetz7908 26:a577c4b69fe0 371 case EOL_WAIT_CAP_OFF: // Cap is on
sgetz7908 26:a577c4b69fe0 372 if(is_cap_off)
sgetz7908 26:a577c4b69fe0 373 { // cap just taken off
sgetz7908 26:a577c4b69fe0 374 debug("EOL Cap Off \n");
sgetz7908 26:a577c4b69fe0 375 state = EOL_WAIT_CAP_ON;
sgetz7908 26:a577c4b69fe0 376 }
sgetz7908 27:bb7247a1704e 377 //else if(!is_package_open)
sgetz7908 27:bb7247a1704e 378 //{ // its dark
sgetz7908 27:bb7247a1704e 379 // start_periodic_tick(EOL_TICK_SEC); // just tick less often
sgetz7908 27:bb7247a1704e 380 // state = EOL_WAIT_LIGHT;
sgetz7908 27:bb7247a1704e 381 //}
sgetz7908 26:a577c4b69fe0 382 break;
sgetz7908 26:a577c4b69fe0 383
sgetz7908 26:a577c4b69fe0 384 case EOL_WAIT_CAP_ON: // Cap is off
sgetz7908 26:a577c4b69fe0 385 if(!is_cap_off)
sgetz7908 26:a577c4b69fe0 386 { // cap just put on
sgetz7908 26:a577c4b69fe0 387 debug("EOL Cap On \n");
sgetz7908 26:a577c4b69fe0 388 set_radio(true);
sgetz7908 27:bb7247a1704e 389 state = EOL_WAIT_CAP_OFF;
sgetz7908 26:a577c4b69fe0 390 }
sgetz7908 26:a577c4b69fe0 391 break;
sgetz7908 29:4b347695b9f7 392 /*
sgetz7908 26:a577c4b69fe0 393 case EOL_WAIT_LIGHT: // EOL and its dark, save power
sgetz7908 26:a577c4b69fe0 394 // set up and enable the Light Sense Interrupt
sgetz7908 26:a577c4b69fe0 395 // go to lowest power state
sgetz7908 27:bb7247a1704e 396
sgetz7908 26:a577c4b69fe0 397 debug("Going to EOL dark mode\n");
sgetz7908 26:a577c4b69fe0 398 led = 0;
sgetz7908 27:bb7247a1704e 399 if(is_package_open)
sgetz7908 27:bb7247a1704e 400 {
sgetz7908 27:bb7247a1704e 401 start_periodic_tick(PERIODIC_TICK_SEC);
sgetz7908 27:bb7247a1704e 402 state = EOL_WAIT_CAP_OFF;
sgetz7908 27:bb7247a1704e 403 }
sgetz7908 26:a577c4b69fe0 404 break;
sgetz7908 29:4b347695b9f7 405 */
sgetz7908 24:761c30334cf4 406 default: // illegal state
sgetz7908 24:761c30334cf4 407 state = INIT;
sgetz7908 23:7ca590427f0e 408 break;
sgetz7908 23:7ca590427f0e 409 }
sgetz7908 24:761c30334cf4 410 } while(state != last_state);
sgetz7908 23:7ca590427f0e 411 }
sgetz7908 23:7ca590427f0e 412
sgetz7908 27:bb7247a1704e 413 void dataWasRead(void)
sgetz7908 27:bb7247a1704e 414 {
sgetz7908 27:bb7247a1704e 415 flash_led(1, 0.04);
sgetz7908 27:bb7247a1704e 416 }
sgetz7908 27:bb7247a1704e 417
sgetz7908 24:761c30334cf4 418 /// process commands sent to the SmartCap over Bluetooth UART
sgetz7908 23:7ca590427f0e 419 void process_cmd(char * cmd)
sgetz7908 23:7ca590427f0e 420 {
sgetz7908 23:7ca590427f0e 421 switch(tolower(cmd[0])) {
sgetz7908 23:7ca590427f0e 422 case 'r': // Get records
sgetz7908 23:7ca590427f0e 423 log_show();
sgetz7908 23:7ca590427f0e 424 //batt_voltage = read_battery_voltage();
sgetz7908 23:7ca590427f0e 425 //updateBattValue(batt_voltage);
sgetz7908 23:7ca590427f0e 426 break;
sgetz7908 23:7ca590427f0e 427
sgetz7908 23:7ca590427f0e 428 case 's': // status
sgetz7908 23:7ca590427f0e 429 switch(tolower(cmd[1])) {
fdelahan 39:93d6d459c76c 430 case 'b': // old, check battery voltage
sgetz7908 23:7ca590427f0e 431 batt_voltage = read_battery_voltage();
sgetz7908 23:7ca590427f0e 432 BLE_UART_xmit("Bat=");
sgetz7908 23:7ca590427f0e 433 BLE_UART_xmit(batt_voltage);
sgetz7908 23:7ca590427f0e 434 BLE_UART_xmit("\n");
sgetz7908 23:7ca590427f0e 435 break;
sgetz7908 23:7ca590427f0e 436
sgetz7908 26:a577c4b69fe0 437 //case 'x': // checksum
sgetz7908 26:a577c4b69fe0 438 // BLE_UART_xmit("sx=");
sgetz7908 26:a577c4b69fe0 439 // BLE_UART_xmit(0);
sgetz7908 26:a577c4b69fe0 440 // BLE_UART_xmit("\n");
sgetz7908 26:a577c4b69fe0 441 // break;
sgetz7908 25:42163d650266 442
sgetz7908 24:761c30334cf4 443 case 'c': // cap sensor analog readings
sgetz7908 24:761c30334cf4 444 BLE_UART_xmit("sc=");
sgetz7908 24:761c30334cf4 445 test_cap();
sgetz7908 24:761c30334cf4 446 BLE_UART_xmit(on_reading);
sgetz7908 24:761c30334cf4 447 BLE_UART_xmit(",");
sgetz7908 24:761c30334cf4 448 BLE_UART_xmit(off_reading);
sgetz7908 24:761c30334cf4 449 BLE_UART_xmit("\n");
sgetz7908 24:761c30334cf4 450 break;
sgetz7908 26:a577c4b69fe0 451
sgetz7908 26:a577c4b69fe0 452 case 'm': // CRC of Softdevice and App (Not including NV storage for logs and flags)
sgetz7908 26:a577c4b69fe0 453 {
sgetz7908 26:a577c4b69fe0 454 uint16_t crc = crc16((const unsigned char*)CRC_START_ADDR, (uint32_t)(CRC_END_ADDR - CRC_START_ADDR + 1) );
sgetz7908 34:c122d842ad9a 455 BLE_UART_xmit("sm=");
sgetz7908 26:a577c4b69fe0 456 BLE_UART_xmit(char2hex(crc, 4));
sgetz7908 26:a577c4b69fe0 457 BLE_UART_xmit("\n");
sgetz7908 26:a577c4b69fe0 458 }
sgetz7908 26:a577c4b69fe0 459 break;
sgetz7908 23:7ca590427f0e 460
sgetz7908 26:a577c4b69fe0 461 case 's': // sensors as binary, with bits '000eutcp', e=(0=EOL), u=(0=in use), t=(1=TESTING REQUIRED), c=(1 is cap off), p=(1 is light sensed)
sgetz7908 25:42163d650266 462 //int val = 0;
sgetz7908 27:bb7247a1704e 463 BLE_UART_xmit("*ss=000");
sgetz7908 26:a577c4b69fe0 464 if(NV_NOT_EOL) BLE_UART_xmit("1"); else BLE_UART_xmit("0");
sgetz7908 26:a577c4b69fe0 465 if(NV_NOT_IN_USE) BLE_UART_xmit("1"); else BLE_UART_xmit("0");
sgetz7908 25:42163d650266 466 if(NV_TESTING_REQUIRED) BLE_UART_xmit("1"); else BLE_UART_xmit("0");
sgetz7908 25:42163d650266 467 int save = package_open_sense_enable;
sgetz7908 24:761c30334cf4 468 package_open_sense_enable = 1;
sgetz7908 24:761c30334cf4 469 test_cap();
sgetz7908 25:42163d650266 470 if(is_cap_off) BLE_UART_xmit("1"); else BLE_UART_xmit("0");
sgetz7908 25:42163d650266 471 if(is_package_open) BLE_UART_xmit("1"); else BLE_UART_xmit("0");
sgetz7908 25:42163d650266 472 package_open_sense_enable = save;
sgetz7908 23:7ca590427f0e 473 BLE_UART_xmit("\n");
sgetz7908 23:7ca590427f0e 474 break;
sgetz7908 38:4b06a103c044 475 case 'l': // read light sensor analog reading via ADC. Circuit enabled before doing reading.
sgetz7908 38:4b06a103c044 476 BLE_UART_xmit("sl=");
sgetz7908 38:4b06a103c044 477 int save2 = package_open_sense_enable;
sgetz7908 38:4b06a103c044 478 package_open_sense_enable = 1;
sgetz7908 38:4b06a103c044 479 wait(LIGHT_SENSE_PWRON_DELAY);
sgetz7908 38:4b06a103c044 480 BLE_UART_xmit(adc_read(ADC_CHAN_LIGHT_SENSE,2));
sgetz7908 38:4b06a103c044 481 package_open_sense_enable = save2;
sgetz7908 38:4b06a103c044 482 BLE_UART_xmit("\n");
sgetz7908 38:4b06a103c044 483 break;
sgetz7908 23:7ca590427f0e 484 }
sgetz7908 23:7ca590427f0e 485 break;
sgetz7908 24:761c30334cf4 486 case 'p': // test passed
sgetz7908 24:761c30334cf4 487 if(tolower(cmd[1])=='z')
sgetz7908 24:761c30334cf4 488 {
sgetz7908 24:761c30334cf4 489 log_add(EVENT_TEST_PASS, 0, 0, 0);
sgetz7908 26:a577c4b69fe0 490 if(NV_TESTING_REQUIRED) nv_clear(NV_TESTING_REQUIRED_ADDR);
sgetz7908 24:761c30334cf4 491 }
sgetz7908 26:a577c4b69fe0 492
sgetz7908 24:761c30334cf4 493 break;
sgetz7908 24:761c30334cf4 494
sgetz7908 23:7ca590427f0e 495 case 't': // get time
sgetz7908 23:7ca590427f0e 496 BLE_UART_xmit(read_clock());
sgetz7908 23:7ca590427f0e 497 BLE_UART_xmit("\n");
sgetz7908 23:7ca590427f0e 498 break;
sgetz7908 23:7ca590427f0e 499
sgetz7908 23:7ca590427f0e 500 case 'c': // set time
sgetz7908 23:7ca590427f0e 501 {
sgetz7908 23:7ca590427f0e 502 int i = 1;
sgetz7908 23:7ca590427f0e 503 uint32_t num = 0;
sgetz7908 23:7ca590427f0e 504
sgetz7908 23:7ca590427f0e 505 while(cmd[i]>='0' && cmd[i]<='9') {
sgetz7908 23:7ca590427f0e 506 num = num*10 + cmd[i++]-'0';
sgetz7908 23:7ca590427f0e 507 }
sgetz7908 23:7ca590427f0e 508
sgetz7908 23:7ca590427f0e 509 if(i>1) {
sgetz7908 23:7ca590427f0e 510 set_time_offset(num);
sgetz7908 23:7ca590427f0e 511 BLE_UART_xmit("*Time Set\n");
sgetz7908 23:7ca590427f0e 512 }
sgetz7908 23:7ca590427f0e 513 }
sgetz7908 23:7ca590427f0e 514 break;
sgetz7908 30:76b51e525c40 515
sgetz7908 23:7ca590427f0e 516 case 'v': // version
sgetz7908 24:761c30334cf4 517 BLE_UART_xmit("v=");
sgetz7908 23:7ca590427f0e 518 BLE_UART_xmit(FW_VERSION);
sgetz7908 23:7ca590427f0e 519 BLE_UART_xmit("\n");
sgetz7908 23:7ca590427f0e 520 break;
sgetz7908 23:7ca590427f0e 521
sgetz7908 23:7ca590427f0e 522 default:
sgetz7908 23:7ca590427f0e 523 BLE_UART_xmit("S=Status\n");
sgetz7908 23:7ca590427f0e 524 break;
sgetz7908 23:7ca590427f0e 525 }
sgetz7908 23:7ca590427f0e 526 cmd[0] = 0;
sgetz7908 23:7ca590427f0e 527 }
sgetz7908 25:42163d650266 528
sgetz7908 25:42163d650266 529 //*****************************************************************************
sgetz7908 25:42163d650266 530
sgetz7908 25:42163d650266 531 int main(void)
sgetz7908 25:42163d650266 532 {
sgetz7908 25:42163d650266 533 // blink LED to indicate power applied
sgetz7908 25:42163d650266 534 //flash_led(1,1.0);
sgetz7908 25:42163d650266 535
sgetz7908 25:42163d650266 536 if(Init_BLE_Stuff()) // init and start advertising
sgetz7908 25:42163d650266 537 {
sgetz7908 25:42163d650266 538 flash_led(0, 0.05); // indicate a ble init error
sgetz7908 25:42163d650266 539 }
sgetz7908 25:42163d650266 540
sgetz7908 25:42163d650266 541 eventQueue.call(process_state);
sgetz7908 25:42163d650266 542
sgetz7908 25:42163d650266 543 eventQueue.dispatch_forever(); // run all tasks in the event queue (non-interrupt routines)
sgetz7908 25:42163d650266 544 return 0;
sgetz7908 25:42163d650266 545 }
sgetz7908 25:42163d650266 546
sgetz7908 25:42163d650266 547