NUCLEO-F401RE + BlueNRG shield client test (TI Sensortag reading)
Embed:
(wiki syntax)
Show/hide line numbers
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 20:44:37 by 1.7.2