Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of X_NUCLEO_IDB0XA1 by
BlueNRGDevice.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2013 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 /** 00018 ****************************************************************************** 00019 * @file BlueNRGDevice.cpp 00020 * @author STMicroelectronics 00021 * @brief Implementation of BLEDeviceInstanceBase 00022 ****************************************************************************** 00023 * @copy 00024 * 00025 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 00026 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE 00027 * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY 00028 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING 00029 * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE 00030 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 00031 * 00032 * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> 00033 */ 00034 00035 /** @defgroup BlueNRGDevice 00036 * @brief BlueNRG BLE_API Device Adaptation 00037 * @{ 00038 */ 00039 00040 #include "mbed.h" 00041 #include "BlueNRGDevice.h" 00042 #include "BlueNRGGap.h" 00043 #include "BlueNRGGattServer.h" 00044 00045 #include "btle.h" 00046 #include "Utils.h" 00047 #include "osal.h" 00048 00049 #include "debug.h" 00050 #include "stm32_bluenrg_ble.h " 00051 00052 extern "C" { 00053 #include "hci.h" 00054 } 00055 00056 #define HEADER_SIZE 5 00057 #define MAX_BUFFER_SIZE 255 00058 00059 /** 00060 * The singleton which represents the BlueNRG transport for the BLEDevice. 00061 * 00062 * See file 'x_nucleo_idb0xa1_targets.h' for details regarding the peripheral pins used! 00063 */ 00064 #include "x_nucleo_idb0xa1_targets.h" 00065 00066 BlueNRGDevice bluenrgDeviceInstance(IDB0XA1_PIN_SPI_MOSI, 00067 IDB0XA1_PIN_SPI_MISO, 00068 IDB0XA1_PIN_SPI_SCK, 00069 IDB0XA1_PIN_SPI_nCS, 00070 IDB0XA1_PIN_SPI_RESET, 00071 IDB0XA1_PIN_SPI_IRQ); 00072 00073 /** 00074 * BLE-API requires an implementation of the following function in order to 00075 * obtain its transport handle. 00076 */ 00077 BLEInstanceBase * 00078 createBLEInstance(void) 00079 { 00080 return (&bluenrgDeviceInstance); 00081 } 00082 00083 /**************************************************************************/ 00084 /** 00085 @brief Constructor 00086 * @param mosi mbed pin to use for MOSI line of SPI interface 00087 * @param miso mbed pin to use for MISO line of SPI interface 00088 * @param sck mbed pin to use for SCK line of SPI interface 00089 * @param cs mbed pin to use for not chip select line of SPI interface 00090 * @param rst mbed pin to use for BlueNRG reset 00091 * @param irq mbed pin for BlueNRG IRQ 00092 */ 00093 /**************************************************************************/ 00094 BlueNRGDevice::BlueNRGDevice(PinName mosi, 00095 PinName miso, 00096 PinName sck, 00097 PinName cs, 00098 PinName rst, 00099 PinName irq) : 00100 isInitialized(false), spi_(mosi, miso, sck), nCS_(cs), rst_(rst), irq_(irq) 00101 { 00102 // Setup the spi for 8 bit data, low clock polarity, 00103 // 1-edge phase, with an 8MHz clock rate 00104 spi_.format(8, 0); 00105 spi_.frequency(8000000); 00106 00107 // Deselect the BlueNRG chip by keeping its nCS signal high 00108 nCS_ = 1; 00109 00110 wait_us(500); 00111 } 00112 00113 /**************************************************************************/ 00114 /** 00115 @brief Destructor 00116 */ 00117 /**************************************************************************/ 00118 BlueNRGDevice::~BlueNRGDevice(void) 00119 { 00120 } 00121 00122 00123 /** 00124 @brief Initialises anything required to start using BLE 00125 @param[in] void 00126 @returns ble_error_t 00127 */ 00128 ble_error_t BlueNRGDevice::init(BLE::InstanceID_t instanceID, FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext *> callback) 00129 { 00130 if (isInitialized) { 00131 BLE::InitializationCompleteCallbackContext context = { 00132 BLE::Instance(instanceID), 00133 BLE_ERROR_ALREADY_INITIALIZED 00134 }; 00135 callback.call(&context); 00136 return BLE_ERROR_ALREADY_INITIALIZED; 00137 } 00138 00139 // Set the interrupt handler for the device 00140 irq_.mode(PullDown); // betzw: set irq mode 00141 irq_.rise(&HCI_Isr); 00142 00143 /* ToDo: Clear memory contents, reset the SD, etc. */ 00144 // By default, we set the device GAP role to PERIPHERAL 00145 btle_init(BlueNRGGap::getInstance().getIsSetAddress(), GAP_PERIPHERAL_ROLE_IDB04A1); 00146 00147 isInitialized = true; 00148 BLE::InitializationCompleteCallbackContext context = { 00149 BLE::Instance(instanceID), 00150 BLE_ERROR_NONE 00151 }; 00152 callback.call(&context); 00153 00154 return BLE_ERROR_NONE; 00155 } 00156 00157 00158 /** 00159 @brief Resets the BLE HW, removing any existing services and 00160 characteristics 00161 @param[in] void 00162 @returns ble_error_t 00163 */ 00164 ble_error_t BlueNRGDevice::reset(void) 00165 { 00166 wait_us(500); 00167 00168 /* Reset BlueNRG SPI interface */ 00169 rst_ = 0; 00170 wait_us(5); 00171 rst_ = 1; 00172 wait_us(5); 00173 00174 /* Wait for the radio to come back up */ 00175 wait_us(500); 00176 00177 isInitialized = false; 00178 00179 return BLE_ERROR_NONE; 00180 } 00181 00182 /*! 00183 @brief Wait for any BLE Event like BLE Connection, Read Request etc. 00184 @param[in] void 00185 @returns char * 00186 */ 00187 void BlueNRGDevice::waitForEvent(void) 00188 { 00189 bool must_return = false; 00190 00191 do { 00192 BlueNRGGap::getInstance().Process(); 00193 00194 HCI_Process(); 00195 00196 if(must_return) return; 00197 00198 __WFE(); /* it is recommended that SEVONPEND in the 00199 System Control Register is NOT set */ 00200 must_return = true; /* after returning from WFE we must guarantee 00201 that conrol is given back to main loop before next WFE */ 00202 } while(true); 00203 00204 } 00205 00206 /*! 00207 @brief get GAP version 00208 @param[in] void 00209 @returns char * 00210 */ 00211 const char *BlueNRGDevice::getVersion(void) 00212 { 00213 char *version = new char[6]; 00214 memcpy((void *)version, "1.0.0", 5); 00215 return version; 00216 } 00217 00218 /**************************************************************************/ 00219 /*! 00220 @brief get reference to GAP object 00221 @param[in] void 00222 @returns Gap& 00223 */ 00224 /**************************************************************************/ 00225 Gap &BlueNRGDevice::getGap() 00226 { 00227 return BlueNRGGap::getInstance(); 00228 } 00229 00230 const Gap &BlueNRGDevice::getGap() const 00231 { 00232 return BlueNRGGap::getInstance(); 00233 } 00234 00235 /**************************************************************************/ 00236 /*! 00237 @brief get reference to GATT server object 00238 @param[in] void 00239 @returns GattServer& 00240 */ 00241 /**************************************************************************/ 00242 GattServer &BlueNRGDevice::getGattServer() 00243 { 00244 return BlueNRGGattServer::getInstance(); 00245 } 00246 00247 const GattServer &BlueNRGDevice::getGattServer() const 00248 { 00249 return BlueNRGGattServer::getInstance(); 00250 } 00251 00252 /**************************************************************************/ 00253 /*! 00254 @brief shut down the the BLE device 00255 @param[out] error if any 00256 */ 00257 /**************************************************************************/ 00258 ble_error_t BlueNRGDevice::shutdown(void) { 00259 return reset(); 00260 } 00261 00262 /** 00263 * @brief Reads from BlueNRG SPI buffer and store data into local buffer. 00264 * @param buffer : Buffer where data from SPI are stored 00265 * @param buff_size: Buffer size 00266 * @retval int32_t : Number of read bytes 00267 */ 00268 int32_t BlueNRGDevice::spiRead(uint8_t *buffer, uint8_t buff_size) 00269 { 00270 uint16_t byte_count; 00271 uint8_t len = 0; 00272 uint8_t char_ff = 0xff; 00273 volatile uint8_t read_char; 00274 00275 uint8_t i = 0; 00276 volatile uint8_t tmpreg; 00277 00278 uint8_t header_master[HEADER_SIZE] = {0x0b, 0x00, 0x00, 0x00, 0x00}; 00279 uint8_t header_slave[HEADER_SIZE]; 00280 00281 /* Select the chip */ 00282 nCS_ = 0; 00283 00284 /* Read the header */ 00285 for (i = 0; i < 5; i++) 00286 { 00287 tmpreg = spi_.write(header_master[i]); 00288 header_slave[i] = (uint8_t)(tmpreg); 00289 } 00290 00291 if (header_slave[0] == 0x02) { 00292 /* device is ready */ 00293 byte_count = (header_slave[4]<<8)|header_slave[3]; 00294 00295 if (byte_count > 0) { 00296 00297 /* avoid to read more data that size of the buffer */ 00298 if (byte_count > buff_size){ 00299 byte_count = buff_size; 00300 } 00301 00302 for (len = 0; len < byte_count; len++){ 00303 read_char = spi_.write(char_ff); 00304 buffer[len] = read_char; 00305 } 00306 } 00307 } 00308 /* Release CS line to deselect the chip */ 00309 nCS_ = 1; 00310 00311 // Add a small delay to give time to the BlueNRG to set the IRQ pin low 00312 // to avoid a useless SPI read at the end of the transaction 00313 for(volatile int i = 0; i < 2; i++)__NOP(); 00314 00315 #ifdef PRINT_CSV_FORMAT 00316 if (len > 0) { 00317 print_csv_time(); 00318 for (int i=0; i<len; i++) { 00319 PRINT_CSV(" %02x", buffer[i]); 00320 } 00321 PRINT_CSV("\n"); 00322 } 00323 #endif 00324 00325 return len; 00326 } 00327 00328 /** 00329 * @brief Writes data from local buffer to SPI. 00330 * @param data1 : First data buffer to be written 00331 * @param data2 : Second data buffer to be written 00332 * @param Nb_bytes1: Size of first data buffer to be written 00333 * @param Nb_bytes2: Size of second data buffer to be written 00334 * @retval Number of read bytes 00335 */ 00336 int32_t BlueNRGDevice::spiWrite(uint8_t* data1, 00337 uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2) 00338 { 00339 int32_t result = 0; 00340 uint32_t i; 00341 volatile uint8_t tmpreg; 00342 00343 unsigned char header_master[HEADER_SIZE] = {0x0a, 0x00, 0x00, 0x00, 0x00}; 00344 unsigned char header_slave[HEADER_SIZE] = {0xaa, 0x00, 0x00, 0x00, 0x00}; 00345 00346 disable_irq(); 00347 00348 /* CS reset */ 00349 nCS_ = 0; 00350 00351 /* Exchange header */ 00352 for (i = 0; i < 5; i++) 00353 { 00354 tmpreg = spi_.write(header_master[i]); 00355 header_slave[i] = tmpreg; 00356 } 00357 00358 if (header_slave[0] == 0x02) { 00359 /* SPI is ready */ 00360 if (header_slave[1] >= (Nb_bytes1+Nb_bytes2)) { 00361 00362 /* Buffer is big enough */ 00363 for (i = 0; i < Nb_bytes1; i++) { 00364 spi_.write(*(data1 + i)); 00365 } 00366 for (i = 0; i < Nb_bytes2; i++) { 00367 spi_.write(*(data2 + i)); 00368 } 00369 } else { 00370 /* Buffer is too small */ 00371 result = -2; 00372 } 00373 } else { 00374 /* SPI is not ready */ 00375 result = -1; 00376 } 00377 00378 /* Release CS line */ 00379 //HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET); 00380 nCS_ = 1; 00381 00382 enable_irq(); 00383 00384 return result; 00385 } 00386 00387 bool BlueNRGDevice::dataPresent() 00388 { 00389 return (irq_ == 1); 00390 } 00391 00392 void BlueNRGDevice::disable_irq() 00393 { 00394 irq_.disable_irq(); 00395 } 00396 00397 void BlueNRGDevice::enable_irq() 00398 { 00399 irq_.enable_irq(); 00400 }
Generated on Tue Jul 12 2022 19:31:15 by
 1.7.2
 1.7.2 
    