High level Bluetooth Low Energy API and radio abstraction layer
Fork of BLE_API by
Revision 15:327d7329072c, committed 2013-12-18
- Comitter:
- ktownsend
- Date:
- Wed Dec 18 12:07:38 2013 +0000
- Parent:
- 14:6ea5d1012a64
- Child:
- 16:542a9db01350
- Commit message:
- Cleanup for GAP publication (iBeacon working)
Changed in this revision
hw/nrf51822.cpp | Show annotated file Show diff for this revision Revisions of this file |
main.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- a/hw/nrf51822.cpp Wed Dec 18 11:52:37 2013 +0000 +++ b/hw/nrf51822.cpp Wed Dec 18 12:07:38 2013 +0000 @@ -1,9 +1,6 @@ #include "nrf51822.h" #include "mbed.h" -/* Enables debug output over USB CDC at 9600 bps */ -#define NRF51822_DEBUG_MODE (1) - /**************************************************************************/ /*! @brief UART callback function @@ -14,11 +11,7 @@ /* ToDo: Check responses and set a flag for success/error/etc. */ /* Read serial to clear the RX interrupt */ - #if NRF51822_DEBUG_MODE - printf("%c", uart.getc()); - #else uart.getc(); - #endif } /**************************************************************************/ @@ -92,39 +85,35 @@ uint8_t len = 0; uint8_t *buffer; - #if NRF51822_DEBUG_MODE - printf("%-40s", "Configuring Advertising"); - #endif - /* Make sure we support the advertising type */ if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) { - #if NRF51822_DEBUG_MODE - printf("[BLE_ERROR = 0x%04X]\r\n", (uint16_t)BLE_ERROR_NOT_IMPLEMENTED); - printf("--> ADV_CONNECTABLE_DIRECTED not supported\r\n"); - #endif return BLE_ERROR_NOT_IMPLEMENTED; } /* Check interval range */ - if ((params.getInterval() < GAP_ADV_PARAMS_INTERVAL_MIN) || - (params.getInterval() > GAP_ADV_PARAMS_INTERVAL_MAX)) + if (params.getAdvertisingType() == GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED) { - #if NRF51822_DEBUG_MODE - printf("[BLE_ERROR = 0x%04X]\r\n", (uint16_t)BLE_ERROR_PARAM_OUT_OF_RANGE); - printf("--> Advertising interval out of range\r\n"); - #endif - return BLE_ERROR_PARAM_OUT_OF_RANGE; + /* Min delay is slightly longer for unconnectable devices */ + if ((params.getInterval() < GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) || + (params.getInterval() > GAP_ADV_PARAMS_INTERVAL_MAX)) + { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + } + else + { + if ((params.getInterval() < GAP_ADV_PARAMS_INTERVAL_MIN) || + (params.getInterval() > GAP_ADV_PARAMS_INTERVAL_MAX)) + { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } } /* Check timeout is zero for Connectable Directed */ if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && (params.getTimeout() != 0)) { - #if NRF51822_DEBUG_MODE - printf("[BLE_ERROR = 0x%04X]\r\n", (uint16_t)BLE_ERROR_PARAM_OUT_OF_RANGE); - printf("--> Timeout must be 0 with ADV_CONNECTABLE_DIRECTED\r\n"); - #endif /* Timeout must be 0 with this type, although we'll never get here */ /* since this isn't implemented yet anyway */ return BLE_ERROR_PARAM_OUT_OF_RANGE; @@ -134,20 +123,12 @@ if ((params.getAdvertisingType() != GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && (params.getTimeout() > GAP_ADV_PARAMS_TIMEOUT_MAX)) { - #if NRF51822_DEBUG_MODE - printf("[BLE_ERROR = 0x%04X]\r\n", (uint16_t)BLE_ERROR_PARAM_OUT_OF_RANGE); - printf("--> Timeout out of range\r\n"); - #endif return BLE_ERROR_PARAM_OUT_OF_RANGE; } /* Make sure we don't exceed the advertising payload length */ if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD) { - #if NRF51822_DEBUG_MODE - printf("[BLE_ERROR = 0x%04X]\r\n", (uint16_t)BLE_ERROR_BUFFER_OVERFLOW); - printf("--> Advertising payload > 31 bytes\r\n"); - #endif return BLE_ERROR_BUFFER_OVERFLOW; } @@ -156,10 +137,6 @@ { if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD) { - #if NRF51822_DEBUG_MODE - printf("[BLE_ERROR = 0x%04X]\r\n", (uint16_t)BLE_ERROR_BUFFER_OVERFLOW); - printf("--> Scan response payload > 31 bytes\r\n"); - #endif return BLE_ERROR_BUFFER_OVERFLOW; } } @@ -227,9 +204,6 @@ wait(0.1); } - #if NRF51822_DEBUG_MODE - printf("[OK]\r\n"); - #endif return BLE_ERROR_NONE; } @@ -251,10 +225,6 @@ /**************************************************************************/ ble_error_t nRF51822::addService(GattService & service) { - #if NRF51822_DEBUG_MODE - printf("%-40s", "Adding a service"); - #endif - /* ToDo: Make sure we don't overflow the array, etc. */ /* ToDo: Make sure this service UUID doesn't already exist (?) */ /* ToDo: Basic validation */ @@ -313,9 +283,6 @@ service.handle = serviceCount; serviceCount++; - #if NRF51822_DEBUG_MODE - printf("[OK]\r\n"); - #endif return BLE_ERROR_NONE; } @@ -348,15 +315,8 @@ /**************************************************************************/ ble_error_t nRF51822::readCharacteristic(GattService &service, GattCharacteristic &characteristic, uint8_t buffer[], uint16_t len) { - #if NRF51822_DEBUG_MODE - printf("Reading characteristic (handle = %d) ", characteristic.handle); - #endif - /* ToDo */ - #if NRF51822_DEBUG_MODE - printf("[OK]\r\n"); - #endif return BLE_ERROR_NONE; } @@ -389,10 +349,6 @@ /**************************************************************************/ ble_error_t nRF51822::writeCharacteristic(GattService &service, GattCharacteristic &characteristic, uint8_t buffer[], uint16_t len) { - #if NRF51822_DEBUG_MODE - printf("Writing characteristic (handle = %d) ", characteristic.handle); - #endif - /* Command ID = 0x0006, Payload = Service ID, Characteristic ID, Value */ uart.printf("10 06 00 %02X %02X %02X", len + 2, characteristic.handle, service.handle); for (uint16_t i = 0; i<len; i++) @@ -404,9 +360,6 @@ /* ToDo: Check response */ wait(0.1); - #if NRF51822_DEBUG_MODE - printf("[OK]\r\n"); - #endif return BLE_ERROR_NONE; } @@ -431,19 +384,12 @@ /**************************************************************************/ ble_error_t nRF51822::start(void) { - #if NRF51822_DEBUG_MODE - printf("%-40s", "Starting the radio"); - #endif - /* Command ID = 0x0003, No payload */ uart.printf("10 03 00 00\r\n"); /* ToDo: Check response */ wait(0.5); - #if NRF51822_DEBUG_MODE - printf("[OK]\r\n"); - #endif return BLE_ERROR_NONE; } @@ -465,19 +411,12 @@ /**************************************************************************/ ble_error_t nRF51822::stop(void) { - #if NRF51822_DEBUG_MODE - printf("%-40s", "Stopping the radio"); - #endif - /* Command ID = 0x0004, No payload */ uart.printf("10 04 00 00\r\n"); /* ToDo: Check response */ wait(0.1); - #if NRF51822_DEBUG_MODE - printf("[OK]\r\n"); - #endif return BLE_ERROR_NONE; } @@ -500,10 +439,6 @@ /**************************************************************************/ ble_error_t nRF51822::reset(void) { - #if NRF51822_DEBUG_MODE - printf("%-40s", "Resetting the radio"); - #endif - /* Command ID = 0x0005, No payload */ uart.printf("10 05 00 00\r\n"); @@ -513,8 +448,5 @@ /* Wait for the radio to come back up */ wait(1); - #if NRF51822_DEBUG_MODE - printf("[OK]\r\n"); - #endif return BLE_ERROR_NONE; }
--- a/main.cpp Wed Dec 18 11:52:37 2013 +0000 +++ b/main.cpp Wed Dec 18 12:07:38 2013 +0000 @@ -10,27 +10,12 @@ /* Radio HW abstraction layer */ nRF51822 radio; -/* Battery Level Service */ -/* See --> https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.battery_service.xml */ -GattService battService ( 0x180F ); -GattCharacteristic battLevel ( 0x2A19, 1, 1, BLE_GATT_CHAR_PROPERTIES_NOTIFY | BLE_GATT_CHAR_PROPERTIES_READ ); - /* Heart Rate Monitor Service */ /* See --> https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.heart_rate.xml */ GattService hrmService ( 0x180D ); GattCharacteristic hrmRate ( 0x2A37, 2, 3, BLE_GATT_CHAR_PROPERTIES_NOTIFY ); GattCharacteristic hrmLocation ( 0x2A39, 1, 1, BLE_GATT_CHAR_PROPERTIES_READ ); -/* Health Thermometer Service */ -/* See --> https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.health_thermometer.xml */ -GattService thermService ( 0x1809 ); -GattCharacteristic thermTemp ( 0x2A1C, 5, 13, BLE_GATT_CHAR_PROPERTIES_INDICATE ); -GattCharacteristic thermType ( 0x2A1D, 1, 1, BLE_GATT_CHAR_PROPERTIES_READ ); -GattCharacteristic thermInterval ( 0x2A21, 2, 2, BLE_GATT_CHAR_PROPERTIES_READ ); - -/* Notify = device (server) sends data when it changes */ -/* Indicate = device (server) sends data when it changes and client confirms reception */ - /* GAP Advertising Example (iBeacon) */ GapAdvertisingParams advParams ( GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED ); GapAdvertisingData advData; @@ -51,60 +36,29 @@ error = radio.start(); } -int main() +void startHRM(void) { - wait(2); - startBeacon(); - while(1); - - /* Add the battery level characteristic to the battery service */ - /* Note: This will also update the characteristic's .index field */ - /* so that we know where it's stored in the BLEService.characteristics */ - /* array. */ - battService.addCharacteristic(battLevel); + uint8_t hrmCounter = 100; /* Add the heart rate and sensor location chars to the HRM service */ hrmService.addCharacteristic(hrmRate); hrmService.addCharacteristic(hrmLocation); - - /* Add the Health Thermometer server characteristics */ - thermService.addCharacteristic(thermTemp); - thermService.addCharacteristic(thermType); - thermService.addCharacteristic(thermInterval); - + /* Reset the BLE hardware to make sure we get a clean start */ wait(2); radio.reset(); /* Add the services to the radio HAL */ - radio.addService(battService); radio.addService(hrmService); - radio.addService(thermService); /* Start the services so that we can start pushing data out */ radio.start(); - + /* Set the heart rate monitor location (one time only) */ /* See --> https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.body_sensor_location.xml */ uint8_t location = 0x01; /* Chest */ radio.writeCharacteristic(hrmService, hrmLocation, (uint8_t*)&location, sizeof(location)); - /* Update the battery level */ - /* See --> https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.battery_level.xml */ - uint8_t batt = 72; /* Percentage (0..100) */ - radio.writeCharacteristic(battService, battLevel, (uint8_t*)&batt, sizeof(batt)); - - /* Update the fixed health thermometer characteristics */ - /* See --> https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.temperature_type.xml */ - uint8_t thermLocation = 6; /* Location = mouth */ - radio.writeCharacteristic(thermService, thermType, (uint8_t*)&thermLocation, sizeof(thermLocation)); - /* See --> https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.measurement_interval.xml */ - uint16_t thermDelay = 5; - radio.writeCharacteristic(thermService, thermInterval, (uint8_t*)&thermDelay, sizeof(thermDelay)); - - /* Blinky + value updates */ - uint8_t hrmCounter = 100; - while(1) { myled = 1; @@ -119,20 +73,17 @@ if (hrmCounter == 175) hrmCounter = 100; uint8_t bpm[2] = { 0x00, hrmCounter }; radio.writeCharacteristic(hrmService, hrmRate, bpm, 2); - - /* Update the Health Thermometer measurement */ - - // NOTE: This is an IEEE-11073 32-bit float NOT a IEEE-754 float (standard single precision float type) !!! - // See: Section 2.2 of https://www.bluetooth.org/docman/handlers/downloaddoc.ashx?doc_id=242961 - // Example: - // Consider a temperature measurement of 36.4 degrees Celsius with precision of 0.1 degrees Celsius. - // The FLOAT-Type representation is a 32-bit value consisting of an exponent of an 8-bit signed integer - // followed by a mantissa of a 24-bit signed integer; here, the exponent is -1 (0xFF) and the mantissa - // is 364 (0x00016C). Therefore, the FLOAT-Type representation of 36.4 is 0xFF00016C. - - uint8_t temperature[5] = { 0x00, 0x00, 0x00, 0x00, 0xFF }; - // Use the hrm counter to provide a shifting temperature value (175 = 17.5C, etc.) - memcpy (temperature+1, &hrmCounter, 1); - radio.writeCharacteristic(thermService, thermTemp, temperature, 5); } } + +int main() +{ + /* Give the radio some time to boot up and settle */ + wait(2); + + /* Only use one of these two options! */ + startBeacon(); + // startHRM(); + + while(1); +}