project
Fork of X_NUCLEO_IDB0XA1 by
Embed:
(wiki syntax)
Show/hide line numbers
BlueNRGDevice.cpp
Go to the documentation of this file.
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