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