Dependencies:   nRF51822

Committer:
sgetz7908
Date:
Fri Dec 11 21:34:00 2020 +0000
Revision:
57:6c0608782fc6
Parent:
56:97c90403d489
Child:
58:9b94a7caadba
No change

Who changed what in which revision?

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