Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of football_project by
main.cpp@37:8f15b14d6994, 2016-01-06 (annotated)
- Committer:
- AntonLS
- Date:
- Wed Jan 06 22:19:10 2016 +0000
- Revision:
- 37:8f15b14d6994
- Parent:
- 35:c1405da88d3a
- Child:
- 44:4ad6133987ed
- Child:
- 45:1eb335c00cb2
Adjustments for more frequent ticks.
Who changed what in which revision?
| User | Revision | Line number | New 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 | 18:affef3a7db2a | 62 | |
| elmbed | 23:26f27c462976 | 63 | #define NEED_CONSOLE_OUTPUT 1 /* Set this if you need debug messages on the console; |
| AntonLS | 0:28ca4562fe1a | 64 | * it will have an impact on code-size and power consumption. */ |
| AntonLS | 0:28ca4562fe1a | 65 | |
| AntonLS | 11:d3aa5fca2330 | 66 | #define LOOPBACK_MODE 0 // Loopback mode |
| AntonLS | 4:17b8edf264c3 | 67 | |
| AntonLS | 0:28ca4562fe1a | 68 | #if NEED_CONSOLE_OUTPUT |
| AntonLS | 0:28ca4562fe1a | 69 | #define DEBUG(...) { printf(__VA_ARGS__); } |
| AntonLS | 0:28ca4562fe1a | 70 | #else |
| AntonLS | 0:28ca4562fe1a | 71 | #define DEBUG(...) /* nothing */ |
| AntonLS | 0:28ca4562fe1a | 72 | #endif /* #if NEED_CONSOLE_OUTPUT */ |
| AntonLS | 0:28ca4562fe1a | 73 | |
| elmbed | 17:d8b901d791fd | 74 | void loop(); |
| elmbed | 17:d8b901d791fd | 75 | void setup(); |
| elmbed | 17:d8b901d791fd | 76 | void getRadioInput(char *ibuffer, int size); |
| elmbed | 17:d8b901d791fd | 77 | |
| AntonLS | 19:afcbb425b3cf | 78 | #define BLENANO 0 // BLE Nano vs. TA New Baseboard (rev Aug-Nov 2015.) |
| AntonLS | 19:afcbb425b3cf | 79 | |
| AntonLS | 19:afcbb425b3cf | 80 | #if BLENANO |
| AntonLS | 19:afcbb425b3cf | 81 | #define SERTX USBTX |
| AntonLS | 19:afcbb425b3cf | 82 | #define SERRX USBRX |
| AntonLS | 19:afcbb425b3cf | 83 | #else // Same RTS pin used by all (P0_08) and unused CTS (P0_10) |
| AntonLS | 19:afcbb425b3cf | 84 | #define SERTX P0_18 |
| AntonLS | 19:afcbb425b3cf | 85 | #define SERRX P0_17 |
| AntonLS | 19:afcbb425b3cf | 86 | #endif |
| AntonLS | 19:afcbb425b3cf | 87 | |
| elmbed | 18:affef3a7db2a | 88 | static Timer tmr; |
| elmbed | 17:d8b901d791fd | 89 | |
| elmbed | 17:d8b901d791fd | 90 | unsigned long millis() |
| elmbed | 17:d8b901d791fd | 91 | { |
| elmbed | 17:d8b901d791fd | 92 | return tmr.read_ms(); |
| elmbed | 17:d8b901d791fd | 93 | } |
| elmbed | 17:d8b901d791fd | 94 | |
| elmbed | 17:d8b901d791fd | 95 | unsigned long micros() |
| elmbed | 17:d8b901d791fd | 96 | { |
| AntonLS | 19:afcbb425b3cf | 97 | return tmr.read_us(); |
| elmbed | 17:d8b901d791fd | 98 | } |
| elmbed | 17:d8b901d791fd | 99 | |
| AntonLS | 0:28ca4562fe1a | 100 | extern "C" |
| AntonLS | 0:28ca4562fe1a | 101 | { |
| AntonLS | 13:28332f65d14b | 102 | #include "softdevice_handler.h" // Attempt to get pstorage enqueued cmd callbacks. |
| AntonLS | 13:28332f65d14b | 103 | #include "app_timer.h" |
| AntonLS | 13:28332f65d14b | 104 | #include "pstorage.h" |
| AntonLS | 13:28332f65d14b | 105 | |
| AntonLS | 16:3c873f2c8a27 | 106 | // void My_UART0_IRQHandler(); |
| AntonLS | 12:6d313d575f84 | 107 | |
| AntonLS | 0:28ca4562fe1a | 108 | void pin_mode( PinName, PinMode ); |
| AntonLS | 0:28ca4562fe1a | 109 | } |
| AntonLS | 0:28ca4562fe1a | 110 | |
| AntonLS | 21:32f022efcc09 | 111 | #if BLENANO |
| AntonLS | 21:32f022efcc09 | 112 | #define ADC_IN_BATT P0_6 |
| AntonLS | 22:f58d4b441aba | 113 | #define CHARGING_IN P0_29 |
| AntonLS | 21:32f022efcc09 | 114 | #else |
| AntonLS | 21:32f022efcc09 | 115 | #define ADC_IN_BATT P0_4 |
| AntonLS | 22:f58d4b441aba | 116 | #define CHARGING_IN P0_2 |
| AntonLS | 21:32f022efcc09 | 117 | #endif |
| AntonLS | 21:32f022efcc09 | 118 | AnalogIn batt( ADC_IN_BATT ); |
| AntonLS | 21:32f022efcc09 | 119 | |
| AntonLS | 12:6d313d575f84 | 120 | // DigitalOut rts( RTS_PIN_NUMBER ); |
| AntonLS | 19:afcbb425b3cf | 121 | DigitalIn cts( CTS_PIN_NUMBER, PullDown ); // We'll use as a mode switch for serial data source. TODO |
| AntonLS | 12:6d313d575f84 | 122 | |
| AntonLS | 12:6d313d575f84 | 123 | // Check if we should swap serial Rx/Tx for early rev of "Little Brain" |
| AntonLS | 19:afcbb425b3cf | 124 | DigitalIn trSwp( P0_30, PullUp ); |
| AntonLS | 12:6d313d575f84 | 125 | |
| AntonLS | 12:6d313d575f84 | 126 | // Wait to settle. |
| AntonLS | 12:6d313d575f84 | 127 | int foo = (wait( 0.1 ), 0); |
| AntonLS | 12:6d313d575f84 | 128 | |
| AntonLS | 14:76fb883a3cb8 | 129 | // Not using "LED" or "LED1" because target NRF51822 for FOTA uses different pins. |
| AntonLS | 20:d6c6099b60be | 130 | static DigitalOut led0( P0_19, 1 ); // TA New Baseboard LED High=On ("STATUS") (OK on Nano: LED Low=On) |
| AntonLS | 19:afcbb425b3cf | 131 | static DigitalOut led1( P0_21, 0 ); // TA New Baseboard High=On (OK on Nano: NC) |
| AntonLS | 19:afcbb425b3cf | 132 | DigitalOut led2( P0_22, 1 ); // TA New Baseboard High=On (OK on Nano: NC) |
| AntonLS | 19:afcbb425b3cf | 133 | |
| AntonLS | 19:afcbb425b3cf | 134 | // DigitalOut led1( P0_3, 0 ); // TA Baseboard High=On (OK on Nano: Alt RxD) |
| AntonLS | 14:76fb883a3cb8 | 135 | // DigitalOut led1( (trSwp ? P0_4 : P0_3), 0 ); // TA Baseboard High=On (And don't use P0_4 on Nano) |
| AntonLS | 14:76fb883a3cb8 | 136 | |
| AntonLS | 30:c60b0d52b067 | 137 | // DigitalOut buzz( P0_20, 1 ); // TA New Baseboard Low=On (OK on Nano: NC) |
| AntonLS | 30:c60b0d52b067 | 138 | |
| AntonLS | 30:c60b0d52b067 | 139 | int tickTock = 0; // Counter used by periodicCallback(). |
| AntonLS | 30:c60b0d52b067 | 140 | |
| AntonLS | 30:c60b0d52b067 | 141 | class ChgChg : public InterruptIn |
| AntonLS | 30:c60b0d52b067 | 142 | { |
| AntonLS | 30:c60b0d52b067 | 143 | public: |
| AntonLS | 30:c60b0d52b067 | 144 | ChgChg( PinName pin, PinMode pull=PullUp ) : InterruptIn( pin ) |
| AntonLS | 30:c60b0d52b067 | 145 | { |
| AntonLS | 30:c60b0d52b067 | 146 | mode( pull ); // Set pull mode |
| AntonLS | 30:c60b0d52b067 | 147 | fall( this, &ChgChg::chargeStart ); // Attach ISR for fall |
| AntonLS | 30:c60b0d52b067 | 148 | rise( this, &ChgChg::chargeStop ); // Attach ISR for rise |
| AntonLS | 30:c60b0d52b067 | 149 | |
| AntonLS | 30:c60b0d52b067 | 150 | led0 = !read(); |
| AntonLS | 30:c60b0d52b067 | 151 | } |
| AntonLS | 30:c60b0d52b067 | 152 | void chargeStart() |
| AntonLS | 30:c60b0d52b067 | 153 | { |
| AntonLS | 30:c60b0d52b067 | 154 | led0 = 1; |
| AntonLS | 30:c60b0d52b067 | 155 | tickTock = 0; // Trigger batt level update. |
| AntonLS | 30:c60b0d52b067 | 156 | } |
| AntonLS | 30:c60b0d52b067 | 157 | void chargeStop() |
| AntonLS | 30:c60b0d52b067 | 158 | { |
| AntonLS | 30:c60b0d52b067 | 159 | led0 = 0; |
| AntonLS | 30:c60b0d52b067 | 160 | tickTock = 0; // Trigger batt level update. |
| AntonLS | 30:c60b0d52b067 | 161 | } |
| AntonLS | 30:c60b0d52b067 | 162 | }; |
| AntonLS | 30:c60b0d52b067 | 163 | ChgChg notcharge( CHARGING_IN, PullUp ); |
| AntonLS | 30:c60b0d52b067 | 164 | |
| AntonLS | 19:afcbb425b3cf | 165 | |
| AntonLS | 13:28332f65d14b | 166 | // App timer, app scheduler, and pstorage are already setup by bootloader. |
| AntonLS | 13:28332f65d14b | 167 | |
| elmbed | 18:affef3a7db2a | 168 | static BLEDevice ble; |
| AntonLS | 19:afcbb425b3cf | 169 | |
| AntonLS | 12:6d313d575f84 | 170 | |
| AntonLS | 1:0ba687d4196f | 171 | // Note: From the datasheet: |
| AntonLS | 1:0ba687d4196f | 172 | // PSELRXD, PSELRTS, PSELTRTS and PSELTXD must only be configured when the UART is disabled. |
| AntonLS | 11:d3aa5fca2330 | 173 | // But a version of serial_init() erroneously enabled the uart before the setting of those, |
| AntonLS | 11:d3aa5fca2330 | 174 | // which messed up flow control. Apparently the setting is ONCE per ON mode. ARGH! |
| AntonLS | 11:d3aa5fca2330 | 175 | // So we made our own versions of Serial and SerialBase (MySerial and MySerialBase) |
| AntonLS | 7:205ef63d311a | 176 | // to not use serial_init() in serial_api.c, so flow control is setup correctly * |
| AntonLS | 7:205ef63d311a | 177 | // MTSSerial now uses our MySerial instead of Serial, and now uses hw flow control by default * |
| AntonLS | 15:b86c4b798aa1 | 178 | // [* We can't change the uart interrupt vector, so we comment-out the handler in |
| AntonLS | 15:b86c4b798aa1 | 179 | // serial_api.c, and rebuild the mbed lib for low-level hw flow control to work.] - No need now. |
| AntonLS | 15:b86c4b798aa1 | 180 | // * Now using $Sub$$UART0_IRQHandler to override UART0_IRQHandler without needing to use lib source. |
| AntonLS | 15:b86c4b798aa1 | 181 | // NVIC_SetVector( UART0_IRQn, (uint32_t)My_UART0_IRQHandler ); // Might have worked--No need. |
| AntonLS | 15:b86c4b798aa1 | 182 | // |
| AntonLS | 6:ef758ac3c928 | 183 | // MTSSerialFlowControl uses "manual" (non-hardware-low-level) flow control based on its |
| AntonLS | 11:d3aa5fca2330 | 184 | // internal buffer--Rx servicing usually is fast enough not to need hw flow control, so it's okay. |
| AntonLS | 1:0ba687d4196f | 185 | // |
| AntonLS | 19:afcbb425b3cf | 186 | // mts::MTSSerialFlowControl pcfc( (trSwp ? SERRX : SERTX), (trSwp ? SERTX : SERRX), RTS_PIN_NUMBER, CTS_PIN_NUMBER, 384, 2688 ); |
| AntonLS | 19:afcbb425b3cf | 187 | //mts::MTSSerial pcfc( (trSwp ? SERRX : SERTX), (trSwp ? SERTX : SERRX), 128, 64, RTS_PIN_NUMBER, NC ); // 256, 1280 // 256, 2560 |
| AntonLS | 0:28ca4562fe1a | 188 | |
| AntonLS | 0:28ca4562fe1a | 189 | uint8_t txPayload[TXRX_BUF_LEN] = { 0 }; |
| AntonLS | 0:28ca4562fe1a | 190 | |
| AntonLS | 0:28ca4562fe1a | 191 | |
| AntonLS | 5:1b9734e68327 | 192 | char deviceName[6]; // "TAF00"; |
| AntonLS | 5:1b9734e68327 | 193 | Gap::address_t macAddr; |
| AntonLS | 5:1b9734e68327 | 194 | Gap::addr_type_t *pAdType; |
| AntonLS | 19:afcbb425b3cf | 195 | static const uint16_t uuid16_list[] = { GattService::UUID_DEVICE_INFORMATION_SERVICE, |
| AntonLS | 19:afcbb425b3cf | 196 | GattService::UUID_BATTERY_SERVICE }; |
| AntonLS | 20:d6c6099b60be | 197 | static uint8_t batt_and_id[] = { GattService::UUID_BATTERY_SERVICE & 0xff, |
| AntonLS | 19:afcbb425b3cf | 198 | GattService::UUID_BATTERY_SERVICE >> 8, |
| AntonLS | 22:f58d4b441aba | 199 | 99, // Batt level |
| AntonLS | 19:afcbb425b3cf | 200 | 'T', 'X' }; // Custom ID trick |
| AntonLS | 19:afcbb425b3cf | 201 | |
| AntonLS | 20:d6c6099b60be | 202 | UARTService *uartServicePtr; |
| AntonLS | 20:d6c6099b60be | 203 | PhoneAppIO *phoneP; |
| AntonLS | 20:d6c6099b60be | 204 | BatteryService *battServiceP; |
| AntonLS | 5:1b9734e68327 | 205 | |
| elmbed | 18:affef3a7db2a | 206 | // Buffer for holding data from the phone |
| elmbed | 18:affef3a7db2a | 207 | // to the device |
| AntonLS | 21:32f022efcc09 | 208 | #define PHTODEV_BUF_LEN 30 /**/ |
| AntonLS | 19:afcbb425b3cf | 209 | static char phoneToDev[PHTODEV_BUF_LEN] = {0}; |
| AntonLS | 0:28ca4562fe1a | 210 | |
| elmbed | 18:affef3a7db2a | 211 | extern TA ta; |
| elmbed | 18:affef3a7db2a | 212 | |
| elmbed | 18:affef3a7db2a | 213 | extern void radio_init(); |
| elmbed | 18:affef3a7db2a | 214 | extern void radio_loop(); |
| elmbed | 18:affef3a7db2a | 215 | |
| AntonLS | 22:f58d4b441aba | 216 | void setAdvData() |
| AntonLS | 22:f58d4b441aba | 217 | { |
| AntonLS | 22:f58d4b441aba | 218 | ble.accumulateAdvertisingPayload( GapAdvertisingData::BREDR_NOT_SUPPORTED | |
| AntonLS | 22:f58d4b441aba | 219 | GapAdvertisingData::LE_GENERAL_DISCOVERABLE ); |
| AntonLS | 22:f58d4b441aba | 220 | ble.setAdvertisingType( GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED ); |
| AntonLS | 22:f58d4b441aba | 221 | |
| AntonLS | 22:f58d4b441aba | 222 | // Get MAC addr so we can create a device name using it. |
| AntonLS | 22:f58d4b441aba | 223 | ble.getAddress( pAdType, macAddr ); |
| elmbed | 28:8e74ddc4f70f | 224 | |
| AntonLS | 30:c60b0d52b067 | 225 | #ifdef MASTER |
| AntonLS | 30:c60b0d52b067 | 226 | sprintf( deviceName, "T%02X%02X", macAddr[1], macAddr[0] ); |
| AntonLS | 30:c60b0d52b067 | 227 | #else |
| elmbed | 28:8e74ddc4f70f | 228 | sprintf( deviceName, "S%02X%02X", macAddr[1], macAddr[0] ); |
| AntonLS | 30:c60b0d52b067 | 229 | #endif |
| AntonLS | 22:f58d4b441aba | 230 | |
| AntonLS | 22:f58d4b441aba | 231 | ble.accumulateAdvertisingPayload( GapAdvertisingData::COMPLETE_LOCAL_NAME, |
| AntonLS | 22:f58d4b441aba | 232 | (const uint8_t *)deviceName, strlen(deviceName) ); |
| AntonLS | 22:f58d4b441aba | 233 | |
| AntonLS | 22:f58d4b441aba | 234 | // Moved to scan response packet to give more room in AD packet... |
| AntonLS | 22:f58d4b441aba | 235 | // ble.accumulateAdvertisingPayload( GapAdvertisingData::INCOMPLETE_LIST_128BIT_SERVICE_IDS, |
| AntonLS | 22:f58d4b441aba | 236 | // (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed) ); |
| AntonLS | 22:f58d4b441aba | 237 | |
| AntonLS | 22:f58d4b441aba | 238 | ble.accumulateAdvertisingPayload( GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, |
| AntonLS | 22:f58d4b441aba | 239 | (uint8_t *)uuid16_list, sizeof( uuid16_list ) ); |
| AntonLS | 22:f58d4b441aba | 240 | ble.accumulateAdvertisingPayload( GapAdvertisingData::SERVICE_DATA, |
| AntonLS | 30:c60b0d52b067 | 241 | (uint8_t *)batt_and_id, sizeof( batt_and_id ) ); // Batt lev + "TX" |
| AntonLS | 22:f58d4b441aba | 242 | |
| AntonLS | 22:f58d4b441aba | 243 | ble.accumulateScanResponse( GapAdvertisingData::INCOMPLETE_LIST_128BIT_SERVICE_IDS, |
| AntonLS | 22:f58d4b441aba | 244 | (const uint8_t *)UARTServiceUUID_reversed, sizeof( UARTServiceUUID_reversed ) ); |
| AntonLS | 22:f58d4b441aba | 245 | } |
| AntonLS | 22:f58d4b441aba | 246 | |
| AntonLS | 22:f58d4b441aba | 247 | void updateBatt( uint8_t pct ) |
| AntonLS | 22:f58d4b441aba | 248 | { |
| AntonLS | 22:f58d4b441aba | 249 | static uint8_t prev; |
| AntonLS | 22:f58d4b441aba | 250 | static bool wasCharging; |
| AntonLS | 22:f58d4b441aba | 251 | |
| AntonLS | 22:f58d4b441aba | 252 | if( notcharge ) |
| AntonLS | 22:f58d4b441aba | 253 | { |
| AntonLS | 30:c60b0d52b067 | 254 | if( wasCharging ) ta.beep_off(); // Alarm Clock TMP TODO remove once hardware is fixed. |
| AntonLS | 30:c60b0d52b067 | 255 | |
| AntonLS | 22:f58d4b441aba | 256 | if( pct > 100 ) pct = 100; |
| AntonLS | 22:f58d4b441aba | 257 | |
| AntonLS | 31:a6110950f385 | 258 | if( wasCharging ) |
| AntonLS | 31:a6110950f385 | 259 | { |
| AntonLS | 31:a6110950f385 | 260 | pct = 102; // Show 102% at charger unplug. |
| AntonLS | 37:8f15b14d6994 | 261 | tickTock = 25; // Cause another normal update in 5 seconds. |
| AntonLS | 31:a6110950f385 | 262 | |
| AntonLS | 31:a6110950f385 | 263 | } else |
| AntonLS | 31:a6110950f385 | 264 | { |
| AntonLS | 31:a6110950f385 | 265 | // Use if we update quite often. |
| AntonLS | 31:a6110950f385 | 266 | // if( abs( (int)prev -(int)pct ) < 3 ) return; // Don't register change of less than 3%. |
| AntonLS | 31:a6110950f385 | 267 | } |
| AntonLS | 22:f58d4b441aba | 268 | |
| AntonLS | 22:f58d4b441aba | 269 | prev = pct; |
| AntonLS | 22:f58d4b441aba | 270 | wasCharging = false; |
| AntonLS | 22:f58d4b441aba | 271 | |
| AntonLS | 30:c60b0d52b067 | 272 | } else // Charging |
| AntonLS | 22:f58d4b441aba | 273 | { |
| AntonLS | 30:c60b0d52b067 | 274 | // Plugged-in seems to add ~23% to level, so checking for 99% is like 76% unplugged. |
| AntonLS | 30:c60b0d52b067 | 275 | // But I had a failure with a smaller gap, so reduced another 8%. |
| AntonLS | 30:c60b0d52b067 | 276 | if( pct >= 91 ) ta.beep( 15000 ); // Alarm Clock TMP TODO remove once hardware is fixed. |
| AntonLS | 30:c60b0d52b067 | 277 | |
| AntonLS | 31:a6110950f385 | 278 | if( !wasCharging ) |
| AntonLS | 31:a6110950f385 | 279 | pct = 101; // Show 101% at start of charging. |
| AntonLS | 22:f58d4b441aba | 280 | wasCharging = true; // Force show when done charging. |
| AntonLS | 22:f58d4b441aba | 281 | } |
| AntonLS | 22:f58d4b441aba | 282 | |
| AntonLS | 22:f58d4b441aba | 283 | batt_and_id[2] = pct; |
| AntonLS | 22:f58d4b441aba | 284 | ble.clearAdvertisingPayload(); |
| AntonLS | 22:f58d4b441aba | 285 | setAdvData(); |
| AntonLS | 22:f58d4b441aba | 286 | ble.setAdvertisingPayload(); |
| AntonLS | 22:f58d4b441aba | 287 | |
| AntonLS | 22:f58d4b441aba | 288 | if( NULL != battServiceP ) battServiceP->updateBatteryLevel( pct ); |
| AntonLS | 22:f58d4b441aba | 289 | } |
| AntonLS | 22:f58d4b441aba | 290 | |
| AntonLS | 22:f58d4b441aba | 291 | #define BAT_TOP 793 // 3250 // 52000 |
| AntonLS | 22:f58d4b441aba | 292 | #define BAT_BOT 684 // 2800 // 44800 |
| AntonLS | 22:f58d4b441aba | 293 | uint8_t getBattLevel() |
| AntonLS | 22:f58d4b441aba | 294 | { |
| AntonLS | 22:f58d4b441aba | 295 | int battI = (int)(batt * 1000.f); |
| AntonLS | 22:f58d4b441aba | 296 | // Normalize to usable range... |
| AntonLS | 22:f58d4b441aba | 297 | // Note: These levels should also give 0% if powered by programmer. |
| AntonLS | 22:f58d4b441aba | 298 | if( battI > BAT_TOP ) battI = BAT_TOP; // Fully charged reading ~3.85V |
| AntonLS | 22:f58d4b441aba | 299 | if( battI < BAT_BOT ) battI = BAT_BOT; // Device failing reading ~3.32V |
| AntonLS | 22:f58d4b441aba | 300 | battI-= BAT_BOT; |
| AntonLS | 22:f58d4b441aba | 301 | return (uint8_t)(battI*100 / (BAT_TOP-BAT_BOT)); |
| AntonLS | 22:f58d4b441aba | 302 | } |
| AntonLS | 22:f58d4b441aba | 303 | |
| elmbed | 18:affef3a7db2a | 304 | // True when connected to a phone |
| AntonLS | 11:d3aa5fca2330 | 305 | bool connected = false; |
| AntonLS | 5:1b9734e68327 | 306 | |
| AntonLS | 11:d3aa5fca2330 | 307 | void connectionCallback( Gap::Handle_t, Gap::addr_type_t peerAddrType, |
| AntonLS | 11:d3aa5fca2330 | 308 | const Gap::address_t peerAddr, const Gap::ConnectionParams_t *connParams ) |
| AntonLS | 11:d3aa5fca2330 | 309 | { |
| AntonLS | 11:d3aa5fca2330 | 310 | connected = true; |
| AntonLS | 19:afcbb425b3cf | 311 | |
| AntonLS | 19:afcbb425b3cf | 312 | // DEBUG( "Connected!\n\r" ); |
| AntonLS | 31:a6110950f385 | 313 | |
| AntonLS | 31:a6110950f385 | 314 | // char dummy; |
| AntonLS | 31:a6110950f385 | 315 | // writeToPhone( "Hi. Curr stack bot: 0x%08X\r\n", &dummy ); |
| AntonLS | 11:d3aa5fca2330 | 316 | } |
| AntonLS | 5:1b9734e68327 | 317 | |
| AntonLS | 0:28ca4562fe1a | 318 | void disconnectionCallback( Gap::Handle_t handle, Gap::DisconnectionReason_t reason ) |
| AntonLS | 0:28ca4562fe1a | 319 | { |
| AntonLS | 11:d3aa5fca2330 | 320 | connected = false; |
| AntonLS | 11:d3aa5fca2330 | 321 | |
| AntonLS | 22:f58d4b441aba | 322 | updateBatt( getBattLevel() ); |
| AntonLS | 22:f58d4b441aba | 323 | |
| AntonLS | 19:afcbb425b3cf | 324 | // DEBUG( "Disconnected!\n\r" ); |
| AntonLS | 19:afcbb425b3cf | 325 | // DEBUG( "Restarting the advertising process\n\r" ); |
| AntonLS | 30:c60b0d52b067 | 326 | // #ifdef MASTER |
| AntonLS | 0:28ca4562fe1a | 327 | ble.startAdvertising(); |
| AntonLS | 30:c60b0d52b067 | 328 | // #endif |
| elmbed | 18:affef3a7db2a | 329 | ta.post_color(0); |
| AntonLS | 0:28ca4562fe1a | 330 | } |
| AntonLS | 0:28ca4562fe1a | 331 | |
| AntonLS | 5:1b9734e68327 | 332 | bool updateCharacteristic( GattAttribute::Handle_t handle, const uint8_t *data, uint16_t bytesRead ) |
| AntonLS | 5:1b9734e68327 | 333 | { |
| AntonLS | 11:d3aa5fca2330 | 334 | ble_error_t err = ble.updateCharacteristicValue( handle, data, bytesRead ); |
| AntonLS | 5:1b9734e68327 | 335 | |
| AntonLS | 5:1b9734e68327 | 336 | if( (err == BLE_ERROR_BUFFER_OVERFLOW) || |
| AntonLS | 5:1b9734e68327 | 337 | (err == BLE_ERROR_PARAM_OUT_OF_RANGE ) ) |
| AntonLS | 7:205ef63d311a | 338 | { |
| AntonLS | 19:afcbb425b3cf | 339 | // pcfc.printf( "\r\nBLE %d! ", err ); |
| AntonLS | 7:205ef63d311a | 340 | |
| AntonLS | 7:205ef63d311a | 341 | } else if ( err == BLE_STACK_BUSY ) |
| AntonLS | 7:205ef63d311a | 342 | { |
| AntonLS | 11:d3aa5fca2330 | 343 | // Common error when pumping data. |
| AntonLS | 7:205ef63d311a | 344 | } |
| AntonLS | 5:1b9734e68327 | 345 | |
| AntonLS | 5:1b9734e68327 | 346 | return (err != BLE_ERROR_NONE); |
| AntonLS | 5:1b9734e68327 | 347 | } |
| AntonLS | 5:1b9734e68327 | 348 | |
| elmbed | 18:affef3a7db2a | 349 | extern "C" void writeToPhone(char *format, ...) |
| elmbed | 18:affef3a7db2a | 350 | { |
| elmbed | 18:affef3a7db2a | 351 | va_list arg; |
| elmbed | 18:affef3a7db2a | 352 | va_start(arg, format ); |
| elmbed | 18:affef3a7db2a | 353 | |
| AntonLS | 19:afcbb425b3cf | 354 | /**/phoneP->vprintf( format, arg ); |
| AntonLS | 19:afcbb425b3cf | 355 | |
| AntonLS | 19:afcbb425b3cf | 356 | /**/// Also write same to serial port... TODO |
| AntonLS | 19:afcbb425b3cf | 357 | /**/ // pcfc.vprintf( format, arg ); |
| AntonLS | 19:afcbb425b3cf | 358 | |
| elmbed | 18:affef3a7db2a | 359 | va_end(arg); |
| elmbed | 18:affef3a7db2a | 360 | } |
| elmbed | 18:affef3a7db2a | 361 | |
| AntonLS | 19:afcbb425b3cf | 362 | /**/ // Byte bits to ASCII - Use until we convert protocol to ASCII-hex. |
| AntonLS | 19:afcbb425b3cf | 363 | extern "C" void writeBitsToPhone( uint8_t byte, uint8_t minbits ) |
| AntonLS | 19:afcbb425b3cf | 364 | { |
| AntonLS | 19:afcbb425b3cf | 365 | static char ascbits[9] = { 0 }; |
| AntonLS | 19:afcbb425b3cf | 366 | int pos = 0; |
| AntonLS | 19:afcbb425b3cf | 367 | if( 0 == minbits ) minbits = 1; |
| AntonLS | 19:afcbb425b3cf | 368 | |
| AntonLS | 19:afcbb425b3cf | 369 | uint16_t ibyt = byte & 0xFF; |
| AntonLS | 19:afcbb425b3cf | 370 | bool leading0 = true; |
| AntonLS | 19:afcbb425b3cf | 371 | |
| AntonLS | 19:afcbb425b3cf | 372 | for( short b=7; b >= 0; b-- ) |
| AntonLS | 19:afcbb425b3cf | 373 | { |
| AntonLS | 19:afcbb425b3cf | 374 | ibyt<<=1; |
| AntonLS | 19:afcbb425b3cf | 375 | if( ibyt & 0x100 ) |
| AntonLS | 19:afcbb425b3cf | 376 | { |
| AntonLS | 19:afcbb425b3cf | 377 | leading0 = false; |
| AntonLS | 19:afcbb425b3cf | 378 | ascbits[pos++] = '1'; |
| AntonLS | 19:afcbb425b3cf | 379 | |
| AntonLS | 19:afcbb425b3cf | 380 | } else if( !leading0 || (b < minbits) ) |
| AntonLS | 19:afcbb425b3cf | 381 | { |
| AntonLS | 19:afcbb425b3cf | 382 | ascbits[pos++] = '0'; |
| AntonLS | 19:afcbb425b3cf | 383 | } |
| AntonLS | 19:afcbb425b3cf | 384 | } |
| AntonLS | 19:afcbb425b3cf | 385 | ascbits[pos] = '\0'; |
| AntonLS | 19:afcbb425b3cf | 386 | |
| AntonLS | 19:afcbb425b3cf | 387 | writeToPhone( "%s", ascbits ); |
| AntonLS | 19:afcbb425b3cf | 388 | } |
| AntonLS | 19:afcbb425b3cf | 389 | |
| AntonLS | 0:28ca4562fe1a | 390 | void onDataWritten( const GattCharacteristicWriteCBParams *params ) |
| AntonLS | 0:28ca4562fe1a | 391 | { |
| AntonLS | 11:d3aa5fca2330 | 392 | if( phoneP != NULL ) |
| AntonLS | 0:28ca4562fe1a | 393 | { |
| AntonLS | 11:d3aa5fca2330 | 394 | uint16_t bytesRead = phoneP->maybeHandleRead( params ); // Also writes to txPayload |
| elmbed | 18:affef3a7db2a | 395 | |
| AntonLS | 11:d3aa5fca2330 | 396 | if( 0 != bytesRead ) |
| AntonLS | 11:d3aa5fca2330 | 397 | { |
| AntonLS | 19:afcbb425b3cf | 398 | /* |
| AntonLS | 19:afcbb425b3cf | 399 | DEBUG( "received %u bytes\n\r", bytesRead ); |
| AntonLS | 19:afcbb425b3cf | 400 | |
| AntonLS | 19:afcbb425b3cf | 401 | // Also write to serial port... |
| AntonLS | 19:afcbb425b3cf | 402 | // pcfc.printf( "From app: " ); |
| AntonLS | 19:afcbb425b3cf | 403 | pcfc.write( (char *)txPayload, bytesRead ); |
| AntonLS | 19:afcbb425b3cf | 404 | // pcfc.printf( "\r\n" ); |
| AntonLS | 19:afcbb425b3cf | 405 | */ |
| AntonLS | 19:afcbb425b3cf | 406 | |
| AntonLS | 11:d3aa5fca2330 | 407 | return; |
| AntonLS | 11:d3aa5fca2330 | 408 | } |
| AntonLS | 0:28ca4562fe1a | 409 | } |
| AntonLS | 0:28ca4562fe1a | 410 | } |
| AntonLS | 0:28ca4562fe1a | 411 | |
| AntonLS | 0:28ca4562fe1a | 412 | void onDataSent( unsigned count ) |
| AntonLS | 0:28ca4562fe1a | 413 | { |
| AntonLS | 0:28ca4562fe1a | 414 | } |
| AntonLS | 0:28ca4562fe1a | 415 | |
| AntonLS | 11:d3aa5fca2330 | 416 | void toPhoneChk( void ) |
| AntonLS | 0:28ca4562fe1a | 417 | { |
| AntonLS | 19:afcbb425b3cf | 418 | if( phoneP != NULL ) |
| AntonLS | 19:afcbb425b3cf | 419 | { |
| AntonLS | 19:afcbb425b3cf | 420 | /* |
| AntonLS | 19:afcbb425b3cf | 421 | char ch; |
| AntonLS | 19:afcbb425b3cf | 422 | // Get any data from serial port buffer--Full lines if avail--Last line after >= 20 chars. |
| AntonLS | 19:afcbb425b3cf | 423 | for( int cnt=1; 0 != pcfc.atomicRead( ch ); cnt++ ) |
| AntonLS | 19:afcbb425b3cf | 424 | { |
| AntonLS | 19:afcbb425b3cf | 425 | /// For from-serial straight to-phone. |
| AntonLS | 19:afcbb425b3cf | 426 | /// if( 0 > phoneP->putchar( ch ) ) |
| AntonLS | 19:afcbb425b3cf | 427 | /// { |
| AntonLS | 19:afcbb425b3cf | 428 | /// pcfc.printf( " * " ); |
| AntonLS | 19:afcbb425b3cf | 429 | /// break; |
| AntonLS | 19:afcbb425b3cf | 430 | /// } |
| AntonLS | 3:388e441be8df | 431 | |
| AntonLS | 19:afcbb425b3cf | 432 | // For from-serial inject-to-dev as-if from phone. |
| AntonLS | 19:afcbb425b3cf | 433 | phoneP->injectHandleRead( &ch, 1 ); |
| AntonLS | 19:afcbb425b3cf | 434 | |
| AntonLS | 19:afcbb425b3cf | 435 | if( (cnt >= 20) && ('\n' == ch) ) break; |
| AntonLS | 19:afcbb425b3cf | 436 | } |
| AntonLS | 19:afcbb425b3cf | 437 | */ |
| AntonLS | 19:afcbb425b3cf | 438 | // Write to outgoing characteristic if anything is pending. |
| AntonLS | 19:afcbb425b3cf | 439 | if( 0 != phoneP->maybeHandleWrite() ) |
| AntonLS | 19:afcbb425b3cf | 440 | { |
| AntonLS | 19:afcbb425b3cf | 441 | // pcfc.printf( "ToPhoneHandler \r\n" ); |
| AntonLS | 19:afcbb425b3cf | 442 | } |
| AntonLS | 19:afcbb425b3cf | 443 | } |
| AntonLS | 0:28ca4562fe1a | 444 | } |
| elmbed | 28:8e74ddc4f70f | 445 | |
| AntonLS | 13:28332f65d14b | 446 | static uint32_t boot_cnt_data = 0; |
| AntonLS | 13:28332f65d14b | 447 | static uint16_t data_block = 9*20 +75; // Last block -- Use for app-start count. |
| AntonLS | 13:28332f65d14b | 448 | static uint16_t data_size = 4; |
| AntonLS | 13:28332f65d14b | 449 | static uint16_t data_offset = 0; // 12 for 16-byte blocks. |
| AntonLS | 13:28332f65d14b | 450 | static bool data_loaded = false; |
| AntonLS | 13:28332f65d14b | 451 | static bool data_cleared = false; |
| AntonLS | 13:28332f65d14b | 452 | static bool data_stored = false; |
| AntonLS | 13:28332f65d14b | 453 | static pstorage_handle_t pstorage_id; |
| AntonLS | 19:afcbb425b3cf | 454 | |
| AntonLS | 13:28332f65d14b | 455 | static uint32_t pstorage_read_test() |
| AntonLS | 13:28332f65d14b | 456 | { |
| AntonLS | 13:28332f65d14b | 457 | uint32_t err_code; |
| AntonLS | 13:28332f65d14b | 458 | |
| AntonLS | 13:28332f65d14b | 459 | pstorage_handle_t p_block_id; |
| AntonLS | 13:28332f65d14b | 460 | |
| AntonLS | 13:28332f65d14b | 461 | do |
| AntonLS | 13:28332f65d14b | 462 | { |
| AntonLS | 13:28332f65d14b | 463 | err_code = pstorage_block_identifier_get( &pstorage_id, data_block, &p_block_id ); |
| AntonLS | 13:28332f65d14b | 464 | if( NRF_SUCCESS != err_code ) break; |
| AntonLS | 13:28332f65d14b | 465 | |
| AntonLS | 13:28332f65d14b | 466 | err_code = pstorage_load( (uint8_t *)&boot_cnt_data, &p_block_id, data_size, data_offset ); |
| AntonLS | 13:28332f65d14b | 467 | if( NRF_SUCCESS != err_code ) break; |
| AntonLS | 13:28332f65d14b | 468 | |
| AntonLS | 13:28332f65d14b | 469 | } while( 0 ); |
| AntonLS | 13:28332f65d14b | 470 | |
| AntonLS | 13:28332f65d14b | 471 | return err_code; |
| AntonLS | 13:28332f65d14b | 472 | } |
| AntonLS | 13:28332f65d14b | 473 | static uint32_t pstorage_clear_test() |
| AntonLS | 13:28332f65d14b | 474 | { |
| AntonLS | 13:28332f65d14b | 475 | uint32_t err_code; |
| AntonLS | 13:28332f65d14b | 476 | |
| AntonLS | 13:28332f65d14b | 477 | pstorage_handle_t p_block_id; |
| AntonLS | 13:28332f65d14b | 478 | |
| AntonLS | 13:28332f65d14b | 479 | do |
| AntonLS | 13:28332f65d14b | 480 | { |
| AntonLS | 13:28332f65d14b | 481 | err_code = pstorage_block_identifier_get( &pstorage_id, data_block, &p_block_id ); |
| AntonLS | 13:28332f65d14b | 482 | if( NRF_SUCCESS != err_code ) break; |
| AntonLS | 13:28332f65d14b | 483 | |
| AntonLS | 13:28332f65d14b | 484 | err_code = pstorage_clear( &p_block_id, PSTORAGE_MIN_BLOCK_SIZE ); |
| AntonLS | 13:28332f65d14b | 485 | if( NRF_SUCCESS != err_code ) break; |
| AntonLS | 13:28332f65d14b | 486 | |
| AntonLS | 13:28332f65d14b | 487 | } while( 0 ); |
| AntonLS | 13:28332f65d14b | 488 | |
| AntonLS | 13:28332f65d14b | 489 | return err_code; |
| AntonLS | 13:28332f65d14b | 490 | } |
| AntonLS | 13:28332f65d14b | 491 | static uint32_t pstorage_write_test() |
| AntonLS | 13:28332f65d14b | 492 | { |
| AntonLS | 13:28332f65d14b | 493 | uint32_t err_code; |
| AntonLS | 13:28332f65d14b | 494 | |
| AntonLS | 13:28332f65d14b | 495 | pstorage_handle_t p_block_id; |
| AntonLS | 13:28332f65d14b | 496 | |
| AntonLS | 13:28332f65d14b | 497 | do |
| AntonLS | 13:28332f65d14b | 498 | { |
| AntonLS | 13:28332f65d14b | 499 | err_code = pstorage_block_identifier_get( &pstorage_id, data_block, &p_block_id ); |
| AntonLS | 13:28332f65d14b | 500 | if( NRF_SUCCESS != err_code ) break; |
| AntonLS | 13:28332f65d14b | 501 | |
| AntonLS | 13:28332f65d14b | 502 | err_code = pstorage_store( &p_block_id, (uint8_t *)&boot_cnt_data, data_size, data_offset ); |
| AntonLS | 13:28332f65d14b | 503 | |
| AntonLS | 13:28332f65d14b | 504 | } while( 0 ); |
| AntonLS | 13:28332f65d14b | 505 | |
| AntonLS | 13:28332f65d14b | 506 | return err_code; |
| AntonLS | 13:28332f65d14b | 507 | } |
| AntonLS | 19:afcbb425b3cf | 508 | |
| AntonLS | 13:28332f65d14b | 509 | static void pstorage_cb_handler( pstorage_handle_t *handle, uint8_t op_code, uint32_t result, uint8_t *p_data, uint32_t data_len ) |
| AntonLS | 13:28332f65d14b | 510 | { |
| AntonLS | 13:28332f65d14b | 511 | switch( op_code ) |
| AntonLS | 13:28332f65d14b | 512 | { |
| AntonLS | 13:28332f65d14b | 513 | case PSTORAGE_LOAD_OP_CODE: |
| AntonLS | 13:28332f65d14b | 514 | if( NRF_SUCCESS == result ) |
| AntonLS | 13:28332f65d14b | 515 | { |
| AntonLS | 13:28332f65d14b | 516 | // Load operation successful. |
| AntonLS | 13:28332f65d14b | 517 | data_loaded = true; // Flag to signal load is done. |
| AntonLS | 13:28332f65d14b | 518 | |
| AntonLS | 13:28332f65d14b | 519 | } else |
| AntonLS | 13:28332f65d14b | 520 | { |
| AntonLS | 13:28332f65d14b | 521 | // Load operation failed. |
| elmbed | 18:affef3a7db2a | 522 | //pcfc.printf( "\r\nWarn: pstorage load operation error: %x\r\n", result ); |
| AntonLS | 13:28332f65d14b | 523 | } |
| AntonLS | 13:28332f65d14b | 524 | break; |
| AntonLS | 13:28332f65d14b | 525 | case PSTORAGE_UPDATE_OP_CODE: |
| AntonLS | 13:28332f65d14b | 526 | case PSTORAGE_STORE_OP_CODE: |
| AntonLS | 13:28332f65d14b | 527 | if( NRF_SUCCESS == result ) |
| AntonLS | 13:28332f65d14b | 528 | { |
| AntonLS | 13:28332f65d14b | 529 | // Store operation successful. |
| AntonLS | 13:28332f65d14b | 530 | data_stored = true; // Flag to signal store is done. |
| AntonLS | 13:28332f65d14b | 531 | |
| AntonLS | 13:28332f65d14b | 532 | } else |
| AntonLS | 13:28332f65d14b | 533 | { |
| AntonLS | 13:28332f65d14b | 534 | // Store operation failed. |
| elmbed | 18:affef3a7db2a | 535 | //pcfc.printf( "\r\nWarn: pstorage store operation error: %x\r\n", result ); |
| AntonLS | 13:28332f65d14b | 536 | } |
| AntonLS | 13:28332f65d14b | 537 | // Source memory can now be reused or freed. |
| AntonLS | 13:28332f65d14b | 538 | break; |
| AntonLS | 13:28332f65d14b | 539 | case PSTORAGE_CLEAR_OP_CODE: |
| AntonLS | 13:28332f65d14b | 540 | if( NRF_SUCCESS == result ) |
| AntonLS | 13:28332f65d14b | 541 | { |
| AntonLS | 13:28332f65d14b | 542 | // Clear operation successful. |
| AntonLS | 13:28332f65d14b | 543 | data_cleared = true; // Flag to store to the same data area. |
| AntonLS | 13:28332f65d14b | 544 | |
| AntonLS | 13:28332f65d14b | 545 | } else |
| AntonLS | 13:28332f65d14b | 546 | { |
| AntonLS | 13:28332f65d14b | 547 | // Clear operation failed. |
| elmbed | 18:affef3a7db2a | 548 | //pcfc.printf( "\r\nWarn: pstorage clear operation error: %x\r\n", result ); |
| AntonLS | 13:28332f65d14b | 549 | } |
| AntonLS | 13:28332f65d14b | 550 | break; |
| AntonLS | 19:afcbb425b3cf | 551 | //default: |
| AntonLS | 19:afcbb425b3cf | 552 | //pcfc.printf( "\r\nWarn: pstorage unknown op: %x error: %x\r\n", op_code, result ); |
| AntonLS | 13:28332f65d14b | 553 | } |
| AntonLS | 13:28332f65d14b | 554 | } |
| AntonLS | 19:afcbb425b3cf | 555 | |
| AntonLS | 13:28332f65d14b | 556 | static uint32_t pstorage_setup() |
| AntonLS | 13:28332f65d14b | 557 | { |
| AntonLS | 13:28332f65d14b | 558 | pstorage_module_param_t pstorage_param; |
| AntonLS | 13:28332f65d14b | 559 | |
| AntonLS | 13:28332f65d14b | 560 | // Setup pstorage with 9*20 +76 blocks of 4 bytes each. (or 9*20/4 + 19 for 16 byte blocks) |
| AntonLS | 13:28332f65d14b | 561 | pstorage_param.block_size = 4; // Recommended to be >= 4 bytes. |
| AntonLS | 13:28332f65d14b | 562 | pstorage_param.block_count = 9*20 +76; // 9 Sequences x 20 Stations + 76 blocks to fill out to 1k. |
| AntonLS | 13:28332f65d14b | 563 | pstorage_param.cb = pstorage_cb_handler; |
| AntonLS | 13:28332f65d14b | 564 | |
| AntonLS | 13:28332f65d14b | 565 | return pstorage_register( &pstorage_param, &pstorage_id ); |
| AntonLS | 13:28332f65d14b | 566 | } |
| elmbed | 28:8e74ddc4f70f | 567 | |
| AntonLS | 13:28332f65d14b | 568 | |
| AntonLS | 13:28332f65d14b | 569 | void periodicCallback( void ) |
| AntonLS | 13:28332f65d14b | 570 | { |
| AntonLS | 37:8f15b14d6994 | 571 | static int callCnt; |
| AntonLS | 37:8f15b14d6994 | 572 | if( (callCnt++ % 5) != 0 ) return; |
| AntonLS | 37:8f15b14d6994 | 573 | callCnt = 1; |
| AntonLS | 37:8f15b14d6994 | 574 | |
| AntonLS | 30:c60b0d52b067 | 575 | #if BLENANO |
| elmbed | 18:affef3a7db2a | 576 | led0 = !led0; |
| AntonLS | 30:c60b0d52b067 | 577 | #endif |
| elmbed | 18:affef3a7db2a | 578 | led1 = !led1; |
| AntonLS | 19:afcbb425b3cf | 579 | led2 = !led2; |
| AntonLS | 13:28332f65d14b | 580 | // rts = !rts; |
| AntonLS | 20:d6c6099b60be | 581 | |
| AntonLS | 21:32f022efcc09 | 582 | // Check battery level every 30s. |
| AntonLS | 37:8f15b14d6994 | 583 | if( 0 == (tickTock % 30) ) updateBatt( getBattLevel() ); |
| AntonLS | 30:c60b0d52b067 | 584 | |
| AntonLS | 30:c60b0d52b067 | 585 | tickTock++; |
| AntonLS | 13:28332f65d14b | 586 | } |
| AntonLS | 13:28332f65d14b | 587 | |
| AntonLS | 12:6d313d575f84 | 588 | /* |
| AntonLS | 12:6d313d575f84 | 589 | void led_thread( void const *args ) |
| AntonLS | 12:6d313d575f84 | 590 | { |
| AntonLS | 12:6d313d575f84 | 591 | while( true ) |
| AntonLS | 12:6d313d575f84 | 592 | { |
| AntonLS | 12:6d313d575f84 | 593 | led0 = !led0; |
| AntonLS | 12:6d313d575f84 | 594 | led1 = !led1; |
| AntonLS | 12:6d313d575f84 | 595 | Thread::wait( 1000 ); |
| AntonLS | 12:6d313d575f84 | 596 | } |
| AntonLS | 12:6d313d575f84 | 597 | } |
| AntonLS | 12:6d313d575f84 | 598 | */ |
| AntonLS | 12:6d313d575f84 | 599 | |
| AntonLS | 13:28332f65d14b | 600 | |
| AntonLS | 0:28ca4562fe1a | 601 | int main( void ) |
| AntonLS | 0:28ca4562fe1a | 602 | { |
| AntonLS | 0:28ca4562fe1a | 603 | Ticker ticker; |
| AntonLS | 37:8f15b14d6994 | 604 | ticker.attach( periodicCallback, 0.2 /** 0.5 **/ /* 1 */ ); |
| AntonLS | 19:afcbb425b3cf | 605 | |
| AntonLS | 19:afcbb425b3cf | 606 | /* |
| AntonLS | 19:afcbb425b3cf | 607 | // Thread thread( led_thread ); |
| AntonLS | 19:afcbb425b3cf | 608 | */ |
| elmbed | 28:8e74ddc4f70f | 609 | |
| AntonLS | 19:afcbb425b3cf | 610 | /////pcfc.baud( 57600 ); |
| AntonLS | 19:afcbb425b3cf | 611 | |
| AntonLS | 19:afcbb425b3cf | 612 | /* |
| AntonLS | 19:afcbb425b3cf | 613 | DEBUG( "Initialising the nRF51822\n\r" ); |
| AntonLS | 19:afcbb425b3cf | 614 | */ |
| AntonLS | 2:fe1566cdb6e7 | 615 | |
| AntonLS | 0:28ca4562fe1a | 616 | ble.init(); |
| elmbed | 18:affef3a7db2a | 617 | |
| AntonLS | 11:d3aa5fca2330 | 618 | ble.onConnection( connectionCallback ); |
| AntonLS | 0:28ca4562fe1a | 619 | ble.onDisconnection( disconnectionCallback ); |
| AntonLS | 0:28ca4562fe1a | 620 | ble.onDataWritten( onDataWritten ); |
| AntonLS | 0:28ca4562fe1a | 621 | ble.onDataSent( onDataSent ); |
| AntonLS | 0:28ca4562fe1a | 622 | |
| AntonLS | 0:28ca4562fe1a | 623 | /* setup advertising */ |
| AntonLS | 20:d6c6099b60be | 624 | setAdvData(); |
| AntonLS | 5:1b9734e68327 | 625 | |
| AntonLS | 19:afcbb425b3cf | 626 | /////pcfc.printf( "\r\nNano nano! I am \"%s\"\r\n", deviceName ); |
| AntonLS | 19:afcbb425b3cf | 627 | |
| AntonLS | 19:afcbb425b3cf | 628 | /* |
| AntonLS | 19:afcbb425b3cf | 629 | #if LOOPBACK_MODE |
| AntonLS | 19:afcbb425b3cf | 630 | pcfc.printf( "\r\nIn BLE Loopback mode.\r\n" ); |
| AntonLS | 19:afcbb425b3cf | 631 | #endif |
| AntonLS | 19:afcbb425b3cf | 632 | */ |
| AntonLS | 19:afcbb425b3cf | 633 | |
| AntonLS | 13:28332f65d14b | 634 | uint32_t p_count; |
| AntonLS | 13:28332f65d14b | 635 | uint32_t pstorageErr = pstorage_init(); // This needs to be called, even though apparently called in bootloader--Check other stuff. |
| AntonLS | 13:28332f65d14b | 636 | pstorage_access_status_get( &p_count ); |
| AntonLS | 13:28332f65d14b | 637 | |
| elmbed | 28:8e74ddc4f70f | 638 | |
| AntonLS | 19:afcbb425b3cf | 639 | // pcfc.printf( "\r\nInitial pstorage count: %d\r\n", p_count ); |
| AntonLS | 19:afcbb425b3cf | 640 | |
| elmbed | 28:8e74ddc4f70f | 641 | if( NRF_SUCCESS != pstorageErr ) |
| elmbed | 28:8e74ddc4f70f | 642 | { |
| AntonLS | 30:c60b0d52b067 | 643 | // pcfc.printf( "\r\nWarn: pstorage init error: %x\r\n", pstorageErr ); |
| AntonLS | 30:c60b0d52b067 | 644 | /// writeToPhone( "\r\nWarn: pstorage init error: %x\r\n", pstorageErr ); |
| AntonLS | 30:c60b0d52b067 | 645 | |
| AntonLS | 30:c60b0d52b067 | 646 | } else |
| AntonLS | 19:afcbb425b3cf | 647 | { |
| AntonLS | 19:afcbb425b3cf | 648 | pstorageErr = pstorage_setup(); |
| AntonLS | 30:c60b0d52b067 | 649 | if( NRF_SUCCESS != pstorageErr ) |
| AntonLS | 30:c60b0d52b067 | 650 | { |
| AntonLS | 30:c60b0d52b067 | 651 | // pcfc.printf( "\r\nWarn: pstorage setup error: %x\r\n", pstorageErr ); |
| AntonLS | 30:c60b0d52b067 | 652 | /// writeToPhone( "\r\nWarn: pstorage setup error: %x\r\n", pstorageErr ); |
| AntonLS | 30:c60b0d52b067 | 653 | |
| AntonLS | 30:c60b0d52b067 | 654 | } else |
| AntonLS | 19:afcbb425b3cf | 655 | { |
| AntonLS | 19:afcbb425b3cf | 656 | pstorageErr = pstorage_read_test(); |
| AntonLS | 30:c60b0d52b067 | 657 | if( NRF_SUCCESS != pstorageErr ) |
| AntonLS | 30:c60b0d52b067 | 658 | { |
| AntonLS | 30:c60b0d52b067 | 659 | // pcfc.printf( "\r\nWarn: pstorage read attempt error: %x\r\n", pstorageErr ); |
| AntonLS | 30:c60b0d52b067 | 660 | /// writeToPhone( "\r\nWarn: pstorage read attempt error: %x\r\n", pstorageErr ); |
| AntonLS | 30:c60b0d52b067 | 661 | |
| AntonLS | 30:c60b0d52b067 | 662 | } else |
| AntonLS | 19:afcbb425b3cf | 663 | { |
| AntonLS | 19:afcbb425b3cf | 664 | // In this test setup, we use the load callback to signal start to clear, |
| AntonLS | 19:afcbb425b3cf | 665 | // then we use the clear callback to signal start to write. |
| AntonLS | 19:afcbb425b3cf | 666 | } |
| AntonLS | 19:afcbb425b3cf | 667 | } |
| AntonLS | 19:afcbb425b3cf | 668 | } |
| elmbed | 28:8e74ddc4f70f | 669 | |
| AntonLS | 19:afcbb425b3cf | 670 | |
| AntonLS | 0:28ca4562fe1a | 671 | DeviceInformationService deviceInfo( ble, "TRX", "TrueAgility", "SN0001", "hw-rev1", "fw-rev1" ); |
| AntonLS | 19:afcbb425b3cf | 672 | BatteryService battService( ble ); |
| AntonLS | 20:d6c6099b60be | 673 | battServiceP = &battService; |
| AntonLS | 21:32f022efcc09 | 674 | updateBatt( getBattLevel() ); |
| AntonLS | 0:28ca4562fe1a | 675 | |
| AntonLS | 19:afcbb425b3cf | 676 | /* Enable over-the-air firmware updates. Instantiating DFUService introduces a |
| AntonLS | 0:28ca4562fe1a | 677 | * control characteristic which can be used to trigger the application to |
| AntonLS | 0:28ca4562fe1a | 678 | * handover control to a resident bootloader. */ |
| AntonLS | 0:28ca4562fe1a | 679 | DFUService dfu( ble ); |
| AntonLS | 0:28ca4562fe1a | 680 | |
| AntonLS | 19:afcbb425b3cf | 681 | UARTService uartService( ble ); |
| AntonLS | 0:28ca4562fe1a | 682 | uartServicePtr = &uartService; |
| AntonLS | 0:28ca4562fe1a | 683 | |
| AntonLS | 21:32f022efcc09 | 684 | ble.setAdvertisingInterval( Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS( 132 ) ); |
| AntonLS | 30:c60b0d52b067 | 685 | // #ifdef MASTER |
| AntonLS | 21:32f022efcc09 | 686 | ble.startAdvertising(); |
| AntonLS | 30:c60b0d52b067 | 687 | // #endif |
| AntonLS | 21:32f022efcc09 | 688 | |
| AntonLS | 19:afcbb425b3cf | 689 | PhoneAppIO *phone = new PhoneAppIO( ble, |
| AntonLS | 19:afcbb425b3cf | 690 | uartServicePtr->getRXCharacteristicHandle(), |
| AntonLS | 19:afcbb425b3cf | 691 | uartServicePtr->getTXCharacteristicHandle() ); |
| AntonLS | 19:afcbb425b3cf | 692 | |
| elmbed | 18:affef3a7db2a | 693 | phone->loopbackMode = LOOPBACK_MODE; |
| elmbed | 18:affef3a7db2a | 694 | phoneP = phone; |
| elmbed | 18:affef3a7db2a | 695 | |
| elmbed | 17:d8b901d791fd | 696 | setup(); |
| elmbed | 23:26f27c462976 | 697 | radio_init(); |
| AntonLS | 11:d3aa5fca2330 | 698 | tmr.start(); |
| elmbed | 18:affef3a7db2a | 699 | |
| AntonLS | 11:d3aa5fca2330 | 700 | // Main Loop |
| AntonLS | 19:afcbb425b3cf | 701 | while( true ) // for( uint32_t loop=1; ;loop++ ) |
| AntonLS | 0:28ca4562fe1a | 702 | { |
| AntonLS | 0:28ca4562fe1a | 703 | ble.waitForEvent(); |
| AntonLS | 19:afcbb425b3cf | 704 | |
| AntonLS | 19:afcbb425b3cf | 705 | /**/ toPhoneChk(); // Write any pending data to phone. |
| AntonLS | 19:afcbb425b3cf | 706 | |
| AntonLS | 19:afcbb425b3cf | 707 | /* |
| AntonLS | 19:afcbb425b3cf | 708 | while( 0 <= phone.getchar() ); // Eat input. |
| AntonLS | 19:afcbb425b3cf | 709 | |
| AntonLS | 19:afcbb425b3cf | 710 | // if( !(loop % 50) ) phone.printf( "Post: %d\r\n", tmr.read_ms() ); |
| AntonLS | 19:afcbb425b3cf | 711 | |
| AntonLS | 19:afcbb425b3cf | 712 | app_sched_execute(); // Attempt to get pstorage enqueued cmd callbacks. |
| AntonLS | 19:afcbb425b3cf | 713 | */ |
| AntonLS | 19:afcbb425b3cf | 714 | |
| AntonLS | 19:afcbb425b3cf | 715 | /**/ int bytes = MIN( PHTODEV_BUF_LEN, phoneP->readable() ); |
| elmbed | 23:26f27c462976 | 716 | /**/ |
| elmbed | 23:26f27c462976 | 717 | #ifdef MASTER |
| elmbed | 23:26f27c462976 | 718 | getRadioInput( phoneToDev, phoneP->read( phoneToDev, bytes, 1 ) ); |
| elmbed | 23:26f27c462976 | 719 | #endif |
| elmbed | 17:d8b901d791fd | 720 | loop(); |
| elmbed | 18:affef3a7db2a | 721 | //radio_loop(); |
| AntonLS | 0:28ca4562fe1a | 722 | } |
| AntonLS | 0:28ca4562fe1a | 723 | } |
| AntonLS | 0:28ca4562fe1a | 724 | |
| AntonLS | 15:b86c4b798aa1 | 725 | /**@brief Function for error handling, which is called when an error has occurred. |
| AntonLS | 15:b86c4b798aa1 | 726 | * |
| AntonLS | 15:b86c4b798aa1 | 727 | * @warning This handler is an example only and does not fit a final product. You need to analyze |
| AntonLS | 15:b86c4b798aa1 | 728 | * how your product is supposed to react in case of error. |
| AntonLS | 15:b86c4b798aa1 | 729 | * |
| AntonLS | 15:b86c4b798aa1 | 730 | * @param[in] error_code Error code supplied to the handler. |
| AntonLS | 15:b86c4b798aa1 | 731 | * @param[in] line_num Line number where the handler is called. |
| AntonLS | 15:b86c4b798aa1 | 732 | * @param[in] p_file_name Pointer to the file name. |
| AntonLS | 15:b86c4b798aa1 | 733 | */ |
| AntonLS | 15:b86c4b798aa1 | 734 | void $Sub$$app_error_handler( uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name ) |
| AntonLS | 15:b86c4b798aa1 | 735 | { |
| AntonLS | 15:b86c4b798aa1 | 736 | // nrf_gpio_pin_set( ASSERT_LED_PIN_NO ); |
| elmbed | 18:affef3a7db2a | 737 | //led1 = 1; |
| AntonLS | 15:b86c4b798aa1 | 738 | |
| AntonLS | 15:b86c4b798aa1 | 739 | // This call can be used for debug purposes during application development. |
| AntonLS | 15:b86c4b798aa1 | 740 | // @note CAUTION: Activating this code will write the stack to flash on an error. |
| AntonLS | 15:b86c4b798aa1 | 741 | // This function should NOT be used in a final product. |
| AntonLS | 15:b86c4b798aa1 | 742 | // It is intended STRICTLY for development/debugging purposes. |
| AntonLS | 15:b86c4b798aa1 | 743 | // The flash write will happen EVEN if the radio is active, thus interrupting |
| AntonLS | 15:b86c4b798aa1 | 744 | // any communication. |
| AntonLS | 15:b86c4b798aa1 | 745 | // Use with care. Uncomment the line below to use. |
| AntonLS | 15:b86c4b798aa1 | 746 | // ble_debug_assert_handler(error_code, line_num, p_file_name); |
| AntonLS | 15:b86c4b798aa1 | 747 | |
| AntonLS | 15:b86c4b798aa1 | 748 | // On assert, the system can only recover with a reset. |
| AntonLS | 15:b86c4b798aa1 | 749 | NVIC_SystemReset(); |
| AntonLS | 15:b86c4b798aa1 | 750 | } |
| AntonLS | 15:b86c4b798aa1 | 751 | |
| AntonLS | 0:28ca4562fe1a | 752 | /* EOF */ |
