This code shows a problem that occurs when a Ticker is used on the nrf51822 along with a BLEDevice. The ticker hangs after a while if the timeout is short enough (around 1ms or less, with 2ms or more being OK). The same ticker works fine if no BLE device is created. The bug was confirmed on both a Nordic nRF51-Dongle and a RedBearLab BLE Nano using the latest BLE_API, mbed-src and nRF51822 libraries as of Jan 3rd 2015.

Dependencies:   BLE_API mbed-src nRF51822

Revision:
0:9e78d3dbb29d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun Jan 04 17:10:18 2015 +0000
@@ -0,0 +1,112 @@
+//==============================================================================
+// This code shows a problem that occurs when a Ticker is used on the nrf51822
+// along with a BLEDevice. The ticker hangs after a while if the timeout is
+// short enough (around 1ms or less, with 2ms or more being OK). The same ticker
+// works fine if no BLE device is created. The bug was confirmed on both a
+// Nordic nRF51-Dongle and a RedBearLab BLE Nano using the latest BLE_API,
+// mbed-src and nRF51822 libraries as of Jan 3rd 2015.
+//==============================================================================
+// My unconfirmed wild guess is that the bug may be somewhere in
+// mbed-src/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/Lib/app_common/app_timer.c
+// and may be triggered by the BLE stack interrupts delaying the Ticker beyond
+// its next timeout.
+//==============================================================================
+// This code blinks the onboard LED 5 times per second via a 1ms ticker that
+// switches the LED state once every 100 invocations.
+// When BLE support is enabled, the LED blinks a few times and then stops.
+// When BLE support is disabled, the LED keeps blinking forever.
+//==============================================================================
+// Set this to 1 to enable BLE support and trigger the Ticker bug, or 0 to fix
+
+#define ENABLE_BLE_AND_BUG 1
+
+//==============================================================================
+
+#include "mbed.h"
+#include "nrf_soc.h"
+#include "BLEDevice.h"
+
+//==============================================================================
+#if ENABLE_BLE_AND_BUG
+//==============================================================================
+
+#define BUFFER_LENGTH 20
+
+static const uint8_t uart_base_uuid[]       = {0x71, 0x3D, 0, 0, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
+static const uint8_t uart_tx_uuid[]         = {0x71, 0x3D, 0, 3, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
+static const uint8_t uart_rx_uuid[]         = {0x71, 0x3D, 0, 2, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
+static const uint8_t uart_base_uuid_rev[]   = {0x1E, 0x94, 0x8D, 0xF1, 0x48, 0x31, 0x94, 0xBA, 0x75, 0x4C, 0x3E, 0x50, 0, 0, 0x3D, 0x71};
+
+static uint8_t txPayload[BUFFER_LENGTH] = {0,};
+static uint8_t rxPayload[BUFFER_LENGTH] = {0,};
+
+GattCharacteristic  txCharacteristic(uart_tx_uuid, txPayload, 1, BUFFER_LENGTH, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE);
+GattCharacteristic  rxCharacteristic(uart_rx_uuid, rxPayload, 1, BUFFER_LENGTH, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
+GattCharacteristic  *uartChars[] = {&txCharacteristic, &rxCharacteristic};
+GattService         uartService(uart_base_uuid, uartChars, sizeof(uartChars) / sizeof(GattCharacteristic*));
+
+BLEDevice   ble;
+
+//==============================================================================
+
+static void handleDisconnect(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
+{
+    ble.startAdvertising();
+}
+
+//==============================================================================
+
+static void handleReceivedData(const GattCharacteristicWriteCBParams *Handler)
+{   
+    // we don't look at incoming data
+}
+
+//==============================================================================
+#endif // ENABLE_BLE_AND_BUG
+//==============================================================================
+
+Ticker      testTicker;
+DigitalOut  testLed(LED1);
+int         testLedState    = 0;
+uint32_t    testLedCount    = 0;
+
+//==============================================================================
+
+static void periodicTask(void)
+{
+    if(++testLedCount >= 100)
+    {
+        testLedCount = 0;
+        if(++testLedState > 1) testLedState = 0;
+        testLed = testLedState;
+    }
+}
+
+//==============================================================================
+
+int main(void)
+{
+#if ENABLE_BLE_AND_BUG
+    ble.init();
+    ble.onDisconnection(handleDisconnect);
+    ble.onDataWritten(handleReceivedData);  
+    ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
+    ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
+    ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME, (const uint8_t*)"Buggy", sizeof("Buggy") - 1);
+    ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, (const uint8_t *)uart_base_uuid_rev, 16);
+    ble.setAdvertisingInterval(160);
+    ble.addService(uartService);
+    ble.startAdvertising();
+#endif
+    
+    testTicker.attach_us(periodicTask, 1000);
+    
+    while(1)
+    {
+#if ENABLE_BLE_AND_BUG
+        ble.waitForEvent();
+#endif
+    }
+}
+
+//==============================================================================