High level Bluetooth Low Energy API and radio abstraction layer

Dependencies:   nRF51822

Dependents:   LinkNode_LIS3DH

Fork of BLE_API by Bluetooth Low Energy

Committer:
ktownsend
Date:
Tue Dec 10 07:32:12 2013 +0000
Revision:
2:ffc5216bd2cc
Parent:
1:fd3ec64b2345
Child:
3:46de446e82ed
UART Tests

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ktownsend 0:ace2e8d3ce79 1 #include "nrf51822.h"
ktownsend 0:ace2e8d3ce79 2 #include "mbed.h"
ktownsend 0:ace2e8d3ce79 3
ktownsend 0:ace2e8d3ce79 4 /**************************************************************************/
ktownsend 0:ace2e8d3ce79 5 /*!
ktownsend 0:ace2e8d3ce79 6 @brief UART callback function
ktownsend 0:ace2e8d3ce79 7 */
ktownsend 0:ace2e8d3ce79 8 /**************************************************************************/
ktownsend 0:ace2e8d3ce79 9 void nRF51822::uartCallback(void)
ktownsend 0:ace2e8d3ce79 10 {
ktownsend 0:ace2e8d3ce79 11 /* ToDo: Check responses and set a flag for success/error/etc. */
ktownsend 0:ace2e8d3ce79 12
ktownsend 0:ace2e8d3ce79 13 /* Read serial to clear the RX interrupt */
ktownsend 0:ace2e8d3ce79 14 uart.getc();
ktownsend 0:ace2e8d3ce79 15 }
ktownsend 0:ace2e8d3ce79 16
ktownsend 0:ace2e8d3ce79 17 /**************************************************************************/
ktownsend 0:ace2e8d3ce79 18 /*!
ktownsend 0:ace2e8d3ce79 19 @brief Constructor
ktownsend 0:ace2e8d3ce79 20 */
ktownsend 0:ace2e8d3ce79 21 /**************************************************************************/
ktownsend 1:fd3ec64b2345 22 //nRF51822::nRF51822() : uart(P0_4, P0_0) /* LPC812 */
ktownsend 1:fd3ec64b2345 23 nRF51822::nRF51822() : uart(p9, p10) /* LPC1768 using apps board */
ktownsend 0:ace2e8d3ce79 24 {
ktownsend 0:ace2e8d3ce79 25 /* Setup the nRF UART interface */
ktownsend 0:ace2e8d3ce79 26 uart.baud(9600);
ktownsend 2:ffc5216bd2cc 27
ktownsend 0:ace2e8d3ce79 28 /* Echo data on the debug CDC port */
ktownsend 0:ace2e8d3ce79 29 uart.attach(this, &nRF51822::uartCallback);
ktownsend 0:ace2e8d3ce79 30
ktownsend 0:ace2e8d3ce79 31 /* Add flow control for UART (required by the nRF51822) */
ktownsend 1:fd3ec64b2345 32 //uart.set_flow_control(Serial::RTSCTS, P0_6, P0_8); /* LPC812 */
ktownsend 1:fd3ec64b2345 33 uart.set_flow_control(Serial::RTSCTS, p30, p29); /* LPC1768 */
ktownsend 2:ffc5216bd2cc 34
ktownsend 0:ace2e8d3ce79 35 /* Reset the service counter */
ktownsend 0:ace2e8d3ce79 36 serviceCount = 0;
ktownsend 0:ace2e8d3ce79 37 }
ktownsend 0:ace2e8d3ce79 38
ktownsend 0:ace2e8d3ce79 39 /**************************************************************************/
ktownsend 0:ace2e8d3ce79 40 /*!
ktownsend 0:ace2e8d3ce79 41 @brief Destructor
ktownsend 0:ace2e8d3ce79 42 */
ktownsend 0:ace2e8d3ce79 43 /**************************************************************************/
ktownsend 0:ace2e8d3ce79 44 nRF51822::~nRF51822(void)
ktownsend 0:ace2e8d3ce79 45 {
ktownsend 0:ace2e8d3ce79 46 }
ktownsend 0:ace2e8d3ce79 47
ktownsend 0:ace2e8d3ce79 48 /**************************************************************************/
ktownsend 0:ace2e8d3ce79 49 /*!
ktownsend 0:ace2e8d3ce79 50
ktownsend 0:ace2e8d3ce79 51 */
ktownsend 0:ace2e8d3ce79 52 /**************************************************************************/
ktownsend 2:ffc5216bd2cc 53 void nRF51822::test(void)
ktownsend 2:ffc5216bd2cc 54 {
ktownsend 2:ffc5216bd2cc 55 /* Send iBeacon data as a test */
ktownsend 2:ffc5216bd2cc 56 uint8_t response[4];
ktownsend 2:ffc5216bd2cc 57 uart.printf("10 0a 00 1e 02 01 04 1A FF 4C 00 02 15 E2 0A 39 F4 73 F5 4B C4 A1 2F 17 D1 AD 07 A9 61 00 00 00 00 C8\r\n");
ktownsend 2:ffc5216bd2cc 58 response[0] = uart.getc();
ktownsend 2:ffc5216bd2cc 59 response[1] = uart.getc();
ktownsend 2:ffc5216bd2cc 60 response[2] = uart.getc();
ktownsend 2:ffc5216bd2cc 61 response[3] = uart.getc();
ktownsend 2:ffc5216bd2cc 62 wait(0.1);
ktownsend 2:ffc5216bd2cc 63 /* Start the radio */
ktownsend 2:ffc5216bd2cc 64 uart.printf("10 03 00 00\r\n");
ktownsend 2:ffc5216bd2cc 65 response[0] = uart.getc();
ktownsend 2:ffc5216bd2cc 66 response[1] = uart.getc();
ktownsend 2:ffc5216bd2cc 67 response[2] = uart.getc();
ktownsend 2:ffc5216bd2cc 68 response[3] = uart.getc();
ktownsend 2:ffc5216bd2cc 69 }
ktownsend 0:ace2e8d3ce79 70
ktownsend 0:ace2e8d3ce79 71 /**************************************************************************/
ktownsend 0:ace2e8d3ce79 72 /*!
ktownsend 0:ace2e8d3ce79 73
ktownsend 0:ace2e8d3ce79 74 */
ktownsend 0:ace2e8d3ce79 75 /**************************************************************************/
ktownsend 2:ffc5216bd2cc 76 ble_error_t nRF51822::setAdvertising(GapAdvertisingParams &, GapAdvertisingData &)
ktownsend 2:ffc5216bd2cc 77 {
ktownsend 2:ffc5216bd2cc 78 return BLE_ERROR_NONE;
ktownsend 2:ffc5216bd2cc 79 }
ktownsend 2:ffc5216bd2cc 80
ktownsend 2:ffc5216bd2cc 81 /**************************************************************************/
ktownsend 2:ffc5216bd2cc 82 /*!
ktownsend 2:ffc5216bd2cc 83
ktownsend 2:ffc5216bd2cc 84 */
ktownsend 2:ffc5216bd2cc 85 /**************************************************************************/
ktownsend 2:ffc5216bd2cc 86 ble_error_t nRF51822::addService(GattService & service)
ktownsend 0:ace2e8d3ce79 87 {
ktownsend 0:ace2e8d3ce79 88 /* ToDo: Make sure we don't overflow the array, etc. */
ktownsend 0:ace2e8d3ce79 89 /* ToDo: Make sure this service UUID doesn't already exist (?) */
ktownsend 0:ace2e8d3ce79 90 /* ToDo: Basic validation */
ktownsend 0:ace2e8d3ce79 91
ktownsend 0:ace2e8d3ce79 92 /* Add the service to the nRF51 */
ktownsend 0:ace2e8d3ce79 93 if (service.primaryServiceID.type == UUID::UUID_TYPE_SHORT)
ktownsend 0:ace2e8d3ce79 94 {
ktownsend 0:ace2e8d3ce79 95 /* 16-bit BLE UUID */
ktownsend 0:ace2e8d3ce79 96 uart.printf("10 01 00 04 01 02 %02X %02X\r\n",
ktownsend 0:ace2e8d3ce79 97 service.primaryServiceID.value & 0xFF,
ktownsend 0:ace2e8d3ce79 98 service.primaryServiceID.value >> 8);
ktownsend 0:ace2e8d3ce79 99 }
ktownsend 0:ace2e8d3ce79 100 else
ktownsend 0:ace2e8d3ce79 101 {
ktownsend 0:ace2e8d3ce79 102 /* 128-bit Custom UUID */
ktownsend 0:ace2e8d3ce79 103 uart.printf("10 01 00 12 01 10 %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\r\n",
ktownsend 0:ace2e8d3ce79 104 service.primaryServiceID.base[0],
ktownsend 0:ace2e8d3ce79 105 service.primaryServiceID.base[1],
ktownsend 0:ace2e8d3ce79 106 service.primaryServiceID.base[2],
ktownsend 0:ace2e8d3ce79 107 service.primaryServiceID.base[3],
ktownsend 0:ace2e8d3ce79 108 service.primaryServiceID.base[4],
ktownsend 0:ace2e8d3ce79 109 service.primaryServiceID.base[5],
ktownsend 0:ace2e8d3ce79 110 service.primaryServiceID.base[6],
ktownsend 0:ace2e8d3ce79 111 service.primaryServiceID.base[7],
ktownsend 0:ace2e8d3ce79 112 service.primaryServiceID.base[8],
ktownsend 0:ace2e8d3ce79 113 service.primaryServiceID.base[9],
ktownsend 0:ace2e8d3ce79 114 service.primaryServiceID.base[10],
ktownsend 0:ace2e8d3ce79 115 service.primaryServiceID.base[11],
ktownsend 0:ace2e8d3ce79 116 service.primaryServiceID.base[12],
ktownsend 0:ace2e8d3ce79 117 service.primaryServiceID.base[13],
ktownsend 0:ace2e8d3ce79 118 service.primaryServiceID.base[14],
ktownsend 0:ace2e8d3ce79 119 service.primaryServiceID.base[15]);
ktownsend 0:ace2e8d3ce79 120 }
ktownsend 0:ace2e8d3ce79 121
ktownsend 0:ace2e8d3ce79 122 /* ToDo: Check response */
ktownsend 0:ace2e8d3ce79 123 wait(0.1);
ktownsend 0:ace2e8d3ce79 124
ktownsend 0:ace2e8d3ce79 125 /* Add characteristics to the service */
ktownsend 0:ace2e8d3ce79 126 for (uint8_t i = 0; i < service.characteristicCount; i++)
ktownsend 0:ace2e8d3ce79 127 {
ktownsend 0:ace2e8d3ce79 128 /* Command ID = 0x0002 */
ktownsend 0:ace2e8d3ce79 129 uart.printf("10 02 00 0F 01 02 %02X %02X 04 02 %02X %02X 05 02 %02X %02X 03 01 %02X\r\n",
ktownsend 0:ace2e8d3ce79 130 service.characteristics[i].id & 0xFF,
ktownsend 0:ace2e8d3ce79 131 service.characteristics[i].id >> 8,
ktownsend 0:ace2e8d3ce79 132 service.characteristics[i].lenMin & 0xFF,
ktownsend 0:ace2e8d3ce79 133 service.characteristics[i].lenMin >> 8,
ktownsend 0:ace2e8d3ce79 134 service.characteristics[i].lenMax & 0xFF,
ktownsend 0:ace2e8d3ce79 135 service.characteristics[i].lenMax >> 8,
ktownsend 0:ace2e8d3ce79 136 service.characteristics[i].properties);
ktownsend 0:ace2e8d3ce79 137
ktownsend 0:ace2e8d3ce79 138 /* ToDo: Check response */
ktownsend 0:ace2e8d3ce79 139 wait(0.1);
ktownsend 0:ace2e8d3ce79 140 }
ktownsend 0:ace2e8d3ce79 141
ktownsend 0:ace2e8d3ce79 142 /* Update the service index value */
ktownsend 0:ace2e8d3ce79 143 service.index = serviceCount;
ktownsend 0:ace2e8d3ce79 144 serviceCount++;
ktownsend 0:ace2e8d3ce79 145
ktownsend 0:ace2e8d3ce79 146 return BLE_ERROR_NONE;
ktownsend 0:ace2e8d3ce79 147 }
ktownsend 0:ace2e8d3ce79 148
ktownsend 0:ace2e8d3ce79 149 /**************************************************************************/
ktownsend 0:ace2e8d3ce79 150 /*!
ktownsend 2:ffc5216bd2cc 151 @brief Reads the value of a characteristic, based on the service
ktownsend 2:ffc5216bd2cc 152 and characteristic index fields
ktownsend 2:ffc5216bd2cc 153
ktownsend 2:ffc5216bd2cc 154 @param[in] service
ktownsend 2:ffc5216bd2cc 155 The GattService to read from
ktownsend 2:ffc5216bd2cc 156 @param[in] characteristic
ktownsend 2:ffc5216bd2cc 157 The GattCharacteristic to read from
ktownsend 2:ffc5216bd2cc 158 @param[in] buffer
ktownsend 2:ffc5216bd2cc 159 Buffer to hold the the characteristic's value
ktownsend 2:ffc5216bd2cc 160 (raw byte array in LSB format)
ktownsend 2:ffc5216bd2cc 161 @param[in] len
ktownsend 2:ffc5216bd2cc 162 The number of bytes read into the buffer
ktownsend 2:ffc5216bd2cc 163 */
ktownsend 2:ffc5216bd2cc 164 /**************************************************************************/
ktownsend 2:ffc5216bd2cc 165 ble_error_t nRF51822::readCharacteristic(GattService &service, GattCharacteristic &characteristic, uint8_t buffer[], uint16_t len)
ktownsend 2:ffc5216bd2cc 166 {
ktownsend 2:ffc5216bd2cc 167 /* ToDo */
ktownsend 2:ffc5216bd2cc 168
ktownsend 2:ffc5216bd2cc 169 return BLE_ERROR_NONE;
ktownsend 2:ffc5216bd2cc 170 }
ktownsend 2:ffc5216bd2cc 171
ktownsend 2:ffc5216bd2cc 172 /**************************************************************************/
ktownsend 2:ffc5216bd2cc 173 /*!
ktownsend 0:ace2e8d3ce79 174 @brief Updates the value of a characteristic, based on the service
ktownsend 0:ace2e8d3ce79 175 and characteristic index fields
ktownsend 0:ace2e8d3ce79 176
ktownsend 2:ffc5216bd2cc 177 @param[in] service
ktownsend 2:ffc5216bd2cc 178 The GattService to write to
ktownsend 2:ffc5216bd2cc 179 @param[in] characteristic
ktownsend 2:ffc5216bd2cc 180 The GattCharacteristic to write to
ktownsend 0:ace2e8d3ce79 181 @param[in] buffer
ktownsend 0:ace2e8d3ce79 182 Data to use when updating the characteristic's value
ktownsend 0:ace2e8d3ce79 183 (raw byte array in LSB format)
ktownsend 0:ace2e8d3ce79 184 @param[in] len
ktownsend 0:ace2e8d3ce79 185 The number of bytes in buffer
ktownsend 0:ace2e8d3ce79 186 */
ktownsend 0:ace2e8d3ce79 187 /**************************************************************************/
ktownsend 2:ffc5216bd2cc 188 ble_error_t nRF51822::writeCharacteristic(GattService &service, GattCharacteristic &characteristic, uint8_t buffer[], uint16_t len)
ktownsend 0:ace2e8d3ce79 189 {
ktownsend 0:ace2e8d3ce79 190 /* Command ID = 0x0006, Payload = Service ID, Characteristic ID, Value */
ktownsend 2:ffc5216bd2cc 191 uart.printf("10 06 00 %02X %02X %02X", len + 2, characteristic.index, service.index);
ktownsend 0:ace2e8d3ce79 192 for (uint16_t i = 0; i<len; i++)
ktownsend 0:ace2e8d3ce79 193 {
ktownsend 0:ace2e8d3ce79 194 uart.printf(" %02X", buffer[i]);
ktownsend 0:ace2e8d3ce79 195 }
ktownsend 0:ace2e8d3ce79 196 uart.printf("\r\n");
ktownsend 0:ace2e8d3ce79 197
ktownsend 0:ace2e8d3ce79 198 /* ToDo: Check response */
ktownsend 0:ace2e8d3ce79 199 wait(0.1);
ktownsend 0:ace2e8d3ce79 200
ktownsend 0:ace2e8d3ce79 201 return BLE_ERROR_NONE;
ktownsend 0:ace2e8d3ce79 202 }
ktownsend 0:ace2e8d3ce79 203
ktownsend 0:ace2e8d3ce79 204 /**************************************************************************/
ktownsend 0:ace2e8d3ce79 205 /*!
ktownsend 0:ace2e8d3ce79 206 @brief Starts the BLE HW, initialising any services that were
ktownsend 0:ace2e8d3ce79 207 added before this function was called.
ktownsend 0:ace2e8d3ce79 208
ktownsend 0:ace2e8d3ce79 209 @note All services must be added before calling this function!
ktownsend 0:ace2e8d3ce79 210 */
ktownsend 0:ace2e8d3ce79 211 /**************************************************************************/
ktownsend 0:ace2e8d3ce79 212 ble_error_t nRF51822::start(void)
ktownsend 0:ace2e8d3ce79 213 {
ktownsend 0:ace2e8d3ce79 214 /* Command ID = 0x0003, No payload */
ktownsend 0:ace2e8d3ce79 215 uart.printf("10 03 00 00\r\n");
ktownsend 0:ace2e8d3ce79 216
ktownsend 0:ace2e8d3ce79 217 /* ToDo: Check response */
ktownsend 0:ace2e8d3ce79 218 wait(0.5);
ktownsend 0:ace2e8d3ce79 219
ktownsend 0:ace2e8d3ce79 220 return BLE_ERROR_NONE;
ktownsend 0:ace2e8d3ce79 221 }
ktownsend 0:ace2e8d3ce79 222
ktownsend 0:ace2e8d3ce79 223 /**************************************************************************/
ktownsend 0:ace2e8d3ce79 224 /*!
ktownsend 0:ace2e8d3ce79 225 @brief Stops the BLE HW and disconnects from any devices
ktownsend 0:ace2e8d3ce79 226 */
ktownsend 0:ace2e8d3ce79 227 /**************************************************************************/
ktownsend 0:ace2e8d3ce79 228 ble_error_t nRF51822::stop(void)
ktownsend 0:ace2e8d3ce79 229 {
ktownsend 0:ace2e8d3ce79 230 /* Command ID = 0x0004, No payload */
ktownsend 0:ace2e8d3ce79 231 uart.printf("10 04 00 00\r\n");
ktownsend 0:ace2e8d3ce79 232
ktownsend 0:ace2e8d3ce79 233 /* ToDo: Check response */
ktownsend 0:ace2e8d3ce79 234 wait(0.1);
ktownsend 0:ace2e8d3ce79 235
ktownsend 0:ace2e8d3ce79 236 return BLE_ERROR_NONE;
ktownsend 0:ace2e8d3ce79 237 }
ktownsend 0:ace2e8d3ce79 238
ktownsend 0:ace2e8d3ce79 239 /**************************************************************************/
ktownsend 0:ace2e8d3ce79 240 /*!
ktownsend 0:ace2e8d3ce79 241 @brief Resets the BLE HW, removing any existing services and
ktownsend 0:ace2e8d3ce79 242 characteristics
ktownsend 0:ace2e8d3ce79 243 */
ktownsend 0:ace2e8d3ce79 244 /**************************************************************************/
ktownsend 0:ace2e8d3ce79 245 ble_error_t nRF51822::reset(void)
ktownsend 0:ace2e8d3ce79 246 {
ktownsend 0:ace2e8d3ce79 247 /* Command ID = 0x0005, No payload */
ktownsend 0:ace2e8d3ce79 248 uart.printf("10 05 00 00\r\n");
ktownsend 0:ace2e8d3ce79 249
ktownsend 0:ace2e8d3ce79 250 /* Reset the service counter */
ktownsend 0:ace2e8d3ce79 251 serviceCount = 0;
ktownsend 0:ace2e8d3ce79 252
ktownsend 0:ace2e8d3ce79 253 /* Wait for the radio to come back up */
ktownsend 0:ace2e8d3ce79 254 wait(1);
ktownsend 0:ace2e8d3ce79 255
ktownsend 0:ace2e8d3ce79 256 return BLE_ERROR_NONE;
ktownsend 0:ace2e8d3ce79 257 }