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 NUCLEO_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 #include "bluenrg_shield_bsp.h" 00037 #include "cube_hal.h" 00038 #include "hci.h" 00039 00040 /** @addtogroup BlueNRG_Shield 00041 * @{ 00042 */ 00043 00044 /** @defgroup BlueNRG_Shield_Driver 00045 * @brief BlueNRG Shield driver based on STM32Cube HAL for STM32 Nucleo boards. 00046 * @{ 00047 */ 00048 00049 00050 /* SPI handler declared in "main.c" file */ 00051 extern SPI_HandleTypeDef SpiHandle; 00052 00053 00054 /** 00055 * @brief This function is used for low level initialization of the SPI 00056 * communication with the BlueNRG Shield. 00057 * @param hspi: handle of the STM32Cube HAL SPI interface 00058 * @retval None 00059 */ 00060 void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi) 00061 { 00062 GPIO_InitTypeDef GPIO_InitStruct; 00063 if(hspi->Instance==BNRG_SPI_INSTANCE) { 00064 /* Enable peripherals clock */ 00065 00066 /* Enable GPIO Ports Clock */ 00067 BNRG_SPI_RESET_CLK_ENABLE(); 00068 BNRG_SPI_SCLK_CLK_ENABLE(); 00069 BNRG_SPI_MISO_CLK_ENABLE(); 00070 BNRG_SPI_MOSI_CLK_ENABLE(); 00071 BNRG_SPI_CS_CLK_ENABLE(); 00072 BNRG_SPI_IRQ_CLK_ENABLE(); 00073 00074 /* Enable SPI clock */ 00075 BNRG_SPI_CLK_ENABLE(); 00076 00077 /* Reset */ 00078 GPIO_InitStruct.Pin = BNRG_SPI_RESET_PIN; 00079 GPIO_InitStruct.Mode = BNRG_SPI_RESET_MODE; 00080 GPIO_InitStruct.Pull = BNRG_SPI_RESET_PULL; 00081 GPIO_InitStruct.Speed = BNRG_SPI_RESET_SPEED; 00082 GPIO_InitStruct.Alternate = BNRG_SPI_RESET_ALTERNATE; 00083 HAL_GPIO_Init(BNRG_SPI_RESET_PORT, &GPIO_InitStruct); 00084 HAL_GPIO_WritePin(BNRG_SPI_RESET_PORT, BNRG_SPI_RESET_PIN, GPIO_PIN_RESET); /*Added to avoid spurious interrupt from the BlueNRG */ 00085 00086 /* SCLK */ 00087 GPIO_InitStruct.Pin = BNRG_SPI_SCLK_PIN; 00088 GPIO_InitStruct.Mode = BNRG_SPI_SCLK_MODE; 00089 GPIO_InitStruct.Pull = BNRG_SPI_SCLK_PULL; 00090 GPIO_InitStruct.Speed = BNRG_SPI_SCLK_SPEED; 00091 GPIO_InitStruct.Alternate = BNRG_SPI_SCLK_ALTERNATE; 00092 HAL_GPIO_Init(BNRG_SPI_SCLK_PORT, &GPIO_InitStruct); 00093 00094 /* MISO */ 00095 GPIO_InitStruct.Pin = BNRG_SPI_MISO_PIN; 00096 GPIO_InitStruct.Mode = BNRG_SPI_MISO_MODE; 00097 GPIO_InitStruct.Pull = BNRG_SPI_MISO_PULL; 00098 GPIO_InitStruct.Speed = BNRG_SPI_MISO_SPEED; 00099 GPIO_InitStruct.Alternate = BNRG_SPI_MISO_ALTERNATE; 00100 HAL_GPIO_Init(BNRG_SPI_MISO_PORT, &GPIO_InitStruct); 00101 00102 /* MOSI */ 00103 GPIO_InitStruct.Pin = BNRG_SPI_MOSI_PIN; 00104 GPIO_InitStruct.Mode = BNRG_SPI_MOSI_MODE; 00105 GPIO_InitStruct.Pull = BNRG_SPI_MOSI_PULL; 00106 GPIO_InitStruct.Speed = BNRG_SPI_MOSI_SPEED; 00107 GPIO_InitStruct.Alternate = BNRG_SPI_MOSI_ALTERNATE; 00108 HAL_GPIO_Init(BNRG_SPI_MOSI_PORT, &GPIO_InitStruct); 00109 00110 /* NSS/CSN/CS */ 00111 GPIO_InitStruct.Pin = BNRG_SPI_CS_PIN; 00112 GPIO_InitStruct.Mode = BNRG_SPI_CS_MODE; 00113 GPIO_InitStruct.Pull = BNRG_SPI_CS_PULL; 00114 GPIO_InitStruct.Speed = BNRG_SPI_CS_SPEED; 00115 GPIO_InitStruct.Alternate = BNRG_SPI_CS_ALTERNATE; 00116 HAL_GPIO_Init(BNRG_SPI_CS_PORT, &GPIO_InitStruct); 00117 HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET); 00118 00119 /* IRQ -- INPUT */ 00120 GPIO_InitStruct.Pin = BNRG_SPI_IRQ_PIN; 00121 GPIO_InitStruct.Mode = BNRG_SPI_IRQ_MODE; 00122 GPIO_InitStruct.Pull = BNRG_SPI_IRQ_PULL; 00123 GPIO_InitStruct.Speed = BNRG_SPI_IRQ_SPEED; 00124 GPIO_InitStruct.Alternate = BNRG_SPI_IRQ_ALTERNATE; 00125 HAL_GPIO_Init(BNRG_SPI_IRQ_PORT, &GPIO_InitStruct); 00126 00127 /* Configure the NVIC for SPI */ 00128 HAL_NVIC_SetPriority(BNRG_SPI_EXTI_IRQn, 4, 0); 00129 HAL_NVIC_EnableIRQ(BNRG_SPI_EXTI_IRQn); 00130 } 00131 } 00132 00133 /** 00134 * @brief EXTI line detection callback. 00135 * @param GPIO_Pin: Specifies the pins connected EXTI line 00136 * @retval None 00137 */ 00138 void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) 00139 { 00140 tHciDataPacket * hciReadPacket;// = NULL; 00141 uint8_t data_len; 00142 /* 00143 * No need to call Clear_SPI_EXTI_Flag() here as 00144 * HAL_GPIO_EXTI_IRQHandler() already does it 00145 */ 00146 00147 if(GPIO_Pin == BNRG_SPI_EXTI_PIN) { 00148 00149 while (HAL_GPIO_ReadPin(BNRG_SPI_EXTI_PORT, BNRG_SPI_EXTI_PIN) == GPIO_PIN_SET) { 00150 if (list_is_empty (&hciReadPktPool) == FALSE) { 00151 /* enqueueing a packet for read */ 00152 list_remove_head (&hciReadPktPool, (tListNode **)&hciReadPacket); 00153 data_len = BlueNRG_SPI_Read_All(&SpiHandle, hciReadPacket->dataBuff, HCI_PACKET_SIZE); 00154 00155 if(data_len > 0) { 00156 /* Packet will be inserted to the correct queue */ 00157 HCI_Input(hciReadPacket); 00158 } else { 00159 /* Insert the packet back into the pool */ 00160 list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); 00161 } 00162 00163 } else { 00164 /* TODO: HCI Read Packet Pool is empty, wait for a free packet */ 00165 } 00166 00167 Clear_SPI_EXTI_Flag(); 00168 } 00169 } 00170 } 00171 00172 00173 /** 00174 * @brief This function is used to initialize the SPI communication with 00175 * the BlueNRG Shield. 00176 * @param None 00177 * @retval None 00178 */ 00179 void BNRG_SPI_Init(void) 00180 { 00181 SpiHandle.Instance = BNRG_SPI_INSTANCE; 00182 SpiHandle.Init.Mode = BNRG_SPI_MODE; 00183 SpiHandle.Init.Direction = BNRG_SPI_DIRECTION; 00184 SpiHandle.Init.DataSize = BNRG_SPI_DATASIZE; 00185 SpiHandle.Init.CLKPolarity = BNRG_SPI_CLKPOLARITY; 00186 SpiHandle.Init.CLKPhase = BNRG_SPI_CLKPHASE; 00187 SpiHandle.Init.NSS = BNRG_SPI_NSS; 00188 SpiHandle.Init.FirstBit = BNRG_SPI_FIRSTBIT; 00189 SpiHandle.Init.TIMode = BNRG_SPI_TIMODE; 00190 SpiHandle.Init.CRCPolynomial = BNRG_SPI_CRCPOLYNOMIAL; 00191 SpiHandle.Init.BaudRatePrescaler = BNRG_SPI_BAUDRATEPRESCALER; 00192 SpiHandle.Init.CRCCalculation = BNRG_SPI_CRCCALCULATION; 00193 00194 HAL_SPI_Init(&SpiHandle); 00195 } 00196 00197 /** 00198 * @brief Read from BlueNRG SPI buffer and store data into local buffer 00199 * @param hspi: handle of the STM32Cube HAL SPI interface 00200 * @param buffer: buffer where data from SPI are stored 00201 * @param buff_size: buffer size 00202 * @retval number of read bytes 00203 */ 00204 int32_t BlueNRG_SPI_Read_All(SPI_HandleTypeDef *hspi, uint8_t *buffer, uint8_t buff_size) 00205 { 00206 uint16_t byte_count; 00207 uint8_t len = 0; 00208 uint8_t i = 0; 00209 uint8_t char_ff = 0xff; 00210 volatile uint8_t read_char; 00211 00212 uint8_t header_master[5] = {0x0b, 0x00, 0x00, 0x00, 0x00}; 00213 uint8_t header_slave[5]; 00214 00215 /* CS reset */ 00216 HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_RESET); 00217 00218 /* Read the header */ 00219 for (i = 0; i < 5; i++) { 00220 HAL_SPI_TransmitReceive(hspi, &header_master[i], &header_slave[i], 1, 15); 00221 } 00222 00223 00224 if (header_slave[0] == 0x02) { 00225 /* device is ready */ 00226 byte_count = (header_slave[4]<<8)|header_slave[3]; 00227 00228 if (byte_count > 0) { 00229 00230 /* avoid to read more data that size of the buffer */ 00231 if (byte_count > buff_size) { 00232 byte_count = buff_size; 00233 } 00234 00235 for (len = 0; len < byte_count; len++) { 00236 HAL_SPI_TransmitReceive(hspi, &char_ff, (uint8_t*)&read_char, 1, 15); 00237 buffer[len] = read_char; 00238 } 00239 } 00240 } 00241 /* Release CS line */ 00242 HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET); 00243 00244 return len; 00245 } 00246 00247 /** 00248 * @brief Write data from local buffer to SPI 00249 * @param hspi: handle of the STM32Cube HAL SPI interface 00250 * @param data1: first data buffer to be written 00251 * @param data2: second data buffer to be written 00252 * @param Nb_bytes1: size of first data buffer to be written 00253 * @param Nb_bytes2: size of second data buffer to be written 00254 * @retval number of read bytes 00255 */ 00256 int32_t BlueNRG_SPI_Write(SPI_HandleTypeDef *hspi, uint8_t* data1, uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2) 00257 { 00258 uint32_t i; 00259 uint8_t read_char; 00260 int32_t result = 0; 00261 00262 unsigned char header_master[5] = {0x0a, 0x00, 0x00, 0x00, 0x00}; 00263 unsigned char header_slave[5] = {0xaa, 0x00, 0x00, 0x00, 0x00}; 00264 00265 Disable_SPI_IRQ(); 00266 00267 /* CS reset */ 00268 HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_RESET); 00269 00270 /* Exchange header */ 00271 00272 00273 for (i = 0; i < 5; i++) { 00274 HAL_SPI_TransmitReceive(hspi, &header_master[i], &header_slave[i], 1, 15); 00275 } 00276 00277 00278 if (header_slave[0] == 0x02) { 00279 /* SPI is ready */ 00280 if (header_slave[1] >= (Nb_bytes1+Nb_bytes2)) { 00281 /* Buffer is big enough */ 00282 for (i = 0; i < Nb_bytes1; i++) { 00283 HAL_SPI_TransmitReceive(hspi, (data1 + i), &read_char, 1, 15); 00284 } 00285 for (i = 0; i < Nb_bytes2; i++) { 00286 HAL_SPI_TransmitReceive(hspi, (data2 + i), &read_char, 1, 15); 00287 } 00288 } else { 00289 /* Buffer is too small */ 00290 result = -2; 00291 } 00292 } else { 00293 /* SPI is not ready */ 00294 result = -1; 00295 } 00296 00297 /* Release CS line */ 00298 HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET); 00299 00300 Enable_SPI_IRQ(); 00301 00302 return result; 00303 } 00304 00305 /** 00306 * Writes data to a serial interface. 00307 * 00308 * @param data1 1st buffer 00309 * @param data2 2nd buffer 00310 * @param n_bytes1 number of bytes in 1st buffer 00311 * @param n_bytes2 number of bytes in 2nd buffer 00312 */ 00313 void Hal_Write_Serial(const void* data1, const void* data2, tHalInt32 n_bytes1, tHalInt32 n_bytes2) 00314 { 00315 struct timer t; 00316 00317 Timer_Set(&t, CLOCK_SECOND/10); 00318 00319 while(1) { 00320 if(BlueNRG_SPI_Write(&SpiHandle, (uint8_t *)data1,(uint8_t *)data2, n_bytes1, n_bytes2)==0) break; 00321 if(Timer_Expired(&t)) { 00322 break; 00323 } 00324 } 00325 } 00326 00327 /** 00328 * @brief Disable SPI IRQ 00329 * @param None 00330 * @retval None 00331 */ 00332 void Disable_SPI_IRQ(void) 00333 { 00334 HAL_NVIC_DisableIRQ(BNRG_SPI_EXTI_IRQn); 00335 } 00336 00337 /** 00338 * @brief Enable SPI IRQ 00339 * @param None 00340 * @retval None 00341 */ 00342 void Enable_SPI_IRQ(void) 00343 { 00344 HAL_NVIC_EnableIRQ(BNRG_SPI_EXTI_IRQn); 00345 } 00346 00347 /** 00348 * @brief Clear Pending SPI IRQ 00349 * @param None 00350 * @retval None 00351 */ 00352 void Clear_SPI_IRQ(void) 00353 { 00354 HAL_NVIC_ClearPendingIRQ(BNRG_SPI_EXTI_IRQn); 00355 } 00356 00357 /** 00358 * @brief Clear EXTI (External Interrupt) line for SPI IRQ 00359 * @param None 00360 * @retval None 00361 */ 00362 void Clear_SPI_EXTI_Flag(void) 00363 { 00364 __HAL_GPIO_EXTI_CLEAR_IT(BNRG_SPI_EXTI_PIN); 00365 } 00366 00367 /** 00368 * @brief Reset the BlueNRG 00369 * @param None 00370 * @retval None 00371 */ 00372 void BlueNRG_RST(void) 00373 { 00374 HAL_GPIO_WritePin(BNRG_SPI_RESET_PORT, BNRG_SPI_RESET_PIN, GPIO_PIN_RESET); 00375 HAL_Delay(5); 00376 HAL_GPIO_WritePin(BNRG_SPI_RESET_PORT, BNRG_SPI_RESET_PIN, GPIO_PIN_SET); 00377 HAL_Delay(5); 00378 } 00379 00380 /** 00381 * @} 00382 */ 00383 00384 /** 00385 * @} 00386 */ 00387 00388 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Tue Jul 12 2022 22:44:50 by
 1.7.2
 1.7.2 
    