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
Revision:
4:3a065a4e3ca6
Parent:
3:3651f1a58d9e
Child:
5:ac98ff227ad7
--- a/main.cpp	Mon Jan 26 14:54:24 2015 +0000
+++ b/main.cpp	Fri Jan 30 01:44:15 2015 +0000
@@ -1,8 +1,8 @@
 //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)
+//To use normal mbed loading set platform to "Nordic nRF51822" and copy to mbed drive (Hex File >250KB)
 
 /* mbed Microcontroller Library
- * Copyright (c) 2006-2013 ARM Limited
+ * Copyright (c) 2006-2015 Paul Russell
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,104 +19,135 @@
 
 //==============================
 // 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 
-
+#define D_MKIT      1  // nRF51822-mkit   
+#define D_EK        2  // nRF51822-EK 
+#define D_BEACON    3  // nRF51822-Beacon 
+#define D_ATOMWEAR  4  // Atomwear  
 //==============================
 // 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
+#define D_BLE_UART      0       // Include BLE UART functionality? (20150129: There may be a clash between BLE_UART and FOTA)
+#define D_PING_SEC      9//1       // Ping Rate in Seconds
+
+#define D_PCB    D_MKIT         // Select target PCB
+//#define D_PCB    D_EK           // Select target PCB
+//#define D_PCB    D_BEACON       // Select target PCB
+//#define D_PCB    D_ATOMWEAR     // Select target PCB
 
 //==============================
 #include "mbed.h"
 #include "BLEDevice.h"
 
-#include "DFUService.h"
-#include "UARTService.h"
-#include "DeviceInformationService.h"
-
 //============================== 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
+    const char *pcDeviceName    = "FOTA4r4m";
+    const char *pcPingBLE       = "m4\n";       // May need "\n" to push BLE Tx
+    const char *pcPingUART      = "u4\n";
+
+    #define DEBUG(...) { printf(__VA_ARGS__); } //UART: p0.08~p0.11, Debug OK over USB Serial
+    DigitalIn       bB1in(BUTTON1);             //p0.16 =Button1
+    DigitalIn       bB2in(BUTTON2);             //p0.17 =Button2
+    InterruptIn     B1int(BUTTON1);             //p0.16 =Button1
+    InterruptIn     B2int(BUTTON2);             //p0.17 =Button2
+    DigitalOut      bL1out(LED1);               //p0.18 =LED1
+    DigitalOut      bL2out(LED2);               //p0.19 =LED2
+    //PwmOut fL1pwm(LED1); float fL1level = 0.1;//p0.18 =LED1, BrightnessFloat(0.0~1.0)
+    //PwmOut fL2pwm(LED2); float fL2level = 0.1;//p0.19 =LED2, BrightnessFloat(0.0~1.0)
+    //AnalogIn      adcA(p1);                   //p0.01 =AIN2
+    //AnalogIn      adcB(p2);                   //p0.02 =AIN3
+
+    #define D_0_LED_TICKER    { bL1out=((uTicker1++)&0x01);}    // LED Follows Ticker (May also follow a button)
+    #define D_1_LED_BUTTON    { bL1out = !bB1in;}               // LED Follows !Button
+    #define D_2_LED_BUTTON    { bL2out = !bB2in;}               // LED Follows !Button
+    #define D_OPERATION_LED   "mkit: LED1=Ticker+Button1, LED2=Button2"
+ 
 #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
+    const char *pcDeviceName = "FOTA4r4e";
+    const char *pcPingBLE  = "e4\n";            // May need "\n" to push BLE Tx
+
+    #define DEBUG(...) {}                       //Serial Debug not connected 
+    DigitalIn       bB1in(BUTTON1);             //p0.16 =Button0
+    DigitalIn       bB2in(BUTTON2);             //p0.17 =Button1
+    InterruptIn     B1int(BUTTON1);             //p0.16 =Button0
+    InterruptIn     B2int(BUTTON2);             //p0.17 =Button1
+    DigitalOut      bL1out(LED1);               //p0.18 =LED0
+    DigitalOut      bL2out(LED2);               //p0.19 =LED1
+    //PwmOut fL1pwm(LED1); float fL1level = 0.1;//p0.18 =LED0, BrightnessFloat(0.0~1.0)
+    //PwmOut fL2pwm(LED2); float fL2level = 0.1;//p0.19 =LED1, BrightnessFloat(0.0~1.0)
+    //AnalogIn      adcA(p1);                   //p0.01 =AIN2
+    //AnalogIn      adcB(p2);                   //p0.02 =AIN3
+  
+    #define D_0_LED_TICKER    { bL1out=((uTicker1++)&0x01);}    // LED Follows Ticker (May also follow a button)
+    #define D_1_LED_BUTTON    { bL1out = !bB1in;}               // LED Follows !Button
+    #define D_2_LED_BUTTON    { bL2out = !bB2in;}               // LED Follows !Button
+    #define D_OPERATION_LED   "EK: LED0=Ticker+Button0, LED1=Button1"
+
+ #elif D_PCB==D_BEACON
+    const char *pcDeviceName = "FOTA4r4b";
+    const char *pcPingBLE  = "b4\n";            // May need "\n" to push BLE Tx
+ 
+    #define DEBUG(...) {}                       //Serial Debug not connected 
+    DigitalIn       bB1in(p8);                  //p0.08 =SW1
+    DigitalIn       bB2in(p18);                 //p0.18 =SW2
+    InterruptIn     B1int(p8);                  //p0.08 =SW1
+    InterruptIn     B2int(p18);                 //p0.18 =SW2
+    DigitalOut      bLRout(p16);                //p0.16 =LEDR
+    DigitalOut      bLGout(p12);                //p0.12 =LEDG
+    DigitalOut      bLBout(p15);                //p0.15 =LEDB
+    //PwmOut fLRpwm(p16); float fLRlevel = 0.1; //p0.16 =LEDR, BrightnessFloat(0.0~1.0)
+    //PwmOut fLGpwm(p12); float fLGlevel = 0.1; //p0.12 =LEDG, BrightnessFloat(0.0~1.0)
+    //PwmOut fLBpwm(p15); float fLBlevel = 0.1; //p0.15 =LEDB, BrightnessFloat(0.0~1.0)
+    //AnalogIn      adcA(p1);                   //p0.01 =AIN2
+    //AnalogIn      adcB(p2);                   //p0.02 =AIN3
+
+    #define D_0_LED_TICKER    { bLRout=((uTicker1++)&0x01);}    // LED Follows Ticker (May also follow a button)
+    #define D_1_LED_BUTTON    { bLGout = bB1in;}                // LED Follows Button
+    #define D_2_LED_BUTTON    { bLBout = bB2in;}                // LED Follows Button
+    #define D_OPERATION_LED   "Beacon: RED=Ticker, Green=SW1, Blue=SW2"
+  
+#elif D_PCB==D_ATOMWEAR     //  USBSerial=None, ButtonLED=atomwear, LEDx=Buttonx, LEDw=Buttony|Ticker
+    const char *pcDeviceName = "FOTA4r4a";
+    const char *pcPingBLE  = "a\n";            // May need "\n" to push BLE Tx
+ 
+    #define DEBUG(...) {}                       //Serial Debug not connected 
+    DigitalIn       bB1in(p29);                 //p0.29 =S1
+    InterruptIn     B1int(p29);                 //p0.29 =S1
+    DigitalOut      bLBout(p17);                //p0.17 =LEDB
+    DigitalOut      bLWout(p18);                //p0.18 =LEDW
+    //PwmOut fLBpwm(p17); float fLBlevel = 0.1; //p0.17 =LEDB, BrightnessFloat(0.0~1.0)
+    //PwmOut fLWpwm(p18); float fLWlevel = 0.1; //p0.18 =LEDW, BrightnessFloat(0.0~1.0)
+    //AnalogIn      adcA(p1);                   //p0.01 =AIN2
+    //AnalogIn      adcB(p2);                   //p0.02 =AIN3
+
+    #define D_0_LED_TICKER    { bLBout=((uTicker1++)&0x01);}    // LED Follows Ticker (May also follow a button)
+    #define D_1_LED_BUTTON    { bLWout = bB1in;}                // LED Follows Button
+    #define D_OPERATION_LED   "Atomwear: Blue=Ticker, White=S1"
+
 #else
     #error Unknown PCB
 #endif
 
-//============================== 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
+//============================== BLE
 BLEDevice ble;
-UARTService *uartServicePtr;
+#if D_BLE_UART==1
+    #include "UARTService.h"
+    UARTService *uartServicePtr;
+    #define D_OPERATION_BLE     ", BLE-UART=[Echo typing, and ping on Ticker]\n"
+#else
+    #define D_OPERATION_BLE     ", BLE-UART not enabled\n"
+#endif
 
-#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
+#include "DeviceInformationService.h"
+//? #include "DFUService.h"   //Required if "DFUService dfu(ble)" is explicitely declared
 
 //============================== 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)
+
+    D_1_LED_BUTTON; // Update LED from Button
+#ifdef D_2_LED_BUTTON
+    D_2_LED_BUTTON; // Update LED from Button
 #endif
-
 };
 
 //============================== Handle Ticker1
@@ -124,11 +155,13 @@
 void onTicker1(void) 
 {
     DEBUG(pcPingUART);
-    bL1out=((uTicker1++)&0x01);    // Blink L1/Lgreen at Ticker Rate
+    D_0_LED_TICKER; // Update LED from Ticker
 
+#if D_BLE_UART==1
     if (uartServicePtr != NULL) { 
         ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), (const uint8_t *)pcPingBLE, strlen(pcPingBLE)); // BLE UART = Ping Message (Max 20char)
     }
+#endif
 }
 
 //============================== Handle BLE: Disconnect, Written...
@@ -147,6 +180,7 @@
 
 void onDataWritten(const GattCharacteristicWriteCBParams *params)
 {
+#if D_BLE_UART==1
     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);
@@ -154,6 +188,9 @@
     } else {
         DEBUG("Unexpected Characteristic Write, Handle:%d\n", params->charHandle);
     }
+#else
+        DEBUG("Unexpected Characteristic Write, Handle:%d\n", params->charHandle);
+#endif
 }
 
 //==============================
@@ -175,24 +212,23 @@
     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");
+    //DeviceInformationService deviceInfo(ble, "ARM", "Model1", "SN1000", "hw-rev1", "fw-rev1");
+    DeviceInformationService deviceInfo(ble, "ARM", pcDeviceName, "SN1000", "hw-rev1", "fw-rev1");
 
-    /* Enable over-the-air firmware updates. Instantiating DFUSservice introduces a
-     * control characteristic which can be used to trigger the application to
-     * handover control to a resident bootloader. */
-    DFUService dfu(ble);
+    //Enable FOTA DFU
+//?    DFUService dfu(ble); // Included implicitely by ble.init() for FOTA platforms, but doing explicitly may be desired for some cases
 
-    /* Setup a BLE service for console output. Redirect stdout to BLE-UART(When connected). */
-    UARTService uartService(ble);
+#if D_BLE_UART==1
+#error BLE_UART
+    UARTService uartService(ble);   //Setup BLE UART
     uartServicePtr = &uartService;
-    //uartService.retargetStdout(); // This isn't working with online libs BLE_API and nRF51822 updated 2015Jan23
+#endif
 
-    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
-
+    DEBUG(D_OPERATION_LED D_OPERATION_BLE);
+    B1int.fall(&onButton); B1int.rise(&onButton); // Button1
+#ifdef D_2_LED_BUTTON
+    B2int.fall(&onButton); B2int.rise(&onButton); // Button2
+#endif
     for (;;) {
         ble.waitForEvent();
    }