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
Diff: main.cpp
- Revision:
- 3:3651f1a58d9e
- Parent:
- 2:0931d94f42a2
- Child:
- 4:3a065a4e3ca6
--- a/main.cpp Sat Jan 24 01:34:23 2015 +0000 +++ b/main.cpp Mon Jan 26 14:54:24 2015 +0000 @@ -1,3 +1,6 @@ +//To load over FOTA set platform to "Nordic nRF51822 FOTA" and use DFU feature of App "nRF Master Control Panel" (Hex file <100K) +//To use normal mbed loading set platform to "Nordic nRF51822" and copy to mbed virtual disk (Hex File >250KB) + /* mbed Microcontroller Library * Copyright (c) 2006-2013 ARM Limited * @@ -14,6 +17,20 @@ * limitations under the License. */ +//============================== +// Build Options for D_PCB +#define D_MKIT 1 // mkit: USBSerial=OK, ButtonLED=m, LED2=Button2, LED1=Button1|Ticker +#define D_EK 2 // mkit: USBSerial=None, ButtonLED=m, LED1=Button1, LED0=Button0|Ticker +#define D_BEACON 3 // mkit: USBSerial=None, ButtonLED=b, LEDx=Buttonx, LEDy=Buttony|Ticker + +//============================== +// Compile Options: +#define D_PING_SEC 1 // Ping Rate in Seconds +#define D_PCB D_MKIT // Define the PCB to compile for +//#define D_PCB D_EK // Define the PCB to compile for +//#define D_PCB D_BEACON // Define the PCB to compile for + +//============================== #include "mbed.h" #include "BLEDevice.h" @@ -21,68 +38,141 @@ #include "UARTService.h" #include "DeviceInformationService.h" -#define NEED_CONSOLE_OUTPUT 1 /* Set this if you need debug messages on the console; - * it will have an impact on code-size and power consumption. */ +//============================== Process PCB Options: +#if D_PCB==D_MKIT + const char *pcDeviceName = "FOTA4.3.m"; + const char *pcPingBLE = "m4\n"; // Need "\n" for BLE to Tx (and possibly so as not to block FOTA DFU). + const char *pcPingUART = "u4\n"; + #define D_ALTBUTTONLED 0 // Use Default + #define D_USBDEBUG 1 // Use USB Serial +#elif D_PCB==D_EK + const char *pcDeviceName = "FOTA4.3.e"; + const char *pcPingBLE = "e4\n"; // Need "\n" for BLE to Tx (and possibly so as not to block FOTA DFU). + #define D_ALTBUTTONLED 0 // Use Default + #define D_USBDEBUG 0 // No USB Serial +#elif D_PCB==D_BEACON + const char *pcDeviceName = "FOTA4.3.b"; + const char *pcPingBLE = "b4\n"; // Need "\n" for BLE to Tx (and possibly so as not to block FOTA DFU). + #define D_ALTBUTTONLED 1 // Use Alternate + #define D_USBDEBUG 0 // No USB Serial +#else + #error Unknown PCB +#endif -#if NEED_CONSOLE_OUTPUT -#define DEBUG(...) { printf(__VA_ARGS__); } -#else -#define DEBUG(...) /* nothing */ -#endif /* #if NEED_CONSOLE_OUTPUT */ +//============================== Debug: BLE vs USBSerial +#if D_USBDEBUG + #define DEBUG(...) { printf(__VA_ARGS__); } // Debug OK over BLE and USB +#else + //#define DEBUG(...) { if(!ble.getGapState().connected){ printf(__VA_ARGS__); } } // Debug Only if BLE Connected *20150123: Not Available: uartService.retargetStdout() + #define DEBUG(...) /* nothing */ + //TODO: sprintf and output length limited string over BLE without using uartService.retargetStdout()? + #endif /* #if D_USBDEBUG */ +//============================== IO BLEDevice ble; UARTService *uartServicePtr; -//const char *deviceName = "DefaultApp"; -const char *pcDeviceName = "FOTA4.2"; -const char *pcPing = "f4\n"; // Need "\n" to for BLE to Tx. +#if D_ALTBUTTONLED //nRFBeacon +#define D_LED_LO 1 // LEDs Active Lo +#define D_BUTTON_LO 1 // Buttons Active Lo +//UART: p0.08~p0.11 // Careful of mkit UART output clashing +DigitalIn bB1in(p8); //nRF51822p0.08 SW1 == Clashes with USBSerial +DigitalIn bB2in(p18); //nRF51822p0.18 SW2 +InterruptIn B1int(p8); //nRF51822p0.08 //B1int.rise(&onB1rise); == Clashes with USBSerial +InterruptIn B2int(p18); //nRF51822p0.18 //B1int.fall(&onB1fall); +DigitalOut bL1out(p16); // Direct LEDR drive +DigitalOut bL2out(p12); // Direct LEDG drive +//DigitalOut bL2out(p15); // Direct LEDB drive +//PwmOut fL0pwm(p16); float fL0level = 0.1; // PWM LED1, brightness=float(0.0~1.0) +//PwmOut fL1pwm(p12); float fL1level = 0.1; // PWM LED2, brightness=float(0.0~1.0) +//PwmOut fL2pwm(p15); float fL2level = 0.1; // PWM LED2, brightness=float(0.0~1.0) +//AnalogIn adcA(p1); // nRF51822p0.01==pin05==AIN2 +//AnalogIn adcB(p2); // nRF51822p0.02==pin06==AIN3 +#else //mkit,ek (Note in EK actually LED0/1 Button0/1) +#define D_LED_LO 0 // LEDs Active Hi +#define D_BUTTON_LO 1 // Buttons Active Lo +//UART: p0.08~p0.11 +DigitalIn bB1in(BUTTON1); //nRF51822p0.16 //if(bB1in){} / +DigitalIn bB2in(BUTTON2); //nRF51822p0.17 //if(bB2in){} +InterruptIn B1int(BUTTON1); //nRF51822p0.16 //B1int.rise(&onB1rise); +InterruptIn B2int(BUTTON2); //nRF51822p0.17 //B1int.fall(&onB1fall); +DigitalOut bL1out(LED1); // Direct LED1 drive +DigitalOut bL2out(LED2); // Direct LED2 drive +//PwmOut fL1pwm(LED1); float fL1level = 0.1; // PWM LED1, brightness=float(0.0~1.0) +//PwmOut fL2pwm(LED2); float fL2level = 0.1; // PWM LED2, brightness=float(0.0~1.0) +//AnalogIn adcA(p1); // nRF51822p0.01==pin05==AIN2 +//AnalogIn adcB(p2); // nRF51822p0.02==pin06==AIN3 +#endif // Beacon or mkit/EK -void periodicCallback(void) +//============================== Handle Button Activity +void onButton(void) +{ // Handle any button changes + DEBUG("B\n"); + //DEBUG("Button Activity!\n"); +#if D_LED_LO //Active Lo + bL1out=bB1in; //Direct LED1=Button1 (Press=LED On), *Will be overridden on next Tick + bL2out=bB2in; //Direct LED2=Button2 (Press=LED On) +#else //LEDs Active Hi + bL1out=!bB1in; //Direct LED1=Button1 (Press=LED On), *Will be overridden on next Tick + bL2out=!bB2in; //Direct LED2=Button2 (Press=LED On) +#endif + +}; + +//============================== Handle Ticker1 +uint8_t uTicker1; +void onTicker1(void) { - //DEBUG("ping\r\n"); - DEBUG("p4\n"); + DEBUG(pcPingUART); + bL1out=((uTicker1++)&0x01); // Blink L1/Lgreen at Ticker Rate - ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), (const uint8_t *)pcPing, strlen(pcPing)); // BLE UART = Ping Message + if (uartServicePtr != NULL) { + ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), (const uint8_t *)pcPingBLE, strlen(pcPingBLE)); // BLE UART = Ping Message (Max 20char) + } } -void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason) +//============================== Handle BLE: Disconnect, Written... +void onDisconnect(Gap::Handle_t tHandle, Gap::DisconnectionReason_t eReason) { - //DEBUG("Disconnected!\n\r"); - DEBUG("Disconnected!\n"); - //DEBUG("Restarting the advertising process\n\r"); - DEBUG("Restart Advertising\n"); - ble.startAdvertising(); + // When BLE Disconnected mkit may output over long DEBUG over USB Serial (Careful of IO clash on other PCBs) + DEBUG("\nBLEi: Callback_BLE_Disconnect(Handle:%d, eReason:0x%02x=", tHandle, eReason );//PR: Occurs properly when click disconnect in App nRFToolbox:HRM + switch(eReason) { + case Gap::REMOTE_USER_TERMINATED_CONNECTION: DEBUG("REMOTE_USER_TERMINATED_CONNECTION"); break; + case Gap::CONN_INTERVAL_UNACCEPTABLE: DEBUG("CONN_INTERVAL_UNACCEPTABLE"); break; + case Gap::LOCAL_HOST_TERMINATED_CONNECTION: DEBUG("LOCAL_HOST_TERMINATED_CONNECTION"); break; + default: DEBUG("UNKNOWN"); break; + } + DEBUG("), Restarting Advertising\n", tHandle, eReason );//PR: Occurs properly when click disconnect in App nRFToolbox:HRM } void onDataWritten(const GattCharacteristicWriteCBParams *params) { - //if ((uartServicePtr != NULL) && (params->charHandle == uartServicePtr->txCharacteristic.getValueAttribute().getHandle())) if ((uartServicePtr != NULL) && (params->charHandle == uartServicePtr->getTXCharacteristicHandle())) { uint16_t bytesRead = params->len; DEBUG("BLE-UART Echo Rx[%u]=[%*s]\n", bytesRead, params->len, params->data); ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), params->data, bytesRead); } else { - DEBUG("Unknown Characteristic Written, Handle:%d\n", params->charHandle); + DEBUG("Unexpected Characteristic Write, Handle:%d\n", params->charHandle); } } +//============================== int main(void) { - Ticker ticker; - ticker.attach(periodicCallback, 1); + Ticker ticker1; + ticker1.attach(onTicker1, D_PING_SEC); //Ping Rate - //DEBUG("Initialising BTLE transport\n\r"); DEBUG("BLE Init %s\n", pcDeviceName); ble.init(); - ble.onDisconnection(disconnectionCallback); + ble.onDisconnection(onDisconnect); ble.onDataWritten(onDataWritten); ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); - //ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME, (const uint8_t *)deviceName, strlen(deviceName)); ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME, (const uint8_t *)pcDeviceName, strlen(pcDeviceName)); ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); /* needs to be connectable to allow use of DFUService */ - ble.setAdvertisingInterval(1600); /* 1s; in multiples of 0.625ms. */ + //ble.setAdvertisingInterval(1600); /* 1s; in multiples of 0.625ms. */ + ble.setAdvertisingInterval(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(1000)); //PR: Advertise 1sec (1Hz) ble.startAdvertising(); DeviceInformationService deviceInfo(ble, "ARM", "Model1", "SN1000", "hw-rev1", "fw-rev1"); @@ -92,12 +182,20 @@ * handover control to a resident bootloader. */ DFUService dfu(ble); - /* Setup a BLE service for console output. Redirect stdout to BLE-UART. */ + /* Setup a BLE service for console output. Redirect stdout to BLE-UART(When connected). */ UARTService uartService(ble); uartServicePtr = &uartService; - // uartService.retargetStdout(); //PR: Doesn't work with online libs BLE_API and nRF51822 updated 2015Jan23 + //uartService.retargetStdout(); // This isn't working with online libs BLE_API and nRF51822 updated 2015Jan23 + + DEBUG("mkit: LED2=[Follow Button2], LED1=[Blink on Ticker, and Follow Button1], BLE-UART=[Echo typing, and ping on Ticker]\n"); + B1int.fall(&onButton); // Button1 Press/fall + B1int.rise(&onButton); // Button1 Release/rise + B2int.fall(&onButton); // Button2 Press/fall + B2int.rise(&onButton); // Button2 Release/rise for (;;) { ble.waitForEvent(); - } + } } +//========== end: main.cpp ========== +