Dependencies:   nRF51822

Committer:
sgetz7908
Date:
Fri Sep 18 21:15:41 2020 +0000
Revision:
51:53fe9aff625a
Parent:
50:8dca54c1e3fd
Child:
52:23cc9f576e4a
Added 2 step cap off detection.; 1st step causes the rate of checking for a cap off to increase.; 2nd step is the actual detection of a cap off.;

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 48:bb7d5118e03c 32
sgetz7908 48:bb7d5118e03c 33 // define I/O
sgetz7908 48:bb7d5118e03c 34 InterruptIn is_package_open(LIGHT_SENSE, PullNone); // will be pulled hi when package_is_open (only if package_open_sense_enable = 1)
sgetz7908 48:bb7d5118e03c 35 DigitalOut package_open_sense_enable(LIGHT_SENSE_ENABLE, 0);
sgetz7908 48:bb7d5118e03c 36
sgetz7908 48:bb7d5118e03c 37 DigitalOut cap_sense_led(CAP_SENSE_LED, 0);
sgetz7908 48:bb7d5118e03c 38 DigitalOut vdd_enable(VDD_ENABLE, 0);
sgetz7908 48:bb7d5118e03c 39
sgetz7908 48:bb7d5118e03c 40 DigitalOut led(LED, 0); // LED for debugging purposes
sgetz7908 48:bb7d5118e03c 41
sgetz7908 48:bb7d5118e03c 42 #if UART_DEBUGGING
sgetz7908 48:bb7d5118e03c 43 #define debug(STR) BLE_UART_xmit(STR); BLE_UART_xmit("\n");
sgetz7908 48:bb7d5118e03c 44 #else
sgetz7908 48:bb7d5118e03c 45 #define debug(...)
sgetz7908 48:bb7d5118e03c 46 #endif
sgetz7908 48:bb7d5118e03c 47
sgetz7908 23:7ca590427f0e 48 LowPowerTicker periodic_ticker; // this handle the RTC
sgetz7908 51:53fe9aff625a 49 LowPowerTicker capofffast_ticker; // this handle accellerated polling of the cap if CAP_THRESHOLD_OFF1 is passed
sgetz7908 51:53fe9aff625a 50
sgetz7908 24:761c30334cf4 51 float tick_rate = FAST_TICK_SEC;
sgetz7908 23:7ca590427f0e 52
fdelahan 40:adabdb1c5abe 53 bool log_enable = true; // turn off event logging when false (engineering function) – DEW
fdelahan 40:adabdb1c5abe 54
sgetz7908 50:8dca54c1e3fd 55 volatile bool package_open_detected = false;
sgetz7908 50:8dca54c1e3fd 56 volatile bool is_cap_off = false; // 0=cap on, 1=cap off
sgetz7908 50:8dca54c1e3fd 57 volatile bool last_cap_off = false;
sgetz7908 50:8dca54c1e3fd 58 volatile bool adaptive_active = false;
sgetz7908 50:8dca54c1e3fd 59
sgetz7908 23:7ca590427f0e 60 uint32_t cap_off_time;
sgetz7908 23:7ca590427f0e 61
sgetz7908 50:8dca54c1e3fd 62 volatile int16_t off_reading;
sgetz7908 50:8dca54c1e3fd 63 volatile int16_t on_reading;
sgetz7908 50:8dca54c1e3fd 64 volatile int16_t on_reading_filtered = 0;
sgetz7908 50:8dca54c1e3fd 65 volatile int16_t on_reading_peak = 0;
sgetz7908 48:bb7d5118e03c 66
sgetz7908 50:8dca54c1e3fd 67 volatile uint16_t cap_threshold_on = CAP_THRESHOLD_ON_INITIAL;
sgetz7908 24:761c30334cf4 68
sgetz7908 23:7ca590427f0e 69 typedef enum {
sgetz7908 23:7ca590427f0e 70 INIT,
sgetz7908 23:7ca590427f0e 71 POST,
sgetz7908 23:7ca590427f0e 72 TEST_MODE,
sgetz7908 23:7ca590427f0e 73 SHIP_MODE_WAIT_DARK,
sgetz7908 23:7ca590427f0e 74 SHIP_MODE_WAIT_LIGHT,
sgetz7908 24:761c30334cf4 75 SHIP_MODE_CHECK_CAP,
sgetz7908 23:7ca590427f0e 76 SHIP_MODE_WAIT_CAP_OFF,
sgetz7908 23:7ca590427f0e 77 IN_USE_SETUP,
sgetz7908 23:7ca590427f0e 78 WAIT_CAP_OFF,
sgetz7908 23:7ca590427f0e 79 WAIT_CAP_ON,
sgetz7908 26:a577c4b69fe0 80 EOL_WAIT_CAP_OFF,
sgetz7908 26:a577c4b69fe0 81 EOL_WAIT_CAP_ON,
sgetz7908 26:a577c4b69fe0 82 EOL_WAIT_LIGHT,
sgetz7908 23:7ca590427f0e 83 OTHER
sgetz7908 23:7ca590427f0e 84 } state_t;
sgetz7908 23:7ca590427f0e 85
sgetz7908 23:7ca590427f0e 86 state_t state = INIT;
sgetz7908 23:7ca590427f0e 87
sgetz7908 51:53fe9aff625a 88 volatile uint8_t veryfasttick_on = 0;
sgetz7908 51:53fe9aff625a 89
sgetz7908 51:53fe9aff625a 90 void fastcap_tick(void);
sgetz7908 51:53fe9aff625a 91
sgetz7908 23:7ca590427f0e 92 /// Light detected interrupt
sgetz7908 23:7ca590427f0e 93 void light_interrupt(void)
sgetz7908 24:761c30334cf4 94 { // dark to light transition
sgetz7908 24:761c30334cf4 95 package_open_detected = true;
sgetz7908 25:42163d650266 96 start_periodic_tick(FAST_TICK_SEC);
sgetz7908 23:7ca590427f0e 97 }
sgetz7908 23:7ca590427f0e 98
sgetz7908 23:7ca590427f0e 99 /// Test to see if Cap is off or on
sgetz7908 23:7ca590427f0e 100 void test_cap(void)
sgetz7908 48:bb7d5118e03c 101 {
sgetz7908 23:7ca590427f0e 102 vdd_enable = 1; // enable analog power
fdelahan 37:0cb0a0b22b99 103 //wait(0.00075);
fdelahan 47:a1e91dea282d 104 wait(CAP_LED_OFF_DELAY); // increase wait time to allow full settling - FTD 11/21/2019
fdelahan 47:a1e91dea282d 105 off_reading = adc_read(ADC_CHAN_CAP_SENSE,CAP_SAMPLES);
sgetz7908 23:7ca590427f0e 106 cap_sense_led = 1; // enable led
fdelahan 47:a1e91dea282d 107 wait(CAP_LED_ON_DELAY);
fdelahan 37:0cb0a0b22b99 108 //wait(0.001); // increase wait time to allow full settling - FTD 11/21/2019
fdelahan 47:a1e91dea282d 109 on_reading = adc_read(ADC_CHAN_CAP_SENSE,CAP_SAMPLES);
sgetz7908 23:7ca590427f0e 110 // turn everything off
sgetz7908 23:7ca590427f0e 111 cap_sense_led = 0;
sgetz7908 23:7ca590427f0e 112 vdd_enable = 0;
sgetz7908 23:7ca590427f0e 113
sgetz7908 46:b85be1ccf179 114 // switch cap state using hysteresis
sgetz7908 46:b85be1ccf179 115 if(last_cap_off)
sgetz7908 46:b85be1ccf179 116 { // cap was off
sgetz7908 49:d2bd9056426e 117 if(on_reading > off_reading + cap_threshold_on)
sgetz7908 48:bb7d5118e03c 118 { // cap is now on
sgetz7908 42:213f9b0cabe4 119 is_cap_off = 0;
sgetz7908 42:213f9b0cabe4 120 #if ENABLE_LED
sgetz7908 42:213f9b0cabe4 121 led = 0;
sgetz7908 46:b85be1ccf179 122 #endif
sgetz7908 42:213f9b0cabe4 123 }
sgetz7908 46:b85be1ccf179 124 }
sgetz7908 46:b85be1ccf179 125 else
sgetz7908 46:b85be1ccf179 126 { // cap was on
sgetz7908 48:bb7d5118e03c 127 uint16_t off_threshold; // there are two cap off thresholds, normal use and EOL, this provides a variable for the proper value - FTD 08212020
fdelahan 47:a1e91dea282d 128 // test for proper threshold needed for EOL - FTD 08212020
sgetz7908 51:53fe9aff625a 129 if(NV_NOT_EOL) off_threshold = CAP_THRESHOLD_OFF2;
fdelahan 47:a1e91dea282d 130 else off_threshold = CAP_THRESHOLD_OFF_EOL;
fdelahan 47:a1e91dea282d 131
fdelahan 47:a1e91dea282d 132 if(on_reading < off_reading + off_threshold)
sgetz7908 48:bb7d5118e03c 133 { // cap is now off
sgetz7908 42:213f9b0cabe4 134 is_cap_off = 1;
sgetz7908 51:53fe9aff625a 135 capofffast_ticker.detach();
sgetz7908 51:53fe9aff625a 136 veryfasttick_on = 0;
sgetz7908 42:213f9b0cabe4 137 #if ENABLE_LED
sgetz7908 42:213f9b0cabe4 138 led = 1;
sgetz7908 46:b85be1ccf179 139 #endif
sgetz7908 51:53fe9aff625a 140 //BLE_UART_xmit("2");
sgetz7908 42:213f9b0cabe4 141 }
sgetz7908 51:53fe9aff625a 142 else if(NV_NOT_EOL && on_reading < off_reading + CAP_THRESHOLD_OFF1) // check for cap moving toward off
sgetz7908 51:53fe9aff625a 143 { // cap is almost off, start fast ticks (turns off after next regular periodic tick, or if full cap off is detected)
sgetz7908 51:53fe9aff625a 144 if(veryfasttick_on==0)
sgetz7908 51:53fe9aff625a 145 {
sgetz7908 51:53fe9aff625a 146 capofffast_ticker.detach();
sgetz7908 51:53fe9aff625a 147 capofffast_ticker.attach(&fastcap_tick ,VERY_FAST_TICK_SEC);
sgetz7908 51:53fe9aff625a 148 veryfasttick_on = VERY_FAST_TICK_ON_TIME_SEC;
sgetz7908 51:53fe9aff625a 149 }
sgetz7908 51:53fe9aff625a 150 //BLE_UART_xmit("1");
sgetz7908 51:53fe9aff625a 151 }
sgetz7908 51:53fe9aff625a 152
sgetz7908 51:53fe9aff625a 153
sgetz7908 23:7ca590427f0e 154 }
sgetz7908 50:8dca54c1e3fd 155
sgetz7908 50:8dca54c1e3fd 156 // if adapting enabled and cap is on then adapt
sgetz7908 50:8dca54c1e3fd 157 if(adaptive_active && !is_cap_off)
sgetz7908 50:8dca54c1e3fd 158 {
sgetz7908 50:8dca54c1e3fd 159 // adaptive cap on threshold processing
sgetz7908 50:8dca54c1e3fd 160 int16_t diff = on_reading - off_reading;
sgetz7908 50:8dca54c1e3fd 161 on_reading_filtered = (256-CAP_THRESHOLD_ADAPT_RATE)*(int32_t)on_reading_filtered/256 + (CAP_THRESHOLD_ADAPT_RATE)*(int32_t)diff/256;
sgetz7908 50:8dca54c1e3fd 162
sgetz7908 50:8dca54c1e3fd 163 if(on_reading_filtered > on_reading_peak)
sgetz7908 50:8dca54c1e3fd 164 { // new higher diff value found
sgetz7908 50:8dca54c1e3fd 165 on_reading_peak = on_reading_filtered;
sgetz7908 50:8dca54c1e3fd 166 cap_threshold_on = CAP_THRESHOLD_PERCENT_OF_PEAK*on_reading_peak/256;
sgetz7908 50:8dca54c1e3fd 167 }
sgetz7908 50:8dca54c1e3fd 168 }
sgetz7908 50:8dca54c1e3fd 169
sgetz7908 46:b85be1ccf179 170 last_cap_off = is_cap_off;
sgetz7908 24:761c30334cf4 171 }
sgetz7908 24:761c30334cf4 172
sgetz7908 51:53fe9aff625a 173 void fastcap_tick(void)
sgetz7908 51:53fe9aff625a 174 {
sgetz7908 51:53fe9aff625a 175 eventQueue.call(test_cap); // starts as non-interrupt task so we can use wait();
sgetz7908 51:53fe9aff625a 176 //test_cap();
sgetz7908 51:53fe9aff625a 177 }
sgetz7908 51:53fe9aff625a 178
sgetz7908 24:761c30334cf4 179 void periodic_tick_task(void)
sgetz7908 24:761c30334cf4 180 {
sgetz7908 51:53fe9aff625a 181 //BLE_UART_xmit("+");
sgetz7908 24:761c30334cf4 182 test_cap();
sgetz7908 24:761c30334cf4 183 process_state();
sgetz7908 51:53fe9aff625a 184 if(veryfasttick_on)
sgetz7908 51:53fe9aff625a 185 {
sgetz7908 51:53fe9aff625a 186 veryfasttick_on--;
sgetz7908 51:53fe9aff625a 187 if(veryfasttick_on==0) capofffast_ticker.detach();
sgetz7908 51:53fe9aff625a 188 }
sgetz7908 23:7ca590427f0e 189 }
sgetz7908 23:7ca590427f0e 190
sgetz7908 23:7ca590427f0e 191 /// this interrupt is run every PERIODIC_TICK_SEC seconds
sgetz7908 23:7ca590427f0e 192 void periodic_tick()
sgetz7908 23:7ca590427f0e 193 {
sgetz7908 24:761c30334cf4 194 update_rtc(tick_rate); // keep rtc updated
sgetz7908 24:761c30334cf4 195 eventQueue.call(periodic_tick_task); // starts as non-interrupt task so we can use wait();
sgetz7908 24:761c30334cf4 196 }
sgetz7908 24:761c30334cf4 197
sgetz7908 24:761c30334cf4 198 void start_periodic_tick(uint32_t sec)
sgetz7908 24:761c30334cf4 199 {
sgetz7908 24:761c30334cf4 200 tick_rate = sec;
sgetz7908 24:761c30334cf4 201 periodic_ticker.detach();
sgetz7908 24:761c30334cf4 202 periodic_ticker.attach(&periodic_tick ,sec);
sgetz7908 24:761c30334cf4 203 }
sgetz7908 24:761c30334cf4 204
sgetz7908 24:761c30334cf4 205 void stop_periodic_tick(void)
sgetz7908 24:761c30334cf4 206 {
sgetz7908 24:761c30334cf4 207 periodic_ticker.detach();
sgetz7908 23:7ca590427f0e 208 }
sgetz7908 23:7ca590427f0e 209
sgetz7908 23:7ca590427f0e 210 /// call here to flash the LED n times.
sgetz7908 23:7ca590427f0e 211 // n=0 to flash forever
sgetz7908 23:7ca590427f0e 212 void flash_led(int n, float sec)
sgetz7908 23:7ca590427f0e 213 {
sgetz7908 23:7ca590427f0e 214 if(n==0)
sgetz7908 23:7ca590427f0e 215 { // flash forever
sgetz7908 23:7ca590427f0e 216 while(1)
sgetz7908 23:7ca590427f0e 217 {
sgetz7908 23:7ca590427f0e 218 led = 1;
sgetz7908 23:7ca590427f0e 219 wait(sec);
sgetz7908 23:7ca590427f0e 220 led = 0;
sgetz7908 23:7ca590427f0e 221 wait(sec);
sgetz7908 23:7ca590427f0e 222 }
sgetz7908 23:7ca590427f0e 223 }
sgetz7908 23:7ca590427f0e 224 else
sgetz7908 23:7ca590427f0e 225 { // flash n times
sgetz7908 23:7ca590427f0e 226 while(n--)
sgetz7908 23:7ca590427f0e 227 {
sgetz7908 23:7ca590427f0e 228 led = 1;
sgetz7908 23:7ca590427f0e 229 wait(sec);
sgetz7908 23:7ca590427f0e 230 led = 0;
sgetz7908 23:7ca590427f0e 231 wait(sec);
sgetz7908 23:7ca590427f0e 232 }
sgetz7908 23:7ca590427f0e 233 }
sgetz7908 23:7ca590427f0e 234 }
sgetz7908 23:7ca590427f0e 235
sgetz7908 23:7ca590427f0e 236
sgetz7908 23:7ca590427f0e 237 state_t last_state = OTHER;
sgetz7908 27:bb7247a1704e 238 int last_cap;
sgetz7908 23:7ca590427f0e 239
sgetz7908 23:7ca590427f0e 240 /// Main state machine
sgetz7908 23:7ca590427f0e 241 /// Called whenever a sensor changes
sgetz7908 23:7ca590427f0e 242 void process_state(void)
sgetz7908 23:7ca590427f0e 243 {
sgetz7908 24:761c30334cf4 244 do
sgetz7908 23:7ca590427f0e 245 {
sgetz7908 24:761c30334cf4 246 #if UART_DEBUGGING==1
sgetz7908 24:761c30334cf4 247 if(last_state != state)
sgetz7908 24:761c30334cf4 248 {
sgetz7908 24:761c30334cf4 249 debug(uli2a(state));
sgetz7908 24:761c30334cf4 250 debug("\n");
sgetz7908 24:761c30334cf4 251 }
sgetz7908 24:761c30334cf4 252 #endif
sgetz7908 23:7ca590427f0e 253 last_state = state;
sgetz7908 23:7ca590427f0e 254
sgetz7908 24:761c30334cf4 255 switch(state)
sgetz7908 24:761c30334cf4 256 {
sgetz7908 24:761c30334cf4 257 case INIT:
sgetz7908 24:761c30334cf4 258 log_add(EVENT_POWER, 0, 0, 0); // log event
sgetz7908 34:c122d842ad9a 259
sgetz7908 25:42163d650266 260 start_periodic_tick(FAST_TICK_SEC);
sgetz7908 24:761c30334cf4 261 #if SKIP_SHIP_MODE
fdelahan 40:adabdb1c5abe 262 // package_open_sense_enable = 1;
sgetz7908 24:761c30334cf4 263 state = IN_USE_SETUP;
sgetz7908 24:761c30334cf4 264 #else
sgetz7908 24:761c30334cf4 265 state = POST;
sgetz7908 24:761c30334cf4 266 #endif
sgetz7908 24:761c30334cf4 267 break;
sgetz7908 24:761c30334cf4 268
sgetz7908 24:761c30334cf4 269 case POST:
sgetz7908 24:761c30334cf4 270 // check CRC ?
sgetz7908 24:761c30334cf4 271
sgetz7908 24:761c30334cf4 272 // Check Misc.
sgetz7908 24:761c30334cf4 273
sgetz7908 24:761c30334cf4 274 //if(error) flash_led(0,0.1); // flash forever to indicate error
sgetz7908 25:42163d650266 275
sgetz7908 24:761c30334cf4 276 if(NV_TESTING_REQUIRED)
sgetz7908 24:761c30334cf4 277 {
sgetz7908 24:761c30334cf4 278 flash_led(1, 1.0);
sgetz7908 24:761c30334cf4 279 package_open_sense_enable = 1;
sgetz7908 25:42163d650266 280 start_periodic_tick(FAST_TICK_SEC);
sgetz7908 27:bb7247a1704e 281 last_cap = 99;
sgetz7908 34:c122d842ad9a 282 set_radio(true, 0); // advertise forever until stopped
sgetz7908 24:761c30334cf4 283 state = TEST_MODE;
sgetz7908 24:761c30334cf4 284 }
sgetz7908 24:761c30334cf4 285 else
sgetz7908 24:761c30334cf4 286 {
fdelahan 40:adabdb1c5abe 287 state = IN_USE_SETUP;
sgetz7908 24:761c30334cf4 288 }
sgetz7908 25:42163d650266 289
sgetz7908 24:761c30334cf4 290 break;
sgetz7908 24:761c30334cf4 291
sgetz7908 25:42163d650266 292 case TEST_MODE:
sgetz7908 24:761c30334cf4 293 test_cap();
sgetz7908 24:761c30334cf4 294 led = is_cap_off;
sgetz7908 27:bb7247a1704e 295 if(last_cap != is_cap_off)
sgetz7908 27:bb7247a1704e 296 {
sgetz7908 27:bb7247a1704e 297 last_cap = is_cap_off;
sgetz7908 27:bb7247a1704e 298 BLE_UART_xmit("*Cap ");
sgetz7908 27:bb7247a1704e 299 if(last_cap) BLE_UART_xmit("Off"); else BLE_UART_xmit("On");
sgetz7908 27:bb7247a1704e 300 BLE_UART_xmit("\n");
sgetz7908 27:bb7247a1704e 301 }
sgetz7908 25:42163d650266 302 if(!NV_TESTING_REQUIRED && is_package_open)
sgetz7908 24:761c30334cf4 303 { // testing passed
sgetz7908 24:761c30334cf4 304 set_radio(false); // already done when NV_TESTING_REQUIRED was cleared.
sgetz7908 24:761c30334cf4 305 led = 0;
sgetz7908 24:761c30334cf4 306 state = SHIP_MODE_WAIT_DARK;
sgetz7908 24:761c30334cf4 307 }
sgetz7908 24:761c30334cf4 308 break;
sgetz7908 24:761c30334cf4 309
sgetz7908 24:761c30334cf4 310 case SHIP_MODE_WAIT_DARK: // Wait for light sensor to see darkness
sgetz7908 27:bb7247a1704e 311 //flash_led(1,0.1);
sgetz7908 25:42163d650266 312 if(!is_package_open)
sgetz7908 24:761c30334cf4 313 { // its dark
sgetz7908 24:761c30334cf4 314 state = SHIP_MODE_WAIT_LIGHT;
sgetz7908 24:761c30334cf4 315 }
sgetz7908 24:761c30334cf4 316 break;
sgetz7908 24:761c30334cf4 317
sgetz7908 24:761c30334cf4 318 case SHIP_MODE_WAIT_LIGHT:
sgetz7908 24:761c30334cf4 319 // set up and enable the Light Sense Interrupt
sgetz7908 24:761c30334cf4 320 // go to lowest power state
sgetz7908 25:42163d650266 321
sgetz7908 50:8dca54c1e3fd 322 // before going to sleep, adapt the cap_on threshold (iff the cap is on)
sgetz7908 50:8dca54c1e3fd 323 {
sgetz7908 50:8dca54c1e3fd 324 adaptive_active = true;
sgetz7908 50:8dca54c1e3fd 325 int i = 20; // multiple calls aallow it to adapt slowly to eliminate potencial noise.
sgetz7908 50:8dca54c1e3fd 326 while(i--)
sgetz7908 50:8dca54c1e3fd 327 {
sgetz7908 50:8dca54c1e3fd 328 test_cap();
sgetz7908 50:8dca54c1e3fd 329 }
sgetz7908 50:8dca54c1e3fd 330 adaptive_active = false;
sgetz7908 50:8dca54c1e3fd 331 }
sgetz7908 50:8dca54c1e3fd 332
sgetz7908 50:8dca54c1e3fd 333 // now go to sleep
sgetz7908 24:761c30334cf4 334 debug("Going SHIP MODE\n");
sgetz7908 24:761c30334cf4 335 is_package_open.disable_irq();
sgetz7908 24:761c30334cf4 336 stop_periodic_tick();
sgetz7908 24:761c30334cf4 337 led = 0;
sgetz7908 24:761c30334cf4 338 package_open_detected = false;
sgetz7908 26:a577c4b69fe0 339 //is_package_open.mode(PullDown);
sgetz7908 24:761c30334cf4 340 is_package_open.rise(&light_interrupt);
sgetz7908 24:761c30334cf4 341 is_package_open.enable_irq();
sgetz7908 24:761c30334cf4 342 state = SHIP_MODE_CHECK_CAP;
sgetz7908 24:761c30334cf4 343
sgetz7908 23:7ca590427f0e 344 break;
sgetz7908 23:7ca590427f0e 345
sgetz7908 24:761c30334cf4 346 case SHIP_MODE_CHECK_CAP:
sgetz7908 25:42163d650266 347
sgetz7908 24:761c30334cf4 348 if(package_open_detected)
sgetz7908 24:761c30334cf4 349 {
sgetz7908 24:761c30334cf4 350 debug("Awake\n");
sgetz7908 27:bb7247a1704e 351 //flash_led(3,0.25);
sgetz7908 24:761c30334cf4 352 test_cap();
sgetz7908 24:761c30334cf4 353 if(is_cap_off)
sgetz7908 24:761c30334cf4 354 {
sgetz7908 24:761c30334cf4 355 state = SHIP_MODE_WAIT_DARK;
sgetz7908 24:761c30334cf4 356 }
sgetz7908 24:761c30334cf4 357 else
sgetz7908 24:761c30334cf4 358 {
sgetz7908 24:761c30334cf4 359 state = SHIP_MODE_WAIT_CAP_OFF;
sgetz7908 24:761c30334cf4 360 }
sgetz7908 24:761c30334cf4 361 }
sgetz7908 24:761c30334cf4 362 break;
sgetz7908 24:761c30334cf4 363
sgetz7908 24:761c30334cf4 364 case SHIP_MODE_WAIT_CAP_OFF:
sgetz7908 25:42163d650266 365 if(!is_package_open)
sgetz7908 24:761c30334cf4 366 {
sgetz7908 24:761c30334cf4 367 state = SHIP_MODE_WAIT_LIGHT;
sgetz7908 24:761c30334cf4 368 }
sgetz7908 24:761c30334cf4 369 else
sgetz7908 24:761c30334cf4 370 {
sgetz7908 24:761c30334cf4 371 test_cap();
sgetz7908 24:761c30334cf4 372 if(is_cap_off)
sgetz7908 24:761c30334cf4 373 {
sgetz7908 24:761c30334cf4 374 package_open_sense_enable = 0;
sgetz7908 35:e8fa201fe147 375 set_rtc(0);
sgetz7908 24:761c30334cf4 376 log_add(EVENT_WAKE_FROM_SHIP, 0, 0, 0);
sgetz7908 24:761c30334cf4 377 state = IN_USE_SETUP;
sgetz7908 24:761c30334cf4 378 }
sgetz7908 24:761c30334cf4 379 }
sgetz7908 24:761c30334cf4 380 break;
sgetz7908 24:761c30334cf4 381
sgetz7908 24:761c30334cf4 382 case IN_USE_SETUP:
sgetz7908 25:42163d650266 383 flash_led(3, .25);
sgetz7908 24:761c30334cf4 384 start_periodic_tick(PERIODIC_TICK_SEC);
sgetz7908 26:a577c4b69fe0 385 debug("In Use\n");
sgetz7908 26:a577c4b69fe0 386 if(NV_NOT_IN_USE) nv_clear(NV_NOT_IN_USE_ADDR);
sgetz7908 24:761c30334cf4 387 state = WAIT_CAP_OFF;
sgetz7908 24:761c30334cf4 388 break;
sgetz7908 23:7ca590427f0e 389
sgetz7908 24:761c30334cf4 390 case WAIT_CAP_OFF: // cap is on, waiting for cap to be removed
sgetz7908 26:a577c4b69fe0 391 if(read_clock()>((uint32_t)EOL_TIMEOUT_DAYS*24*60*60))
sgetz7908 26:a577c4b69fe0 392 { // EOL detected due to maximum time
sgetz7908 27:bb7247a1704e 393 if(NV_NOT_EOL) nv_clear(NV_NOT_EOL_ADDR);
sgetz7908 26:a577c4b69fe0 394 }
sgetz7908 26:a577c4b69fe0 395
sgetz7908 26:a577c4b69fe0 396 if(!NV_NOT_EOL)
sgetz7908 26:a577c4b69fe0 397 { // EOL flagged
sgetz7908 27:bb7247a1704e 398 if(log_code_count(EVENT_EOL)==0) log_add(EVENT_EOL, 0, 0, 0); // log event
sgetz7908 27:bb7247a1704e 399 start_periodic_tick(EOL_TICK_SEC); // just tick less often
sgetz7908 26:a577c4b69fe0 400 state = EOL_WAIT_CAP_OFF;
sgetz7908 26:a577c4b69fe0 401 }
sgetz7908 26:a577c4b69fe0 402 else if(is_cap_off)
sgetz7908 26:a577c4b69fe0 403 { // cap just taken off
sgetz7908 26:a577c4b69fe0 404 // save cap off time
sgetz7908 26:a577c4b69fe0 405 cap_off_time = read_clock();
sgetz7908 26:a577c4b69fe0 406 debug("Cap Off \n");
sgetz7908 26:a577c4b69fe0 407 state = WAIT_CAP_ON;
sgetz7908 26:a577c4b69fe0 408 }
sgetz7908 24:761c30334cf4 409
sgetz7908 24:761c30334cf4 410 break;
sgetz7908 24:761c30334cf4 411
sgetz7908 24:761c30334cf4 412 case WAIT_CAP_ON: // cap currently off, waiting for cap to be put on
sgetz7908 26:a577c4b69fe0 413 if(!is_cap_off)
sgetz7908 26:a577c4b69fe0 414 { // cap just put on
sgetz7908 26:a577c4b69fe0 415 // log time cap was off
sgetz7908 26:a577c4b69fe0 416 uint32_t cap_off_dur = read_clock()-cap_off_time;
sgetz7908 26:a577c4b69fe0 417 if(cap_off_dur>65535) cap_off_dur = 65535;
sgetz7908 26:a577c4b69fe0 418 log_add(EVENT_CAP_ON, cap_off_dur & 0xff, (cap_off_dur >> 8)&0xff, 0); // log event
sgetz7908 26:a577c4b69fe0 419
sgetz7908 26:a577c4b69fe0 420 if(log_code_count(EVENT_CAP_ON)>= EOL_MAX_USES)
sgetz7908 26:a577c4b69fe0 421 { // EOL detected due to maximum uses
sgetz7908 27:bb7247a1704e 422 if(NV_NOT_EOL) nv_clear(NV_NOT_EOL_ADDR);
sgetz7908 26:a577c4b69fe0 423 }
sgetz7908 27:bb7247a1704e 424
sgetz7908 27:bb7247a1704e 425 set_radio(true);
sgetz7908 27:bb7247a1704e 426 state = WAIT_CAP_OFF;
sgetz7908 26:a577c4b69fe0 427 }
sgetz7908 26:a577c4b69fe0 428 break;
sgetz7908 24:761c30334cf4 429
sgetz7908 26:a577c4b69fe0 430 case EOL_WAIT_CAP_OFF: // Cap is on
sgetz7908 26:a577c4b69fe0 431 if(is_cap_off)
sgetz7908 26:a577c4b69fe0 432 { // cap just taken off
sgetz7908 26:a577c4b69fe0 433 debug("EOL Cap Off \n");
sgetz7908 26:a577c4b69fe0 434 state = EOL_WAIT_CAP_ON;
sgetz7908 26:a577c4b69fe0 435 }
sgetz7908 27:bb7247a1704e 436 //else if(!is_package_open)
sgetz7908 27:bb7247a1704e 437 //{ // its dark
sgetz7908 27:bb7247a1704e 438 // start_periodic_tick(EOL_TICK_SEC); // just tick less often
sgetz7908 27:bb7247a1704e 439 // state = EOL_WAIT_LIGHT;
sgetz7908 27:bb7247a1704e 440 //}
sgetz7908 26:a577c4b69fe0 441 break;
sgetz7908 26:a577c4b69fe0 442
sgetz7908 26:a577c4b69fe0 443 case EOL_WAIT_CAP_ON: // Cap is off
sgetz7908 26:a577c4b69fe0 444 if(!is_cap_off)
sgetz7908 26:a577c4b69fe0 445 { // cap just put on
sgetz7908 26:a577c4b69fe0 446 debug("EOL Cap On \n");
sgetz7908 26:a577c4b69fe0 447 set_radio(true);
sgetz7908 27:bb7247a1704e 448 state = EOL_WAIT_CAP_OFF;
sgetz7908 26:a577c4b69fe0 449 }
sgetz7908 26:a577c4b69fe0 450 break;
sgetz7908 29:4b347695b9f7 451 /*
sgetz7908 26:a577c4b69fe0 452 case EOL_WAIT_LIGHT: // EOL and its dark, save power
sgetz7908 26:a577c4b69fe0 453 // set up and enable the Light Sense Interrupt
sgetz7908 26:a577c4b69fe0 454 // go to lowest power state
sgetz7908 27:bb7247a1704e 455
sgetz7908 26:a577c4b69fe0 456 debug("Going to EOL dark mode\n");
sgetz7908 26:a577c4b69fe0 457 led = 0;
sgetz7908 27:bb7247a1704e 458 if(is_package_open)
sgetz7908 27:bb7247a1704e 459 {
sgetz7908 27:bb7247a1704e 460 start_periodic_tick(PERIODIC_TICK_SEC);
sgetz7908 27:bb7247a1704e 461 state = EOL_WAIT_CAP_OFF;
sgetz7908 27:bb7247a1704e 462 }
sgetz7908 26:a577c4b69fe0 463 break;
sgetz7908 29:4b347695b9f7 464 */
sgetz7908 24:761c30334cf4 465 default: // illegal state
sgetz7908 24:761c30334cf4 466 state = INIT;
sgetz7908 23:7ca590427f0e 467 break;
sgetz7908 23:7ca590427f0e 468 }
sgetz7908 24:761c30334cf4 469 } while(state != last_state);
sgetz7908 23:7ca590427f0e 470 }
sgetz7908 23:7ca590427f0e 471
sgetz7908 27:bb7247a1704e 472 void dataWasRead(void)
sgetz7908 27:bb7247a1704e 473 {
sgetz7908 27:bb7247a1704e 474 flash_led(1, 0.04);
sgetz7908 27:bb7247a1704e 475 }
sgetz7908 27:bb7247a1704e 476
sgetz7908 24:761c30334cf4 477 /// process commands sent to the SmartCap over Bluetooth UART
sgetz7908 23:7ca590427f0e 478 void process_cmd(char * cmd)
sgetz7908 23:7ca590427f0e 479 {
sgetz7908 23:7ca590427f0e 480 switch(tolower(cmd[0])) {
sgetz7908 23:7ca590427f0e 481 case 'r': // Get records
sgetz7908 23:7ca590427f0e 482 log_show();
sgetz7908 23:7ca590427f0e 483 //batt_voltage = read_battery_voltage();
sgetz7908 23:7ca590427f0e 484 //updateBattValue(batt_voltage);
sgetz7908 23:7ca590427f0e 485 break;
sgetz7908 23:7ca590427f0e 486
sgetz7908 23:7ca590427f0e 487 case 's': // status
sgetz7908 23:7ca590427f0e 488 switch(tolower(cmd[1])) {
fdelahan 40:adabdb1c5abe 489
fdelahan 40:adabdb1c5abe 490 case 'd': // disable event logging with cap sensor toggle - DEW
fdelahan 40:adabdb1c5abe 491 log_enable = false;
fdelahan 40:adabdb1c5abe 492 BLE_UART_xmit("Log DISABLED\n");
fdelahan 40:adabdb1c5abe 493 break;
fdelahan 40:adabdb1c5abe 494
fdelahan 40:adabdb1c5abe 495 case 'e': // (default) enable event logging with cap sensor toggle - DEW
fdelahan 40:adabdb1c5abe 496 log_enable = true;
fdelahan 40:adabdb1c5abe 497 BLE_UART_xmit("Log ENABLED\n");
fdelahan 40:adabdb1c5abe 498 break;
fdelahan 40:adabdb1c5abe 499
fdelahan 40:adabdb1c5abe 500 case 'f': // show current state of logging enable function - DEW
fdelahan 40:adabdb1c5abe 501 if(log_enable) BLE_UART_xmit("Log ENABLED\n");
fdelahan 40:adabdb1c5abe 502 else BLE_UART_xmit("Log DISABLED\n");
fdelahan 40:adabdb1c5abe 503 break;
fdelahan 40:adabdb1c5abe 504
fdelahan 41:80f618bb53a4 505 case 0: // old, check battery voltage
fdelahan 41:80f618bb53a4 506 case 'b': // new, check battery voltage
sgetz7908 23:7ca590427f0e 507 batt_voltage = read_battery_voltage();
sgetz7908 23:7ca590427f0e 508 BLE_UART_xmit("Bat=");
sgetz7908 23:7ca590427f0e 509 BLE_UART_xmit(batt_voltage);
sgetz7908 23:7ca590427f0e 510 BLE_UART_xmit("\n");
sgetz7908 23:7ca590427f0e 511 break;
sgetz7908 23:7ca590427f0e 512
sgetz7908 26:a577c4b69fe0 513 //case 'x': // checksum
sgetz7908 26:a577c4b69fe0 514 // BLE_UART_xmit("sx=");
sgetz7908 26:a577c4b69fe0 515 // BLE_UART_xmit(0);
sgetz7908 26:a577c4b69fe0 516 // BLE_UART_xmit("\n");
sgetz7908 26:a577c4b69fe0 517 // break;
sgetz7908 25:42163d650266 518
sgetz7908 24:761c30334cf4 519 case 'c': // cap sensor analog readings
sgetz7908 24:761c30334cf4 520 BLE_UART_xmit("sc=");
sgetz7908 24:761c30334cf4 521 test_cap();
sgetz7908 24:761c30334cf4 522 BLE_UART_xmit(on_reading);
sgetz7908 24:761c30334cf4 523 BLE_UART_xmit(",");
sgetz7908 24:761c30334cf4 524 BLE_UART_xmit(off_reading);
sgetz7908 24:761c30334cf4 525 BLE_UART_xmit("\n");
sgetz7908 24:761c30334cf4 526 break;
sgetz7908 26:a577c4b69fe0 527
sgetz7908 26:a577c4b69fe0 528 case 'm': // CRC of Softdevice and App (Not including NV storage for logs and flags)
sgetz7908 26:a577c4b69fe0 529 {
sgetz7908 26:a577c4b69fe0 530 uint16_t crc = crc16((const unsigned char*)CRC_START_ADDR, (uint32_t)(CRC_END_ADDR - CRC_START_ADDR + 1) );
sgetz7908 34:c122d842ad9a 531 BLE_UART_xmit("sm=");
sgetz7908 26:a577c4b69fe0 532 BLE_UART_xmit(char2hex(crc, 4));
sgetz7908 26:a577c4b69fe0 533 BLE_UART_xmit("\n");
sgetz7908 26:a577c4b69fe0 534 }
sgetz7908 26:a577c4b69fe0 535 break;
sgetz7908 23:7ca590427f0e 536
sgetz7908 26:a577c4b69fe0 537 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 48:bb7d5118e03c 538 {
sgetz7908 48:bb7d5118e03c 539 //int val = 0;
sgetz7908 48:bb7d5118e03c 540 BLE_UART_xmit("*ss=000");
sgetz7908 48:bb7d5118e03c 541 if(NV_NOT_EOL) BLE_UART_xmit("1"); else BLE_UART_xmit("0");
sgetz7908 48:bb7d5118e03c 542 if(NV_NOT_IN_USE) BLE_UART_xmit("1"); else BLE_UART_xmit("0");
sgetz7908 48:bb7d5118e03c 543 if(NV_TESTING_REQUIRED) BLE_UART_xmit("1"); else BLE_UART_xmit("0");
sgetz7908 48:bb7d5118e03c 544 int save = package_open_sense_enable;
sgetz7908 48:bb7d5118e03c 545 package_open_sense_enable = 1;
sgetz7908 48:bb7d5118e03c 546 test_cap();
sgetz7908 48:bb7d5118e03c 547 if(is_cap_off) BLE_UART_xmit("1"); else BLE_UART_xmit("0");
sgetz7908 48:bb7d5118e03c 548 wait(LIGHT_SENSE_PWRON_DELAY);
sgetz7908 48:bb7d5118e03c 549 if(is_package_open) BLE_UART_xmit("1"); else BLE_UART_xmit("0");
sgetz7908 48:bb7d5118e03c 550 package_open_sense_enable = save;
sgetz7908 48:bb7d5118e03c 551 BLE_UART_xmit("\n");
sgetz7908 48:bb7d5118e03c 552 }
sgetz7908 48:bb7d5118e03c 553 break;
sgetz7908 48:bb7d5118e03c 554 case 'l': // read light sensor analog reading via ADC. Circuit enabled before doing reading.
sgetz7908 48:bb7d5118e03c 555 {
sgetz7908 48:bb7d5118e03c 556 BLE_UART_xmit("sl=");
sgetz7908 48:bb7d5118e03c 557 int save2 = package_open_sense_enable;
sgetz7908 48:bb7d5118e03c 558 package_open_sense_enable = 1;
sgetz7908 48:bb7d5118e03c 559 wait(LIGHT_SENSE_PWRON_DELAY);
sgetz7908 48:bb7d5118e03c 560 BLE_UART_xmit(adc_read(ADC_CHAN_LIGHT_SENSE,2));
sgetz7908 48:bb7d5118e03c 561 package_open_sense_enable = save2;
sgetz7908 48:bb7d5118e03c 562 BLE_UART_xmit("\n");
sgetz7908 48:bb7d5118e03c 563 }
sgetz7908 48:bb7d5118e03c 564 break;
sgetz7908 48:bb7d5118e03c 565 case 'q':
sgetz7908 48:bb7d5118e03c 566 BLE_UART_xmit("sq=");
sgetz7908 48:bb7d5118e03c 567 BLE_UART_xmit(on_reading_filtered);
sgetz7908 48:bb7d5118e03c 568 BLE_UART_xmit(", ");
sgetz7908 48:bb7d5118e03c 569 BLE_UART_xmit(on_reading_peak);
sgetz7908 48:bb7d5118e03c 570 BLE_UART_xmit(", ");
sgetz7908 48:bb7d5118e03c 571 BLE_UART_xmit(cap_threshold_on);
sgetz7908 23:7ca590427f0e 572 BLE_UART_xmit("\n");
sgetz7908 23:7ca590427f0e 573 break;
sgetz7908 23:7ca590427f0e 574 }
sgetz7908 23:7ca590427f0e 575 break;
sgetz7908 24:761c30334cf4 576 case 'p': // test passed
sgetz7908 24:761c30334cf4 577 if(tolower(cmd[1])=='z')
sgetz7908 24:761c30334cf4 578 {
sgetz7908 24:761c30334cf4 579 log_add(EVENT_TEST_PASS, 0, 0, 0);
sgetz7908 26:a577c4b69fe0 580 if(NV_TESTING_REQUIRED) nv_clear(NV_TESTING_REQUIRED_ADDR);
sgetz7908 24:761c30334cf4 581 }
sgetz7908 26:a577c4b69fe0 582
sgetz7908 24:761c30334cf4 583 break;
sgetz7908 24:761c30334cf4 584
sgetz7908 23:7ca590427f0e 585 case 't': // get time
sgetz7908 23:7ca590427f0e 586 BLE_UART_xmit(read_clock());
sgetz7908 23:7ca590427f0e 587 BLE_UART_xmit("\n");
sgetz7908 23:7ca590427f0e 588 break;
sgetz7908 23:7ca590427f0e 589
sgetz7908 23:7ca590427f0e 590 case 'c': // set time
sgetz7908 23:7ca590427f0e 591 {
sgetz7908 23:7ca590427f0e 592 int i = 1;
sgetz7908 23:7ca590427f0e 593 uint32_t num = 0;
sgetz7908 23:7ca590427f0e 594
sgetz7908 23:7ca590427f0e 595 while(cmd[i]>='0' && cmd[i]<='9') {
sgetz7908 23:7ca590427f0e 596 num = num*10 + cmd[i++]-'0';
sgetz7908 23:7ca590427f0e 597 }
sgetz7908 23:7ca590427f0e 598
sgetz7908 23:7ca590427f0e 599 if(i>1) {
sgetz7908 23:7ca590427f0e 600 set_time_offset(num);
sgetz7908 23:7ca590427f0e 601 BLE_UART_xmit("*Time Set\n");
sgetz7908 23:7ca590427f0e 602 }
sgetz7908 23:7ca590427f0e 603 }
sgetz7908 23:7ca590427f0e 604 break;
sgetz7908 30:76b51e525c40 605
sgetz7908 23:7ca590427f0e 606 case 'v': // version
sgetz7908 24:761c30334cf4 607 BLE_UART_xmit("v=");
sgetz7908 23:7ca590427f0e 608 BLE_UART_xmit(FW_VERSION);
sgetz7908 23:7ca590427f0e 609 BLE_UART_xmit("\n");
sgetz7908 23:7ca590427f0e 610 break;
sgetz7908 23:7ca590427f0e 611
sgetz7908 23:7ca590427f0e 612 default:
sgetz7908 23:7ca590427f0e 613 BLE_UART_xmit("S=Status\n");
sgetz7908 23:7ca590427f0e 614 break;
sgetz7908 23:7ca590427f0e 615 }
sgetz7908 23:7ca590427f0e 616 cmd[0] = 0;
sgetz7908 23:7ca590427f0e 617 }
sgetz7908 25:42163d650266 618
sgetz7908 25:42163d650266 619 //*****************************************************************************
sgetz7908 25:42163d650266 620
sgetz7908 25:42163d650266 621 int main(void)
sgetz7908 25:42163d650266 622 {
sgetz7908 25:42163d650266 623 // blink LED to indicate power applied
sgetz7908 25:42163d650266 624 //flash_led(1,1.0);
sgetz7908 25:42163d650266 625
sgetz7908 25:42163d650266 626 if(Init_BLE_Stuff()) // init and start advertising
sgetz7908 25:42163d650266 627 {
sgetz7908 25:42163d650266 628 flash_led(0, 0.05); // indicate a ble init error
sgetz7908 25:42163d650266 629 }
sgetz7908 25:42163d650266 630
sgetz7908 25:42163d650266 631 eventQueue.call(process_state);
sgetz7908 25:42163d650266 632
sgetz7908 25:42163d650266 633 eventQueue.dispatch_forever(); // run all tasks in the event queue (non-interrupt routines)
sgetz7908 25:42163d650266 634 return 0;
sgetz7908 25:42163d650266 635 }
sgetz7908 25:42163d650266 636
sgetz7908 25:42163d650266 637