football_project_wo_output

Dependencies:   mbed

Fork of football_project by MZJ

Committer:
AntonLS
Date:
Thu Feb 11 17:47:28 2016 +0000
Revision:
67:5650f461722a
Parent:
66:18c214707b0c
Child:
70:bd4b1e19a0c6
Radio message arch like old cones. Static or Auto node IDs.  Missed ack detect. Dark alert fix. Fixes cone death.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AntonLS 0:28ca4562fe1a 1 /*
AntonLS 0:28ca4562fe1a 2 * TA test
AntonLS 0:28ca4562fe1a 3 *
AntonLS 19:afcbb425b3cf 4 * Updated for New TA Baseboard (rev Aug-Nov 2015.)
AntonLS 19:afcbb425b3cf 5 *
AntonLS 11:d3aa5fca2330 6 * TODO maybe have a mode where the serial port I/O can be swapped,
AntonLS 11:d3aa5fca2330 7 * such that what the nRF generates is sent out the serial port,
AntonLS 11:d3aa5fca2330 8 * and what comes in the serial port goes into the nRF.
AntonLS 11:d3aa5fca2330 9 * Maybe could use the now-unused CTS pin for that.
AntonLS 13:28332f65d14b 10 *
AntonLS 13:28332f65d14b 11 * Using
AntonLS 13:28332f65d14b 12 * rev 327 of BLE_API
AntonLS 13:28332f65d14b 13 * rev 102 of nRF51822 w/ modification--See below
AntonLS 15:b86c4b798aa1 14 * rev 97 of mbed lib
AntonLS 15:b86c4b798aa1 15 * corresponding to:
AntonLS 15:b86c4b798aa1 16 * rev 493 of mbed-src w/ modification to targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/serial_api.c
AntonLS 19:afcbb425b3cf 17 * so things compile properly.*
AntonLS 19:afcbb425b3cf 18 * * Now using $Sub$$UART0_IRQHandler to override UART0_IRQHandler without needing to use lib source.
AntonLS 13:28332f65d14b 19 *
AntonLS 31:a6110950f385 20 * *** Now using mbed-src again to modify startup code to use full 32k RAM on QFAC part 20160104 ALS
AntonLS 31:a6110950f385 21 * while still using RBL BLE Nano as a target:
AntonLS 31:a6110950f385 22 * Copied files nRF51822.sct and startup_nRF51822.s
AntonLS 31:a6110950f385 23 * from targets/cmsis/TARGET_NORDIC/TARGET_MCU_NRF51822/TOOLCHAIN_ARM_STD/TARGET_MCU_NORDIC_32K
AntonLS 31:a6110950f385 24 * to targets/cmsis/TARGET_NORDIC/TARGET_MCU_NRF51822/TOOLCHAIN_ARM_STD/TARGET_MCU_NORDIC_16K
AntonLS 31:a6110950f385 25 * (Stomping the 16k settings w/ 32k settings.)
AntonLS 31:a6110950f385 26 *
AntonLS 13:28332f65d14b 27 * Changed
AntonLS 13:28332f65d14b 28 * nRF51822/nordic/pstorage_platform.h PSTORAGE_MIN_BLOCK_SIZE changed from 0x010 to 4.
AntonLS 0:28ca4562fe1a 29 */
AntonLS 0:28ca4562fe1a 30
AntonLS 0:28ca4562fe1a 31 /* mbed Microcontroller Library
AntonLS 0:28ca4562fe1a 32 * Copyright (c) 2006-2013 ARM Limited
AntonLS 0:28ca4562fe1a 33 *
AntonLS 0:28ca4562fe1a 34 * Licensed under the Apache License, Version 2.0 (the "License");
AntonLS 0:28ca4562fe1a 35 * you may not use this file except in compliance with the License.
AntonLS 0:28ca4562fe1a 36 * You may obtain a copy of the License at
AntonLS 0:28ca4562fe1a 37 *
AntonLS 0:28ca4562fe1a 38 * http://www.apache.org/licenses/LICENSE-2.0
AntonLS 0:28ca4562fe1a 39 *
AntonLS 0:28ca4562fe1a 40 * Unless required by applicable law or agreed to in writing, software
AntonLS 0:28ca4562fe1a 41 * distributed under the License is distributed on an "AS IS" BASIS,
AntonLS 0:28ca4562fe1a 42 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
AntonLS 0:28ca4562fe1a 43 * See the License for the specific language governing permissions and
AntonLS 0:28ca4562fe1a 44 * limitations under the License.
AntonLS 0:28ca4562fe1a 45 */
elmbed 18:affef3a7db2a 46 #include <cstdarg>
elmbed 18:affef3a7db2a 47 #include <cstdio>
AntonLS 0:28ca4562fe1a 48 #include "mbed.h"
AntonLS 12:6d313d575f84 49 // #include "rtos.h"
AntonLS 0:28ca4562fe1a 50 #include "BLEDevice.h"
AntonLS 0:28ca4562fe1a 51
AntonLS 0:28ca4562fe1a 52 #include "DFUService.h"
AntonLS 0:28ca4562fe1a 53 #include "UARTService.h"
AntonLS 0:28ca4562fe1a 54 #include "DeviceInformationService.h"
AntonLS 19:afcbb425b3cf 55 #include "BatteryService.h"
AntonLS 0:28ca4562fe1a 56
AntonLS 0:28ca4562fe1a 57 #include "MTSSerialFlowControl.h"
AntonLS 5:1b9734e68327 58 #include "PhoneAppIO.h"
AntonLS 0:28ca4562fe1a 59
elmbed 23:26f27c462976 60 #include "types.h"
elmbed 18:affef3a7db2a 61 #include "TA.h"
elmbed 62:9b34dc1b265d 62 #include "DataStore.hh"
AntonLS 67:5650f461722a 63 // #include "Radio.hh"
elmbed 18:affef3a7db2a 64
AntonLS 67:5650f461722a 65 #define NEED_CONSOLE_OUTPUT 0 /* Set this if you need debug messages on the console;
AntonLS 0:28ca4562fe1a 66 * it will have an impact on code-size and power consumption. */
AntonLS 0:28ca4562fe1a 67
AntonLS 11:d3aa5fca2330 68 #define LOOPBACK_MODE 0 // Loopback mode
AntonLS 4:17b8edf264c3 69
AntonLS 67:5650f461722a 70 // #if NEED_CONSOLE_OUTPUT
AntonLS 67:5650f461722a 71 // #define DEBUG(...) { printf(__VA_ARGS__); }
AntonLS 67:5650f461722a 72 // #else
AntonLS 67:5650f461722a 73 // #define DEBUG(...) /* nothing */
AntonLS 67:5650f461722a 74 // #endif /* #if NEED_CONSOLE_OUTPUT */
AntonLS 0:28ca4562fe1a 75
elmbed 17:d8b901d791fd 76 void loop();
elmbed 17:d8b901d791fd 77 void setup();
elmbed 17:d8b901d791fd 78 void getRadioInput(char *ibuffer, int size);
elmbed 17:d8b901d791fd 79
AntonLS 19:afcbb425b3cf 80 #define BLENANO 0 // BLE Nano vs. TA New Baseboard (rev Aug-Nov 2015.)
AntonLS 19:afcbb425b3cf 81
AntonLS 19:afcbb425b3cf 82 #if BLENANO
AntonLS 19:afcbb425b3cf 83 #define SERTX USBTX
AntonLS 19:afcbb425b3cf 84 #define SERRX USBRX
AntonLS 19:afcbb425b3cf 85 #else // Same RTS pin used by all (P0_08) and unused CTS (P0_10)
AntonLS 19:afcbb425b3cf 86 #define SERTX P0_18
AntonLS 19:afcbb425b3cf 87 #define SERRX P0_17
AntonLS 19:afcbb425b3cf 88 #endif
AntonLS 19:afcbb425b3cf 89
elmbed 18:affef3a7db2a 90 static Timer tmr;
elmbed 17:d8b901d791fd 91
elmbed 17:d8b901d791fd 92 unsigned long millis()
elmbed 17:d8b901d791fd 93 {
elmbed 17:d8b901d791fd 94 return tmr.read_ms();
elmbed 17:d8b901d791fd 95 }
elmbed 17:d8b901d791fd 96
elmbed 17:d8b901d791fd 97 unsigned long micros()
elmbed 17:d8b901d791fd 98 {
AntonLS 19:afcbb425b3cf 99 return tmr.read_us();
elmbed 17:d8b901d791fd 100 }
elmbed 17:d8b901d791fd 101
AntonLS 0:28ca4562fe1a 102 extern "C"
AntonLS 0:28ca4562fe1a 103 {
AntonLS 13:28332f65d14b 104 #include "softdevice_handler.h" // Attempt to get pstorage enqueued cmd callbacks.
AntonLS 13:28332f65d14b 105 #include "app_timer.h"
AntonLS 13:28332f65d14b 106 #include "pstorage.h"
AntonLS 13:28332f65d14b 107
AntonLS 16:3c873f2c8a27 108 // void My_UART0_IRQHandler();
AntonLS 12:6d313d575f84 109
AntonLS 0:28ca4562fe1a 110 void pin_mode( PinName, PinMode );
AntonLS 0:28ca4562fe1a 111 }
AntonLS 0:28ca4562fe1a 112
AntonLS 21:32f022efcc09 113 #if BLENANO
AntonLS 21:32f022efcc09 114 #define ADC_IN_BATT P0_6
AntonLS 22:f58d4b441aba 115 #define CHARGING_IN P0_29
AntonLS 21:32f022efcc09 116 #else
AntonLS 21:32f022efcc09 117 #define ADC_IN_BATT P0_4
AntonLS 22:f58d4b441aba 118 #define CHARGING_IN P0_2
AntonLS 21:32f022efcc09 119 #endif
AntonLS 21:32f022efcc09 120 AnalogIn batt( ADC_IN_BATT );
AntonLS 21:32f022efcc09 121
AntonLS 12:6d313d575f84 122 // DigitalOut rts( RTS_PIN_NUMBER );
AntonLS 19:afcbb425b3cf 123 DigitalIn cts( CTS_PIN_NUMBER, PullDown ); // We'll use as a mode switch for serial data source. TODO
AntonLS 12:6d313d575f84 124
AntonLS 12:6d313d575f84 125 // Check if we should swap serial Rx/Tx for early rev of "Little Brain"
AntonLS 19:afcbb425b3cf 126 DigitalIn trSwp( P0_30, PullUp );
AntonLS 12:6d313d575f84 127
AntonLS 12:6d313d575f84 128 // Wait to settle.
AntonLS 12:6d313d575f84 129 int foo = (wait( 0.1 ), 0);
AntonLS 12:6d313d575f84 130
AntonLS 14:76fb883a3cb8 131 // Not using "LED" or "LED1" because target NRF51822 for FOTA uses different pins.
AntonLS 20:d6c6099b60be 132 static DigitalOut led0( P0_19, 1 ); // TA New Baseboard LED High=On ("STATUS") (OK on Nano: LED Low=On)
AntonLS 19:afcbb425b3cf 133 static DigitalOut led1( P0_21, 0 ); // TA New Baseboard High=On (OK on Nano: NC)
AntonLS 19:afcbb425b3cf 134 DigitalOut led2( P0_22, 1 ); // TA New Baseboard High=On (OK on Nano: NC)
AntonLS 19:afcbb425b3cf 135
AntonLS 63:efba30dea1f0 136 // DigitalOut led1( P0_3, 0 ); // TA Baseboard High=On (OK on Nano: Alt RxD)
AntonLS 63:efba30dea1f0 137 // DigitalOut led1( (trSwp ? P0_4 : P0_3), 0 ); // TA Baseboard High=On (And don't use P0_4 on Nano)
AntonLS 63:efba30dea1f0 138
AntonLS 63:efba30dea1f0 139 // DigitalOut buzz( P0_20, 1 ); // TA New Baseboard Low=On (OK on Nano: NC)
AntonLS 63:efba30dea1f0 140
AntonLS 30:c60b0d52b067 141 int tickTock = 0; // Counter used by periodicCallback().
AntonLS 30:c60b0d52b067 142
AntonLS 30:c60b0d52b067 143 class ChgChg : public InterruptIn
AntonLS 30:c60b0d52b067 144 {
AntonLS 30:c60b0d52b067 145 public:
AntonLS 30:c60b0d52b067 146 ChgChg( PinName pin, PinMode pull=PullUp ) : InterruptIn( pin )
AntonLS 30:c60b0d52b067 147 {
AntonLS 30:c60b0d52b067 148 mode( pull ); // Set pull mode
AntonLS 30:c60b0d52b067 149 fall( this, &ChgChg::chargeStart ); // Attach ISR for fall
AntonLS 30:c60b0d52b067 150 rise( this, &ChgChg::chargeStop ); // Attach ISR for rise
AntonLS 30:c60b0d52b067 151
AntonLS 30:c60b0d52b067 152 led0 = !read();
AntonLS 30:c60b0d52b067 153 }
AntonLS 30:c60b0d52b067 154 void chargeStart()
AntonLS 30:c60b0d52b067 155 {
AntonLS 30:c60b0d52b067 156 led0 = 1;
AntonLS 30:c60b0d52b067 157 tickTock = 0; // Trigger batt level update.
AntonLS 30:c60b0d52b067 158 }
AntonLS 30:c60b0d52b067 159 void chargeStop()
AntonLS 30:c60b0d52b067 160 {
AntonLS 30:c60b0d52b067 161 led0 = 0;
AntonLS 30:c60b0d52b067 162 tickTock = 0; // Trigger batt level update.
AntonLS 30:c60b0d52b067 163 }
AntonLS 30:c60b0d52b067 164 };
AntonLS 30:c60b0d52b067 165 ChgChg notcharge( CHARGING_IN, PullUp );
AntonLS 30:c60b0d52b067 166
AntonLS 19:afcbb425b3cf 167
AntonLS 13:28332f65d14b 168 // App timer, app scheduler, and pstorage are already setup by bootloader.
AntonLS 13:28332f65d14b 169
elmbed 18:affef3a7db2a 170 static BLEDevice ble;
AntonLS 19:afcbb425b3cf 171
AntonLS 12:6d313d575f84 172
AntonLS 1:0ba687d4196f 173 // Note: From the datasheet:
AntonLS 1:0ba687d4196f 174 // PSELRXD, PSELRTS, PSELTRTS and PSELTXD must only be configured when the UART is disabled.
AntonLS 11:d3aa5fca2330 175 // But a version of serial_init() erroneously enabled the uart before the setting of those,
AntonLS 11:d3aa5fca2330 176 // which messed up flow control. Apparently the setting is ONCE per ON mode. ARGH!
AntonLS 11:d3aa5fca2330 177 // So we made our own versions of Serial and SerialBase (MySerial and MySerialBase)
AntonLS 7:205ef63d311a 178 // to not use serial_init() in serial_api.c, so flow control is setup correctly *
AntonLS 7:205ef63d311a 179 // MTSSerial now uses our MySerial instead of Serial, and now uses hw flow control by default *
AntonLS 15:b86c4b798aa1 180 // [* We can't change the uart interrupt vector, so we comment-out the handler in
AntonLS 15:b86c4b798aa1 181 // serial_api.c, and rebuild the mbed lib for low-level hw flow control to work.] - No need now.
AntonLS 15:b86c4b798aa1 182 // * Now using $Sub$$UART0_IRQHandler to override UART0_IRQHandler without needing to use lib source.
AntonLS 15:b86c4b798aa1 183 // NVIC_SetVector( UART0_IRQn, (uint32_t)My_UART0_IRQHandler ); // Might have worked--No need.
AntonLS 15:b86c4b798aa1 184 //
AntonLS 6:ef758ac3c928 185 // MTSSerialFlowControl uses "manual" (non-hardware-low-level) flow control based on its
AntonLS 11:d3aa5fca2330 186 // internal buffer--Rx servicing usually is fast enough not to need hw flow control, so it's okay.
AntonLS 1:0ba687d4196f 187 //
AntonLS 19:afcbb425b3cf 188 // mts::MTSSerialFlowControl pcfc( (trSwp ? SERRX : SERTX), (trSwp ? SERTX : SERRX), RTS_PIN_NUMBER, CTS_PIN_NUMBER, 384, 2688 );
AntonLS 19:afcbb425b3cf 189 //mts::MTSSerial pcfc( (trSwp ? SERRX : SERTX), (trSwp ? SERTX : SERRX), 128, 64, RTS_PIN_NUMBER, NC ); // 256, 1280 // 256, 2560
AntonLS 0:28ca4562fe1a 190
AntonLS 0:28ca4562fe1a 191 uint8_t txPayload[TXRX_BUF_LEN] = { 0 };
AntonLS 0:28ca4562fe1a 192
AntonLS 0:28ca4562fe1a 193
AntonLS 5:1b9734e68327 194 char deviceName[6]; // "TAF00";
AntonLS 5:1b9734e68327 195 Gap::address_t macAddr;
AntonLS 5:1b9734e68327 196 Gap::addr_type_t *pAdType;
AntonLS 19:afcbb425b3cf 197 static const uint16_t uuid16_list[] = { GattService::UUID_DEVICE_INFORMATION_SERVICE,
AntonLS 19:afcbb425b3cf 198 GattService::UUID_BATTERY_SERVICE };
AntonLS 20:d6c6099b60be 199 static uint8_t batt_and_id[] = { GattService::UUID_BATTERY_SERVICE & 0xff,
AntonLS 19:afcbb425b3cf 200 GattService::UUID_BATTERY_SERVICE >> 8,
AntonLS 22:f58d4b441aba 201 99, // Batt level
AntonLS 19:afcbb425b3cf 202 'T', 'X' }; // Custom ID trick
AntonLS 19:afcbb425b3cf 203
AntonLS 20:d6c6099b60be 204 UARTService *uartServicePtr;
AntonLS 49:626e84ce5e52 205 PhoneAppIO *phoneP;
AntonLS 20:d6c6099b60be 206 BatteryService *battServiceP;
AntonLS 5:1b9734e68327 207
elmbed 18:affef3a7db2a 208 // Buffer for holding data from the phone
elmbed 18:affef3a7db2a 209 // to the device
AntonLS 45:1eb335c00cb2 210 static char phoneToDev[MAX_LEN] = {0};
AntonLS 0:28ca4562fe1a 211
elmbed 18:affef3a7db2a 212 extern TA ta;
elmbed 18:affef3a7db2a 213
AntonLS 67:5650f461722a 214 //// extern void radio_init();
elmbed 44:4ad6133987ed 215 extern void radio_loop(int mac);
elmbed 18:affef3a7db2a 216
AntonLS 63:efba30dea1f0 217 #ifdef MASTER
AntonLS 63:efba30dea1f0 218 bool is_master = true;
AntonLS 63:efba30dea1f0 219 #else
AntonLS 63:efba30dea1f0 220 bool is_master = false;
AntonLS 63:efba30dea1f0 221 #endif
AntonLS 63:efba30dea1f0 222
AntonLS 22:f58d4b441aba 223 void setAdvData()
AntonLS 22:f58d4b441aba 224 {
AntonLS 22:f58d4b441aba 225 ble.accumulateAdvertisingPayload( GapAdvertisingData::BREDR_NOT_SUPPORTED |
AntonLS 22:f58d4b441aba 226 GapAdvertisingData::LE_GENERAL_DISCOVERABLE );
AntonLS 22:f58d4b441aba 227 ble.setAdvertisingType( GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED );
AntonLS 22:f58d4b441aba 228
AntonLS 22:f58d4b441aba 229 // Get MAC addr so we can create a device name using it.
AntonLS 22:f58d4b441aba 230 ble.getAddress( pAdType, macAddr );
elmbed 28:8e74ddc4f70f 231
AntonLS 46:28c29ef61276 232 sprintf( deviceName, "%c%02X%02X", (is_master?'T':'S'), macAddr[1], macAddr[0] );
AntonLS 22:f58d4b441aba 233
AntonLS 22:f58d4b441aba 234 ble.accumulateAdvertisingPayload( GapAdvertisingData::COMPLETE_LOCAL_NAME,
AntonLS 22:f58d4b441aba 235 (const uint8_t *)deviceName, strlen(deviceName) );
AntonLS 22:f58d4b441aba 236
AntonLS 22:f58d4b441aba 237 // Moved to scan response packet to give more room in AD packet...
AntonLS 22:f58d4b441aba 238 // ble.accumulateAdvertisingPayload( GapAdvertisingData::INCOMPLETE_LIST_128BIT_SERVICE_IDS,
AntonLS 22:f58d4b441aba 239 // (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed) );
AntonLS 22:f58d4b441aba 240
AntonLS 22:f58d4b441aba 241 ble.accumulateAdvertisingPayload( GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS,
AntonLS 22:f58d4b441aba 242 (uint8_t *)uuid16_list, sizeof( uuid16_list ) );
AntonLS 22:f58d4b441aba 243 ble.accumulateAdvertisingPayload( GapAdvertisingData::SERVICE_DATA,
AntonLS 30:c60b0d52b067 244 (uint8_t *)batt_and_id, sizeof( batt_and_id ) ); // Batt lev + "TX"
AntonLS 22:f58d4b441aba 245
AntonLS 22:f58d4b441aba 246 ble.accumulateScanResponse( GapAdvertisingData::INCOMPLETE_LIST_128BIT_SERVICE_IDS,
AntonLS 22:f58d4b441aba 247 (const uint8_t *)UARTServiceUUID_reversed, sizeof( UARTServiceUUID_reversed ) );
AntonLS 22:f58d4b441aba 248 }
AntonLS 22:f58d4b441aba 249
AntonLS 22:f58d4b441aba 250 void updateBatt( uint8_t pct )
AntonLS 22:f58d4b441aba 251 {
AntonLS 22:f58d4b441aba 252 static uint8_t prev;
AntonLS 22:f58d4b441aba 253 static bool wasCharging;
AntonLS 22:f58d4b441aba 254
AntonLS 22:f58d4b441aba 255 if( notcharge )
AntonLS 22:f58d4b441aba 256 {
AntonLS 30:c60b0d52b067 257 if( wasCharging ) ta.beep_off(); // Alarm Clock TMP TODO remove once hardware is fixed.
AntonLS 30:c60b0d52b067 258
AntonLS 22:f58d4b441aba 259 if( pct > 100 ) pct = 100;
AntonLS 22:f58d4b441aba 260
AntonLS 31:a6110950f385 261 if( wasCharging )
AntonLS 31:a6110950f385 262 {
AntonLS 31:a6110950f385 263 pct = 102; // Show 102% at charger unplug.
AntonLS 51:fabe54861f1b 264 tickTock = 50; // Cause another normal update in 5s (60 -50 = 10 half s).
AntonLS 31:a6110950f385 265
AntonLS 31:a6110950f385 266 } else
AntonLS 31:a6110950f385 267 {
AntonLS 31:a6110950f385 268 // Use if we update quite often.
AntonLS 31:a6110950f385 269 // if( abs( (int)prev -(int)pct ) < 3 ) return; // Don't register change of less than 3%.
AntonLS 31:a6110950f385 270 }
AntonLS 22:f58d4b441aba 271
AntonLS 22:f58d4b441aba 272 prev = pct;
AntonLS 22:f58d4b441aba 273 wasCharging = false;
AntonLS 22:f58d4b441aba 274
AntonLS 30:c60b0d52b067 275 } else // Charging
AntonLS 22:f58d4b441aba 276 {
AntonLS 30:c60b0d52b067 277 // Plugged-in seems to add ~23% to level, so checking for 99% is like 76% unplugged.
AntonLS 67:5650f461722a 278 // But I had a failure with a smaller gap, so reduced another 8%. Also: Prevent alarm initially.
AntonLS 67:5650f461722a 279 if( millis() > 5000 && /* pct < 100 && TMP to prevent alarm on disconnected battery */
AntonLS 67:5650f461722a 280 pct >= 91 ) ta.beep( 15000 ); // Alarm Clock TMP TODO remove once hardware is fixed.
AntonLS 30:c60b0d52b067 281
AntonLS 31:a6110950f385 282 if( !wasCharging )
AntonLS 31:a6110950f385 283 pct = 101; // Show 101% at start of charging.
AntonLS 22:f58d4b441aba 284 wasCharging = true; // Force show when done charging.
AntonLS 22:f58d4b441aba 285 }
AntonLS 22:f58d4b441aba 286
AntonLS 54:2878d62714d6 287 if( pct <= 10 ) ta.batteryLow = true;
AntonLS 54:2878d62714d6 288
AntonLS 22:f58d4b441aba 289 batt_and_id[2] = pct;
AntonLS 22:f58d4b441aba 290 ble.clearAdvertisingPayload();
AntonLS 22:f58d4b441aba 291 setAdvData();
AntonLS 22:f58d4b441aba 292 ble.setAdvertisingPayload();
AntonLS 22:f58d4b441aba 293
AntonLS 22:f58d4b441aba 294 if( NULL != battServiceP ) battServiceP->updateBatteryLevel( pct );
AntonLS 22:f58d4b441aba 295 }
AntonLS 22:f58d4b441aba 296
AntonLS 22:f58d4b441aba 297 #define BAT_TOP 793 // 3250 // 52000
AntonLS 22:f58d4b441aba 298 #define BAT_BOT 684 // 2800 // 44800
AntonLS 22:f58d4b441aba 299 uint8_t getBattLevel()
AntonLS 22:f58d4b441aba 300 {
AntonLS 22:f58d4b441aba 301 int battI = (int)(batt * 1000.f);
AntonLS 22:f58d4b441aba 302 // Normalize to usable range...
AntonLS 22:f58d4b441aba 303 // Note: These levels should also give 0% if powered by programmer.
AntonLS 22:f58d4b441aba 304 if( battI > BAT_TOP ) battI = BAT_TOP; // Fully charged reading ~3.85V
AntonLS 22:f58d4b441aba 305 if( battI < BAT_BOT ) battI = BAT_BOT; // Device failing reading ~3.32V
AntonLS 22:f58d4b441aba 306 battI-= BAT_BOT;
AntonLS 22:f58d4b441aba 307 return (uint8_t)(battI*100 / (BAT_TOP-BAT_BOT));
AntonLS 22:f58d4b441aba 308 }
AntonLS 22:f58d4b441aba 309
elmbed 18:affef3a7db2a 310 // True when connected to a phone
AntonLS 11:d3aa5fca2330 311 bool connected = false;
AntonLS 5:1b9734e68327 312
AntonLS 11:d3aa5fca2330 313 void connectionCallback( Gap::Handle_t, Gap::addr_type_t peerAddrType,
AntonLS 11:d3aa5fca2330 314 const Gap::address_t peerAddr, const Gap::ConnectionParams_t *connParams )
AntonLS 11:d3aa5fca2330 315 {
AntonLS 11:d3aa5fca2330 316 connected = true;
AntonLS 63:efba30dea1f0 317
AntonLS 63:efba30dea1f0 318 // DEBUG( "Connected!\n\r" );
AntonLS 63:efba30dea1f0 319
AntonLS 63:efba30dea1f0 320 // char dummy;
AntonLS 63:efba30dea1f0 321 // writeToPhone( "Hi. Curr stack bot: 0x%08X\r\n", &dummy );
AntonLS 11:d3aa5fca2330 322 }
AntonLS 5:1b9734e68327 323
AntonLS 0:28ca4562fe1a 324 void disconnectionCallback( Gap::Handle_t handle, Gap::DisconnectionReason_t reason )
AntonLS 0:28ca4562fe1a 325 {
AntonLS 11:d3aa5fca2330 326 connected = false;
AntonLS 11:d3aa5fca2330 327
AntonLS 22:f58d4b441aba 328 updateBatt( getBattLevel() );
AntonLS 22:f58d4b441aba 329
AntonLS 63:efba30dea1f0 330 // DEBUG( "Disconnected!\n\r" );
AntonLS 63:efba30dea1f0 331 // DEBUG( "Restarting the advertising process\n\r" );
AntonLS 0:28ca4562fe1a 332 ble.startAdvertising();
AntonLS 46:28c29ef61276 333
elmbed 18:affef3a7db2a 334 ta.post_color(0);
AntonLS 0:28ca4562fe1a 335 }
AntonLS 0:28ca4562fe1a 336
AntonLS 5:1b9734e68327 337 bool updateCharacteristic( GattAttribute::Handle_t handle, const uint8_t *data, uint16_t bytesRead )
AntonLS 5:1b9734e68327 338 {
AntonLS 11:d3aa5fca2330 339 ble_error_t err = ble.updateCharacteristicValue( handle, data, bytesRead );
AntonLS 5:1b9734e68327 340
AntonLS 5:1b9734e68327 341 if( (err == BLE_ERROR_BUFFER_OVERFLOW) ||
AntonLS 5:1b9734e68327 342 (err == BLE_ERROR_PARAM_OUT_OF_RANGE ) )
AntonLS 7:205ef63d311a 343 {
AntonLS 19:afcbb425b3cf 344 // pcfc.printf( "\r\nBLE %d! ", err );
AntonLS 7:205ef63d311a 345
AntonLS 7:205ef63d311a 346 } else if ( err == BLE_STACK_BUSY )
AntonLS 7:205ef63d311a 347 {
AntonLS 11:d3aa5fca2330 348 // Common error when pumping data.
AntonLS 7:205ef63d311a 349 }
AntonLS 5:1b9734e68327 350
AntonLS 5:1b9734e68327 351 return (err != BLE_ERROR_NONE);
AntonLS 5:1b9734e68327 352 }
AntonLS 5:1b9734e68327 353
elmbed 18:affef3a7db2a 354 extern "C" void writeToPhone(char *format, ...)
elmbed 18:affef3a7db2a 355 {
AntonLS 49:626e84ce5e52 356 if( NULL == phoneP ) return;
AntonLS 49:626e84ce5e52 357
elmbed 18:affef3a7db2a 358 va_list arg;
AntonLS 48:4c9551c826e9 359 va_start( arg, format );
elmbed 18:affef3a7db2a 360
elmbed 60:d1fad57e8bfb 361 phoneP->vprintf( format, arg );
AntonLS 63:efba30dea1f0 362 // Also write same to serial port... TODO
AntonLS 63:efba30dea1f0 363 // pcfc.vprintf( format, arg );
AntonLS 19:afcbb425b3cf 364
elmbed 18:affef3a7db2a 365 va_end(arg);
elmbed 18:affef3a7db2a 366 }
elmbed 18:affef3a7db2a 367
AntonLS 66:18c214707b0c 368 // Byte bits to ASCII.
AntonLS 19:afcbb425b3cf 369 extern "C" void writeBitsToPhone( uint8_t byte, uint8_t minbits )
AntonLS 19:afcbb425b3cf 370 {
AntonLS 19:afcbb425b3cf 371 static char ascbits[9] = { 0 };
AntonLS 19:afcbb425b3cf 372 int pos = 0;
AntonLS 19:afcbb425b3cf 373 if( 0 == minbits ) minbits = 1;
AntonLS 19:afcbb425b3cf 374
AntonLS 19:afcbb425b3cf 375 uint16_t ibyt = byte & 0xFF;
AntonLS 19:afcbb425b3cf 376 bool leading0 = true;
AntonLS 19:afcbb425b3cf 377
AntonLS 19:afcbb425b3cf 378 for( short b=7; b >= 0; b-- )
AntonLS 19:afcbb425b3cf 379 {
AntonLS 19:afcbb425b3cf 380 ibyt<<=1;
AntonLS 19:afcbb425b3cf 381 if( ibyt & 0x100 )
AntonLS 19:afcbb425b3cf 382 {
AntonLS 19:afcbb425b3cf 383 leading0 = false;
AntonLS 19:afcbb425b3cf 384 ascbits[pos++] = '1';
AntonLS 19:afcbb425b3cf 385
AntonLS 19:afcbb425b3cf 386 } else if( !leading0 || (b < minbits) )
AntonLS 19:afcbb425b3cf 387 {
AntonLS 19:afcbb425b3cf 388 ascbits[pos++] = '0';
AntonLS 19:afcbb425b3cf 389 }
AntonLS 19:afcbb425b3cf 390 }
AntonLS 19:afcbb425b3cf 391 ascbits[pos] = '\0';
AntonLS 19:afcbb425b3cf 392
AntonLS 19:afcbb425b3cf 393 writeToPhone( "%s", ascbits );
AntonLS 19:afcbb425b3cf 394 }
AntonLS 19:afcbb425b3cf 395
AntonLS 0:28ca4562fe1a 396 void onDataWritten( const GattCharacteristicWriteCBParams *params )
AntonLS 0:28ca4562fe1a 397 {
AntonLS 11:d3aa5fca2330 398 if( phoneP != NULL )
AntonLS 0:28ca4562fe1a 399 {
AntonLS 11:d3aa5fca2330 400 uint16_t bytesRead = phoneP->maybeHandleRead( params ); // Also writes to txPayload
elmbed 18:affef3a7db2a 401
AntonLS 11:d3aa5fca2330 402 if( 0 != bytesRead )
AntonLS 11:d3aa5fca2330 403 {
AntonLS 19:afcbb425b3cf 404 /*
AntonLS 19:afcbb425b3cf 405 DEBUG( "received %u bytes\n\r", bytesRead );
AntonLS 19:afcbb425b3cf 406
AntonLS 19:afcbb425b3cf 407 // Also write to serial port...
AntonLS 19:afcbb425b3cf 408 // pcfc.printf( "From app: " );
AntonLS 19:afcbb425b3cf 409 pcfc.write( (char *)txPayload, bytesRead );
AntonLS 19:afcbb425b3cf 410 // pcfc.printf( "\r\n" );
AntonLS 19:afcbb425b3cf 411 */
AntonLS 19:afcbb425b3cf 412
AntonLS 11:d3aa5fca2330 413 return;
AntonLS 11:d3aa5fca2330 414 }
AntonLS 0:28ca4562fe1a 415 }
AntonLS 0:28ca4562fe1a 416 }
AntonLS 0:28ca4562fe1a 417
AntonLS 0:28ca4562fe1a 418 void onDataSent( unsigned count )
AntonLS 0:28ca4562fe1a 419 {
AntonLS 0:28ca4562fe1a 420 }
AntonLS 0:28ca4562fe1a 421
AntonLS 11:d3aa5fca2330 422 void toPhoneChk( void )
AntonLS 0:28ca4562fe1a 423 {
AntonLS 19:afcbb425b3cf 424 if( phoneP != NULL )
AntonLS 19:afcbb425b3cf 425 {
AntonLS 19:afcbb425b3cf 426 /*
AntonLS 19:afcbb425b3cf 427 char ch;
AntonLS 19:afcbb425b3cf 428 // Get any data from serial port buffer--Full lines if avail--Last line after >= 20 chars.
AntonLS 19:afcbb425b3cf 429 for( int cnt=1; 0 != pcfc.atomicRead( ch ); cnt++ )
AntonLS 19:afcbb425b3cf 430 {
AntonLS 19:afcbb425b3cf 431 /// For from-serial straight to-phone.
AntonLS 19:afcbb425b3cf 432 /// if( 0 > phoneP->putchar( ch ) )
AntonLS 19:afcbb425b3cf 433 /// {
AntonLS 19:afcbb425b3cf 434 /// pcfc.printf( " * " );
AntonLS 19:afcbb425b3cf 435 /// break;
AntonLS 19:afcbb425b3cf 436 /// }
AntonLS 3:388e441be8df 437
AntonLS 19:afcbb425b3cf 438 // For from-serial inject-to-dev as-if from phone.
AntonLS 19:afcbb425b3cf 439 phoneP->injectHandleRead( &ch, 1 );
AntonLS 19:afcbb425b3cf 440
AntonLS 19:afcbb425b3cf 441 if( (cnt >= 20) && ('\n' == ch) ) break;
AntonLS 19:afcbb425b3cf 442 }
AntonLS 19:afcbb425b3cf 443 */
AntonLS 19:afcbb425b3cf 444 // Write to outgoing characteristic if anything is pending.
AntonLS 19:afcbb425b3cf 445 if( 0 != phoneP->maybeHandleWrite() )
AntonLS 19:afcbb425b3cf 446 {
AntonLS 19:afcbb425b3cf 447 // pcfc.printf( "ToPhoneHandler \r\n" );
AntonLS 19:afcbb425b3cf 448 }
AntonLS 19:afcbb425b3cf 449 }
AntonLS 0:28ca4562fe1a 450 }
elmbed 28:8e74ddc4f70f 451
AntonLS 13:28332f65d14b 452 void periodicCallback( void )
AntonLS 13:28332f65d14b 453 {
AntonLS 51:fabe54861f1b 454 static unsigned long prevMillis = millis() +125;
AntonLS 51:fabe54861f1b 455 static int callCnt = 0;
AntonLS 51:fabe54861f1b 456
AntonLS 51:fabe54861f1b 457 unsigned long elapsedMillis = millis() -prevMillis;
AntonLS 51:fabe54861f1b 458
AntonLS 51:fabe54861f1b 459 if( elapsedMillis >= 125 )
AntonLS 49:626e84ce5e52 460 {
AntonLS 51:fabe54861f1b 461 do
AntonLS 51:fabe54861f1b 462 {
AntonLS 51:fabe54861f1b 463 prevMillis = millis();
AntonLS 51:fabe54861f1b 464
AntonLS 51:fabe54861f1b 465 // if( is_master && ((callCnt % 3) == 0) ) writeToPhone( "Rnd: %x\r\n", rndHW() );
AntonLS 51:fabe54861f1b 466
AntonLS 51:fabe54861f1b 467 if( (callCnt % 4) != 0 ) break;
AntonLS 37:8f15b14d6994 468
AntonLS 30:c60b0d52b067 469 #if BLENANO
AntonLS 51:fabe54861f1b 470 led0 = !led0;
AntonLS 30:c60b0d52b067 471 #endif
AntonLS 51:fabe54861f1b 472 led1 = !led1;
AntonLS 51:fabe54861f1b 473 led2 = !led2;
AntonLS 51:fabe54861f1b 474 // rts = !rts;
AntonLS 20:d6c6099b60be 475
AntonLS 51:fabe54861f1b 476 // Check battery level every 30s.
AntonLS 51:fabe54861f1b 477 if( 0 == (tickTock % 60 ) ) updateBatt( getBattLevel() );
AntonLS 51:fabe54861f1b 478
AntonLS 51:fabe54861f1b 479 tickTock++;
AntonLS 30:c60b0d52b067 480
AntonLS 51:fabe54861f1b 481 } while( false );
AntonLS 49:626e84ce5e52 482
AntonLS 51:fabe54861f1b 483 callCnt++;
AntonLS 51:fabe54861f1b 484 }
AntonLS 13:28332f65d14b 485 }
AntonLS 13:28332f65d14b 486
AntonLS 67:5650f461722a 487 #define LOOPUS 1250
AntonLS 67:5650f461722a 488 #define LOOPMS (LOOPUS/1000) /* 2 */ /* 5 */ /* 25 */
AntonLS 66:18c214707b0c 489
AntonLS 0:28ca4562fe1a 490 int main( void )
AntonLS 0:28ca4562fe1a 491 {
elmbed 62:9b34dc1b265d 492 init_datastore();
elmbed 62:9b34dc1b265d 493
elmbed 62:9b34dc1b265d 494 wait_us(400);
elmbed 62:9b34dc1b265d 495
AntonLS 63:efba30dea1f0 496 //is_master = datastore_is_master();
AntonLS 2:fe1566cdb6e7 497
AntonLS 63:efba30dea1f0 498 // Ticker ticker;
AntonLS 63:efba30dea1f0 499 //////ticker.attach( periodicCallback, 0.125 /** 0.2 **/ /** 0.5 **/ /* 1 */ );
AntonLS 63:efba30dea1f0 500
AntonLS 63:efba30dea1f0 501 /////pcfc.baud( 57600 );
AntonLS 63:efba30dea1f0 502
AntonLS 0:28ca4562fe1a 503 ble.init();
elmbed 18:affef3a7db2a 504
AntonLS 11:d3aa5fca2330 505 ble.onConnection( connectionCallback );
AntonLS 0:28ca4562fe1a 506 ble.onDisconnection( disconnectionCallback );
AntonLS 0:28ca4562fe1a 507 ble.onDataWritten( onDataWritten );
AntonLS 0:28ca4562fe1a 508 ble.onDataSent( onDataSent );
AntonLS 0:28ca4562fe1a 509
AntonLS 0:28ca4562fe1a 510 /* setup advertising */
AntonLS 20:d6c6099b60be 511 setAdvData();
AntonLS 5:1b9734e68327 512
AntonLS 63:efba30dea1f0 513 /////pcfc.printf( "\r\nHello! I am \"%s\"\r\n", deviceName );
AntonLS 63:efba30dea1f0 514
AntonLS 63:efba30dea1f0 515 /*
AntonLS 63:efba30dea1f0 516 #if LOOPBACK_MODE
AntonLS 63:efba30dea1f0 517 pcfc.printf( "\r\nIn BLE Loopback mode.\r\n" );
AntonLS 63:efba30dea1f0 518 #endif
AntonLS 63:efba30dea1f0 519 */
AntonLS 63:efba30dea1f0 520
AntonLS 48:4c9551c826e9 521 srnd( rndHW() ); // Seed the sw RNG w/ the hw.
AntonLS 48:4c9551c826e9 522
AntonLS 0:28ca4562fe1a 523 DeviceInformationService deviceInfo( ble, "TRX", "TrueAgility", "SN0001", "hw-rev1", "fw-rev1" );
AntonLS 19:afcbb425b3cf 524 BatteryService battService( ble );
AntonLS 20:d6c6099b60be 525 battServiceP = &battService;
AntonLS 67:5650f461722a 526
AntonLS 21:32f022efcc09 527 updateBatt( getBattLevel() );
AntonLS 0:28ca4562fe1a 528
AntonLS 19:afcbb425b3cf 529 /* Enable over-the-air firmware updates. Instantiating DFUService introduces a
AntonLS 0:28ca4562fe1a 530 * control characteristic which can be used to trigger the application to
AntonLS 0:28ca4562fe1a 531 * handover control to a resident bootloader. */
AntonLS 0:28ca4562fe1a 532 DFUService dfu( ble );
AntonLS 0:28ca4562fe1a 533
AntonLS 19:afcbb425b3cf 534 UARTService uartService( ble );
AntonLS 0:28ca4562fe1a 535 uartServicePtr = &uartService;
AntonLS 0:28ca4562fe1a 536
AntonLS 49:626e84ce5e52 537 ble.setAdvertisingInterval( Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS( is_master ? 132 : 132 ) );
AntonLS 46:28c29ef61276 538
AntonLS 21:32f022efcc09 539 ble.startAdvertising();
AntonLS 21:32f022efcc09 540
AntonLS 19:afcbb425b3cf 541 PhoneAppIO *phone = new PhoneAppIO( ble,
AntonLS 19:afcbb425b3cf 542 uartServicePtr->getRXCharacteristicHandle(),
AntonLS 19:afcbb425b3cf 543 uartServicePtr->getTXCharacteristicHandle() );
AntonLS 19:afcbb425b3cf 544
elmbed 18:affef3a7db2a 545 phone->loopbackMode = LOOPBACK_MODE;
elmbed 18:affef3a7db2a 546 phoneP = phone;
elmbed 18:affef3a7db2a 547
elmbed 17:d8b901d791fd 548 setup();
AntonLS 67:5650f461722a 549 /// radio_init(); //// Moved back to TA::initialize()
AntonLS 11:d3aa5fca2330 550 tmr.start();
elmbed 18:affef3a7db2a 551
elmbed 44:4ad6133987ed 552 int mac_addr = ((int)macAddr[0]);
elmbed 44:4ad6133987ed 553 mac_addr |= ((int)macAddr[1] << 8);
AntonLS 51:fabe54861f1b 554
AntonLS 67:5650f461722a 555 unsigned long lastMicros = micros();
AntonLS 51:fabe54861f1b 556 unsigned long lastMillis = millis();
AntonLS 67:5650f461722a 557 unsigned long currMicros = lastMicros +LOOPUS;
AntonLS 66:18c214707b0c 558 unsigned long currMillis = lastMillis +LOOPMS;
AntonLS 66:18c214707b0c 559
AntonLS 67:5650f461722a 560 //// Test stuff...
AntonLS 67:5650f461722a 561 unsigned long countLoop = 0L;
AntonLS 67:5650f461722a 562 unsigned long overage = 0L;
AntonLS 67:5650f461722a 563 ////
AntonLS 67:5650f461722a 564
AntonLS 11:d3aa5fca2330 565 // Main Loop
AntonLS 63:efba30dea1f0 566 while( true ) // for( uint32_t loop=1; ;loop++ )
AntonLS 0:28ca4562fe1a 567 {
AntonLS 63:efba30dea1f0 568 // ble.waitForEvent();
AntonLS 63:efba30dea1f0 569
AntonLS 67:5650f461722a 570 currMicros = micros();
AntonLS 51:fabe54861f1b 571 currMillis = millis();
AntonLS 67:5650f461722a 572
AntonLS 67:5650f461722a 573 if( currMicros -lastMicros < LOOPUS )
elmbed 59:297133497153 574 {
elmbed 59:297133497153 575 continue;
elmbed 59:297133497153 576 }
AntonLS 66:18c214707b0c 577
AntonLS 67:5650f461722a 578 //// Test stuff...
AntonLS 67:5650f461722a 579 overage += ((currMicros -lastMicros) -LOOPUS);
AntonLS 67:5650f461722a 580 countLoop++;
AntonLS 67:5650f461722a 581 if( (countLoop * LOOPUS) >= 30000000 )
AntonLS 67:5650f461722a 582 {
AntonLS 67:5650f461722a 583 if( Dbg ) writeToPhone( "Loop avg over: %.2fus\r", (float)overage / (float)countLoop );
AntonLS 67:5650f461722a 584 // writeToPhone( "RSSI: %d\r", get_rssi() );
AntonLS 67:5650f461722a 585 // read_all_regs();
AntonLS 67:5650f461722a 586 countLoop = 0L;
AntonLS 67:5650f461722a 587 overage = 0L;
AntonLS 67:5650f461722a 588 }
AntonLS 67:5650f461722a 589 ////
AntonLS 67:5650f461722a 590
AntonLS 67:5650f461722a 591 lastMicros = currMicros;
AntonLS 51:fabe54861f1b 592 lastMillis = currMillis;
AntonLS 51:fabe54861f1b 593
AntonLS 51:fabe54861f1b 594 periodicCallback();
AntonLS 19:afcbb425b3cf 595
AntonLS 67:5650f461722a 596 toPhoneChk(); // Write any pending data to phone.
AntonLS 19:afcbb425b3cf 597
AntonLS 63:efba30dea1f0 598 if( is_master || Dbg )
AntonLS 63:efba30dea1f0 599 {
AntonLS 63:efba30dea1f0 600 int bytes = MIN( MAX_LEN, phoneP->readable() );
AntonLS 63:efba30dea1f0 601 getRadioInput( phoneToDev, phoneP->read( phoneToDev, bytes, 1 ) );
AntonLS 63:efba30dea1f0 602 }
AntonLS 63:efba30dea1f0 603
elmbed 17:d8b901d791fd 604 loop();
AntonLS 67:5650f461722a 605 radio_loop( mac_addr );
AntonLS 0:28ca4562fe1a 606 }
AntonLS 0:28ca4562fe1a 607 }
AntonLS 0:28ca4562fe1a 608
AntonLS 15:b86c4b798aa1 609 /**@brief Function for error handling, which is called when an error has occurred.
AntonLS 15:b86c4b798aa1 610 *
AntonLS 15:b86c4b798aa1 611 * @warning This handler is an example only and does not fit a final product. You need to analyze
AntonLS 15:b86c4b798aa1 612 * how your product is supposed to react in case of error.
AntonLS 15:b86c4b798aa1 613 *
AntonLS 15:b86c4b798aa1 614 * @param[in] error_code Error code supplied to the handler.
AntonLS 15:b86c4b798aa1 615 * @param[in] line_num Line number where the handler is called.
AntonLS 15:b86c4b798aa1 616 * @param[in] p_file_name Pointer to the file name.
AntonLS 15:b86c4b798aa1 617 */
AntonLS 15:b86c4b798aa1 618 void $Sub$$app_error_handler( uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name )
AntonLS 15:b86c4b798aa1 619 {
AntonLS 15:b86c4b798aa1 620 // nrf_gpio_pin_set( ASSERT_LED_PIN_NO );
elmbed 18:affef3a7db2a 621 //led1 = 1;
AntonLS 15:b86c4b798aa1 622
AntonLS 15:b86c4b798aa1 623 // This call can be used for debug purposes during application development.
AntonLS 15:b86c4b798aa1 624 // @note CAUTION: Activating this code will write the stack to flash on an error.
AntonLS 15:b86c4b798aa1 625 // This function should NOT be used in a final product.
AntonLS 15:b86c4b798aa1 626 // It is intended STRICTLY for development/debugging purposes.
AntonLS 15:b86c4b798aa1 627 // The flash write will happen EVEN if the radio is active, thus interrupting
AntonLS 15:b86c4b798aa1 628 // any communication.
AntonLS 15:b86c4b798aa1 629 // Use with care. Uncomment the line below to use.
AntonLS 15:b86c4b798aa1 630 // ble_debug_assert_handler(error_code, line_num, p_file_name);
AntonLS 15:b86c4b798aa1 631
AntonLS 15:b86c4b798aa1 632 // On assert, the system can only recover with a reset.
AntonLS 15:b86c4b798aa1 633 NVIC_SystemReset();
AntonLS 15:b86c4b798aa1 634 }
AntonLS 15:b86c4b798aa1 635
AntonLS 49:626e84ce5e52 636 uint32_t rndHW()
AntonLS 48:4c9551c826e9 637 {
AntonLS 48:4c9551c826e9 638 uint32_t rndVal;
AntonLS 48:4c9551c826e9 639 uint8_t bytes_available;
AntonLS 48:4c9551c826e9 640 for(;;)
AntonLS 48:4c9551c826e9 641 {
AntonLS 48:4c9551c826e9 642 sd_rand_application_bytes_available_get( &bytes_available );
AntonLS 48:4c9551c826e9 643 if( bytes_available >= 4 )
AntonLS 48:4c9551c826e9 644 {
AntonLS 48:4c9551c826e9 645 if( NRF_SUCCESS == sd_rand_application_vector_get( (uint8_t *)&rndVal, 4 ) )
AntonLS 48:4c9551c826e9 646 break;
AntonLS 48:4c9551c826e9 647 }
AntonLS 48:4c9551c826e9 648 }
AntonLS 48:4c9551c826e9 649
AntonLS 48:4c9551c826e9 650 return rndVal;
AntonLS 48:4c9551c826e9 651 }
AntonLS 48:4c9551c826e9 652
AntonLS 48:4c9551c826e9 653 static uint32_t rndZ = 0xCAFE, rndW = 0xF00D;
AntonLS 48:4c9551c826e9 654 // Seed for rnd()
AntonLS 49:626e84ce5e52 655 void srnd( uint32_t seed )
AntonLS 48:4c9551c826e9 656 {
AntonLS 48:4c9551c826e9 657 rndZ = 0xCAFE;
AntonLS 48:4c9551c826e9 658 rndW = seed;
AntonLS 48:4c9551c826e9 659 }
AntonLS 48:4c9551c826e9 660
AntonLS 48:4c9551c826e9 661 // Simple RNG -- Allows cross-platform compat if we want to run
AntonLS 48:4c9551c826e9 662 // an apples-to-apples freeform competition by using same seed.
AntonLS 49:626e84ce5e52 663 uint32_t rnd()
AntonLS 48:4c9551c826e9 664 {
AntonLS 48:4c9551c826e9 665 rndZ = 36969 * (rndZ & 0xffff) + (rndZ >>16);
AntonLS 48:4c9551c826e9 666 rndW = 18000 * (rndW & 0xffff) + (rndW >>16);
AntonLS 48:4c9551c826e9 667
AntonLS 48:4c9551c826e9 668 return ((rndZ <<16) + rndW);
AntonLS 48:4c9551c826e9 669 }
AntonLS 48:4c9551c826e9 670
AntonLS 0:28ca4562fe1a 671 /* EOF */