STSW-STLKT01: Drivers/BSP/SensorTile/SensorTile_BlueNRG.c Source File

STSW-STLKT01

STSW-STLKT01
SensorTile_BlueNRG.c
Go to the documentation of this file.
1 
39 /* Includes ------------------------------------------------------------------*/
40 #include "SensorTile_BlueNRG.h"
41 #include "gp_timer.h"
42 #include "debug.h"
43 
44 #ifdef PRINT_CSV_FORMAT
45 extern volatile uint32_t ms_counter;
46 #endif /* PRINT_CSV_FORMAT */
47 
65 #define HEADER_SIZE 5
66 #define MAX_BUFFER_SIZE 255
67 #define TIMEOUT_DURATION 15
68 
77 SPI_HandleTypeDef SpiHandle;
78 
87 /* Private function prototypes -----------------------------------------------*/
88 static void us150Delay(void);
89 void set_irq_as_output(void);
90 void set_irq_as_input(void);
91 
100 #ifdef PRINT_CSV_FORMAT
101 
107 void print_csv_time(void){
108  uint32_t ms = ms_counter;
109  PRINT_CSV("%02d:%02d:%02d.%03d", ms/(60*60*1000)%24, ms/(60*1000)%60, (ms/1000)%60, ms%1000);
110 }
111 #endif /* PRINT_CSV_FORMAT */
112 
119 void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
120 {
121  GPIO_InitTypeDef GPIO_InitStruct;
122  if(hspi->Instance==BNRG_SPI_INSTANCE)
123  {
124  /* Enable peripherals clock */
125 
126  /* Enable GPIO Ports Clock */
127  BNRG_SPI_RESET_CLK_ENABLE();
128  BNRG_SPI_SCLK_CLK_ENABLE();
129  BNRG_SPI_MISO_CLK_ENABLE();
130  BNRG_SPI_MOSI_CLK_ENABLE();
131  BNRG_SPI_CS_CLK_ENABLE();
132  BNRG_SPI_IRQ_CLK_ENABLE();
133 
134  /* Enable SPI clock */
135  BNRG_SPI_CLK_ENABLE();
136 
137  /* Reset */
138  GPIO_InitStruct.Pin = BNRG_SPI_RESET_PIN;
139  GPIO_InitStruct.Mode = BNRG_SPI_RESET_MODE;
140  GPIO_InitStruct.Pull = BNRG_SPI_RESET_PULL;
141  GPIO_InitStruct.Speed = BNRG_SPI_RESET_SPEED;
142  GPIO_InitStruct.Alternate = BNRG_SPI_RESET_ALTERNATE;
143  HAL_GPIO_Init(BNRG_SPI_RESET_PORT, &GPIO_InitStruct);
144  HAL_GPIO_WritePin(BNRG_SPI_RESET_PORT, BNRG_SPI_RESET_PIN, GPIO_PIN_RESET); /*Added to avoid spurious interrupt from the BlueNRG */
145 
146  /* SCLK */
147  GPIO_InitStruct.Pin = BNRG_SPI_SCLK_PIN;
148  GPIO_InitStruct.Mode = BNRG_SPI_SCLK_MODE;
149  GPIO_InitStruct.Pull = BNRG_SPI_SCLK_PULL;
150  GPIO_InitStruct.Speed = BNRG_SPI_SCLK_SPEED;
151  GPIO_InitStruct.Alternate = BNRG_SPI_SCLK_ALTERNATE;
152  HAL_GPIO_Init(BNRG_SPI_SCLK_PORT, &GPIO_InitStruct);
153 
154  /* MISO */
155  GPIO_InitStruct.Pin = BNRG_SPI_MISO_PIN;
156  GPIO_InitStruct.Mode = BNRG_SPI_MISO_MODE;
157  GPIO_InitStruct.Pull = BNRG_SPI_MISO_PULL;
158  GPIO_InitStruct.Speed = BNRG_SPI_MISO_SPEED;
159  GPIO_InitStruct.Alternate = BNRG_SPI_MISO_ALTERNATE;
160  HAL_GPIO_Init(BNRG_SPI_MISO_PORT, &GPIO_InitStruct);
161 
162  /* MOSI */
163  GPIO_InitStruct.Pin = BNRG_SPI_MOSI_PIN;
164  GPIO_InitStruct.Mode = BNRG_SPI_MOSI_MODE;
165  GPIO_InitStruct.Pull = BNRG_SPI_MOSI_PULL;
166  GPIO_InitStruct.Speed = BNRG_SPI_MOSI_SPEED;
167  GPIO_InitStruct.Alternate = BNRG_SPI_MOSI_ALTERNATE;
168  HAL_GPIO_Init(BNRG_SPI_MOSI_PORT, &GPIO_InitStruct);
169 
170  /* NSS/CSN/CS */
171  GPIO_InitStruct.Pin = BNRG_SPI_CS_PIN;
172  GPIO_InitStruct.Mode = BNRG_SPI_CS_MODE;
173  GPIO_InitStruct.Pull = BNRG_SPI_CS_PULL;
174  GPIO_InitStruct.Speed = BNRG_SPI_CS_SPEED;
175  GPIO_InitStruct.Alternate = BNRG_SPI_CS_ALTERNATE;
176  HAL_GPIO_Init(BNRG_SPI_CS_PORT, &GPIO_InitStruct);
177  HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET);
178 
179  /* IRQ -- INPUT */
180  GPIO_InitStruct.Pin = BNRG_SPI_IRQ_PIN;
181  GPIO_InitStruct.Mode = BNRG_SPI_IRQ_MODE;
182  GPIO_InitStruct.Pull = BNRG_SPI_IRQ_PULL;
183  GPIO_InitStruct.Speed = BNRG_SPI_IRQ_SPEED;
184  GPIO_InitStruct.Alternate = BNRG_SPI_IRQ_ALTERNATE;
185  HAL_GPIO_Init(BNRG_SPI_IRQ_PORT, &GPIO_InitStruct);
186 
187  /* Configure the NVIC for SPI */
188  HAL_NVIC_SetPriority(BNRG_SPI_EXTI_IRQn, 3, 0);
189  // HAL_NVIC_EnableIRQ(BNRG_SPI_EXTI_IRQn);
190  }
191 }
192 
201 void Hal_Write_Serial(const void* data1, const void* data2, int32_t n_bytes1,
202  int32_t n_bytes2)
203 {
204  struct timer t;
205 
206  Timer_Set(&t, CLOCK_SECOND/10);
207 
208 #ifdef PRINT_CSV_FORMAT
209  print_csv_time();
210  for (int i=0; i<n_bytes1; i++) {
211  PRINT_CSV(" %02x", ((uint8_t *)data1)[i]);
212  }
213  for (int i=0; i<n_bytes2; i++) {
214  PRINT_CSV(" %02x", ((uint8_t *)data2)[i]);
215  }
216  PRINT_CSV("\n");
217 #endif
218 
219  while(1){
220  if(BlueNRG_SPI_Write(&SpiHandle, (uint8_t *)data1,(uint8_t *)data2, n_bytes1, n_bytes2)==0) break;
221  if(Timer_Expired(&t)){
222  break;
223  }
224  }
225 }
226 
233 void BNRG_SPI_Init(void)
234 {
235  SpiHandle.Instance = BNRG_SPI_INSTANCE;
236  SpiHandle.Init.Mode = BNRG_SPI_MODE;
237  SpiHandle.Init.Direction = BNRG_SPI_DIRECTION;
238  SpiHandle.Init.DataSize = BNRG_SPI_DATASIZE;
239  SpiHandle.Init.CLKPolarity = BNRG_SPI_CLKPOLARITY;
240  SpiHandle.Init.CLKPhase = BNRG_SPI_CLKPHASE;
241  SpiHandle.Init.NSS = BNRG_SPI_NSS;
242  SpiHandle.Init.FirstBit = BNRG_SPI_FIRSTBIT;
243  SpiHandle.Init.TIMode = BNRG_SPI_TIMODE;
244  SpiHandle.Init.CRCPolynomial = BNRG_SPI_CRCPOLYNOMIAL;
245  SpiHandle.Init.BaudRatePrescaler = BNRG_SPI_BAUDRATEPRESCALER;
246  SpiHandle.Init.CRCCalculation = BNRG_SPI_CRCCALCULATION;
247 
248  HAL_SPI_Init(&SpiHandle);
249 }
250 
256 void BlueNRG_RST(void)
257 {
258  HAL_GPIO_WritePin(BNRG_SPI_RESET_PORT, BNRG_SPI_RESET_PIN, GPIO_PIN_RESET);
259  HAL_Delay(5);
260  HAL_GPIO_WritePin(BNRG_SPI_RESET_PORT, BNRG_SPI_RESET_PIN, GPIO_PIN_SET);
261  HAL_Delay(5);
262 }
263 
269 // FIXME: find a better way to handle this return value (bool type? TRUE and FALSE)
270 uint8_t BlueNRG_DataPresent(void)
271 {
272  if (HAL_GPIO_ReadPin(BNRG_SPI_EXTI_PORT, BNRG_SPI_EXTI_PIN) == GPIO_PIN_SET)
273  return 1;
274  else
275  return 0;
276 } /* end BlueNRG_DataPresent() */
277 
284 {
285  Disable_SPI_IRQ();
287  BlueNRG_RST();
289  Enable_SPI_IRQ();
290 }
291 
299 int32_t BlueNRG_SPI_Read_All(SPI_HandleTypeDef *hspi, uint8_t *buffer,
300  uint8_t buff_size)
301 {
302  uint16_t byte_count;
303  uint8_t len = 0;
304  uint8_t char_ff = 0xff;
305  volatile uint8_t read_char;
306 
307  uint8_t header_master[HEADER_SIZE] = {0x0b, 0x00, 0x00, 0x00, 0x00};
308  uint8_t header_slave[HEADER_SIZE];
309 
310  /* CS reset */
311  HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_RESET);
312 
313  /* Read the header */
314  HAL_SPI_TransmitReceive(hspi, header_master, header_slave, HEADER_SIZE, TIMEOUT_DURATION);
315 
316  if (header_slave[0] == 0x02) {
317  /* device is ready */
318  byte_count = (header_slave[4]<<8)|header_slave[3];
319  if (byte_count > 0) {
320 
321  /* avoid to read more data that size of the buffer */
322  if (byte_count > buff_size){
323  byte_count = buff_size;
324  }
325 
326  for (len = 0; len < byte_count; len++){
327  __disable_irq();
328  HAL_SPI_TransmitReceive(hspi, &char_ff, (uint8_t*)&read_char, 1, TIMEOUT_DURATION);
329  __enable_irq();
330  buffer[len] = read_char;
331  }
332  }
333  }
334  /* Release CS line */
335  HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET);
336 
337  // Add a small delay to give time to the BlueNRG to set the IRQ pin low
338  // to avoid a useless SPI read at the end of the transaction
339  for(volatile int i = 0; i < 2; i++)__NOP();
340 
341 #ifdef PRINT_CSV_FORMAT
342  if (len > 0) {
343  print_csv_time();
344  for (int i=0; i<len; i++) {
345  PRINT_CSV(" %02x", buffer[i]);
346  }
347  PRINT_CSV("\n");
348  }
349 #endif
350 
351  return len;
352 }
353 
363 int32_t BlueNRG_SPI_Write(SPI_HandleTypeDef *hspi, uint8_t* data1,
364  uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2)
365 {
366  int32_t result = 0;
367 
368  int32_t spi_fix_enabled = 0;
369 
370 #ifdef ENABLE_SPI_FIX
371  spi_fix_enabled = 1;
372 #endif //ENABLE_SPI_FIX
373 
374  unsigned char header_master[HEADER_SIZE] = {0x0a, 0x00, 0x00, 0x00, 0x00};
375  unsigned char header_slave[HEADER_SIZE] = {0xaa, 0x00, 0x00, 0x00, 0x00};
376 
377  unsigned char read_char_buf[MAX_BUFFER_SIZE];
378 
379  Disable_SPI_IRQ();
380 
381  /*
382  If the SPI_FIX is enabled the IRQ is set in Output mode, then it is pulled
383  high and, after a delay of at least 112us, the CS line is asserted and the
384  header transmit/receive operations are started.
385  After these transmit/receive operations the IRQ is reset in input mode.
386  */
387  if (spi_fix_enabled) {
389 
390  /* Assert CS line after at least 112us */
391  us150Delay();
392  }
393 
394  /* CS reset */
395  HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_RESET);
396 
397  /* Exchange header */
398  __disable_irq();
399  HAL_SPI_TransmitReceive(hspi, header_master, header_slave, HEADER_SIZE, TIMEOUT_DURATION);
400  __enable_irq();
401 
402  if (spi_fix_enabled) {
404  }
405 
406  if (header_slave[0] == 0x02) {
407  /* SPI is ready */
408  if (header_slave[1] >= (Nb_bytes1+Nb_bytes2)) {
409 
410  /* Buffer is big enough */
411  if (Nb_bytes1 > 0) {
412  __disable_irq();
413  HAL_SPI_TransmitReceive(hspi, data1, read_char_buf, Nb_bytes1, TIMEOUT_DURATION);
414  __enable_irq();
415 
416  }
417  if (Nb_bytes2 > 0) {
418  __disable_irq();
419  HAL_SPI_TransmitReceive(hspi, data2, read_char_buf, Nb_bytes2, TIMEOUT_DURATION);
420  __enable_irq();
421 
422  }
423 
424  } else {
425  /* Buffer is too small */
426  result = -2;
427  }
428  } else {
429  /* SPI is not ready */
430  result = -1;
431  }
432 
433  /* Release CS line */
434  HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET);
435 
436 
437  Enable_SPI_IRQ();
438 
439  return result;
440 }
441 
448 {
449  GPIO_InitTypeDef GPIO_InitStructure;
450 
451  /* Pull IRQ high */
452  GPIO_InitStructure.Pin = BNRG_SPI_IRQ_PIN;
453  GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
454  GPIO_InitStructure.Speed = BNRG_SPI_IRQ_SPEED;
455  GPIO_InitStructure.Pull = GPIO_NOPULL;
456  HAL_GPIO_Init(BNRG_SPI_IRQ_PORT, &GPIO_InitStructure);
457  HAL_GPIO_WritePin(BNRG_SPI_IRQ_PORT, BNRG_SPI_IRQ_PIN, GPIO_PIN_SET);
458 }
459 
466 {
467  GPIO_InitTypeDef GPIO_InitStructure;
468 
469  /* IRQ input */
470  GPIO_InitStructure.Pin = BNRG_SPI_IRQ_PIN;
471  GPIO_InitStructure.Mode = BNRG_SPI_IRQ_MODE;
472  GPIO_InitStructure.Pull = GPIO_PULLDOWN;
473  GPIO_InitStructure.Speed = BNRG_SPI_IRQ_SPEED;
474  GPIO_InitStructure.Alternate = BNRG_SPI_IRQ_ALTERNATE;
475  HAL_GPIO_Init(BNRG_SPI_IRQ_PORT, &GPIO_InitStructure);
476 
477  GPIO_InitStructure.Pull = BNRG_SPI_IRQ_PULL;
478  HAL_GPIO_Init(BNRG_SPI_IRQ_PORT, &GPIO_InitStructure);
479 }
480 
487 static void us150Delay(void)
488 {
489 #if SYSCLK_FREQ == 4000000
490  for(volatile int i = 0; i < 35; i++)__NOP();
491 #elif SYSCLK_FREQ == 32000000
492  for(volatile int i = 0; i < 420; i++)__NOP();
493 #elif SYSCLK_FREQ == 80000000
494  for(volatile int i = 0; i < 1072; i++)__NOP();
495 #elif SYSCLK_FREQ == 84000000
496  for(volatile int i = 0; i < 1125; i++)__NOP();
497 #elif SYSCLK_FREQ == 168000000
498  for(volatile int i = 0; i < 2250; i++)__NOP();
499 #else
500 #error Implement delay function.
501 #endif
502 }
503 
509 void Enable_SPI_IRQ(void)
510 {
511  HAL_NVIC_EnableIRQ(BNRG_SPI_EXTI_IRQn);
512 }
513 
519 void Disable_SPI_IRQ(void)
520 {
521  HAL_NVIC_DisableIRQ(BNRG_SPI_EXTI_IRQn);
522 }
523 
529 void Clear_SPI_IRQ(void)
530 {
531  HAL_NVIC_ClearPendingIRQ(BNRG_SPI_EXTI_IRQn);
532 }
533 
540 {
541  __HAL_GPIO_EXTI_CLEAR_IT(BNRG_SPI_EXTI_PIN);
542 }
543 
560 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
static void us150Delay(void)
Utility function for delay.
void Disable_SPI_IRQ(void)
Disable SPI IRQ.
int32_t BlueNRG_SPI_Write(SPI_HandleTypeDef *hspi, uint8_t *data1, uint8_t *data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2)
Writes data from local buffer to SPI.
void set_irq_as_output(void)
Set in Output mode the IRQ.
void Clear_SPI_IRQ(void)
Clear Pending SPI IRQ.
void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
This function is used for low level initialization of the SPI communication with the BlueNRG Expansio...
void Clear_SPI_EXTI_Flag(void)
Clear EXTI (External Interrupt) line for SPI IRQ.
void Enable_SPI_IRQ(void)
Enable SPI IRQ.
uint8_t BlueNRG_DataPresent(void)
Reports if the BlueNRG has data for the host micro.
void BlueNRG_HW_Bootloader(void)
Activate internal bootloader using pin.
void BNRG_SPI_Init(void)
Initializes the SPI communication with the BlueNRG Expansion Board.
void set_irq_as_input(void)
Set the IRQ in input mode.
int32_t BlueNRG_SPI_Read_All(SPI_HandleTypeDef *hspi, uint8_t *buffer, uint8_t buff_size)
Reads from BlueNRG SPI buffer and store data into local buffer.
This file contains definitions for the SensorTile_BlueNRG.c.
void Hal_Write_Serial(const void *data1, const void *data2, int32_t n_bytes1, int32_t n_bytes2)
Writes data to a serial interface.
void BlueNRG_RST(void)
Resets the BlueNRG.
Generated by   doxygen 1.8.13