This is a modified "BLE_Default_App". It doesn't use retargetStdout() which allows it to work with online Libs available on 20150123 (nRF51822, BLE_API)

Dependencies:   BLE_API mbed nRF51822

App for FOTA testing:

  • IO:
    • Blinks a LED on platform to show App alive
    • LEDs also follow buttons to show immediate response.
    • BLE UART has ping message, and also echos back any received bytes (Use with Android App: nRF UART 2.0).
  • It compiles and runs as FOTA and non-FOTA platform which may assist debugging
    • platform "Nordic nRF51822 FOTA" for FOTA Loading
    • platform "Nordic nRF51822" for mbed drive loading
  • Supports mbed and non-mbed PCBs (all compiled using platform "Nordic nRF51822 FOTA")
  • Compile options available for:
    • nRF51822-mkit (Includes USB Serial Debug)
    • nRF51822-EK
    • nRF51822-Beacon (nRFBeacon)
    • Atomwear (Button and LED on main PCB only)
    • *If anyone gets this working with other publicly available PCBs let me know and we can add it in
Committer:
prussell
Date:
Mon Jan 26 14:54:24 2015 +0000
Revision:
3:3651f1a58d9e
Parent:
2:0931d94f42a2
Child:
4:3a065a4e3ca6
Corrected nRFBeacon LED Polarity (Active Lo)
; Works for mkit, nRF51822-EK, nRFBeacon

Who changed what in which revision?

