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

Committer:
mbuddy
Date:
Sun Jan 04 17:10:18 2015 +0000
Revision:
0:9e78d3dbb29d
First version, published to show an issue with Tickers on the nRF51822.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbuddy 0:9e78d3dbb29d 1 //==============================================================================
mbuddy 0:9e78d3dbb29d 2 // This code shows a problem that occurs when a Ticker is used on the nrf51822
mbuddy 0:9e78d3dbb29d 3 // along with a BLEDevice. The ticker hangs after a while if the timeout is
mbuddy 0:9e78d3dbb29d 4 // short enough (around 1ms or less, with 2ms or more being OK). The same ticker
mbuddy 0:9e78d3dbb29d 5 // works fine if no BLE device is created. The bug was confirmed on both a
mbuddy 0:9e78d3dbb29d 6 // Nordic nRF51-Dongle and a RedBearLab BLE Nano using the latest BLE_API,
mbuddy 0:9e78d3dbb29d 7 // mbed-src and nRF51822 libraries as of Jan 3rd 2015.
mbuddy 0:9e78d3dbb29d 8 //==============================================================================
mbuddy 0:9e78d3dbb29d 9 // My unconfirmed wild guess is that the bug may be somewhere in
mbuddy 0:9e78d3dbb29d 10 // mbed-src/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/Lib/app_common/app_timer.c
mbuddy 0:9e78d3dbb29d 11 // and may be triggered by the BLE stack interrupts delaying the Ticker beyond
mbuddy 0:9e78d3dbb29d 12 // its next timeout.
mbuddy 0:9e78d3dbb29d 13 //==============================================================================
mbuddy 0:9e78d3dbb29d 14 // This code blinks the onboard LED 5 times per second via a 1ms ticker that
mbuddy 0:9e78d3dbb29d 15 // switches the LED state once every 100 invocations.
mbuddy 0:9e78d3dbb29d 16 // When BLE support is enabled, the LED blinks a few times and then stops.
mbuddy 0:9e78d3dbb29d 17 // When BLE support is disabled, the LED keeps blinking forever.
mbuddy 0:9e78d3dbb29d 18 //==============================================================================
mbuddy 0:9e78d3dbb29d 19 // Set this to 1 to enable BLE support and trigger the Ticker bug, or 0 to fix
mbuddy 0:9e78d3dbb29d 20
mbuddy 0:9e78d3dbb29d 21 #define ENABLE_BLE_AND_BUG 1
mbuddy 0:9e78d3dbb29d 22
mbuddy 0:9e78d3dbb29d 23 //==============================================================================
mbuddy 0:9e78d3dbb29d 24
mbuddy 0:9e78d3dbb29d 25 #include "mbed.h"
mbuddy 0:9e78d3dbb29d 26 #include "nrf_soc.h"
mbuddy 0:9e78d3dbb29d 27 #include "BLEDevice.h"
mbuddy 0:9e78d3dbb29d 28
mbuddy 0:9e78d3dbb29d 29 //==============================================================================
mbuddy 0:9e78d3dbb29d 30 #if ENABLE_BLE_AND_BUG
mbuddy 0:9e78d3dbb29d 31 //==============================================================================
mbuddy 0:9e78d3dbb29d 32
mbuddy 0:9e78d3dbb29d 33 #define BUFFER_LENGTH 20
mbuddy 0:9e78d3dbb29d 34
mbuddy 0:9e78d3dbb29d 35 static const uint8_t uart_base_uuid[] = {0x71, 0x3D, 0, 0, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
mbuddy 0:9e78d3dbb29d 36 static const uint8_t uart_tx_uuid[] = {0x71, 0x3D, 0, 3, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
mbuddy 0:9e78d3dbb29d 37 static const uint8_t uart_rx_uuid[] = {0x71, 0x3D, 0, 2, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
mbuddy 0:9e78d3dbb29d 38 static const uint8_t uart_base_uuid_rev[] = {0x1E, 0x94, 0x8D, 0xF1, 0x48, 0x31, 0x94, 0xBA, 0x75, 0x4C, 0x3E, 0x50, 0, 0, 0x3D, 0x71};
mbuddy 0:9e78d3dbb29d 39
mbuddy 0:9e78d3dbb29d 40 static uint8_t txPayload[BUFFER_LENGTH] = {0,};
mbuddy 0:9e78d3dbb29d 41 static uint8_t rxPayload[BUFFER_LENGTH] = {0,};
mbuddy 0:9e78d3dbb29d 42
mbuddy 0:9e78d3dbb29d 43 GattCharacteristic txCharacteristic(uart_tx_uuid, txPayload, 1, BUFFER_LENGTH, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE);
mbuddy 0:9e78d3dbb29d 44 GattCharacteristic rxCharacteristic(uart_rx_uuid, rxPayload, 1, BUFFER_LENGTH, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
mbuddy 0:9e78d3dbb29d 45 GattCharacteristic *uartChars[] = {&txCharacteristic, &rxCharacteristic};
mbuddy 0:9e78d3dbb29d 46 GattService uartService(uart_base_uuid, uartChars, sizeof(uartChars) / sizeof(GattCharacteristic*));
mbuddy 0:9e78d3dbb29d 47
mbuddy 0:9e78d3dbb29d 48 BLEDevice ble;
mbuddy 0:9e78d3dbb29d 49
mbuddy 0:9e78d3dbb29d 50 //==============================================================================
mbuddy 0:9e78d3dbb29d 51
mbuddy 0:9e78d3dbb29d 52 static void handleDisconnect(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
mbuddy 0:9e78d3dbb29d 53 {
mbuddy 0:9e78d3dbb29d 54 ble.startAdvertising();
mbuddy 0:9e78d3dbb29d 55 }
mbuddy 0:9e78d3dbb29d 56
mbuddy 0:9e78d3dbb29d 57 //==============================================================================
mbuddy 0:9e78d3dbb29d 58
mbuddy 0:9e78d3dbb29d 59 static void handleReceivedData(const GattCharacteristicWriteCBParams *Handler)
mbuddy 0:9e78d3dbb29d 60 {
mbuddy 0:9e78d3dbb29d 61 // we don't look at incoming data
mbuddy 0:9e78d3dbb29d 62 }
mbuddy 0:9e78d3dbb29d 63
mbuddy 0:9e78d3dbb29d 64 //==============================================================================
mbuddy 0:9e78d3dbb29d 65 #endif // ENABLE_BLE_AND_BUG
mbuddy 0:9e78d3dbb29d 66 //==============================================================================
mbuddy 0:9e78d3dbb29d 67
mbuddy 0:9e78d3dbb29d 68 Ticker testTicker;
mbuddy 0:9e78d3dbb29d 69 DigitalOut testLed(LED1);
mbuddy 0:9e78d3dbb29d 70 int testLedState = 0;
mbuddy 0:9e78d3dbb29d 71 uint32_t testLedCount = 0;
mbuddy 0:9e78d3dbb29d 72
mbuddy 0:9e78d3dbb29d 73 //==============================================================================
mbuddy 0:9e78d3dbb29d 74
mbuddy 0:9e78d3dbb29d 75 static void periodicTask(void)
mbuddy 0:9e78d3dbb29d 76 {
mbuddy 0:9e78d3dbb29d 77 if(++testLedCount >= 100)
mbuddy 0:9e78d3dbb29d 78 {
mbuddy 0:9e78d3dbb29d 79 testLedCount = 0;
mbuddy 0:9e78d3dbb29d 80 if(++testLedState > 1) testLedState = 0;
mbuddy 0:9e78d3dbb29d 81 testLed = testLedState;
mbuddy 0:9e78d3dbb29d 82 }
mbuddy 0:9e78d3dbb29d 83 }
mbuddy 0:9e78d3dbb29d 84
mbuddy 0:9e78d3dbb29d 85 //==============================================================================
mbuddy 0:9e78d3dbb29d 86
mbuddy 0:9e78d3dbb29d 87 int main(void)
mbuddy 0:9e78d3dbb29d 88 {
mbuddy 0:9e78d3dbb29d 89 #if ENABLE_BLE_AND_BUG
mbuddy 0:9e78d3dbb29d 90 ble.init();
mbuddy 0:9e78d3dbb29d 91 ble.onDisconnection(handleDisconnect);
mbuddy 0:9e78d3dbb29d 92 ble.onDataWritten(handleReceivedData);
mbuddy 0:9e78d3dbb29d 93 ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
mbuddy 0:9e78d3dbb29d 94 ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
mbuddy 0:9e78d3dbb29d 95 ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME, (const uint8_t*)"Buggy", sizeof("Buggy") - 1);
mbuddy 0:9e78d3dbb29d 96 ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, (const uint8_t *)uart_base_uuid_rev, 16);
mbuddy 0:9e78d3dbb29d 97 ble.setAdvertisingInterval(160);
mbuddy 0:9e78d3dbb29d 98 ble.addService(uartService);
mbuddy 0:9e78d3dbb29d 99 ble.startAdvertising();
mbuddy 0:9e78d3dbb29d 100 #endif
mbuddy 0:9e78d3dbb29d 101
mbuddy 0:9e78d3dbb29d 102 testTicker.attach_us(periodicTask, 1000);
mbuddy 0:9e78d3dbb29d 103
mbuddy 0:9e78d3dbb29d 104 while(1)
mbuddy 0:9e78d3dbb29d 105 {
mbuddy 0:9e78d3dbb29d 106 #if ENABLE_BLE_AND_BUG
mbuddy 0:9e78d3dbb29d 107 ble.waitForEvent();
mbuddy 0:9e78d3dbb29d 108 #endif
mbuddy 0:9e78d3dbb29d 109 }
mbuddy 0:9e78d3dbb29d 110 }
mbuddy 0:9e78d3dbb29d 111
mbuddy 0:9e78d3dbb29d 112 //==============================================================================