BLE_API wrapper library for STMicroelectronics' BlueNRG Bluetooth Low Energy expansion board shield (Component)

Dependents:   Nucleo_Zumo_BLE_IDB04A1 contest_IOT5 contest_IOT6 contest_IOT_10 ... more

Fork of X_NUCLEO_IDB0XA1 by ST Expansion SW Team

Arduino Connector Compatibility Warning

X-NUCLEO-IDB04A1 and X-NUCLEO-IDB05A1 are Arduino compatible with an exception: instead of using pin D13 for the SPI clock, they use pin D3. The default configuration for this library is having the SPI clock on pin D3.

To be fully Arduino compatible, X-NUCLEO-IDB04A1 and X-NUCLEO-IDB05A1 need a small HW patch.

For X-NUCLEO-IDB04A1 this patch consists in removing zero resistor R10 and instead soldering zero resistor R11. For X-NUCLEO-IDB05A1 this patch consists in removing zero resistor R4 and instead soldering zero resistor R6.

In case you patch your board, then you also have to configure this library to use pin D13 to drive the SPI clock (see macro IDB0XA1_D13_PATCH in file x_nucleo_idb0xa1_targets.h).

If you use pin D13 for the SPI clock, please be aware that on STM32 Nucleo boards you may not drive the LED, otherwise you will get a conflict: the LED on STM32 Nucleo boards is connected to pin D13.

Referring to the current list of tested platforms (see X-NUCLEO-IDB04A1 and X-NUCLEO-IDB05A1 pages), the patch is required by ST-Nucleo-F103RB; ST-Nucleo-F302R8; ST-Nucleo-F411RE; and ST-Nucleo-F446RE.

Committer:
Andrea Palmieri
Date:
Fri Sep 16 12:03:25 2016 +0200
Revision:
307:fa98703ece8e
Parent:
293:5a1f577bf92f
Sync with 21bfd161ace255bb6214d6b74cae1fd30b3e24c9

