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 BLE_BlueNRG by
bluenrg_shield_bsp.c
00001 /** 00002 ****************************************************************************** 00003 * File Name : bluenrg_shield_bsp.c 00004 * Date : 16/05/2014 00005 * Description : This file provides code for the BlueNRG Shield driver 00006 * based on STM32Cube HAL for STM32 Nucleo boards. 00007 ****************************************************************************** 00008 * 00009 * COPYRIGHT(c) 2014 STMicroelectronics 00010 * 00011 * Redistribution and use in source and binary forms, with or without modification, 00012 * are permitted provided that the following conditions are met: 00013 * 1. Redistributions of source code must retain the above copyright notice, 00014 * this list of conditions and the following disclaimer. 00015 * 2. Redistributions in binary form must reproduce the above copyright notice, 00016 * this list of conditions and the following disclaimer in the documentation 00017 * and/or other materials provided with the distribution. 00018 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00019 * may be used to endorse or promote products derived from this software 00020 * without specific prior written permission. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00023 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00024 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00025 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00026 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00027 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00028 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00029 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00030 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00031 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00032 * 00033 ****************************************************************************** 00034 */ 00035 /* Includes ------------------------------------------------------------------*/ 00036 //#ifdef USE_STM32F4XX_NUCLEO 00037 //#include "stm32f4xx_bluenrg_shield_bsp.h" 00038 //#else 00039 //#ifdef USE_STM32L0XX_NUCLEO 00040 #include "stm32l0xx_bluenrg_shield_bsp.h" 00041 //#endif 00042 //#endif 00043 00044 #include "cube_hal.h" 00045 #include "hci.h" 00046 00047 /** @addtogroup BlueNRG_Shield 00048 * @{ 00049 */ 00050 00051 /** @defgroup BlueNRG_Shield_Driver 00052 * @brief BlueNRG Shield driver based on STM32Cube HAL for STM32 Nucleo boards. 00053 * @{ 00054 */ 00055 00056 00057 /* SPI handler declared in "main.c" file */ 00058 extern SPI_HandleTypeDef SpiHandle; 00059 00060 00061 /** 00062 * @brief This function is used for low level initialization of the SPI 00063 * communication with the BlueNRG Shield. 00064 * @param hspi: handle of the STM32Cube HAL SPI interface 00065 * @retval None 00066 */ 00067 void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi) 00068 { 00069 GPIO_InitTypeDef GPIO_InitStruct; 00070 if(hspi->Instance==BNRG_SPI_INSTANCE) 00071 { 00072 /* Enable peripherals clock */ 00073 00074 /* Enable GPIO Ports Clock */ 00075 BNRG_SPI_RESET_CLK_ENABLE(); 00076 BNRG_SPI_SCLK_CLK_ENABLE(); 00077 BNRG_SPI_MISO_CLK_ENABLE(); 00078 BNRG_SPI_MOSI_CLK_ENABLE(); 00079 BNRG_SPI_CS_CLK_ENABLE(); 00080 BNRG_SPI_IRQ_CLK_ENABLE(); 00081 00082 /* Enable SPI clock */ 00083 BNRG_SPI_CLK_ENABLE(); 00084 00085 /* Reset */ 00086 GPIO_InitStruct.Pin = BNRG_SPI_RESET_PIN; 00087 GPIO_InitStruct.Mode = BNRG_SPI_RESET_MODE; 00088 GPIO_InitStruct.Pull = BNRG_SPI_RESET_PULL; 00089 GPIO_InitStruct.Speed = BNRG_SPI_RESET_SPEED; 00090 GPIO_InitStruct.Alternate = BNRG_SPI_RESET_ALTERNATE; 00091 HAL_GPIO_Init(BNRG_SPI_RESET_PORT, &GPIO_InitStruct); 00092 HAL_GPIO_WritePin(BNRG_SPI_RESET_PORT, BNRG_SPI_RESET_PIN, GPIO_PIN_RESET); /*Added to avoid spurious interrupt from the BlueNRG */ 00093 00094 /* SCLK */ 00095 GPIO_InitStruct.Pin = BNRG_SPI_SCLK_PIN; 00096 GPIO_InitStruct.Mode = BNRG_SPI_SCLK_MODE; 00097 GPIO_InitStruct.Pull = BNRG_SPI_SCLK_PULL; 00098 GPIO_InitStruct.Speed = BNRG_SPI_SCLK_SPEED; 00099 GPIO_InitStruct.Alternate = BNRG_SPI_SCLK_ALTERNATE; 00100 HAL_GPIO_Init(BNRG_SPI_SCLK_PORT, &GPIO_InitStruct); 00101 00102 /* MISO */ 00103 GPIO_InitStruct.Pin = BNRG_SPI_MISO_PIN; 00104 GPIO_InitStruct.Mode = BNRG_SPI_MISO_MODE; 00105 GPIO_InitStruct.Pull = BNRG_SPI_MISO_PULL; 00106 GPIO_InitStruct.Speed = BNRG_SPI_MISO_SPEED; 00107 GPIO_InitStruct.Alternate = BNRG_SPI_MISO_ALTERNATE; 00108 HAL_GPIO_Init(BNRG_SPI_MISO_PORT, &GPIO_InitStruct); 00109 00110 /* MOSI */ 00111 GPIO_InitStruct.Pin = BNRG_SPI_MOSI_PIN; 00112 GPIO_InitStruct.Mode = BNRG_SPI_MOSI_MODE; 00113 GPIO_InitStruct.Pull = BNRG_SPI_MOSI_PULL; 00114 GPIO_InitStruct.Speed = BNRG_SPI_MOSI_SPEED; 00115 GPIO_InitStruct.Alternate = BNRG_SPI_MOSI_ALTERNATE; 00116 HAL_GPIO_Init(BNRG_SPI_MOSI_PORT, &GPIO_InitStruct); 00117 00118 /* NSS/CSN/CS */ 00119 GPIO_InitStruct.Pin = BNRG_SPI_CS_PIN; 00120 GPIO_InitStruct.Mode = BNRG_SPI_CS_MODE; 00121 GPIO_InitStruct.Pull = BNRG_SPI_CS_PULL; 00122 GPIO_InitStruct.Speed = BNRG_SPI_CS_SPEED; 00123 GPIO_InitStruct.Alternate = BNRG_SPI_CS_ALTERNATE; 00124 HAL_GPIO_Init(BNRG_SPI_CS_PORT, &GPIO_InitStruct); 00125 HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET); 00126 00127 /* IRQ -- INPUT */ 00128 GPIO_InitStruct.Pin = BNRG_SPI_IRQ_PIN; 00129 GPIO_InitStruct.Mode = BNRG_SPI_IRQ_MODE; 00130 GPIO_InitStruct.Pull = BNRG_SPI_IRQ_PULL; 00131 GPIO_InitStruct.Speed = BNRG_SPI_IRQ_SPEED; 00132 GPIO_InitStruct.Alternate = BNRG_SPI_IRQ_ALTERNATE; 00133 HAL_GPIO_Init(BNRG_SPI_IRQ_PORT, &GPIO_InitStruct); 00134 00135 /* Configure the NVIC for SPI */ 00136 HAL_NVIC_SetPriority(BNRG_SPI_EXTI_IRQn, 4, 0); 00137 HAL_NVIC_EnableIRQ(BNRG_SPI_EXTI_IRQn); 00138 } 00139 } 00140 00141 /** 00142 * @brief EXTI line detection callback. 00143 * @param GPIO_Pin: Specifies the pins connected EXTI line 00144 * @retval None 00145 */ 00146 void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) 00147 { 00148 tHciDataPacket * hciReadPacket = NULL; 00149 uint8_t data_len; 00150 /* 00151 * No need to call Clear_SPI_EXTI_Flag() here as 00152 * HAL_GPIO_EXTI_IRQHandler() already does it 00153 */ 00154 00155 if(GPIO_Pin == BNRG_SPI_EXTI_PIN) { 00156 00157 while (HAL_GPIO_ReadPin(BNRG_SPI_EXTI_PORT, BNRG_SPI_EXTI_PIN) == GPIO_PIN_SET) { 00158 if (list_is_empty (&hciReadPktPool) == FALSE){ 00159 /* enqueueing a packet for read */ 00160 list_remove_head (&hciReadPktPool, (tListNode **)&hciReadPacket); 00161 data_len = BlueNRG_SPI_Read_All(&SpiHandle, hciReadPacket->dataBuff, HCI_PACKET_SIZE); 00162 00163 if(data_len > 0){ 00164 /* Packet will be inserted to the correct queue */ 00165 HCI_Input(hciReadPacket); 00166 } else { 00167 /* Insert the packet back into the pool */ 00168 list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); 00169 } 00170 00171 } else{ 00172 /* TODO: HCI Read Packet Pool is empty, wait for a free packet */ 00173 } 00174 00175 Clear_SPI_EXTI_Flag(); 00176 } 00177 } 00178 } 00179 00180 00181 /** 00182 * @brief This function is used to initialize the SPI communication with 00183 * the BlueNRG Shield. 00184 * @param None 00185 * @retval None 00186 */ 00187 void BNRG_SPI_Init(void) 00188 { 00189 SpiHandle.Instance = BNRG_SPI_INSTANCE; 00190 SpiHandle.Init.Mode = BNRG_SPI_MODE; 00191 SpiHandle.Init.Direction = BNRG_SPI_DIRECTION; 00192 SpiHandle.Init.DataSize = BNRG_SPI_DATASIZE; 00193 SpiHandle.Init.CLKPolarity = BNRG_SPI_CLKPOLARITY; 00194 SpiHandle.Init.CLKPhase = BNRG_SPI_CLKPHASE; 00195 SpiHandle.Init.NSS = BNRG_SPI_NSS; 00196 SpiHandle.Init.FirstBit = BNRG_SPI_FIRSTBIT; 00197 SpiHandle.Init.TIMode = BNRG_SPI_TIMODE; 00198 SpiHandle.Init.CRCPolynomial = BNRG_SPI_CRCPOLYNOMIAL; 00199 SpiHandle.Init.BaudRatePrescaler = BNRG_SPI_BAUDRATEPRESCALER; 00200 SpiHandle.Init.CRCCalculation = BNRG_SPI_CRCCALCULATION; 00201 00202 HAL_SPI_Init(&SpiHandle); 00203 } 00204 00205 /** 00206 * @brief Read from BlueNRG SPI buffer and store data into local buffer 00207 * @param hspi: handle of the STM32Cube HAL SPI interface 00208 * @param buffer: buffer where data from SPI are stored 00209 * @param buff_size: buffer size 00210 * @retval number of read bytes 00211 */ 00212 int32_t BlueNRG_SPI_Read_All(SPI_HandleTypeDef *hspi, uint8_t *buffer, uint8_t buff_size) 00213 { 00214 uint16_t byte_count; 00215 uint8_t len = 0; 00216 uint8_t i = 0; 00217 uint8_t char_ff = 0xff; 00218 volatile uint8_t read_char; 00219 00220 uint8_t header_master[5] = {0x0b, 0x00, 0x00, 0x00, 0x00}; 00221 uint8_t header_slave[5]; 00222 00223 /* CS reset */ 00224 HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_RESET); 00225 00226 /* Read the header */ 00227 for (i = 0; i < 5; i++) 00228 { 00229 HAL_SPI_TransmitReceive(hspi, &header_master[i], &header_slave[i], 1, 15); 00230 } 00231 00232 00233 if (header_slave[0] == 0x02) { 00234 /* device is ready */ 00235 byte_count = (header_slave[4]<<8)|header_slave[3]; 00236 00237 if (byte_count > 0) { 00238 00239 /* avoid to read more data that size of the buffer */ 00240 if (byte_count > buff_size){ 00241 byte_count = buff_size; 00242 } 00243 00244 for (len = 0; len < byte_count; len++){ 00245 HAL_SPI_TransmitReceive(hspi, &char_ff, (uint8_t*)&read_char, 1, 15); 00246 buffer[len] = read_char; 00247 } 00248 } 00249 } 00250 /* Release CS line */ 00251 HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET); 00252 00253 return len; 00254 } 00255 00256 /** 00257 * @brief Write data from local buffer to SPI 00258 * @param hspi: handle of the STM32Cube HAL SPI interface 00259 * @param data1: first data buffer to be written 00260 * @param data2: second data buffer to be written 00261 * @param Nb_bytes1: size of first data buffer to be written 00262 * @param Nb_bytes2: size of second data buffer to be written 00263 * @retval number of read bytes 00264 */ 00265 int32_t BlueNRG_SPI_Write(SPI_HandleTypeDef *hspi, uint8_t* data1, uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2) 00266 { 00267 uint32_t i; 00268 uint8_t read_char; 00269 int32_t result = 0; 00270 00271 unsigned char header_master[5] = {0x0a, 0x00, 0x00, 0x00, 0x00}; 00272 unsigned char header_slave[5] = {0xaa, 0x00, 0x00, 0x00, 0x00}; 00273 00274 Disable_SPI_IRQ(); 00275 00276 /* CS reset */ 00277 HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_RESET); 00278 00279 /* Exchange header */ 00280 00281 00282 for (i = 0; i < 5; i++) 00283 { 00284 HAL_SPI_TransmitReceive(hspi, &header_master[i], &header_slave[i], 1, 15); 00285 } 00286 00287 00288 if (header_slave[0] == 0x02) { 00289 /* SPI is ready */ 00290 if (header_slave[1] >= (Nb_bytes1+Nb_bytes2)) { 00291 /* Buffer is big enough */ 00292 for (i = 0; i < Nb_bytes1; i++) { 00293 HAL_SPI_TransmitReceive(hspi, (data1 + i), &read_char, 1, 15); 00294 } 00295 for (i = 0; i < Nb_bytes2; i++) { 00296 HAL_SPI_TransmitReceive(hspi, (data2 + i), &read_char, 1, 15); 00297 } 00298 } else { 00299 /* Buffer is too small */ 00300 result = -2; 00301 } 00302 } else { 00303 /* SPI is not ready */ 00304 result = -1; 00305 } 00306 00307 /* Release CS line */ 00308 HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET); 00309 00310 Enable_SPI_IRQ(); 00311 00312 return result; 00313 } 00314 00315 /** 00316 * Writes data to a serial interface. 00317 * 00318 * @param data1 1st buffer 00319 * @param data2 2nd buffer 00320 * @param n_bytes1 number of bytes in 1st buffer 00321 * @param n_bytes2 number of bytes in 2nd buffer 00322 */ 00323 void Hal_Write_Serial(const void* data1, const void* data2, tHalInt32 n_bytes1, tHalInt32 n_bytes2) 00324 { 00325 struct timer t; 00326 00327 Timer_Set(&t, CLOCK_SECOND/10); 00328 00329 while(1){ 00330 if(BlueNRG_SPI_Write(&SpiHandle, (uint8_t *)data1,(uint8_t *)data2, n_bytes1, n_bytes2)==0) break; 00331 if(Timer_Expired(&t)){ 00332 break; 00333 } 00334 } 00335 } 00336 00337 /** 00338 * @brief Disable SPI IRQ 00339 * @param None 00340 * @retval None 00341 */ 00342 void Disable_SPI_IRQ(void) 00343 { 00344 HAL_NVIC_DisableIRQ(BNRG_SPI_EXTI_IRQn); 00345 } 00346 00347 /** 00348 * @brief Enable SPI IRQ 00349 * @param None 00350 * @retval None 00351 */ 00352 void Enable_SPI_IRQ(void) 00353 { 00354 HAL_NVIC_EnableIRQ(BNRG_SPI_EXTI_IRQn); 00355 } 00356 00357 /** 00358 * @brief Clear Pending SPI IRQ 00359 * @param None 00360 * @retval None 00361 */ 00362 void Clear_SPI_IRQ(void) 00363 { 00364 HAL_NVIC_ClearPendingIRQ(BNRG_SPI_EXTI_IRQn); 00365 } 00366 00367 /** 00368 * @brief Clear EXTI (External Interrupt) line for SPI IRQ 00369 * @param None 00370 * @retval None 00371 */ 00372 void Clear_SPI_EXTI_Flag(void) 00373 { 00374 __HAL_GPIO_EXTI_CLEAR_IT(BNRG_SPI_EXTI_PIN); 00375 } 00376 00377 /** 00378 * @brief Reset the BlueNRG 00379 * @param None 00380 * @retval None 00381 */ 00382 void BlueNRG_RST(void) 00383 { 00384 HAL_GPIO_WritePin(BNRG_SPI_RESET_PORT, BNRG_SPI_RESET_PIN, GPIO_PIN_RESET); 00385 HAL_Delay(5); 00386 HAL_GPIO_WritePin(BNRG_SPI_RESET_PORT, BNRG_SPI_RESET_PIN, GPIO_PIN_SET); 00387 HAL_Delay(5); 00388 } 00389 00390 /** 00391 * @} 00392 */ 00393 00394 /** 00395 * @} 00396 */ 00397 00398 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Tue Jul 12 2022 16:24:20 by
 1.7.2
 1.7.2 
    