UserRevisionLine numberNew contents of line
prussell 3:3651f1a58d9e 1 //To load over FOTA set platform to "Nordic nRF51822 FOTA" and use DFU feature of App "nRF Master Control Panel" (Hex file <100K)
prussell 3:3651f1a58d9e 2 //To use normal mbed loading set platform to "Nordic nRF51822" and copy to mbed virtual disk (Hex File >250KB)
prussell 3:3651f1a58d9e 3
prussell 0:aa7314f3fa84 4 /* mbed Microcontroller Library
prussell 0:aa7314f3fa84 5 * Copyright (c) 2006-2013 ARM Limited
prussell 0:aa7314f3fa84 6 *
prussell 0:aa7314f3fa84 7 * Licensed under the Apache License, Version 2.0 (the "License");
prussell 0:aa7314f3fa84 8 * you may not use this file except in compliance with the License.
prussell 0:aa7314f3fa84 9 * You may obtain a copy of the License at
prussell 0:aa7314f3fa84 10 *
prussell 0:aa7314f3fa84 11 * http://www.apache.org/licenses/LICENSE-2.0
prussell 0:aa7314f3fa84 12 *
prussell 0:aa7314f3fa84 13 * Unless required by applicable law or agreed to in writing, software
prussell 0:aa7314f3fa84 14 * distributed under the License is distributed on an "AS IS" BASIS,
prussell 0:aa7314f3fa84 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
prussell 0:aa7314f3fa84 16 * See the License for the specific language governing permissions and
prussell 0:aa7314f3fa84 17 * limitations under the License.
prussell 0:aa7314f3fa84 18 */
prussell 0:aa7314f3fa84 19
prussell 3:3651f1a58d9e 20 //==============================
prussell 3:3651f1a58d9e 21 // Build Options for D_PCB
prussell 3:3651f1a58d9e 22 #define D_MKIT 1 // mkit: USBSerial=OK, ButtonLED=m, LED2=Button2, LED1=Button1|Ticker
prussell 3:3651f1a58d9e 23 #define D_EK 2 // mkit: USBSerial=None, ButtonLED=m, LED1=Button1, LED0=Button0|Ticker
prussell 3:3651f1a58d9e 24 #define D_BEACON 3 // mkit: USBSerial=None, ButtonLED=b, LEDx=Buttonx, LEDy=Buttony|Ticker
prussell 3:3651f1a58d9e 25
prussell 3:3651f1a58d9e 26 //==============================
prussell 3:3651f1a58d9e 27 // Compile Options:
prussell 3:3651f1a58d9e 28 #define D_PING_SEC 1 // Ping Rate in Seconds
prussell 3:3651f1a58d9e 29 #define D_PCB D_MKIT // Define the PCB to compile for
prussell 3:3651f1a58d9e 30 //#define D_PCB D_EK // Define the PCB to compile for
prussell 3:3651f1a58d9e 31 //#define D_PCB D_BEACON // Define the PCB to compile for
prussell 3:3651f1a58d9e 32
prussell 3:3651f1a58d9e 33 //==============================
prussell 0:aa7314f3fa84 34 #include "mbed.h"
prussell 0:aa7314f3fa84 35 #include "BLEDevice.h"
prussell 0:aa7314f3fa84 36
prussell 0:aa7314f3fa84 37 #include "DFUService.h"
prussell 0:aa7314f3fa84 38 #include "UARTService.h"
prussell 0:aa7314f3fa84 39 #include "DeviceInformationService.h"
prussell 0:aa7314f3fa84 40
prussell 3:3651f1a58d9e 41 //============================== Process PCB Options:
prussell 3:3651f1a58d9e 42 #if D_PCB==D_MKIT
prussell 3:3651f1a58d9e 43 const char *pcDeviceName = "FOTA4.3.m";
prussell 3:3651f1a58d9e 44 const char *pcPingBLE = "m4\n"; // Need "\n" for BLE to Tx (and possibly so as not to block FOTA DFU).
prussell 3:3651f1a58d9e 45 const char *pcPingUART = "u4\n";
prussell 3:3651f1a58d9e 46 #define D_ALTBUTTONLED 0 // Use Default
prussell 3:3651f1a58d9e 47 #define D_USBDEBUG 1 // Use USB Serial
prussell 3:3651f1a58d9e 48 #elif D_PCB==D_EK
prussell 3:3651f1a58d9e 49 const char *pcDeviceName = "FOTA4.3.e";
prussell 3:3651f1a58d9e 50 const char *pcPingBLE = "e4\n"; // Need "\n" for BLE to Tx (and possibly so as not to block FOTA DFU).
prussell 3:3651f1a58d9e 51 #define D_ALTBUTTONLED 0 // Use Default
prussell 3:3651f1a58d9e 52 #define D_USBDEBUG 0 // No USB Serial
prussell 3:3651f1a58d9e 53 #elif D_PCB==D_BEACON
prussell 3:3651f1a58d9e 54 const char *pcDeviceName = "FOTA4.3.b";
prussell 3:3651f1a58d9e 55 const char *pcPingBLE = "b4\n"; // Need "\n" for BLE to Tx (and possibly so as not to block FOTA DFU).
prussell 3:3651f1a58d9e 56 #define D_ALTBUTTONLED 1 // Use Alternate
prussell 3:3651f1a58d9e 57 #define D_USBDEBUG 0 // No USB Serial
prussell 3:3651f1a58d9e 58 #else
prussell 3:3651f1a58d9e 59 #error Unknown PCB
prussell 3:3651f1a58d9e 60 #endif
prussell 0:aa7314f3fa84 61
prussell 3:3651f1a58d9e 62 //============================== Debug: BLE vs USBSerial
prussell 3:3651f1a58d9e 63 #if D_USBDEBUG
prussell 3:3651f1a58d9e 64 #define DEBUG(...) { printf(__VA_ARGS__); } // Debug OK over BLE and USB
prussell 3:3651f1a58d9e 65 #else
prussell 3:3651f1a58d9e 66 //#define DEBUG(...) { if(!ble.getGapState().connected){ printf(__VA_ARGS__); } } // Debug Only if BLE Connected *20150123: Not Available: uartService.retargetStdout()
prussell 3:3651f1a58d9e 67 #define DEBUG(...) /* nothing */
prussell 3:3651f1a58d9e 68 //TODO: sprintf and output length limited string over BLE without using uartService.retargetStdout()?
prussell 3:3651f1a58d9e 69 #endif /* #if D_USBDEBUG */
prussell 0:aa7314f3fa84 70
prussell 3:3651f1a58d9e 71 //============================== IO
prussell 0:aa7314f3fa84 72 BLEDevice ble;
prussell 0:aa7314f3fa84 73 UARTService *uartServicePtr;
prussell 0:aa7314f3fa84 74
prussell 3:3651f1a58d9e 75 #if D_ALTBUTTONLED //nRFBeacon
prussell 3:3651f1a58d9e 76 #define D_LED_LO 1 // LEDs Active Lo
prussell 3:3651f1a58d9e 77 #define D_BUTTON_LO 1 // Buttons Active Lo
prussell 3:3651f1a58d9e 78 //UART: p0.08~p0.11 // Careful of mkit UART output clashing
prussell 3:3651f1a58d9e 79 DigitalIn bB1in(p8); //nRF51822p0.08 SW1 == Clashes with USBSerial
prussell 3:3651f1a58d9e 80 DigitalIn bB2in(p18); //nRF51822p0.18 SW2
prussell 3:3651f1a58d9e 81 InterruptIn B1int(p8); //nRF51822p0.08 //B1int.rise(&onB1rise); == Clashes with USBSerial
prussell 3:3651f1a58d9e 82 InterruptIn B2int(p18); //nRF51822p0.18 //B1int.fall(&onB1fall);
prussell 3:3651f1a58d9e 83 DigitalOut bL1out(p16); // Direct LEDR drive
prussell 3:3651f1a58d9e 84 DigitalOut bL2out(p12); // Direct LEDG drive
prussell 3:3651f1a58d9e 85 //DigitalOut bL2out(p15); // Direct LEDB drive
prussell 3:3651f1a58d9e 86 //PwmOut fL0pwm(p16); float fL0level = 0.1; // PWM LED1, brightness=float(0.0~1.0)
prussell 3:3651f1a58d9e 87 //PwmOut fL1pwm(p12); float fL1level = 0.1; // PWM LED2, brightness=float(0.0~1.0)
prussell 3:3651f1a58d9e 88 //PwmOut fL2pwm(p15); float fL2level = 0.1; // PWM LED2, brightness=float(0.0~1.0)
prussell 3:3651f1a58d9e 89 //AnalogIn adcA(p1); // nRF51822p0.01==pin05==AIN2
prussell 3:3651f1a58d9e 90 //AnalogIn adcB(p2); // nRF51822p0.02==pin06==AIN3
prussell 3:3651f1a58d9e 91 #else //mkit,ek (Note in EK actually LED0/1 Button0/1)
prussell 3:3651f1a58d9e 92 #define D_LED_LO 0 // LEDs Active Hi
prussell 3:3651f1a58d9e 93 #define D_BUTTON_LO 1 // Buttons Active Lo
prussell 3:3651f1a58d9e 94 //UART: p0.08~p0.11
prussell 3:3651f1a58d9e 95 DigitalIn bB1in(BUTTON1); //nRF51822p0.16 //if(bB1in){} /
prussell 3:3651f1a58d9e 96 DigitalIn bB2in(BUTTON2); //nRF51822p0.17 //if(bB2in){}
prussell 3:3651f1a58d9e 97 InterruptIn B1int(BUTTON1); //nRF51822p0.16 //B1int.rise(&onB1rise);
prussell 3:3651f1a58d9e 98 InterruptIn B2int(BUTTON2); //nRF51822p0.17 //B1int.fall(&onB1fall);
prussell 3:3651f1a58d9e 99 DigitalOut bL1out(LED1); // Direct LED1 drive
prussell 3:3651f1a58d9e 100 DigitalOut bL2out(LED2); // Direct LED2 drive
prussell 3:3651f1a58d9e 101 //PwmOut fL1pwm(LED1); float fL1level = 0.1; // PWM LED1, brightness=float(0.0~1.0)
prussell 3:3651f1a58d9e 102 //PwmOut fL2pwm(LED2); float fL2level = 0.1; // PWM LED2, brightness=float(0.0~1.0)
prussell 3:3651f1a58d9e 103 //AnalogIn adcA(p1); // nRF51822p0.01==pin05==AIN2
prussell 3:3651f1a58d9e 104 //AnalogIn adcB(p2); // nRF51822p0.02==pin06==AIN3
prussell 3:3651f1a58d9e 105 #endif // Beacon or mkit/EK
prussell 0:aa7314f3fa84 106
prussell 3:3651f1a58d9e 107 //============================== Handle Button Activity
prussell 3:3651f1a58d9e 108 void onButton(void)
prussell 3:3651f1a58d9e 109 { // Handle any button changes
prussell 3:3651f1a58d9e 110 DEBUG("B\n");
prussell 3:3651f1a58d9e 111 //DEBUG("Button Activity!\n");
prussell 3:3651f1a58d9e 112 #if D_LED_LO //Active Lo
prussell 3:3651f1a58d9e 113 bL1out=bB1in; //Direct LED1=Button1 (Press=LED On), *Will be overridden on next Tick
prussell 3:3651f1a58d9e 114 bL2out=bB2in; //Direct LED2=Button2 (Press=LED On)
prussell 3:3651f1a58d9e 115 #else //LEDs Active Hi
prussell 3:3651f1a58d9e 116 bL1out=!bB1in; //Direct LED1=Button1 (Press=LED On), *Will be overridden on next Tick
prussell 3:3651f1a58d9e 117 bL2out=!bB2in; //Direct LED2=Button2 (Press=LED On)
prussell 3:3651f1a58d9e 118 #endif
prussell 3:3651f1a58d9e 119
prussell 3:3651f1a58d9e 120 };
prussell 3:3651f1a58d9e 121
prussell 3:3651f1a58d9e 122 //============================== Handle Ticker1
prussell 3:3651f1a58d9e 123 uint8_t uTicker1;
prussell 3:3651f1a58d9e 124 void onTicker1(void)
prussell 0:aa7314f3fa84 125 {
prussell 3:3651f1a58d9e 126 DEBUG(pcPingUART);
prussell 3:3651f1a58d9e 127 bL1out=((uTicker1++)&0x01); // Blink L1/Lgreen at Ticker Rate
prussell 0:aa7314f3fa84 128
prussell 3:3651f1a58d9e 129 if (uartServicePtr != NULL) {
prussell 3:3651f1a58d9e 130 ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), (const uint8_t *)pcPingBLE, strlen(pcPingBLE)); // BLE UART = Ping Message (Max 20char)
prussell 3:3651f1a58d9e 131 }
prussell 0:aa7314f3fa84 132 }
prussell 0:aa7314f3fa84 133
prussell 3:3651f1a58d9e 134 //============================== Handle BLE: Disconnect, Written...
prussell 3:3651f1a58d9e 135 void onDisconnect(Gap::Handle_t tHandle, Gap::DisconnectionReason_t eReason)
prussell 0:aa7314f3fa84 136 {
prussell 3:3651f1a58d9e 137 // When BLE Disconnected mkit may output over long DEBUG over USB Serial (Careful of IO clash on other PCBs)
prussell 3:3651f1a58d9e 138 DEBUG("\nBLEi: Callback_BLE_Disconnect(Handle:%d, eReason:0x%02x=", tHandle, eReason );//PR: Occurs properly when click disconnect in App nRFToolbox:HRM
prussell 3:3651f1a58d9e 139 switch(eReason) {
prussell 3:3651f1a58d9e 140 case Gap::REMOTE_USER_TERMINATED_CONNECTION: DEBUG("REMOTE_USER_TERMINATED_CONNECTION"); break;
prussell 3:3651f1a58d9e 141 case Gap::CONN_INTERVAL_UNACCEPTABLE: DEBUG("CONN_INTERVAL_UNACCEPTABLE"); break;
prussell 3:3651f1a58d9e 142 case Gap::LOCAL_HOST_TERMINATED_CONNECTION: DEBUG("LOCAL_HOST_TERMINATED_CONNECTION"); break;
prussell 3:3651f1a58d9e 143 default: DEBUG("UNKNOWN"); break;
prussell 3:3651f1a58d9e 144 }
prussell 3:3651f1a58d9e 145 DEBUG("), Restarting Advertising\n", tHandle, eReason );//PR: Occurs properly when click disconnect in App nRFToolbox:HRM
prussell 0:aa7314f3fa84 146 }
prussell 0:aa7314f3fa84 147
prussell 0:aa7314f3fa84 148 void onDataWritten(const GattCharacteristicWriteCBParams *params)
prussell 0:aa7314f3fa84 149 {
prussell 0:aa7314f3fa84 150 if ((uartServicePtr != NULL) && (params->charHandle == uartServicePtr->getTXCharacteristicHandle())) {
prussell 0:aa7314f3fa84 151 uint16_t bytesRead = params->len;
prussell 0:aa7314f3fa84 152 DEBUG("BLE-UART Echo Rx[%u]=[%*s]\n", bytesRead, params->len, params->data);
prussell 0:aa7314f3fa84 153 ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), params->data, bytesRead);
prussell 0:aa7314f3fa84 154 } else {
prussell 3:3651f1a58d9e 155 DEBUG("Unexpected Characteristic Write, Handle:%d\n", params->charHandle);
prussell 0:aa7314f3fa84 156 }
prussell 0:aa7314f3fa84 157 }
prussell 0:aa7314f3fa84 158
prussell 3:3651f1a58d9e 159 //==============================
prussell 0:aa7314f3fa84 160 int main(void)
prussell 0:aa7314f3fa84 161 {
prussell 3:3651f1a58d9e 162 Ticker ticker1;
prussell 3:3651f1a58d9e 163 ticker1.attach(onTicker1, D_PING_SEC); //Ping Rate
prussell 0:aa7314f3fa84 164
prussell 2:0931d94f42a2 165 DEBUG("BLE Init %s\n", pcDeviceName);
prussell 0:aa7314f3fa84 166 ble.init();
prussell 3:3651f1a58d9e 167 ble.onDisconnection(onDisconnect);
prussell 2:0931d94f42a2 168 ble.onDataWritten(onDataWritten);
prussell 0:aa7314f3fa84 169
prussell 0:aa7314f3fa84 170 ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
prussell 0:aa7314f3fa84 171 ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME, (const uint8_t *)pcDeviceName, strlen(pcDeviceName));
prussell 0:aa7314f3fa84 172
prussell 0:aa7314f3fa84 173 ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); /* needs to be connectable to allow use of DFUService */
prussell 3:3651f1a58d9e 174 //ble.setAdvertisingInterval(1600); /* 1s; in multiples of 0.625ms. */
prussell 3:3651f1a58d9e 175 ble.setAdvertisingInterval(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(1000)); //PR: Advertise 1sec (1Hz)
prussell 0:aa7314f3fa84 176 ble.startAdvertising();
prussell 0:aa7314f3fa84 177
prussell 0:aa7314f3fa84 178 DeviceInformationService deviceInfo(ble, "ARM", "Model1", "SN1000", "hw-rev1", "fw-rev1");
prussell 0:aa7314f3fa84 179
prussell 0:aa7314f3fa84 180 /* Enable over-the-air firmware updates. Instantiating DFUSservice introduces a
prussell 0:aa7314f3fa84 181 * control characteristic which can be used to trigger the application to
prussell 0:aa7314f3fa84 182 * handover control to a resident bootloader. */
prussell 0:aa7314f3fa84 183 DFUService dfu(ble);
prussell 0:aa7314f3fa84 184
prussell 3:3651f1a58d9e 185 /* Setup a BLE service for console output. Redirect stdout to BLE-UART(When connected). */
prussell 0:aa7314f3fa84 186 UARTService uartService(ble);
prussell 0:aa7314f3fa84 187 uartServicePtr = &uartService;
prussell 3:3651f1a58d9e 188 //uartService.retargetStdout(); // This isn't working with online libs BLE_API and nRF51822 updated 2015Jan23
prussell 3:3651f1a58d9e 189
prussell 3:3651f1a58d9e 190 DEBUG("mkit: LED2=[Follow Button2], LED1=[Blink on Ticker, and Follow Button1], BLE-UART=[Echo typing, and ping on Ticker]\n");
prussell 3:3651f1a58d9e 191 B1int.fall(&onButton); // Button1 Press/fall
prussell 3:3651f1a58d9e 192 B1int.rise(&onButton); // Button1 Release/rise
prussell 3:3651f1a58d9e 193 B2int.fall(&onButton); // Button2 Press/fall
prussell 3:3651f1a58d9e 194 B2int.rise(&onButton); // Button2 Release/rise
prussell 0:aa7314f3fa84 195
prussell 0:aa7314f3fa84 196 for (;;) {
prussell 0:aa7314f3fa84 197 ble.waitForEvent();
prussell 3:3651f1a58d9e 198 }
prussell 0:aa7314f3fa84 199 }
prussell 3:3651f1a58d9e 200 //========== end: main.cpp ==========
prussell 3:3651f1a58d9e 201