2016-09-16 11:53:47+02:00: Andrea Palmieri
Get rid of warnings

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Wolfgang Betz 130:770ce14d3d15 1 /* mbed Microcontroller Library
Wolfgang Betz 130:770ce14d3d15 2 * Copyright (c) 2006-2013 ARM Limited
Wolfgang Betz 130:770ce14d3d15 3 *
Wolfgang Betz 130:770ce14d3d15 4 * Licensed under the Apache License, Version 2.0 (the "License");
Wolfgang Betz 130:770ce14d3d15 5 * you may not use this file except in compliance with the License.
Wolfgang Betz 130:770ce14d3d15 6 * You may obtain a copy of the License at
Wolfgang Betz 130:770ce14d3d15 7 *
Wolfgang Betz 130:770ce14d3d15 8 * http://www.apache.org/licenses/LICENSE-2.0
Wolfgang Betz 130:770ce14d3d15 9 *
Wolfgang Betz 130:770ce14d3d15 10 * Unless required by applicable law or agreed to in writing, software
Wolfgang Betz 130:770ce14d3d15 11 * distributed under the License is distributed on an "AS IS" BASIS,
Wolfgang Betz 130:770ce14d3d15 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Wolfgang Betz 130:770ce14d3d15 13 * See the License for the specific language governing permissions and
Wolfgang Betz 130:770ce14d3d15 14 * limitations under the License.
Wolfgang Betz 130:770ce14d3d15 15 */
Wolfgang Betz 130:770ce14d3d15 16
Wolfgang Betz 130:770ce14d3d15 17 /**
Wolfgang Betz 130:770ce14d3d15 18 ******************************************************************************
Vincent Coubard 278:a5209d8cfd61 19 * @file BlueNRGDevice.cpp
Wolfgang Betz 130:770ce14d3d15 20 * @author STMicroelectronics
Wolfgang Betz 130:770ce14d3d15 21 * @brief Implementation of BLEDeviceInstanceBase
Wolfgang Betz 130:770ce14d3d15 22 ******************************************************************************
Wolfgang Betz 130:770ce14d3d15 23 * @copy
Wolfgang Betz 130:770ce14d3d15 24 *
Wolfgang Betz 130:770ce14d3d15 25 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
Wolfgang Betz 130:770ce14d3d15 26 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
Wolfgang Betz 130:770ce14d3d15 27 * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
Wolfgang Betz 130:770ce14d3d15 28 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
Wolfgang Betz 130:770ce14d3d15 29 * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
Wolfgang Betz 130:770ce14d3d15 30 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
Wolfgang Betz 130:770ce14d3d15 31 *
Wolfgang Betz 130:770ce14d3d15 32 * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
Vincent Coubard 278:a5209d8cfd61 33 */
Vincent Coubard 278:a5209d8cfd61 34
Wolfgang Betz 130:770ce14d3d15 35 /** @defgroup BlueNRGDevice
Wolfgang Betz 130:770ce14d3d15 36 * @brief BlueNRG BLE_API Device Adaptation
Wolfgang Betz 130:770ce14d3d15 37 * @{
Wolfgang Betz 130:770ce14d3d15 38 */
Wolfgang Betz 130:770ce14d3d15 39
Vincent Coubard 278:a5209d8cfd61 40 #ifdef YOTTA_CFG_MBED_OS
Vincent Coubard 278:a5209d8cfd61 41 #include "mbed-drivers/mbed.h"
Vincent Coubard 278:a5209d8cfd61 42 #else
Vincent Coubard 278:a5209d8cfd61 43 #include "mbed.h"
Vincent Coubard 278:a5209d8cfd61 44 #endif
Wolfgang Betz 130:770ce14d3d15 45 #include "BlueNRGDevice.h"
Wolfgang Betz 130:770ce14d3d15 46 #include "BlueNRGGap.h"
Wolfgang Betz 130:770ce14d3d15 47 #include "BlueNRGGattServer.h"
Wolfgang Betz 130:770ce14d3d15 48
Wolfgang Betz 130:770ce14d3d15 49 #include "btle.h"
Vincent Coubard 293:5a1f577bf92f 50 #include "ble_utils.h"
Vincent Coubard 293:5a1f577bf92f 51 #include "ble_osal.h"
Wolfgang Betz 130:770ce14d3d15 52
Vincent Coubard 293:5a1f577bf92f 53 #include "ble_debug.h"
Wolfgang Betz 130:770ce14d3d15 54 #include "stm32_bluenrg_ble.h"
Wolfgang Betz 130:770ce14d3d15 55
Wolfgang Betz 130:770ce14d3d15 56 extern "C" {
Vincent Coubard 293:5a1f577bf92f 57 #include "ble_hci.h"
Antonio Vilei 245:6830f71c197c 58 #include "bluenrg_utils.h"
Wolfgang Betz 130:770ce14d3d15 59 }
Wolfgang Betz 130:770ce14d3d15 60
Wolfgang Betz 130:770ce14d3d15 61 #define HEADER_SIZE 5
Wolfgang Betz 130:770ce14d3d15 62 #define MAX_BUFFER_SIZE 255
Wolfgang Betz 130:770ce14d3d15 63
Wolfgang Betz 130:770ce14d3d15 64 /**
Wolfgang Betz 130:770ce14d3d15 65 * The singleton which represents the BlueNRG transport for the BLEDevice.
Wolfgang Betz 130:770ce14d3d15 66 *
Wolfgang Betz 130:770ce14d3d15 67 * See file 'x_nucleo_idb0xa1_targets.h' for details regarding the peripheral pins used!
Wolfgang Betz 130:770ce14d3d15 68 */
Wolfgang Betz 130:770ce14d3d15 69 #include "x_nucleo_idb0xa1_targets.h"
Wolfgang Betz 130:770ce14d3d15 70
Wolfgang Betz 130:770ce14d3d15 71 BlueNRGDevice bluenrgDeviceInstance(IDB0XA1_PIN_SPI_MOSI,
Wolfgang Betz 130:770ce14d3d15 72 IDB0XA1_PIN_SPI_MISO,
Wolfgang Betz 130:770ce14d3d15 73 IDB0XA1_PIN_SPI_SCK,
Wolfgang Betz 130:770ce14d3d15 74 IDB0XA1_PIN_SPI_nCS,
Wolfgang Betz 130:770ce14d3d15 75 IDB0XA1_PIN_SPI_RESET,
Wolfgang Betz 130:770ce14d3d15 76 IDB0XA1_PIN_SPI_IRQ);
Wolfgang Betz 130:770ce14d3d15 77
Wolfgang Betz 130:770ce14d3d15 78 /**
Wolfgang Betz 130:770ce14d3d15 79 * BLE-API requires an implementation of the following function in order to
Wolfgang Betz 130:770ce14d3d15 80 * obtain its transport handle.
Wolfgang Betz 130:770ce14d3d15 81 */
Wolfgang Betz 130:770ce14d3d15 82 BLEInstanceBase *
Wolfgang Betz 130:770ce14d3d15 83 createBLEInstance(void)
Wolfgang Betz 130:770ce14d3d15 84 {
Wolfgang Betz 130:770ce14d3d15 85 return (&bluenrgDeviceInstance);
Wolfgang Betz 130:770ce14d3d15 86 }
Wolfgang Betz 130:770ce14d3d15 87
Wolfgang Betz 130:770ce14d3d15 88 /**************************************************************************/
Wolfgang Betz 130:770ce14d3d15 89 /**
Wolfgang Betz 130:770ce14d3d15 90 @brief Constructor
Wolfgang Betz 130:770ce14d3d15 91 * @param mosi mbed pin to use for MOSI line of SPI interface
Wolfgang Betz 130:770ce14d3d15 92 * @param miso mbed pin to use for MISO line of SPI interface
Wolfgang Betz 130:770ce14d3d15 93 * @param sck mbed pin to use for SCK line of SPI interface
Wolfgang Betz 130:770ce14d3d15 94 * @param cs mbed pin to use for not chip select line of SPI interface
Wolfgang Betz 130:770ce14d3d15 95 * @param rst mbed pin to use for BlueNRG reset
Wolfgang Betz 130:770ce14d3d15 96 * @param irq mbed pin for BlueNRG IRQ
Wolfgang Betz 130:770ce14d3d15 97 */
Wolfgang Betz 130:770ce14d3d15 98 /**************************************************************************/
Wolfgang Betz 130:770ce14d3d15 99 BlueNRGDevice::BlueNRGDevice(PinName mosi,
Wolfgang Betz 130:770ce14d3d15 100 PinName miso,
Wolfgang Betz 130:770ce14d3d15 101 PinName sck,
Wolfgang Betz 130:770ce14d3d15 102 PinName cs,
Wolfgang Betz 130:770ce14d3d15 103 PinName rst,
Vincent Coubard 278:a5209d8cfd61 104 PinName irq) :
Wolfgang Betz 168:ad1dff5dca1f 105 isInitialized(false), spi_(mosi, miso, sck), nCS_(cs), rst_(rst), irq_(irq)
Wolfgang Betz 130:770ce14d3d15 106 {
Wolfgang Betz 130:770ce14d3d15 107 // Setup the spi for 8 bit data, low clock polarity,
Wolfgang Betz 130:770ce14d3d15 108 // 1-edge phase, with an 8MHz clock rate
Wolfgang Betz 130:770ce14d3d15 109 spi_.format(8, 0);
Wolfgang Betz 130:770ce14d3d15 110 spi_.frequency(8000000);
Vincent Coubard 278:a5209d8cfd61 111
Wolfgang Betz 130:770ce14d3d15 112 // Deselect the BlueNRG chip by keeping its nCS signal high
Wolfgang Betz 130:770ce14d3d15 113 nCS_ = 1;
Wolfgang Betz 130:770ce14d3d15 114
Wolfgang Betz 130:770ce14d3d15 115 wait_us(500);
Antonio Vilei 245:6830f71c197c 116
Antonio Vilei 246:d73c4f798379 117 // Prepare communication between the host and the BlueNRG SPI interface
Antonio Vilei 246:d73c4f798379 118 HCI_Init();
Antonio Vilei 246:d73c4f798379 119
Antonio Vilei 245:6830f71c197c 120 // Set the interrupt handler for the device
Antonio Vilei 245:6830f71c197c 121 irq_.mode(PullDown); // set irq mode
Antonio Vilei 245:6830f71c197c 122 irq_.rise(&HCI_Isr);
Wolfgang Betz 130:770ce14d3d15 123 }
Wolfgang Betz 130:770ce14d3d15 124
Wolfgang Betz 130:770ce14d3d15 125 /**************************************************************************/
Wolfgang Betz 130:770ce14d3d15 126 /**
Wolfgang Betz 130:770ce14d3d15 127 @brief Destructor
Wolfgang Betz 130:770ce14d3d15 128 */
Wolfgang Betz 130:770ce14d3d15 129 /**************************************************************************/
Wolfgang Betz 130:770ce14d3d15 130 BlueNRGDevice::~BlueNRGDevice(void)
Wolfgang Betz 130:770ce14d3d15 131 {
Wolfgang Betz 130:770ce14d3d15 132 }
Wolfgang Betz 130:770ce14d3d15 133
Antonio Vilei 245:6830f71c197c 134 /**
Antonio Vilei 245:6830f71c197c 135 * @brief Get BlueNRG HW version in bootloader mode
Antonio Vilei 245:6830f71c197c 136 * @param hw_version The HW version is written to this parameter
Antonio Vilei 245:6830f71c197c 137 * @retval It returns BLE_STATUS_SUCCESS on success or an error code otherwise
Antonio Vilei 245:6830f71c197c 138 */
Antonio Vilei 245:6830f71c197c 139 uint8_t BlueNRGDevice::getUpdaterHardwareVersion(uint8_t *hw_version)
Antonio Vilei 245:6830f71c197c 140 {
Antonio Vilei 245:6830f71c197c 141 uint8_t status;
Antonio Vilei 245:6830f71c197c 142
Antonio Vilei 245:6830f71c197c 143 status = getBlueNRGUpdaterHWVersion(hw_version);
Antonio Vilei 245:6830f71c197c 144
Antonio Vilei 245:6830f71c197c 145 return (status);
Antonio Vilei 245:6830f71c197c 146 }
Wolfgang Betz 130:770ce14d3d15 147
Wolfgang Betz 130:770ce14d3d15 148 /**
Antonio Vilei 245:6830f71c197c 149 * @brief Flash a new firmware using internal bootloader.
Antonio Vilei 245:6830f71c197c 150 * @param fw_image Pointer to the firmware image (raw binary data,
Antonio Vilei 245:6830f71c197c 151 * little-endian).
Antonio Vilei 245:6830f71c197c 152 * @param fw_size Size of the firmware image. The firmware image size shall
Antonio Vilei 245:6830f71c197c 153 * be multiple of 4 bytes.
Antonio Vilei 245:6830f71c197c 154 * @retval int It returns BLE_STATUS_SUCCESS on success, or a number
Antonio Vilei 245:6830f71c197c 155 * not equal to 0 in case of error
Antonio Vilei 245:6830f71c197c 156 * (ACI_ERROR, UNSUPPORTED_VERSION, WRONG_IMAGE_SIZE, CRC_ERROR)
Antonio Vilei 245:6830f71c197c 157 */
Antonio Vilei 245:6830f71c197c 158 int BlueNRGDevice::updateFirmware(const uint8_t *fw_image, uint32_t fw_size)
Antonio Vilei 245:6830f71c197c 159 {
Antonio Vilei 245:6830f71c197c 160 int status = program_device(fw_image, fw_size);
Vincent Coubard 278:a5209d8cfd61 161
Antonio Vilei 245:6830f71c197c 162 return (status);
Antonio Vilei 245:6830f71c197c 163 }
Antonio Vilei 245:6830f71c197c 164
Antonio Vilei 245:6830f71c197c 165
Antonio Vilei 245:6830f71c197c 166 /**
Antonio Vilei 245:6830f71c197c 167 * @brief Initialises anything required to start using BLE
Antonio Vilei 245:6830f71c197c 168 * @param[in] instanceID
Antonio Vilei 245:6830f71c197c 169 * The ID of the instance to initialize.
Antonio Vilei 245:6830f71c197c 170 * @param[in] callback
Antonio Vilei 245:6830f71c197c 171 * A callback for when initialization completes for a BLE
Antonio Vilei 245:6830f71c197c 172 * instance. This is an optional parameter set to NULL when not
Antonio Vilei 245:6830f71c197c 173 * supplied.
Antonio Vilei 245:6830f71c197c 174 *
Antonio Vilei 245:6830f71c197c 175 * @return BLE_ERROR_NONE if the initialization procedure was started
Antonio Vilei 245:6830f71c197c 176 * successfully.
Antonio Vilei 245:6830f71c197c 177 */
Andrea Palmieri 167:abc42e7158a6 178 ble_error_t BlueNRGDevice::init(BLE::InstanceID_t instanceID, FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext *> callback)
Wolfgang Betz 130:770ce14d3d15 179 {
Andrea Palmieri 167:abc42e7158a6 180 if (isInitialized) {
Andrea Palmieri 167:abc42e7158a6 181 BLE::InitializationCompleteCallbackContext context = {
Andrea Palmieri 167:abc42e7158a6 182 BLE::Instance(instanceID),
Andrea Palmieri 167:abc42e7158a6 183 BLE_ERROR_ALREADY_INITIALIZED
Andrea Palmieri 167:abc42e7158a6 184 };
Andrea Palmieri 167:abc42e7158a6 185 callback.call(&context);
Andrea Palmieri 167:abc42e7158a6 186 return BLE_ERROR_ALREADY_INITIALIZED;
Andrea Palmieri 167:abc42e7158a6 187 }
Vincent Coubard 271:7dc6261c33e5 188
Antonio Vilei 245:6830f71c197c 189 // Init the BlueNRG/BlueNRG-MS stack
Vincent Coubard 271:7dc6261c33e5 190 btleInit();
Vincent Coubard 278:a5209d8cfd61 191
Wolfgang Betz 130:770ce14d3d15 192 isInitialized = true;
Andrea Palmieri 167:abc42e7158a6 193 BLE::InitializationCompleteCallbackContext context = {
Andrea Palmieri 167:abc42e7158a6 194 BLE::Instance(instanceID),
Andrea Palmieri 167:abc42e7158a6 195 BLE_ERROR_NONE
Andrea Palmieri 167:abc42e7158a6 196 };
Andrea Palmieri 167:abc42e7158a6 197 callback.call(&context);
Vincent Coubard 278:a5209d8cfd61 198
Wolfgang Betz 130:770ce14d3d15 199 return BLE_ERROR_NONE;
Wolfgang Betz 130:770ce14d3d15 200 }
Wolfgang Betz 130:770ce14d3d15 201
Wolfgang Betz 130:770ce14d3d15 202
Wolfgang Betz 130:770ce14d3d15 203 /**
Wolfgang Betz 130:770ce14d3d15 204 @brief Resets the BLE HW, removing any existing services and
Wolfgang Betz 130:770ce14d3d15 205 characteristics
Wolfgang Betz 130:770ce14d3d15 206 @param[in] void
Andrea Palmieri 229:9981f62cdb1a 207 @returns void
Wolfgang Betz 130:770ce14d3d15 208 */
Andrea Palmieri 229:9981f62cdb1a 209 void BlueNRGDevice::reset(void)
Wolfgang Betz 130:770ce14d3d15 210 {
Wolfgang Betz 130:770ce14d3d15 211 wait_us(500);
Wolfgang Betz 130:770ce14d3d15 212
Wolfgang Betz 130:770ce14d3d15 213 /* Reset BlueNRG SPI interface */
Wolfgang Betz 130:770ce14d3d15 214 rst_ = 0;
Wolfgang Betz 130:770ce14d3d15 215 wait_us(5);
Wolfgang Betz 130:770ce14d3d15 216 rst_ = 1;
Wolfgang Betz 130:770ce14d3d15 217 wait_us(5);
Wolfgang Betz 130:770ce14d3d15 218
Wolfgang Betz 130:770ce14d3d15 219 /* Wait for the radio to come back up */
Wolfgang Betz 130:770ce14d3d15 220 wait_us(500);
Wolfgang Betz 130:770ce14d3d15 221
Wolfgang Betz 130:770ce14d3d15 222 }
Wolfgang Betz 130:770ce14d3d15 223
Wolfgang Betz 130:770ce14d3d15 224 /*!
Vincent Coubard 278:a5209d8cfd61 225 @brief Wait for any BLE Event like BLE Connection, Read Request etc.
Wolfgang Betz 130:770ce14d3d15 226 @param[in] void
Vincent Coubard 278:a5209d8cfd61 227 @returns char *
Wolfgang Betz 130:770ce14d3d15 228 */
Wolfgang Betz 130:770ce14d3d15 229 void BlueNRGDevice::waitForEvent(void)
Wolfgang Betz 130:770ce14d3d15 230 {
Wolfgang Betz 130:770ce14d3d15 231 bool must_return = false;
Wolfgang Betz 130:770ce14d3d15 232
Wolfgang Betz 130:770ce14d3d15 233 do {
Vincent Coubard 264:1e754a01869e 234 bluenrgDeviceInstance.processEvents();
Vincent Coubard 278:a5209d8cfd61 235
Wolfgang Betz 130:770ce14d3d15 236 if(must_return) return;
Wolfgang Betz 130:770ce14d3d15 237
Wolfgang Betz 130:770ce14d3d15 238 __WFE(); /* it is recommended that SEVONPEND in the
Wolfgang Betz 130:770ce14d3d15 239 System Control Register is NOT set */
Wolfgang Betz 130:770ce14d3d15 240 must_return = true; /* after returning from WFE we must guarantee
Wolfgang Betz 130:770ce14d3d15 241 that conrol is given back to main loop before next WFE */
Wolfgang Betz 130:770ce14d3d15 242 } while(true);
Wolfgang Betz 130:770ce14d3d15 243
Vincent Coubard 278:a5209d8cfd61 244 }
Vincent Coubard 278:a5209d8cfd61 245
Wolfgang Betz 130:770ce14d3d15 246 /*!
Wolfgang Betz 130:770ce14d3d15 247 @brief get GAP version
Andrea Palmieri 216:7aa807180321 248 @brief Get the BLE stack version information
Wolfgang Betz 130:770ce14d3d15 249 @param[in] void
Wolfgang Betz 130:770ce14d3d15 250 @returns char *
Andrea Palmieri 216:7aa807180321 251 @returns char *
Wolfgang Betz 130:770ce14d3d15 252 */
Wolfgang Betz 130:770ce14d3d15 253 const char *BlueNRGDevice::getVersion(void)
Wolfgang Betz 130:770ce14d3d15 254 {
Andrea Palmieri 216:7aa807180321 255 return getVersionString();
Wolfgang Betz 130:770ce14d3d15 256 }
Wolfgang Betz 130:770ce14d3d15 257
Wolfgang Betz 130:770ce14d3d15 258 /**************************************************************************/
Wolfgang Betz 130:770ce14d3d15 259 /*!
Wolfgang Betz 130:770ce14d3d15 260 @brief get reference to GAP object
Wolfgang Betz 130:770ce14d3d15 261 @param[in] void
Vincent Coubard 278:a5209d8cfd61 262 @returns Gap&
Wolfgang Betz 130:770ce14d3d15 263 */
Wolfgang Betz 130:770ce14d3d15 264 /**************************************************************************/
Vincent Coubard 278:a5209d8cfd61 265 Gap &BlueNRGDevice::getGap()
Wolfgang Betz 130:770ce14d3d15 266 {
Wolfgang Betz 130:770ce14d3d15 267 return BlueNRGGap::getInstance();
Wolfgang Betz 130:770ce14d3d15 268 }
Wolfgang Betz 130:770ce14d3d15 269
Vincent Coubard 278:a5209d8cfd61 270 const Gap &BlueNRGDevice::getGap() const
Wolfgang Betz 130:770ce14d3d15 271 {
Wolfgang Betz 130:770ce14d3d15 272 return BlueNRGGap::getInstance();
Wolfgang Betz 130:770ce14d3d15 273 }
Wolfgang Betz 130:770ce14d3d15 274
Wolfgang Betz 130:770ce14d3d15 275 /**************************************************************************/
Wolfgang Betz 130:770ce14d3d15 276 /*!
Wolfgang Betz 130:770ce14d3d15 277 @brief get reference to GATT server object
Wolfgang Betz 130:770ce14d3d15 278 @param[in] void
Vincent Coubard 278:a5209d8cfd61 279 @returns GattServer&
Wolfgang Betz 130:770ce14d3d15 280 */
Wolfgang Betz 130:770ce14d3d15 281 /**************************************************************************/
Vincent Coubard 278:a5209d8cfd61 282 GattServer &BlueNRGDevice::getGattServer()
Wolfgang Betz 130:770ce14d3d15 283 {
Wolfgang Betz 130:770ce14d3d15 284 return BlueNRGGattServer::getInstance();
Wolfgang Betz 130:770ce14d3d15 285 }
Wolfgang Betz 130:770ce14d3d15 286
Wolfgang Betz 130:770ce14d3d15 287 const GattServer &BlueNRGDevice::getGattServer() const
Wolfgang Betz 130:770ce14d3d15 288 {
Wolfgang Betz 130:770ce14d3d15 289 return BlueNRGGattServer::getInstance();
Wolfgang Betz 130:770ce14d3d15 290 }
Vincent Coubard 278:a5209d8cfd61 291
Wolfgang Betz 130:770ce14d3d15 292 /**************************************************************************/
Wolfgang Betz 130:770ce14d3d15 293 /*!
Andrea Palmieri 216:7aa807180321 294 @brief shut down the BLE device
Wolfgang Betz 130:770ce14d3d15 295 @param[out] error if any
Wolfgang Betz 130:770ce14d3d15 296 */
Wolfgang Betz 130:770ce14d3d15 297 /**************************************************************************/
Wolfgang Betz 130:770ce14d3d15 298 ble_error_t BlueNRGDevice::shutdown(void) {
Andrea Palmieri 216:7aa807180321 299 if (!isInitialized) {
Andrea Palmieri 216:7aa807180321 300 return BLE_ERROR_INITIALIZATION_INCOMPLETE;
Andrea Palmieri 216:7aa807180321 301 }
Andrea Palmieri 216:7aa807180321 302
Andrea Palmieri 229:9981f62cdb1a 303 /* Reset the BlueNRG device first */
Andrea Palmieri 229:9981f62cdb1a 304 reset();
Andrea Palmieri 229:9981f62cdb1a 305
Andrea Palmieri 229:9981f62cdb1a 306 /* Shutdown the BLE API and BlueNRG glue code */
Andrea Palmieri 229:9981f62cdb1a 307 ble_error_t error;
Andrea Palmieri 229:9981f62cdb1a 308
Andrea Palmieri 229:9981f62cdb1a 309 /* GattServer instance */
Andrea Palmieri 229:9981f62cdb1a 310 error = BlueNRGGattServer::getInstance().reset();
Andrea Palmieri 229:9981f62cdb1a 311 if (error != BLE_ERROR_NONE) {
Andrea Palmieri 229:9981f62cdb1a 312 return error;
Andrea Palmieri 229:9981f62cdb1a 313 }
Andrea Palmieri 229:9981f62cdb1a 314
Andrea Palmieri 229:9981f62cdb1a 315 /* GattClient instance */
Andrea Palmieri 229:9981f62cdb1a 316 error = BlueNRGGattClient::getInstance().reset();
Andrea Palmieri 229:9981f62cdb1a 317 if (error != BLE_ERROR_NONE) {
Andrea Palmieri 229:9981f62cdb1a 318 return error;
Andrea Palmieri 229:9981f62cdb1a 319 }
Andrea Palmieri 229:9981f62cdb1a 320
Andrea Palmieri 229:9981f62cdb1a 321 /* Gap instance */
Andrea Palmieri 229:9981f62cdb1a 322 error = BlueNRGGap::getInstance().reset();
Andrea Palmieri 229:9981f62cdb1a 323 if (error != BLE_ERROR_NONE) {
Andrea Palmieri 229:9981f62cdb1a 324 return error;
Andrea Palmieri 229:9981f62cdb1a 325 }
Andrea Palmieri 229:9981f62cdb1a 326
Andrea Palmieri 229:9981f62cdb1a 327 isInitialized = false;
Andrea Palmieri 229:9981f62cdb1a 328
Andrea Palmieri 229:9981f62cdb1a 329 return BLE_ERROR_NONE;
Andrea Palmieri 229:9981f62cdb1a 330
Wolfgang Betz 130:770ce14d3d15 331 }
Vincent Coubard 278:a5209d8cfd61 332
Wolfgang Betz 130:770ce14d3d15 333 /**
Wolfgang Betz 130:770ce14d3d15 334 * @brief Reads from BlueNRG SPI buffer and store data into local buffer.
Wolfgang Betz 130:770ce14d3d15 335 * @param buffer : Buffer where data from SPI are stored
Wolfgang Betz 130:770ce14d3d15 336 * @param buff_size: Buffer size
Wolfgang Betz 130:770ce14d3d15 337 * @retval int32_t : Number of read bytes
Wolfgang Betz 130:770ce14d3d15 338 */
Wolfgang Betz 130:770ce14d3d15 339 int32_t BlueNRGDevice::spiRead(uint8_t *buffer, uint8_t buff_size)
Wolfgang Betz 130:770ce14d3d15 340 {
Wolfgang Betz 130:770ce14d3d15 341 uint16_t byte_count;
Wolfgang Betz 130:770ce14d3d15 342 uint8_t len = 0;
Wolfgang Betz 130:770ce14d3d15 343 uint8_t char_ff = 0xff;
Wolfgang Betz 130:770ce14d3d15 344 volatile uint8_t read_char;
Vincent Coubard 278:a5209d8cfd61 345
Wolfgang Betz 130:770ce14d3d15 346 uint8_t i = 0;
Wolfgang Betz 130:770ce14d3d15 347 volatile uint8_t tmpreg;
Wolfgang Betz 130:770ce14d3d15 348
Wolfgang Betz 130:770ce14d3d15 349 uint8_t header_master[HEADER_SIZE] = {0x0b, 0x00, 0x00, 0x00, 0x00};
Wolfgang Betz 130:770ce14d3d15 350 uint8_t header_slave[HEADER_SIZE];
Wolfgang Betz 130:770ce14d3d15 351
Wolfgang Betz 130:770ce14d3d15 352 /* Select the chip */
Wolfgang Betz 130:770ce14d3d15 353 nCS_ = 0;
Vincent Coubard 278:a5209d8cfd61 354
Vincent Coubard 278:a5209d8cfd61 355 /* Read the header */
Wolfgang Betz 130:770ce14d3d15 356 for (i = 0; i < 5; i++)
Vincent Coubard 278:a5209d8cfd61 357 {
Wolfgang Betz 130:770ce14d3d15 358 tmpreg = spi_.write(header_master[i]);
Wolfgang Betz 130:770ce14d3d15 359 header_slave[i] = (uint8_t)(tmpreg);
Vincent Coubard 278:a5209d8cfd61 360 }
Vincent Coubard 278:a5209d8cfd61 361
Wolfgang Betz 130:770ce14d3d15 362 if (header_slave[0] == 0x02) {
Wolfgang Betz 130:770ce14d3d15 363 /* device is ready */
Wolfgang Betz 130:770ce14d3d15 364 byte_count = (header_slave[4]<<8)|header_slave[3];
Vincent Coubard 278:a5209d8cfd61 365
Wolfgang Betz 130:770ce14d3d15 366 if (byte_count > 0) {
Vincent Coubard 278:a5209d8cfd61 367
Wolfgang Betz 130:770ce14d3d15 368 /* avoid to read more data that size of the buffer */
Wolfgang Betz 130:770ce14d3d15 369 if (byte_count > buff_size){
Wolfgang Betz 130:770ce14d3d15 370 byte_count = buff_size;
Wolfgang Betz 130:770ce14d3d15 371 }
Vincent Coubard 278:a5209d8cfd61 372
Wolfgang Betz 130:770ce14d3d15 373 for (len = 0; len < byte_count; len++){
Wolfgang Betz 130:770ce14d3d15 374 read_char = spi_.write(char_ff);
Wolfgang Betz 130:770ce14d3d15 375 buffer[len] = read_char;
Wolfgang Betz 130:770ce14d3d15 376 }
Vincent Coubard 278:a5209d8cfd61 377 }
Wolfgang Betz 130:770ce14d3d15 378 }
Wolfgang Betz 130:770ce14d3d15 379 /* Release CS line to deselect the chip */
Wolfgang Betz 130:770ce14d3d15 380 nCS_ = 1;
Vincent Coubard 278:a5209d8cfd61 381
Wolfgang Betz 130:770ce14d3d15 382 // Add a small delay to give time to the BlueNRG to set the IRQ pin low
Wolfgang Betz 130:770ce14d3d15 383 // to avoid a useless SPI read at the end of the transaction
Wolfgang Betz 130:770ce14d3d15 384 for(volatile int i = 0; i < 2; i++)__NOP();
Vincent Coubard 278:a5209d8cfd61 385
Wolfgang Betz 130:770ce14d3d15 386 #ifdef PRINT_CSV_FORMAT
Wolfgang Betz 130:770ce14d3d15 387 if (len > 0) {
Wolfgang Betz 130:770ce14d3d15 388 print_csv_time();
Wolfgang Betz 130:770ce14d3d15 389 for (int i=0; i<len; i++) {
Wolfgang Betz 130:770ce14d3d15 390 PRINT_CSV(" %02x", buffer[i]);
Wolfgang Betz 130:770ce14d3d15 391 }
Wolfgang Betz 130:770ce14d3d15 392 PRINT_CSV("\n");
Wolfgang Betz 130:770ce14d3d15 393 }
Wolfgang Betz 130:770ce14d3d15 394 #endif
Vincent Coubard 278:a5209d8cfd61 395
Vincent Coubard 278:a5209d8cfd61 396 return len;
Wolfgang Betz 130:770ce14d3d15 397 }
Wolfgang Betz 130:770ce14d3d15 398
Wolfgang Betz 130:770ce14d3d15 399 /**
Wolfgang Betz 130:770ce14d3d15 400 * @brief Writes data from local buffer to SPI.
Wolfgang Betz 130:770ce14d3d15 401 * @param data1 : First data buffer to be written
Wolfgang Betz 130:770ce14d3d15 402 * @param data2 : Second data buffer to be written
Wolfgang Betz 130:770ce14d3d15 403 * @param Nb_bytes1: Size of first data buffer to be written
Wolfgang Betz 130:770ce14d3d15 404 * @param Nb_bytes2: Size of second data buffer to be written
Wolfgang Betz 130:770ce14d3d15 405 * @retval Number of read bytes
Wolfgang Betz 130:770ce14d3d15 406 */
Wolfgang Betz 130:770ce14d3d15 407 int32_t BlueNRGDevice::spiWrite(uint8_t* data1,
Wolfgang Betz 130:770ce14d3d15 408 uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2)
Vincent Coubard 278:a5209d8cfd61 409 {
Wolfgang Betz 130:770ce14d3d15 410 int32_t result = 0;
Wolfgang Betz 130:770ce14d3d15 411 uint32_t i;
Wolfgang Betz 130:770ce14d3d15 412 volatile uint8_t tmpreg;
Vincent Coubard 278:a5209d8cfd61 413
Wolfgang Betz 130:770ce14d3d15 414 unsigned char header_master[HEADER_SIZE] = {0x0a, 0x00, 0x00, 0x00, 0x00};
Wolfgang Betz 130:770ce14d3d15 415 unsigned char header_slave[HEADER_SIZE] = {0xaa, 0x00, 0x00, 0x00, 0x00};
Wolfgang Betz 130:770ce14d3d15 416
Wolfgang Betz 130:770ce14d3d15 417 disable_irq();
Wolfgang Betz 130:770ce14d3d15 418
Wolfgang Betz 130:770ce14d3d15 419 /* CS reset */
Wolfgang Betz 130:770ce14d3d15 420 nCS_ = 0;
Wolfgang Betz 130:770ce14d3d15 421
Vincent Coubard 278:a5209d8cfd61 422 /* Exchange header */
Wolfgang Betz 130:770ce14d3d15 423 for (i = 0; i < 5; i++)
Vincent Coubard 278:a5209d8cfd61 424 {
Wolfgang Betz 130:770ce14d3d15 425 tmpreg = spi_.write(header_master[i]);
Wolfgang Betz 130:770ce14d3d15 426 header_slave[i] = tmpreg;
Vincent Coubard 278:a5209d8cfd61 427 }
Vincent Coubard 278:a5209d8cfd61 428
Wolfgang Betz 130:770ce14d3d15 429 if (header_slave[0] == 0x02) {
Wolfgang Betz 130:770ce14d3d15 430 /* SPI is ready */
Wolfgang Betz 130:770ce14d3d15 431 if (header_slave[1] >= (Nb_bytes1+Nb_bytes2)) {
Vincent Coubard 278:a5209d8cfd61 432
Wolfgang Betz 130:770ce14d3d15 433 /* Buffer is big enough */
Wolfgang Betz 130:770ce14d3d15 434 for (i = 0; i < Nb_bytes1; i++) {
Wolfgang Betz 130:770ce14d3d15 435 spi_.write(*(data1 + i));
Wolfgang Betz 130:770ce14d3d15 436 }
Wolfgang Betz 130:770ce14d3d15 437 for (i = 0; i < Nb_bytes2; i++) {
Wolfgang Betz 130:770ce14d3d15 438 spi_.write(*(data2 + i));
Vincent Coubard 278:a5209d8cfd61 439 }
Wolfgang Betz 130:770ce14d3d15 440 } else {
Wolfgang Betz 130:770ce14d3d15 441 /* Buffer is too small */
Wolfgang Betz 130:770ce14d3d15 442 result = -2;
Wolfgang Betz 130:770ce14d3d15 443 }
Wolfgang Betz 130:770ce14d3d15 444 } else {
Wolfgang Betz 130:770ce14d3d15 445 /* SPI is not ready */
Wolfgang Betz 130:770ce14d3d15 446 result = -1;
Wolfgang Betz 130:770ce14d3d15 447 }
Vincent Coubard 278:a5209d8cfd61 448
Wolfgang Betz 130:770ce14d3d15 449 /* Release CS line */
Wolfgang Betz 130:770ce14d3d15 450 //HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET);
Wolfgang Betz 130:770ce14d3d15 451 nCS_ = 1;
Vincent Coubard 278:a5209d8cfd61 452
Wolfgang Betz 130:770ce14d3d15 453 enable_irq();
Vincent Coubard 278:a5209d8cfd61 454
Wolfgang Betz 130:770ce14d3d15 455 return result;
Wolfgang Betz 130:770ce14d3d15 456 }
Wolfgang Betz 130:770ce14d3d15 457
Wolfgang Betz 130:770ce14d3d15 458 bool BlueNRGDevice::dataPresent()
Wolfgang Betz 130:770ce14d3d15 459 {
Wolfgang Betz 130:770ce14d3d15 460 return (irq_ == 1);
Wolfgang Betz 130:770ce14d3d15 461 }
Wolfgang Betz 130:770ce14d3d15 462
Wolfgang Betz 130:770ce14d3d15 463 void BlueNRGDevice::disable_irq()
Wolfgang Betz 130:770ce14d3d15 464 {
Wolfgang Betz 130:770ce14d3d15 465 irq_.disable_irq();
Wolfgang Betz 130:770ce14d3d15 466 }
Wolfgang Betz 130:770ce14d3d15 467
Wolfgang Betz 130:770ce14d3d15 468 void BlueNRGDevice::enable_irq()
Wolfgang Betz 130:770ce14d3d15 469 {
Wolfgang Betz 130:770ce14d3d15 470 irq_.enable_irq();
Wolfgang Betz 130:770ce14d3d15 471 }
Vincent Coubard 264:1e754a01869e 472
Vincent Coubard 264:1e754a01869e 473 void BlueNRGDevice::processEvents() {
Vincent Coubard 264:1e754a01869e 474 btle_handler();
Vincent Coubard 271:7dc6261c33e5 475 }