Bill Schilit / BLE_API

Fork of BLE_API by Bluetooth Low Energy

Committer:
ktownsend
Date:
Wed Dec 18 06:22:35 2013 +0000
Revision:
13:a585c98b6abc
Parent:
12:2c6b1059ed36
Child:
14:6ea5d1012a64
Better debugging output

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 11:200931be5617 4 #define NRF51822_DEBUG_MODE (1)
ktownsend 11:200931be5617 5
ktownsend 0:ace2e8d3ce79 6 /**************************************************************************/
ktownsend 0:ace2e8d3ce79 7 /*!
ktownsend 0:ace2e8d3ce79 8 @brief UART callback function
ktownsend 0:ace2e8d3ce79 9 */
ktownsend 0:ace2e8d3ce79 10 /**************************************************************************/
ktownsend 0:ace2e8d3ce79 11 void nRF51822::uartCallback(void)
ktownsend 0:ace2e8d3ce79 12 {
ktownsend 0:ace2e8d3ce79 13 /* ToDo: Check responses and set a flag for success/error/etc. */
ktownsend 0:ace2e8d3ce79 14
ktownsend 0:ace2e8d3ce79 15 /* Read serial to clear the RX interrupt */
ktownsend 11:200931be5617 16 #if NRF51822_DEBUG_MODE
ktownsend 11:200931be5617 17 printf("%c", uart.getc());
ktownsend 11:200931be5617 18 #else
ktownsend 0:ace2e8d3ce79 19 uart.getc();
ktownsend 11:200931be5617 20 #endif
ktownsend 0:ace2e8d3ce79 21 }
ktownsend 0:ace2e8d3ce79 22
ktownsend 0:ace2e8d3ce79 23 /**************************************************************************/
ktownsend 0:ace2e8d3ce79 24 /*!
ktownsend 0:ace2e8d3ce79 25 @brief Constructor
ktownsend 0:ace2e8d3ce79 26 */
ktownsend 0:ace2e8d3ce79 27 /**************************************************************************/
ktownsend 9:124ae067ae27 28 nRF51822::nRF51822() : uart(p9, p10)
ktownsend 0:ace2e8d3ce79 29 {
ktownsend 0:ace2e8d3ce79 30 /* Setup the nRF UART interface */
ktownsend 0:ace2e8d3ce79 31 uart.baud(9600);
ktownsend 2:ffc5216bd2cc 32
ktownsend 0:ace2e8d3ce79 33 /* Echo data on the debug CDC port */
ktownsend 0:ace2e8d3ce79 34 uart.attach(this, &nRF51822::uartCallback);
ktownsend 0:ace2e8d3ce79 35
ktownsend 0:ace2e8d3ce79 36 /* Add flow control for UART (required by the nRF51822) */
ktownsend 9:124ae067ae27 37 uart.set_flow_control(Serial::RTSCTS, p30, p29);
ktownsend 2:ffc5216bd2cc 38
ktownsend 0:ace2e8d3ce79 39 /* Reset the service counter */
ktownsend 0:ace2e8d3ce79 40 serviceCount = 0;
ktownsend 0:ace2e8d3ce79 41 }
ktownsend 0:ace2e8d3ce79 42
ktownsend 0:ace2e8d3ce79 43 /**************************************************************************/
ktownsend 0:ace2e8d3ce79 44 /*!
ktownsend 0:ace2e8d3ce79 45 @brief Destructor
ktownsend 0:ace2e8d3ce79 46 */
ktownsend 0:ace2e8d3ce79 47 /**************************************************************************/
ktownsend 0:ace2e8d3ce79 48 nRF51822::~nRF51822(void)
ktownsend 0:ace2e8d3ce79 49 {
ktownsend 0:ace2e8d3ce79 50 }
ktownsend 0:ace2e8d3ce79 51
ktownsend 0:ace2e8d3ce79 52 /**************************************************************************/
ktownsend 0:ace2e8d3ce79 53 /*!
ktownsend 7:5e1f0d7f7c7d 54 @brief Sets the advertising parameters and payload for the device
ktownsend 0:ace2e8d3ce79 55
ktownsend 7:5e1f0d7f7c7d 56 @param[in] params
ktownsend 7:5e1f0d7f7c7d 57 Basic advertising details, including the advertising
ktownsend 7:5e1f0d7f7c7d 58 delay, timeout and how the device should be advertised
ktownsend 7:5e1f0d7f7c7d 59 @params[in] advData
ktownsend 7:5e1f0d7f7c7d 60 The primary advertising data payload
ktownsend 7:5e1f0d7f7c7d 61 @params[in] scanResponse
ktownsend 7:5e1f0d7f7c7d 62 The optional Scan Response payload if the advertising
ktownsend 7:5e1f0d7f7c7d 63 type is set to \ref GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED
ktownsend 7:5e1f0d7f7c7d 64 in \ref GapAdveritinngParams
ktownsend 7:5e1f0d7f7c7d 65
ktownsend 9:124ae067ae27 66 @returns \ref ble_error_t
ktownsend 7:5e1f0d7f7c7d 67
ktownsend 7:5e1f0d7f7c7d 68 @retval BLE_ERROR_NONE
ktownsend 7:5e1f0d7f7c7d 69 Everything executed properly
ktownsend 7:5e1f0d7f7c7d 70
ktownsend 7:5e1f0d7f7c7d 71 @retval BLE_ERROR_BUFFER_OVERFLOW
ktownsend 7:5e1f0d7f7c7d 72 The proposed action would cause a buffer overflow. All
ktownsend 9:124ae067ae27 73 advertising payloads must be <= 31 bytes, for example.
ktownsend 7:5e1f0d7f7c7d 74
ktownsend 9:124ae067ae27 75 @retval BLE_ERROR_NOT_IMPLEMENTED
ktownsend 9:124ae067ae27 76 A feature was requested that is not yet supported in the
ktownsend 9:124ae067ae27 77 nRF51 firmware or hardware.
ktownsend 9:124ae067ae27 78
ktownsend 9:124ae067ae27 79 @retval BLE_ERROR_PARAM_OUT_OF_RANGE
ktownsend 9:124ae067ae27 80 One of the proposed values is outside the valid range.
ktownsend 9:124ae067ae27 81
ktownsend 7:5e1f0d7f7c7d 82 @section EXAMPLE
ktownsend 7:5e1f0d7f7c7d 83
ktownsend 7:5e1f0d7f7c7d 84 @code
ktownsend 7:5e1f0d7f7c7d 85
ktownsend 7:5e1f0d7f7c7d 86 @endcode
ktownsend 0:ace2e8d3ce79 87 */
ktownsend 0:ace2e8d3ce79 88 /**************************************************************************/
ktownsend 7:5e1f0d7f7c7d 89 ble_error_t nRF51822::setAdvertising(GapAdvertisingParams & params, GapAdvertisingData & advData, GapAdvertisingData & scanResponse)
ktownsend 2:ffc5216bd2cc 90 {
ktownsend 7:5e1f0d7f7c7d 91 uint8_t len = 0;
ktownsend 7:5e1f0d7f7c7d 92 uint8_t *buffer;
ktownsend 9:124ae067ae27 93
ktownsend 11:200931be5617 94 #if NRF51822_DEBUG_MODE
ktownsend 13:a585c98b6abc 95 printf("%-40s", "Configuring Advertising");
ktownsend 11:200931be5617 96 #endif
ktownsend 11:200931be5617 97
ktownsend 9:124ae067ae27 98 /* Make sure we support the advertising type */
ktownsend 9:124ae067ae27 99 if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED)
ktownsend 9:124ae067ae27 100 {
ktownsend 11:200931be5617 101 #if NRF51822_DEBUG_MODE
ktownsend 13:a585c98b6abc 102 printf("[BLE_ERROR = 0x%04X]\r\n", (uint16_t)BLE_ERROR_NOT_IMPLEMENTED);
ktownsend 13:a585c98b6abc 103 printf("--> ADV_CONNECTABLE_DIRECTED not supported\r\n");
ktownsend 11:200931be5617 104 #endif
ktownsend 9:124ae067ae27 105 return BLE_ERROR_NOT_IMPLEMENTED;
ktownsend 9:124ae067ae27 106 }
ktownsend 9:124ae067ae27 107
ktownsend 9:124ae067ae27 108 /* Check interval range */
ktownsend 9:124ae067ae27 109 if ((params.getInterval() < GAP_ADV_PARAMS_INTERVAL_MIN) ||
ktownsend 9:124ae067ae27 110 (params.getInterval() > GAP_ADV_PARAMS_INTERVAL_MAX))
ktownsend 9:124ae067ae27 111 {
ktownsend 11:200931be5617 112 #if NRF51822_DEBUG_MODE
ktownsend 13:a585c98b6abc 113 printf("[BLE_ERROR = 0x%04X]\r\n", (uint16_t)BLE_ERROR_PARAM_OUT_OF_RANGE);
ktownsend 13:a585c98b6abc 114 printf("--> Advertising interval out of range\r\n");
ktownsend 11:200931be5617 115 #endif
ktownsend 9:124ae067ae27 116 return BLE_ERROR_PARAM_OUT_OF_RANGE;
ktownsend 9:124ae067ae27 117 }
ktownsend 9:124ae067ae27 118
ktownsend 9:124ae067ae27 119 /* Check timeout is zero for Connectable Directed */
ktownsend 12:2c6b1059ed36 120 if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) &&
ktownsend 9:124ae067ae27 121 (params.getTimeout() != 0))
ktownsend 9:124ae067ae27 122 {
ktownsend 11:200931be5617 123 #if NRF51822_DEBUG_MODE
ktownsend 13:a585c98b6abc 124 printf("[BLE_ERROR = 0x%04X]\r\n", (uint16_t)BLE_ERROR_PARAM_OUT_OF_RANGE);
ktownsend 13:a585c98b6abc 125 printf("--> Timeout must be 0 with ADV_CONNECTABLE_DIRECTED\r\n");
ktownsend 11:200931be5617 126 #endif
ktownsend 9:124ae067ae27 127 /* Timeout must be 0 with this type, although we'll never get here */
ktownsend 9:124ae067ae27 128 /* since this isn't implemented yet anyway */
ktownsend 9:124ae067ae27 129 return BLE_ERROR_PARAM_OUT_OF_RANGE;
ktownsend 9:124ae067ae27 130 }
ktownsend 9:124ae067ae27 131
ktownsend 9:124ae067ae27 132 /* Check timeout for other advertising types */
ktownsend 12:2c6b1059ed36 133 if ((params.getAdvertisingType() != GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) &&
ktownsend 11:200931be5617 134 (params.getTimeout() > GAP_ADV_PARAMS_TIMEOUT_MAX))
ktownsend 9:124ae067ae27 135 {
ktownsend 11:200931be5617 136 #if NRF51822_DEBUG_MODE
ktownsend 13:a585c98b6abc 137 printf("[BLE_ERROR = 0x%04X]\r\n", (uint16_t)BLE_ERROR_PARAM_OUT_OF_RANGE);
ktownsend 13:a585c98b6abc 138 printf("--> Timeout out of range\r\n");
ktownsend 11:200931be5617 139 #endif
ktownsend 9:124ae067ae27 140 return BLE_ERROR_PARAM_OUT_OF_RANGE;
ktownsend 9:124ae067ae27 141 }
ktownsend 7:5e1f0d7f7c7d 142
ktownsend 9:124ae067ae27 143 /* Make sure we don't exceed the advertising payload length */
ktownsend 9:124ae067ae27 144 if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD)
ktownsend 7:5e1f0d7f7c7d 145 {
ktownsend 11:200931be5617 146 #if NRF51822_DEBUG_MODE
ktownsend 13:a585c98b6abc 147 printf("[BLE_ERROR = 0x%04X]\r\n", (uint16_t)BLE_ERROR_BUFFER_OVERFLOW);
ktownsend 13:a585c98b6abc 148 printf("--> Advertising payload > 31 bytes\r\n");
ktownsend 11:200931be5617 149 #endif
ktownsend 7:5e1f0d7f7c7d 150 return BLE_ERROR_BUFFER_OVERFLOW;
ktownsend 7:5e1f0d7f7c7d 151 }
ktownsend 7:5e1f0d7f7c7d 152
ktownsend 9:124ae067ae27 153 /* Make sure we don't exceed the scan response payload length */
ktownsend 9:124ae067ae27 154 if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED))
ktownsend 9:124ae067ae27 155 {
ktownsend 9:124ae067ae27 156 if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD)
ktownsend 9:124ae067ae27 157 {
ktownsend 11:200931be5617 158 #if NRF51822_DEBUG_MODE
ktownsend 13:a585c98b6abc 159 printf("[BLE_ERROR = 0x%04X]\r\n", (uint16_t)BLE_ERROR_BUFFER_OVERFLOW);
ktownsend 13:a585c98b6abc 160 printf("--> Scan response payload > 31 bytes\r\n");
ktownsend 11:200931be5617 161 #endif
ktownsend 9:124ae067ae27 162 return BLE_ERROR_BUFFER_OVERFLOW;
ktownsend 9:124ae067ae27 163 }
ktownsend 9:124ae067ae27 164 }
ktownsend 9:124ae067ae27 165
ktownsend 9:124ae067ae27 166 /* ToDo: Perform some checks on the payload, for example the Scan Response can't */
ktownsend 9:124ae067ae27 167 /* contains a flags AD type, etc. */
ktownsend 9:124ae067ae27 168
ktownsend 9:124ae067ae27 169 /* ToDo: Refactor these actions into separate private functions */
ktownsend 9:124ae067ae27 170
ktownsend 9:124ae067ae27 171 /* 1.) Send advertising params, Command IDs = 0x000C, 0x000D, 0x000E */
ktownsend 9:124ae067ae27 172 /* A.) Command ID = 0x000C, Advertising Interval, uint16_t */
ktownsend 9:124ae067ae27 173 uart.printf("10 0C 00 02 %02X %02X\r\n", (uint8_t)(params.getInterval() & 0xFF),
ktownsend 9:124ae067ae27 174 (uint8_t)(params.getInterval() >> 8));
ktownsend 9:124ae067ae27 175 /* ToDo: Check response */
ktownsend 9:124ae067ae27 176 wait(0.5);
ktownsend 9:124ae067ae27 177
ktownsend 9:124ae067ae27 178 /* B.) Command ID = 0x000D, Advertising Timeout, uint16_t */
ktownsend 9:124ae067ae27 179 uart.printf("10 0D 00 02 %02X %02X\r\n", (uint8_t)(params.getTimeout() & 0xFF),
ktownsend 9:124ae067ae27 180 (uint8_t)(params.getTimeout() >> 8));
ktownsend 9:124ae067ae27 181 /* ToDo: Check response */
ktownsend 9:124ae067ae27 182 wait(0.5);
ktownsend 9:124ae067ae27 183
ktownsend 9:124ae067ae27 184 /* C.) Command ID = 0x000E, Advertising Type, uint8_t */
ktownsend 9:124ae067ae27 185 uart.printf("10 0E 00 01 %02X\r\n", (uint8_t)(params.getAdvertisingType()));
ktownsend 9:124ae067ae27 186 /* ToDo: Check response */
ktownsend 9:124ae067ae27 187 wait(0.5);
ktownsend 9:124ae067ae27 188
ktownsend 9:124ae067ae27 189 /* 2.) Send advertising data, Command ID = 0x000A */
ktownsend 9:124ae067ae27 190 len = advData.getPayloadLen();
ktownsend 9:124ae067ae27 191 buffer = advData.getPayload();
ktownsend 7:5e1f0d7f7c7d 192 uart.printf("10 0A 00 %02X ", len);
ktownsend 7:5e1f0d7f7c7d 193 for (uint16_t i = 0; i < len; i++)
ktownsend 7:5e1f0d7f7c7d 194 {
ktownsend 7:5e1f0d7f7c7d 195 uart.printf(" %02X", buffer[i]);
ktownsend 13:a585c98b6abc 196 }
ktownsend 7:5e1f0d7f7c7d 197 uart.printf("\r\n");
ktownsend 7:5e1f0d7f7c7d 198
ktownsend 7:5e1f0d7f7c7d 199 /* ToDo: Check response */
ktownsend 7:5e1f0d7f7c7d 200 wait(0.1);
ktownsend 7:5e1f0d7f7c7d 201
ktownsend 10:f905b036bb07 202 /* 3.) Send scan response data, Command ID = 0x000B */
ktownsend 7:5e1f0d7f7c7d 203 if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED))
ktownsend 7:5e1f0d7f7c7d 204 {
ktownsend 7:5e1f0d7f7c7d 205 len = advData.getPayloadLen();
ktownsend 7:5e1f0d7f7c7d 206 buffer = advData.getPayload();
ktownsend 10:f905b036bb07 207 uart.printf("10 0B 00 %02X ", len);
ktownsend 7:5e1f0d7f7c7d 208 for (uint16_t i = 0; i < len; i++)
ktownsend 7:5e1f0d7f7c7d 209 {
ktownsend 7:5e1f0d7f7c7d 210 uart.printf(" %02X", buffer[i]);
ktownsend 7:5e1f0d7f7c7d 211 }
ktownsend 7:5e1f0d7f7c7d 212 uart.printf("\r\n");
ktownsend 10:f905b036bb07 213
ktownsend 7:5e1f0d7f7c7d 214 /* ToDo: Check response */
ktownsend 7:5e1f0d7f7c7d 215 wait(0.1);
ktownsend 7:5e1f0d7f7c7d 216 }
ktownsend 7:5e1f0d7f7c7d 217
ktownsend 11:200931be5617 218 #if NRF51822_DEBUG_MODE
ktownsend 13:a585c98b6abc 219 printf("[OK]\r\n");
ktownsend 11:200931be5617 220 #endif
ktownsend 2:ffc5216bd2cc 221 return BLE_ERROR_NONE;
ktownsend 2:ffc5216bd2cc 222 }
ktownsend 2:ffc5216bd2cc 223
ktownsend 2:ffc5216bd2cc 224 /**************************************************************************/
ktownsend 2:ffc5216bd2cc 225 /*!
ktownsend 7:5e1f0d7f7c7d 226 @brief Adds a new service to the GATT table on the peripheral
ktownsend 7:5e1f0d7f7c7d 227
ktownsend 7:5e1f0d7f7c7d 228 @returns ble_error_t
ktownsend 7:5e1f0d7f7c7d 229
ktownsend 7:5e1f0d7f7c7d 230 @retval BLE_ERROR_NONE
ktownsend 7:5e1f0d7f7c7d 231 Everything executed properly
ktownsend 7:5e1f0d7f7c7d 232
ktownsend 7:5e1f0d7f7c7d 233 @section EXAMPLE
ktownsend 2:ffc5216bd2cc 234
ktownsend 7:5e1f0d7f7c7d 235 @code
ktownsend 7:5e1f0d7f7c7d 236
ktownsend 7:5e1f0d7f7c7d 237 @endcode
ktownsend 2:ffc5216bd2cc 238 */
ktownsend 2:ffc5216bd2cc 239 /**************************************************************************/
ktownsend 2:ffc5216bd2cc 240 ble_error_t nRF51822::addService(GattService & service)
ktownsend 0:ace2e8d3ce79 241 {
ktownsend 11:200931be5617 242 #if NRF51822_DEBUG_MODE
ktownsend 13:a585c98b6abc 243 printf("%-40s", "Adding a service");
ktownsend 11:200931be5617 244 #endif
ktownsend 11:200931be5617 245
ktownsend 0:ace2e8d3ce79 246 /* ToDo: Make sure we don't overflow the array, etc. */
ktownsend 0:ace2e8d3ce79 247 /* ToDo: Make sure this service UUID doesn't already exist (?) */
ktownsend 0:ace2e8d3ce79 248 /* ToDo: Basic validation */
ktownsend 0:ace2e8d3ce79 249
ktownsend 0:ace2e8d3ce79 250 /* Add the service to the nRF51 */
ktownsend 0:ace2e8d3ce79 251 if (service.primaryServiceID.type == UUID::UUID_TYPE_SHORT)
ktownsend 0:ace2e8d3ce79 252 {
ktownsend 0:ace2e8d3ce79 253 /* 16-bit BLE UUID */
ktownsend 0:ace2e8d3ce79 254 uart.printf("10 01 00 04 01 02 %02X %02X\r\n",
ktownsend 0:ace2e8d3ce79 255 service.primaryServiceID.value & 0xFF,
ktownsend 0:ace2e8d3ce79 256 service.primaryServiceID.value >> 8);
ktownsend 0:ace2e8d3ce79 257 }
ktownsend 0:ace2e8d3ce79 258 else
ktownsend 0:ace2e8d3ce79 259 {
ktownsend 0:ace2e8d3ce79 260 /* 128-bit Custom UUID */
ktownsend 0:ace2e8d3ce79 261 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 262 service.primaryServiceID.base[0],
ktownsend 0:ace2e8d3ce79 263 service.primaryServiceID.base[1],
ktownsend 0:ace2e8d3ce79 264 service.primaryServiceID.base[2],
ktownsend 0:ace2e8d3ce79 265 service.primaryServiceID.base[3],
ktownsend 0:ace2e8d3ce79 266 service.primaryServiceID.base[4],
ktownsend 0:ace2e8d3ce79 267 service.primaryServiceID.base[5],
ktownsend 0:ace2e8d3ce79 268 service.primaryServiceID.base[6],
ktownsend 0:ace2e8d3ce79 269 service.primaryServiceID.base[7],
ktownsend 0:ace2e8d3ce79 270 service.primaryServiceID.base[8],
ktownsend 0:ace2e8d3ce79 271 service.primaryServiceID.base[9],
ktownsend 0:ace2e8d3ce79 272 service.primaryServiceID.base[10],
ktownsend 0:ace2e8d3ce79 273 service.primaryServiceID.base[11],
ktownsend 0:ace2e8d3ce79 274 service.primaryServiceID.base[12],
ktownsend 0:ace2e8d3ce79 275 service.primaryServiceID.base[13],
ktownsend 0:ace2e8d3ce79 276 service.primaryServiceID.base[14],
ktownsend 0:ace2e8d3ce79 277 service.primaryServiceID.base[15]);
ktownsend 0:ace2e8d3ce79 278 }
ktownsend 0:ace2e8d3ce79 279
ktownsend 0:ace2e8d3ce79 280 /* ToDo: Check response */
ktownsend 0:ace2e8d3ce79 281 wait(0.1);
ktownsend 0:ace2e8d3ce79 282
ktownsend 0:ace2e8d3ce79 283 /* Add characteristics to the service */
ktownsend 0:ace2e8d3ce79 284 for (uint8_t i = 0; i < service.characteristicCount; i++)
ktownsend 0:ace2e8d3ce79 285 {
ktownsend 0:ace2e8d3ce79 286 /* Command ID = 0x0002 */
ktownsend 0:ace2e8d3ce79 287 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 288 service.characteristics[i].id & 0xFF,
ktownsend 0:ace2e8d3ce79 289 service.characteristics[i].id >> 8,
ktownsend 0:ace2e8d3ce79 290 service.characteristics[i].lenMin & 0xFF,
ktownsend 0:ace2e8d3ce79 291 service.characteristics[i].lenMin >> 8,
ktownsend 0:ace2e8d3ce79 292 service.characteristics[i].lenMax & 0xFF,
ktownsend 0:ace2e8d3ce79 293 service.characteristics[i].lenMax >> 8,
ktownsend 0:ace2e8d3ce79 294 service.characteristics[i].properties);
ktownsend 0:ace2e8d3ce79 295
ktownsend 0:ace2e8d3ce79 296 /* ToDo: Check response */
ktownsend 0:ace2e8d3ce79 297 wait(0.1);
ktownsend 0:ace2e8d3ce79 298 }
ktownsend 0:ace2e8d3ce79 299
ktownsend 0:ace2e8d3ce79 300 /* Update the service index value */
ktownsend 11:200931be5617 301 service.handle = serviceCount;
ktownsend 0:ace2e8d3ce79 302 serviceCount++;
ktownsend 0:ace2e8d3ce79 303
ktownsend 11:200931be5617 304 #if NRF51822_DEBUG_MODE
ktownsend 13:a585c98b6abc 305 printf("[OK]\r\n");
ktownsend 11:200931be5617 306 #endif
ktownsend 0:ace2e8d3ce79 307 return BLE_ERROR_NONE;
ktownsend 0:ace2e8d3ce79 308 }
ktownsend 0:ace2e8d3ce79 309
ktownsend 0:ace2e8d3ce79 310 /**************************************************************************/
ktownsend 0:ace2e8d3ce79 311 /*!
ktownsend 2:ffc5216bd2cc 312 @brief Reads the value of a characteristic, based on the service
ktownsend 2:ffc5216bd2cc 313 and characteristic index fields
ktownsend 2:ffc5216bd2cc 314
ktownsend 2:ffc5216bd2cc 315 @param[in] service
ktownsend 2:ffc5216bd2cc 316 The GattService to read from
ktownsend 2:ffc5216bd2cc 317 @param[in] characteristic
ktownsend 2:ffc5216bd2cc 318 The GattCharacteristic to read from
ktownsend 2:ffc5216bd2cc 319 @param[in] buffer
ktownsend 2:ffc5216bd2cc 320 Buffer to hold the the characteristic's value
ktownsend 2:ffc5216bd2cc 321 (raw byte array in LSB format)
ktownsend 2:ffc5216bd2cc 322 @param[in] len
ktownsend 2:ffc5216bd2cc 323 The number of bytes read into the buffer
ktownsend 7:5e1f0d7f7c7d 324
ktownsend 7:5e1f0d7f7c7d 325 @returns ble_error_t
ktownsend 7:5e1f0d7f7c7d 326
ktownsend 7:5e1f0d7f7c7d 327 @retval BLE_ERROR_NONE
ktownsend 7:5e1f0d7f7c7d 328 Everything executed properly
ktownsend 7:5e1f0d7f7c7d 329
ktownsend 7:5e1f0d7f7c7d 330 @section EXAMPLE
ktownsend 7:5e1f0d7f7c7d 331
ktownsend 7:5e1f0d7f7c7d 332 @code
ktownsend 7:5e1f0d7f7c7d 333
ktownsend 7:5e1f0d7f7c7d 334 @endcode
ktownsend 2:ffc5216bd2cc 335 */
ktownsend 2:ffc5216bd2cc 336 /**************************************************************************/
ktownsend 2:ffc5216bd2cc 337 ble_error_t nRF51822::readCharacteristic(GattService &service, GattCharacteristic &characteristic, uint8_t buffer[], uint16_t len)
ktownsend 2:ffc5216bd2cc 338 {
ktownsend 11:200931be5617 339 #if NRF51822_DEBUG_MODE
ktownsend 13:a585c98b6abc 340 printf("Reading characteristic (handle = %d) ", characteristic.handle);
ktownsend 11:200931be5617 341 #endif
ktownsend 11:200931be5617 342
ktownsend 2:ffc5216bd2cc 343 /* ToDo */
ktownsend 2:ffc5216bd2cc 344
ktownsend 11:200931be5617 345 #if NRF51822_DEBUG_MODE
ktownsend 13:a585c98b6abc 346 printf("[OK]\r\n");
ktownsend 11:200931be5617 347 #endif
ktownsend 2:ffc5216bd2cc 348 return BLE_ERROR_NONE;
ktownsend 2:ffc5216bd2cc 349 }
ktownsend 2:ffc5216bd2cc 350
ktownsend 2:ffc5216bd2cc 351 /**************************************************************************/
ktownsend 2:ffc5216bd2cc 352 /*!
ktownsend 0:ace2e8d3ce79 353 @brief Updates the value of a characteristic, based on the service
ktownsend 0:ace2e8d3ce79 354 and characteristic index fields
ktownsend 0:ace2e8d3ce79 355
ktownsend 2:ffc5216bd2cc 356 @param[in] service
ktownsend 2:ffc5216bd2cc 357 The GattService to write to
ktownsend 2:ffc5216bd2cc 358 @param[in] characteristic
ktownsend 2:ffc5216bd2cc 359 The GattCharacteristic to write to
ktownsend 0:ace2e8d3ce79 360 @param[in] buffer
ktownsend 0:ace2e8d3ce79 361 Data to use when updating the characteristic's value
ktownsend 0:ace2e8d3ce79 362 (raw byte array in LSB format)
ktownsend 0:ace2e8d3ce79 363 @param[in] len
ktownsend 0:ace2e8d3ce79 364 The number of bytes in buffer
ktownsend 7:5e1f0d7f7c7d 365
ktownsend 7:5e1f0d7f7c7d 366 @returns ble_error_t
ktownsend 7:5e1f0d7f7c7d 367
ktownsend 7:5e1f0d7f7c7d 368 @retval BLE_ERROR_NONE
ktownsend 7:5e1f0d7f7c7d 369 Everything executed properly
ktownsend 7:5e1f0d7f7c7d 370
ktownsend 7:5e1f0d7f7c7d 371 @section EXAMPLE
ktownsend 7:5e1f0d7f7c7d 372
ktownsend 7:5e1f0d7f7c7d 373 @code
ktownsend 7:5e1f0d7f7c7d 374
ktownsend 7:5e1f0d7f7c7d 375 @endcode
ktownsend 0:ace2e8d3ce79 376 */
ktownsend 0:ace2e8d3ce79 377 /**************************************************************************/
ktownsend 2:ffc5216bd2cc 378 ble_error_t nRF51822::writeCharacteristic(GattService &service, GattCharacteristic &characteristic, uint8_t buffer[], uint16_t len)
ktownsend 0:ace2e8d3ce79 379 {
ktownsend 11:200931be5617 380 #if NRF51822_DEBUG_MODE
ktownsend 13:a585c98b6abc 381 printf("Writing characteristic (handle = %d) ", characteristic.handle);
ktownsend 11:200931be5617 382 #endif
ktownsend 11:200931be5617 383
ktownsend 0:ace2e8d3ce79 384 /* Command ID = 0x0006, Payload = Service ID, Characteristic ID, Value */
ktownsend 11:200931be5617 385 uart.printf("10 06 00 %02X %02X %02X", len + 2, characteristic.handle, service.handle);
ktownsend 0:ace2e8d3ce79 386 for (uint16_t i = 0; i<len; i++)
ktownsend 0:ace2e8d3ce79 387 {
ktownsend 0:ace2e8d3ce79 388 uart.printf(" %02X", buffer[i]);
ktownsend 0:ace2e8d3ce79 389 }
ktownsend 0:ace2e8d3ce79 390 uart.printf("\r\n");
ktownsend 0:ace2e8d3ce79 391
ktownsend 0:ace2e8d3ce79 392 /* ToDo: Check response */
ktownsend 0:ace2e8d3ce79 393 wait(0.1);
ktownsend 0:ace2e8d3ce79 394
ktownsend 11:200931be5617 395 #if NRF51822_DEBUG_MODE
ktownsend 13:a585c98b6abc 396 printf("[OK]\r\n");
ktownsend 11:200931be5617 397 #endif
ktownsend 0:ace2e8d3ce79 398 return BLE_ERROR_NONE;
ktownsend 0:ace2e8d3ce79 399 }
ktownsend 0:ace2e8d3ce79 400
ktownsend 0:ace2e8d3ce79 401 /**************************************************************************/
ktownsend 0:ace2e8d3ce79 402 /*!
ktownsend 0:ace2e8d3ce79 403 @brief Starts the BLE HW, initialising any services that were
ktownsend 0:ace2e8d3ce79 404 added before this function was called.
ktownsend 0:ace2e8d3ce79 405
ktownsend 0:ace2e8d3ce79 406 @note All services must be added before calling this function!
ktownsend 7:5e1f0d7f7c7d 407
ktownsend 7:5e1f0d7f7c7d 408 @returns ble_error_t
ktownsend 7:5e1f0d7f7c7d 409
ktownsend 7:5e1f0d7f7c7d 410 @retval BLE_ERROR_NONE
ktownsend 7:5e1f0d7f7c7d 411 Everything executed properly
ktownsend 7:5e1f0d7f7c7d 412
ktownsend 7:5e1f0d7f7c7d 413 @section EXAMPLE
ktownsend 7:5e1f0d7f7c7d 414
ktownsend 7:5e1f0d7f7c7d 415 @code
ktownsend 7:5e1f0d7f7c7d 416
ktownsend 7:5e1f0d7f7c7d 417 @endcode
ktownsend 0:ace2e8d3ce79 418 */
ktownsend 0:ace2e8d3ce79 419 /**************************************************************************/
ktownsend 0:ace2e8d3ce79 420 ble_error_t nRF51822::start(void)
ktownsend 0:ace2e8d3ce79 421 {
ktownsend 11:200931be5617 422 #if NRF51822_DEBUG_MODE
ktownsend 13:a585c98b6abc 423 printf("%-40s", "Starting the radio");
ktownsend 11:200931be5617 424 #endif
ktownsend 11:200931be5617 425
ktownsend 0:ace2e8d3ce79 426 /* Command ID = 0x0003, No payload */
ktownsend 0:ace2e8d3ce79 427 uart.printf("10 03 00 00\r\n");
ktownsend 0:ace2e8d3ce79 428
ktownsend 0:ace2e8d3ce79 429 /* ToDo: Check response */
ktownsend 0:ace2e8d3ce79 430 wait(0.5);
ktownsend 0:ace2e8d3ce79 431
ktownsend 11:200931be5617 432 #if NRF51822_DEBUG_MODE
ktownsend 13:a585c98b6abc 433 printf("[OK]\r\n");
ktownsend 11:200931be5617 434 #endif
ktownsend 0:ace2e8d3ce79 435 return BLE_ERROR_NONE;
ktownsend 0:ace2e8d3ce79 436 }
ktownsend 0:ace2e8d3ce79 437
ktownsend 0:ace2e8d3ce79 438 /**************************************************************************/
ktownsend 0:ace2e8d3ce79 439 /*!
ktownsend 0:ace2e8d3ce79 440 @brief Stops the BLE HW and disconnects from any devices
ktownsend 7:5e1f0d7f7c7d 441
ktownsend 7:5e1f0d7f7c7d 442 @returns ble_error_t
ktownsend 7:5e1f0d7f7c7d 443
ktownsend 7:5e1f0d7f7c7d 444 @retval BLE_ERROR_NONE
ktownsend 7:5e1f0d7f7c7d 445 Everything executed properly
ktownsend 7:5e1f0d7f7c7d 446
ktownsend 7:5e1f0d7f7c7d 447 @section EXAMPLE
ktownsend 7:5e1f0d7f7c7d 448
ktownsend 7:5e1f0d7f7c7d 449 @code
ktownsend 7:5e1f0d7f7c7d 450
ktownsend 7:5e1f0d7f7c7d 451 @endcode
ktownsend 0:ace2e8d3ce79 452 */
ktownsend 0:ace2e8d3ce79 453 /**************************************************************************/
ktownsend 0:ace2e8d3ce79 454 ble_error_t nRF51822::stop(void)
ktownsend 0:ace2e8d3ce79 455 {
ktownsend 11:200931be5617 456 #if NRF51822_DEBUG_MODE
ktownsend 13:a585c98b6abc 457 printf("%-40s", "Stopping the radio");
ktownsend 11:200931be5617 458 #endif
ktownsend 11:200931be5617 459
ktownsend 0:ace2e8d3ce79 460 /* Command ID = 0x0004, No payload */
ktownsend 0:ace2e8d3ce79 461 uart.printf("10 04 00 00\r\n");
ktownsend 0:ace2e8d3ce79 462
ktownsend 0:ace2e8d3ce79 463 /* ToDo: Check response */
ktownsend 0:ace2e8d3ce79 464 wait(0.1);
ktownsend 0:ace2e8d3ce79 465
ktownsend 11:200931be5617 466 #if NRF51822_DEBUG_MODE
ktownsend 13:a585c98b6abc 467 printf("[OK]\r\n");
ktownsend 11:200931be5617 468 #endif
ktownsend 0:ace2e8d3ce79 469 return BLE_ERROR_NONE;
ktownsend 0:ace2e8d3ce79 470 }
ktownsend 0:ace2e8d3ce79 471
ktownsend 0:ace2e8d3ce79 472 /**************************************************************************/
ktownsend 0:ace2e8d3ce79 473 /*!
ktownsend 0:ace2e8d3ce79 474 @brief Resets the BLE HW, removing any existing services and
ktownsend 0:ace2e8d3ce79 475 characteristics
ktownsend 7:5e1f0d7f7c7d 476
ktownsend 7:5e1f0d7f7c7d 477 @returns ble_error_t
ktownsend 7:5e1f0d7f7c7d 478
ktownsend 7:5e1f0d7f7c7d 479 @retval BLE_ERROR_NONE
ktownsend 7:5e1f0d7f7c7d 480 Everything executed properly
ktownsend 7:5e1f0d7f7c7d 481
ktownsend 7:5e1f0d7f7c7d 482 @section EXAMPLE
ktownsend 7:5e1f0d7f7c7d 483
ktownsend 7:5e1f0d7f7c7d 484 @code
ktownsend 7:5e1f0d7f7c7d 485
ktownsend 7:5e1f0d7f7c7d 486 @endcode
ktownsend 0:ace2e8d3ce79 487 */
ktownsend 0:ace2e8d3ce79 488 /**************************************************************************/
ktownsend 0:ace2e8d3ce79 489 ble_error_t nRF51822::reset(void)
ktownsend 0:ace2e8d3ce79 490 {
ktownsend 11:200931be5617 491 #if NRF51822_DEBUG_MODE
ktownsend 13:a585c98b6abc 492 printf("%-40s", "Resetting the radio");
ktownsend 11:200931be5617 493 #endif
ktownsend 11:200931be5617 494
ktownsend 0:ace2e8d3ce79 495 /* Command ID = 0x0005, No payload */
ktownsend 0:ace2e8d3ce79 496 uart.printf("10 05 00 00\r\n");
ktownsend 0:ace2e8d3ce79 497
ktownsend 0:ace2e8d3ce79 498 /* Reset the service counter */
ktownsend 0:ace2e8d3ce79 499 serviceCount = 0;
ktownsend 0:ace2e8d3ce79 500
ktownsend 0:ace2e8d3ce79 501 /* Wait for the radio to come back up */
ktownsend 0:ace2e8d3ce79 502 wait(1);
ktownsend 0:ace2e8d3ce79 503
ktownsend 11:200931be5617 504 #if NRF51822_DEBUG_MODE
ktownsend 13:a585c98b6abc 505 printf("[OK]\r\n");
ktownsend 11:200931be5617 506 #endif
ktownsend 0:ace2e8d3ce79 507 return BLE_ERROR_NONE;
ktownsend 0:ace2e8d3ce79 508 }