1 /**
2 ******************************************************************************
3 * @file stm32n6xx_hal_spi.c
4 * @author MCD Application Team
5 * @brief SPI HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the Serial Peripheral Interface (SPI) peripheral:
8 * + Initialization and de-initialization functions
9 * + IO operation functions
10 * + Peripheral Control functions
11 * + Peripheral State functions
12 *
13 ******************************************************************************
14 * @attention
15 *
16 * Copyright (c) 2023 STMicroelectronics.
17 * All rights reserved.
18 *
19 * This software is licensed under terms that can be found in the LICENSE file
20 * in the root directory of this software component.
21 * If no LICENSE file comes with this software, it is provided AS-IS.
22 *
23 ******************************************************************************
24 @verbatim
25 ==============================================================================
26 ##### How to use this driver #####
27 ==============================================================================
28 [..]
29 The SPI HAL driver can be used as follows:
30
31 (#) Declare a SPI_HandleTypeDef handle structure, for example:
32 SPI_HandleTypeDef hspi;
33
34 (#)Initialize the SPI low level resources by implementing the HAL_SPI_MspInit() API:
35 (##) Enable the SPIx interface clock
36 (##) SPI pins configuration
37 (+++) Enable the clock for the SPI GPIOs
38 (+++) Configure these SPI pins as alternate function push-pull
39 (##) NVIC configuration if you need to use interrupt process or DMA process
40 (+++) Configure the SPIx interrupt priority
41 (+++) Enable the NVIC SPI IRQ handle
42 (##) DMA Configuration if you need to use DMA process
43 (+++) Declare a DMA_HandleTypeDef handle structure for the transmit or receive Stream/Channel
44 (+++) Enable the DMAx clock
45 (+++) Configure the DMA handle parameters
46 (+++) Configure the DMA Tx or Rx Stream/Channel
47 (+++) Associate the initialized hdma_tx handle to the hspi DMA Tx or Rx handle
48 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx
49 or Rx Stream/Channel
50
51 (#) Program the Mode, BidirectionalMode , Data size, Baudrate Prescaler, NSS
52 management, Clock polarity and phase, FirstBit and CRC configuration in the hspi Init structure.
53
54 (#) Initialize the SPI registers by calling the HAL_SPI_Init() API:
55 (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
56 by calling the customized HAL_SPI_MspInit() API.
57 [..]
58 Callback registration:
59
60 (#) The compilation flag USE_HAL_SPI_REGISTER_CALLBACKS when set to 1UL
61 allows the user to configure dynamically the driver callbacks.
62 Use Functions HAL_SPI_RegisterCallback() to register an interrupt callback.
63
64 Function HAL_SPI_RegisterCallback() allows to register following callbacks:
65 (+) TxCpltCallback : SPI Tx Completed callback
66 (+) RxCpltCallback : SPI Rx Completed callback
67 (+) TxRxCpltCallback : SPI TxRx Completed callback
68 (+) TxHalfCpltCallback : SPI Tx Half Completed callback
69 (+) RxHalfCpltCallback : SPI Rx Half Completed callback
70 (+) TxRxHalfCpltCallback : SPI TxRx Half Completed callback
71 (+) ErrorCallback : SPI Error callback
72 (+) AbortCpltCallback : SPI Abort callback
73 (+) SuspendCallback : SPI Suspend callback
74 (+) MspInitCallback : SPI Msp Init callback
75 (+) MspDeInitCallback : SPI Msp DeInit callback
76 This function takes as parameters the HAL peripheral handle, the Callback ID
77 and a pointer to the user callback function.
78
79
80 (#) Use function HAL_SPI_UnRegisterCallback to reset a callback to the default
81 weak function.
82 HAL_SPI_UnRegisterCallback takes as parameters the HAL peripheral handle,
83 and the Callback ID.
84 This function allows to reset following callbacks:
85 (+) TxCpltCallback : SPI Tx Completed callback
86 (+) RxCpltCallback : SPI Rx Completed callback
87 (+) TxRxCpltCallback : SPI TxRx Completed callback
88 (+) TxHalfCpltCallback : SPI Tx Half Completed callback
89 (+) RxHalfCpltCallback : SPI Rx Half Completed callback
90 (+) TxRxHalfCpltCallback : SPI TxRx Half Completed callback
91 (+) ErrorCallback : SPI Error callback
92 (+) AbortCpltCallback : SPI Abort callback
93 (+) SuspendCallback : SPI Suspend callback
94 (+) MspInitCallback : SPI Msp Init callback
95 (+) MspDeInitCallback : SPI Msp DeInit callback
96
97 By default, after the HAL_SPI_Init() and when the state is HAL_SPI_STATE_RESET
98 all callbacks are set to the corresponding weak functions:
99 examples HAL_SPI_MasterTxCpltCallback(), HAL_SPI_MasterRxCpltCallback().
100 Exception done for MspInit and MspDeInit functions that are
101 reset to the legacy weak functions in the HAL_SPI_Init()/ HAL_SPI_DeInit() only when
102 these callbacks are null (not registered beforehand).
103 If MspInit or MspDeInit are not null, the HAL_SPI_Init()/ HAL_SPI_DeInit()
104 keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
105
106 Callbacks can be registered/unregistered in HAL_SPI_STATE_READY state only.
107 Exception done MspInit/MspDeInit functions that can be registered/unregistered
108 in HAL_SPI_STATE_READY or HAL_SPI_STATE_RESET state,
109 thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
110 Then, the user first registers the MspInit/MspDeInit user callbacks
111 using HAL_SPI_RegisterCallback() before calling HAL_SPI_DeInit()
112 or HAL_SPI_Init() function.
113
114 When The compilation define USE_HAL_PPP_REGISTER_CALLBACKS is set to 0 or not defined,
115 the callback registering feature is not available and weak callbacks are used.
116
117 SuspendCallback restriction:
118 SuspendCallback is called only when MasterReceiverAutoSusp is enabled and
119 EOT interrupt is activated. SuspendCallback is used in relation with functions
120 HAL_SPI_Transmit_IT, HAL_SPI_Receive_IT and HAL_SPI_TransmitReceive_IT.
121
122 [..]
123 Circular mode restriction:
124 (+) The DMA circular mode cannot be used when the SPI is configured in these modes:
125 (++) Master 2Lines RxOnly
126 (++) Master 1Line Rx
127 (+) The CRC feature is not managed when the DMA circular mode is enabled
128 (+) The functions HAL_SPI_DMAPause()/ HAL_SPI_DMAResume() are not supported. Return always
129 HAL_ERROR with ErrorCode set to HAL_SPI_ERROR_NOT_SUPPORTED.
130 Those functions are maintained for backward compatibility reasons.
131
132 @endverbatim
133 */
134
135 /* Includes ------------------------------------------------------------------*/
136 #include "stm32n6xx_hal.h"
137
138 /** @addtogroup STM32N6xx_HAL_Driver
139 * @{
140 */
141
142 /** @defgroup SPI SPI
143 * @brief SPI HAL module driver
144 * @{
145 */
146 #ifdef HAL_SPI_MODULE_ENABLED
147
148 /* Private typedef -----------------------------------------------------------*/
149 /* Private defines -----------------------------------------------------------*/
150 /** @defgroup SPI_Private_Constants SPI Private Constants
151 * @{
152 */
153 #define SPI_DEFAULT_TIMEOUT 100UL
154 /**
155 * @}
156 */
157
158 /* Private macros ------------------------------------------------------------*/
159 /* Private variables ---------------------------------------------------------*/
160 /* Private function prototypes -----------------------------------------------*/
161 /** @defgroup SPI_Private_Functions SPI Private Functions
162 * @{
163 */
164 static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma);
165 static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
166 static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma);
167 static void SPI_DMAHalfTransmitCplt(DMA_HandleTypeDef *hdma);
168 static void SPI_DMAHalfReceiveCplt(DMA_HandleTypeDef *hdma);
169 static void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma);
170 static void SPI_DMAError(DMA_HandleTypeDef *hdma);
171 static void SPI_DMAAbortOnError(DMA_HandleTypeDef *hdma);
172 static void SPI_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
173 static void SPI_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
174 static HAL_StatusTypeDef SPI_WaitOnFlagUntilTimeout(const SPI_HandleTypeDef *hspi, uint32_t Flag,
175 FlagStatus FlagStatus, uint32_t Timeout, uint32_t Tickstart);
176 static void SPI_TxISR_8BIT(SPI_HandleTypeDef *hspi);
177 static void SPI_TxISR_16BIT(SPI_HandleTypeDef *hspi);
178 static void SPI_TxISR_32BIT(SPI_HandleTypeDef *hspi);
179 static void SPI_RxISR_8BIT(SPI_HandleTypeDef *hspi);
180 static void SPI_RxISR_16BIT(SPI_HandleTypeDef *hspi);
181 static void SPI_RxISR_32BIT(SPI_HandleTypeDef *hspi);
182 static void SPI_AbortTransfer(SPI_HandleTypeDef *hspi);
183 static void SPI_CloseTransfer(SPI_HandleTypeDef *hspi);
184 static uint32_t SPI_GetPacketSize(const SPI_HandleTypeDef *hspi);
185
186
187 /**
188 * @}
189 */
190
191 /* Exported functions --------------------------------------------------------*/
192 /** @defgroup SPI_Exported_Functions SPI Exported Functions
193 * @{
194 */
195
196 /** @defgroup SPI_Exported_Functions_Group1 Initialization and de-initialization functions
197 * @brief Initialization and Configuration functions
198 *
199 @verbatim
200 ===============================================================================
201 ##### Initialization and de-initialization functions #####
202 ===============================================================================
203 [..] This subsection provides a set of functions allowing to initialize and
204 de-initialize the SPIx peripheral:
205
206 (+) User must implement HAL_SPI_MspInit() function in which he configures
207 all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
208
209 (+) Call the function HAL_SPI_Init() to configure the selected device with
210 the selected configuration:
211 (++) Mode
212 (++) Direction
213 (++) Data Size
214 (++) Clock Polarity and Phase
215 (++) NSS Management
216 (++) BaudRate Prescaler
217 (++) FirstBit
218 (++) TIMode
219 (++) CRC Calculation
220 (++) CRC Polynomial if CRC enabled
221 (++) CRC Length, used only with Data8 and Data16
222 (++) FIFO reception threshold
223 (++) FIFO transmission threshold
224
225 (+) Call the function HAL_SPI_DeInit() to restore the default configuration
226 of the selected SPIx peripheral.
227
228 @endverbatim
229 * @{
230 */
231
232 /**
233 * @brief Initialize the SPI according to the specified parameters
234 * in the SPI_InitTypeDef and initialize the associated handle.
235 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
236 * the configuration information for SPI module.
237 * @retval HAL status
238 */
HAL_SPI_Init(SPI_HandleTypeDef * hspi)239 HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi)
240 {
241 uint32_t crc_length;
242 uint32_t packet_length;
243 #if (USE_SPI_CRC != 0UL)
244 uint32_t crc_poly_msb_mask;
245 #endif /* USE_SPI_CRC */
246
247 /* Check the SPI handle allocation */
248 if (hspi == NULL)
249 {
250 return HAL_ERROR;
251 }
252
253 /* Check the parameters */
254 assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance));
255 assert_param(IS_SPI_MODE(hspi->Init.Mode));
256 assert_param(IS_SPI_DIRECTION(hspi->Init.Direction));
257 if (IS_SPI_LIMITED_INSTANCE(hspi->Instance))
258 {
259 assert_param(IS_SPI_LIMITED_DATASIZE(hspi->Init.DataSize));
260 assert_param(IS_SPI_LIMITED_FIFOTHRESHOLD(hspi->Init.FifoThreshold));
261 }
262 else
263 {
264 assert_param(IS_SPI_DATASIZE(hspi->Init.DataSize));
265 assert_param(IS_SPI_FIFOTHRESHOLD(hspi->Init.FifoThreshold));
266 }
267 assert_param(IS_SPI_NSS(hspi->Init.NSS));
268 assert_param(IS_SPI_NSSP(hspi->Init.NSSPMode));
269 assert_param(IS_SPI_BAUDRATE_PRESCALER(hspi->Init.BaudRatePrescaler));
270 assert_param(IS_SPI_FIRST_BIT(hspi->Init.FirstBit));
271 assert_param(IS_SPI_TIMODE(hspi->Init.TIMode));
272 if (hspi->Init.TIMode == SPI_TIMODE_DISABLE)
273 {
274 assert_param(IS_SPI_CPOL(hspi->Init.CLKPolarity));
275 assert_param(IS_SPI_CPHA(hspi->Init.CLKPhase));
276 }
277 #if (USE_SPI_CRC != 0UL)
278 assert_param(IS_SPI_CRC_CALCULATION(hspi->Init.CRCCalculation));
279 if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
280 {
281 if (IS_SPI_LIMITED_INSTANCE(hspi->Instance))
282 {
283 assert_param(IS_SPI_LIMITED_CRC_LENGTH(hspi->Init.CRCLength));
284 }
285 else
286 {
287 assert_param(IS_SPI_CRC_LENGTH(hspi->Init.CRCLength));
288 }
289 assert_param(IS_SPI_CRC_POLYNOMIAL(hspi->Init.CRCPolynomial));
290 assert_param(IS_SPI_CRC_INITIALIZATION_PATTERN(hspi->Init.TxCRCInitializationPattern));
291 assert_param(IS_SPI_CRC_INITIALIZATION_PATTERN(hspi->Init.RxCRCInitializationPattern));
292 }
293 #else
294 hspi->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
295 #endif /* USE_SPI_CRC */
296
297 assert_param(IS_SPI_RDY_MASTER_MANAGEMENT(hspi->Init.ReadyMasterManagement));
298 assert_param(IS_SPI_RDY_POLARITY(hspi->Init.ReadyPolarity));
299 assert_param(IS_SPI_MASTER_RX_AUTOSUSP(hspi->Init.MasterReceiverAutoSusp));
300
301 /* Verify that the SPI instance supports Data Size higher than 16bits */
302 if ((IS_SPI_LIMITED_INSTANCE(hspi->Instance)) && (hspi->Init.DataSize > SPI_DATASIZE_16BIT))
303 {
304 return HAL_ERROR;
305 }
306
307 /* Verify that the SPI instance supports requested data packing */
308 packet_length = SPI_GetPacketSize(hspi);
309 if (((IS_SPI_LIMITED_INSTANCE(hspi->Instance)) && (packet_length > SPI_LOWEND_FIFO_SIZE)) ||
310 ((IS_SPI_FULL_INSTANCE(hspi->Instance)) && (packet_length > SPI_HIGHEND_FIFO_SIZE)))
311 {
312 return HAL_ERROR;
313 }
314 #if (USE_SPI_CRC != 0UL)
315 if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
316 {
317 /* Verify that the SPI instance supports CRC Length higher than 16bits */
318 if ((IS_SPI_LIMITED_INSTANCE(hspi->Instance)) && (hspi->Init.CRCLength > SPI_CRC_LENGTH_16BIT))
319 {
320 return HAL_ERROR;
321 }
322
323 /* Align the CRC Length on the data size */
324 if (hspi->Init.CRCLength == SPI_CRC_LENGTH_DATASIZE)
325 {
326 crc_length = (hspi->Init.DataSize >> SPI_CFG1_DSIZE_Pos) << SPI_CFG1_CRCSIZE_Pos;
327 }
328 else
329 {
330 crc_length = hspi->Init.CRCLength;
331 }
332
333 /* Verify the correctness of polynom size */
334 assert_param(IS_SPI_CRC_POLYNOMIAL_SIZE(hspi->Init.CRCPolynomial, crc_length));
335
336 /* Verify that the CRC Length is higher than DataSize */
337 if ((hspi->Init.DataSize >> SPI_CFG1_DSIZE_Pos) > (crc_length >> SPI_CFG1_CRCSIZE_Pos))
338 {
339 return HAL_ERROR;
340 }
341 }
342 else
343 {
344 crc_length = hspi->Init.DataSize << SPI_CFG1_CRCSIZE_Pos;
345 }
346 #endif /* USE_SPI_CRC */
347
348 if (hspi->State == HAL_SPI_STATE_RESET)
349 {
350 /* Allocate lock resource and initialize it */
351 hspi->Lock = HAL_UNLOCKED;
352
353 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
354 /* Init the SPI Callback settings */
355 hspi->TxCpltCallback = HAL_SPI_TxCpltCallback; /* Legacy weak TxCpltCallback */
356 hspi->RxCpltCallback = HAL_SPI_RxCpltCallback; /* Legacy weak RxCpltCallback */
357 hspi->TxRxCpltCallback = HAL_SPI_TxRxCpltCallback; /* Legacy weak TxRxCpltCallback */
358 hspi->TxHalfCpltCallback = HAL_SPI_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
359 hspi->RxHalfCpltCallback = HAL_SPI_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
360 hspi->TxRxHalfCpltCallback = HAL_SPI_TxRxHalfCpltCallback; /* Legacy weak TxRxHalfCpltCallback */
361 hspi->ErrorCallback = HAL_SPI_ErrorCallback; /* Legacy weak ErrorCallback */
362 hspi->AbortCpltCallback = HAL_SPI_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
363 hspi->SuspendCallback = HAL_SPI_SuspendCallback; /* Legacy weak SuspendCallback */
364
365 if (hspi->MspInitCallback == NULL)
366 {
367 hspi->MspInitCallback = HAL_SPI_MspInit; /* Legacy weak MspInit */
368 }
369
370 /* Init the low level hardware : GPIO, CLOCK, NVIC... */
371 hspi->MspInitCallback(hspi);
372 #else
373 /* Init the low level hardware : GPIO, CLOCK, NVIC... */
374 HAL_SPI_MspInit(hspi);
375 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
376 }
377
378 hspi->State = HAL_SPI_STATE_BUSY;
379
380 /* Disable the selected SPI peripheral */
381 __HAL_SPI_DISABLE(hspi);
382
383 #if (USE_SPI_CRC == 0)
384 /* Keep the default value of CRCSIZE in case of CRC is not used */
385 crc_length = hspi->Instance->CFG1 & SPI_CFG1_CRCSIZE;
386 #endif /* USE_SPI_CRC */
387
388 /*----------------------- SPIx CR1 & CR2 Configuration ---------------------*/
389 /* Configure : SPI Mode, Communication Mode, Clock polarity and phase, NSS management,
390 Communication speed, First bit, CRC calculation state, CRC Length */
391
392 /* SPIx NSS Software Management Configuration */
393 if ((hspi->Init.NSS == SPI_NSS_SOFT) && (((hspi->Init.Mode == SPI_MODE_MASTER) && \
394 (hspi->Init.NSSPolarity == SPI_NSS_POLARITY_LOW)) || \
395 ((hspi->Init.Mode == SPI_MODE_SLAVE) && \
396 (hspi->Init.NSSPolarity == SPI_NSS_POLARITY_HIGH))))
397 {
398 SET_BIT(hspi->Instance->CR1, SPI_CR1_SSI);
399 }
400
401 /* SPIx Master Rx Auto Suspend Configuration */
402 if (((hspi->Init.Mode & SPI_MODE_MASTER) == SPI_MODE_MASTER) && (hspi->Init.DataSize >= SPI_DATASIZE_8BIT))
403 {
404 MODIFY_REG(hspi->Instance->CR1, SPI_CR1_MASRX, hspi->Init.MasterReceiverAutoSusp);
405 }
406 else
407 {
408 CLEAR_BIT(hspi->Instance->CR1, SPI_CR1_MASRX);
409 }
410
411 /* SPIx CFG1 Configuration */
412 WRITE_REG(hspi->Instance->CFG1, (hspi->Init.BaudRatePrescaler | hspi->Init.CRCCalculation | crc_length |
413 hspi->Init.FifoThreshold | hspi->Init.DataSize));
414
415 /* SPIx CFG2 Configuration */
416 WRITE_REG(hspi->Instance->CFG2, (hspi->Init.NSSPMode | hspi->Init.TIMode |
417 hspi->Init.NSSPolarity | hspi->Init.NSS |
418 hspi->Init.CLKPolarity | hspi->Init.CLKPhase |
419 hspi->Init.FirstBit | hspi->Init.Mode |
420 hspi->Init.MasterInterDataIdleness | hspi->Init.Direction |
421 hspi->Init.MasterSSIdleness | hspi->Init.IOSwap |
422 hspi->Init.ReadyMasterManagement | hspi->Init.ReadyPolarity));
423
424 #if (USE_SPI_CRC != 0UL)
425 /*---------------------------- SPIx CRCPOLY Configuration ------------------*/
426 /* Configure : CRC Polynomial */
427 if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
428 {
429 /* Initialize TXCRC Pattern Initial Value */
430 if (hspi->Init.TxCRCInitializationPattern == SPI_CRC_INITIALIZATION_ALL_ONE_PATTERN)
431 {
432 SET_BIT(hspi->Instance->CR1, SPI_CR1_TCRCINI);
433 }
434 else
435 {
436 CLEAR_BIT(hspi->Instance->CR1, SPI_CR1_TCRCINI);
437 }
438
439 /* Initialize RXCRC Pattern Initial Value */
440 if (hspi->Init.RxCRCInitializationPattern == SPI_CRC_INITIALIZATION_ALL_ONE_PATTERN)
441 {
442 SET_BIT(hspi->Instance->CR1, SPI_CR1_RCRCINI);
443 }
444 else
445 {
446 CLEAR_BIT(hspi->Instance->CR1, SPI_CR1_RCRCINI);
447 }
448
449 /* Enable 33/17 bits CRC computation */
450 if (((IS_SPI_LIMITED_INSTANCE(hspi->Instance)) && (crc_length == SPI_CRC_LENGTH_16BIT)) ||
451 ((IS_SPI_FULL_INSTANCE(hspi->Instance)) && (crc_length == SPI_CRC_LENGTH_32BIT)))
452 {
453 /* Set SPI_CR1_CRC33_17 bit */
454 SET_BIT(hspi->Instance->CR1, SPI_CR1_CRC33_17);
455 /* Write CRC polynomial in SPI Register */
456 WRITE_REG(hspi->Instance->CRCPOLY, hspi->Init.CRCPolynomial);
457 }
458 else
459 {
460 /* Clear SPI_CR1_CRC33_17 bit */
461 CLEAR_BIT(hspi->Instance->CR1, SPI_CR1_CRC33_17);
462
463 /* Write CRC polynomial and set MSB bit at 1 in SPI Register */
464 /* Set MSB is mandatory for a correct CRC computation */
465 crc_poly_msb_mask = (0x1UL << ((crc_length >> SPI_CFG1_CRCSIZE_Pos) + 0x1U));
466 WRITE_REG(hspi->Instance->CRCPOLY, (hspi->Init.CRCPolynomial) | crc_poly_msb_mask);
467 }
468 }
469 #endif /* USE_SPI_CRC */
470
471 /* Insure that Underrun configuration is managed only by Salve */
472 if (hspi->Init.Mode == SPI_MODE_SLAVE)
473 {
474 #if (USE_SPI_CRC != 0UL)
475 MODIFY_REG(hspi->Instance->CFG1, SPI_CFG1_UDRCFG, SPI_CFG1_UDRCFG);
476 #endif /* USE_SPI_CRC */
477 }
478
479 #if defined(SPI_I2SCFGR_I2SMOD)
480 /* Activate the SPI mode (Make sure that I2SMOD bit in I2SCFGR register is reset) */
481 CLEAR_BIT(hspi->Instance->I2SCFGR, SPI_I2SCFGR_I2SMOD);
482 #endif /* SPI_I2SCFGR_I2SMOD */
483
484 /* Insure that AFCNTR is managed only by Master */
485 if ((hspi->Init.Mode & SPI_MODE_MASTER) == SPI_MODE_MASTER)
486 {
487 /* Alternate function GPIOs control */
488 MODIFY_REG(hspi->Instance->CFG2, SPI_CFG2_AFCNTR, (hspi->Init.MasterKeepIOState));
489 }
490
491 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
492 hspi->State = HAL_SPI_STATE_READY;
493
494 return HAL_OK;
495 }
496
497 /**
498 * @brief De-Initialize the SPI peripheral.
499 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
500 * the configuration information for SPI module.
501 * @retval HAL status
502 */
HAL_SPI_DeInit(SPI_HandleTypeDef * hspi)503 HAL_StatusTypeDef HAL_SPI_DeInit(SPI_HandleTypeDef *hspi)
504 {
505 /* Check the SPI handle allocation */
506 if (hspi == NULL)
507 {
508 return HAL_ERROR;
509 }
510
511 /* Check SPI Instance parameter */
512 assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance));
513
514 hspi->State = HAL_SPI_STATE_BUSY;
515
516 /* Disable the SPI Peripheral Clock */
517 __HAL_SPI_DISABLE(hspi);
518
519 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
520 if (hspi->MspDeInitCallback == NULL)
521 {
522 hspi->MspDeInitCallback = HAL_SPI_MspDeInit; /* Legacy weak MspDeInit */
523 }
524
525 /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
526 hspi->MspDeInitCallback(hspi);
527 #else
528 /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
529 HAL_SPI_MspDeInit(hspi);
530 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
531
532 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
533 hspi->State = HAL_SPI_STATE_RESET;
534
535 /* Release Lock */
536 __HAL_UNLOCK(hspi);
537
538 return HAL_OK;
539 }
540
541 /**
542 * @brief Initialize the SPI MSP.
543 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
544 * the configuration information for SPI module.
545 * @retval None
546 */
HAL_SPI_MspInit(SPI_HandleTypeDef * hspi)547 __weak void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
548 {
549 /* Prevent unused argument(s) compilation warning */
550 UNUSED(hspi);
551
552 /* NOTE : This function should not be modified, when the callback is needed,
553 the HAL_SPI_MspInit should be implemented in the user file
554 */
555 }
556
557 /**
558 * @brief De-Initialize the SPI MSP.
559 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
560 * the configuration information for SPI module.
561 * @retval None
562 */
HAL_SPI_MspDeInit(SPI_HandleTypeDef * hspi)563 __weak void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi)
564 {
565 /* Prevent unused argument(s) compilation warning */
566 UNUSED(hspi);
567
568 /* NOTE : This function should not be modified, when the callback is needed,
569 the HAL_SPI_MspDeInit should be implemented in the user file
570 */
571 }
572
573 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
574 /**
575 * @brief Register a User SPI Callback
576 * To be used instead of the weak predefined callback
577 * @param hspi Pointer to a SPI_HandleTypeDef structure that contains
578 * the configuration information for the specified SPI.
579 * @param CallbackID ID of the callback to be registered
580 * @param pCallback pointer to the Callback function
581 * @note The HAL_SPI_RegisterCallback() may be called before HAL_SPI_Init() in HAL_SPI_STATE_RESET
582 * to register callbacks for HAL_SPI_MSPINIT_CB_ID and HAL_SPI_MSPDEINIT_CB_ID
583 * @retval HAL status
584 */
HAL_SPI_RegisterCallback(SPI_HandleTypeDef * hspi,HAL_SPI_CallbackIDTypeDef CallbackID,pSPI_CallbackTypeDef pCallback)585 HAL_StatusTypeDef HAL_SPI_RegisterCallback(SPI_HandleTypeDef *hspi, HAL_SPI_CallbackIDTypeDef CallbackID,
586 pSPI_CallbackTypeDef pCallback)
587 {
588 HAL_StatusTypeDef status = HAL_OK;
589
590 if (pCallback == NULL)
591 {
592 /* Update the error code */
593 hspi->ErrorCode |= HAL_SPI_ERROR_INVALID_CALLBACK;
594
595 return HAL_ERROR;
596 }
597
598 if (HAL_SPI_STATE_READY == hspi->State)
599 {
600 switch (CallbackID)
601 {
602 case HAL_SPI_TX_COMPLETE_CB_ID :
603 hspi->TxCpltCallback = pCallback;
604 break;
605
606 case HAL_SPI_RX_COMPLETE_CB_ID :
607 hspi->RxCpltCallback = pCallback;
608 break;
609
610 case HAL_SPI_TX_RX_COMPLETE_CB_ID :
611 hspi->TxRxCpltCallback = pCallback;
612 break;
613
614 case HAL_SPI_TX_HALF_COMPLETE_CB_ID :
615 hspi->TxHalfCpltCallback = pCallback;
616 break;
617
618 case HAL_SPI_RX_HALF_COMPLETE_CB_ID :
619 hspi->RxHalfCpltCallback = pCallback;
620 break;
621
622 case HAL_SPI_TX_RX_HALF_COMPLETE_CB_ID :
623 hspi->TxRxHalfCpltCallback = pCallback;
624 break;
625
626 case HAL_SPI_ERROR_CB_ID :
627 hspi->ErrorCallback = pCallback;
628 break;
629
630 case HAL_SPI_ABORT_CB_ID :
631 hspi->AbortCpltCallback = pCallback;
632 break;
633
634 case HAL_SPI_SUSPEND_CB_ID :
635 hspi->SuspendCallback = pCallback;
636 break;
637
638 case HAL_SPI_MSPINIT_CB_ID :
639 hspi->MspInitCallback = pCallback;
640 break;
641
642 case HAL_SPI_MSPDEINIT_CB_ID :
643 hspi->MspDeInitCallback = pCallback;
644 break;
645
646 default :
647 /* Update the error code */
648 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK);
649
650 /* Return error status */
651 status = HAL_ERROR;
652 break;
653 }
654 }
655 else if (HAL_SPI_STATE_RESET == hspi->State)
656 {
657 switch (CallbackID)
658 {
659 case HAL_SPI_MSPINIT_CB_ID :
660 hspi->MspInitCallback = pCallback;
661 break;
662
663 case HAL_SPI_MSPDEINIT_CB_ID :
664 hspi->MspDeInitCallback = pCallback;
665 break;
666
667 default :
668 /* Update the error code */
669 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK);
670
671 /* Return error status */
672 status = HAL_ERROR;
673 break;
674 }
675 }
676 else
677 {
678 /* Update the error code */
679 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK);
680
681 /* Return error status */
682 status = HAL_ERROR;
683 }
684
685 return status;
686 }
687
688 /**
689 * @brief Unregister an SPI Callback
690 * SPI callback is redirected to the weak predefined callback
691 * @param hspi Pointer to a SPI_HandleTypeDef structure that contains
692 * the configuration information for the specified SPI.
693 * @param CallbackID ID of the callback to be unregistered
694 * @note The HAL_SPI_UnRegisterCallback() may be called before HAL_SPI_Init() in HAL_SPI_STATE_RESET
695 * to un-register callbacks for HAL_SPI_MSPINIT_CB_ID and HAL_SPI_MSPDEINIT_CB_ID
696 * @retval HAL status
697 */
HAL_SPI_UnRegisterCallback(SPI_HandleTypeDef * hspi,HAL_SPI_CallbackIDTypeDef CallbackID)698 HAL_StatusTypeDef HAL_SPI_UnRegisterCallback(SPI_HandleTypeDef *hspi, HAL_SPI_CallbackIDTypeDef CallbackID)
699 {
700 HAL_StatusTypeDef status = HAL_OK;
701
702 if (HAL_SPI_STATE_READY == hspi->State)
703 {
704 switch (CallbackID)
705 {
706 case HAL_SPI_TX_COMPLETE_CB_ID :
707 hspi->TxCpltCallback = HAL_SPI_TxCpltCallback; /* Legacy weak TxCpltCallback */
708 break;
709
710 case HAL_SPI_RX_COMPLETE_CB_ID :
711 hspi->RxCpltCallback = HAL_SPI_RxCpltCallback; /* Legacy weak RxCpltCallback */
712 break;
713
714 case HAL_SPI_TX_RX_COMPLETE_CB_ID :
715 hspi->TxRxCpltCallback = HAL_SPI_TxRxCpltCallback; /* Legacy weak TxRxCpltCallback */
716 break;
717
718 case HAL_SPI_TX_HALF_COMPLETE_CB_ID :
719 hspi->TxHalfCpltCallback = HAL_SPI_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
720 break;
721
722 case HAL_SPI_RX_HALF_COMPLETE_CB_ID :
723 hspi->RxHalfCpltCallback = HAL_SPI_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
724 break;
725
726 case HAL_SPI_TX_RX_HALF_COMPLETE_CB_ID :
727 hspi->TxRxHalfCpltCallback = HAL_SPI_TxRxHalfCpltCallback; /* Legacy weak TxRxHalfCpltCallback */
728 break;
729
730 case HAL_SPI_ERROR_CB_ID :
731 hspi->ErrorCallback = HAL_SPI_ErrorCallback; /* Legacy weak ErrorCallback */
732 break;
733
734 case HAL_SPI_ABORT_CB_ID :
735 hspi->AbortCpltCallback = HAL_SPI_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
736 break;
737
738 case HAL_SPI_SUSPEND_CB_ID :
739 hspi->SuspendCallback = HAL_SPI_SuspendCallback; /* Legacy weak SuspendCallback */
740 break;
741
742 case HAL_SPI_MSPINIT_CB_ID :
743 hspi->MspInitCallback = HAL_SPI_MspInit; /* Legacy weak MspInit */
744 break;
745
746 case HAL_SPI_MSPDEINIT_CB_ID :
747 hspi->MspDeInitCallback = HAL_SPI_MspDeInit; /* Legacy weak MspDeInit */
748 break;
749
750 default :
751 /* Update the error code */
752 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK);
753
754 /* Return error status */
755 status = HAL_ERROR;
756 break;
757 }
758 }
759 else if (HAL_SPI_STATE_RESET == hspi->State)
760 {
761 switch (CallbackID)
762 {
763 case HAL_SPI_MSPINIT_CB_ID :
764 hspi->MspInitCallback = HAL_SPI_MspInit; /* Legacy weak MspInit */
765 break;
766
767 case HAL_SPI_MSPDEINIT_CB_ID :
768 hspi->MspDeInitCallback = HAL_SPI_MspDeInit; /* Legacy weak MspDeInit */
769 break;
770
771 default :
772 /* Update the error code */
773 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK);
774
775 /* Return error status */
776 status = HAL_ERROR;
777 break;
778 }
779 }
780 else
781 {
782 /* Update the error code */
783 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK);
784
785 /* Return error status */
786 status = HAL_ERROR;
787 }
788
789 return status;
790 }
791 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
792 /**
793 * @}
794 */
795
796 /** @defgroup SPI_Exported_Functions_Group2 IO operation functions
797 * @brief Data transfers functions
798 *
799 @verbatim
800 ==============================================================================
801 ##### IO operation functions #####
802 ===============================================================================
803 [..]
804 This subsection provides a set of functions allowing to manage the SPI
805 data transfers.
806
807 [..] The SPI supports master and slave mode :
808
809 (#) There are two modes of transfer:
810 (##) Blocking mode: The communication is performed in polling mode.
811 The HAL status of all data processing is returned by the same function
812 after finishing transfer.
813 (##) No-Blocking mode: The communication is performed using Interrupts
814 or DMA, These APIs return the HAL status.
815 The end of the data processing will be indicated through the
816 dedicated SPI IRQ when using Interrupt mode or the DMA IRQ when
817 using DMA mode.
818 The HAL_SPI_TxCpltCallback(), HAL_SPI_RxCpltCallback() and HAL_SPI_TxRxCpltCallback() user callbacks
819 will be executed respectively at the end of the transmit or Receive process
820 The HAL_SPI_ErrorCallback()user callback will be executed when a communication error is detected
821
822 (#) APIs provided for these 2 transfer modes (Blocking mode or Non blocking mode using either Interrupt or DMA)
823 exist for 1Line (simplex) and 2Lines (full duplex) modes.
824
825 @endverbatim
826 * @{
827 */
828
829 /**
830 * @brief Transmit an amount of data in blocking mode.
831 * @param hspi : pointer to a SPI_HandleTypeDef structure that contains
832 * the configuration information for SPI module.
833 * @param pData : pointer to data buffer
834 * @param Size : amount of data to be sent
835 * @param Timeout: Timeout duration
836 * @retval HAL status
837 */
HAL_SPI_Transmit(SPI_HandleTypeDef * hspi,const uint8_t * pData,uint16_t Size,uint32_t Timeout)838 HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, const uint8_t *pData, uint16_t Size, uint32_t Timeout)
839 {
840 #if defined (__GNUC__)
841 __IO uint16_t *ptxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->TXDR));
842 #endif /* __GNUC__ */
843
844 uint32_t tickstart;
845
846 /* Check Direction parameter */
847 assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_TXONLY(hspi->Init.Direction));
848
849 /* Init tickstart for timeout management*/
850 tickstart = HAL_GetTick();
851
852 if (hspi->State != HAL_SPI_STATE_READY)
853 {
854 return HAL_BUSY;
855 }
856
857 if ((pData == NULL) || (Size == 0UL))
858 {
859 return HAL_ERROR;
860 }
861
862 /* Lock the process */
863 __HAL_LOCK(hspi);
864
865 /* Set the transaction information */
866 hspi->State = HAL_SPI_STATE_BUSY_TX;
867 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
868 hspi->pTxBuffPtr = (const uint8_t *)pData;
869 hspi->TxXferSize = Size;
870 hspi->TxXferCount = Size;
871
872 /*Init field not used in handle to zero */
873 hspi->pRxBuffPtr = NULL;
874 hspi->RxXferSize = (uint16_t) 0UL;
875 hspi->RxXferCount = (uint16_t) 0UL;
876 hspi->TxISR = NULL;
877 hspi->RxISR = NULL;
878
879 /* Configure communication direction : 1Line */
880 if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
881 {
882 SPI_1LINE_TX(hspi);
883 }
884 else
885 {
886 SPI_2LINES_TX(hspi);
887 }
888
889 /* Set the number of data at current transfer */
890 MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size);
891
892 /* Enable SPI peripheral */
893 __HAL_SPI_ENABLE(hspi);
894
895 if (hspi->Init.Mode == SPI_MODE_MASTER)
896 {
897 /* Master transfer start */
898 SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART);
899 }
900
901 /* Transmit data in 32 Bit mode */
902 if ((hspi->Init.DataSize > SPI_DATASIZE_16BIT) && (IS_SPI_FULL_INSTANCE(hspi->Instance)))
903 {
904 /* Transmit data in 32 Bit mode */
905 while (hspi->TxXferCount > 0UL)
906 {
907 /* Wait until TXP flag is set to send data */
908 if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP))
909 {
910 *((__IO uint32_t *)&hspi->Instance->TXDR) = *((const uint32_t *)hspi->pTxBuffPtr);
911 hspi->pTxBuffPtr += sizeof(uint32_t);
912 hspi->TxXferCount--;
913 }
914 else
915 {
916 /* Timeout management */
917 if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
918 {
919 /* Call standard close procedure with error check */
920 SPI_CloseTransfer(hspi);
921
922 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
923 hspi->State = HAL_SPI_STATE_READY;
924
925 /* Unlock the process */
926 __HAL_UNLOCK(hspi);
927
928 return HAL_TIMEOUT;
929 }
930 }
931 }
932 }
933 /* Transmit data in 16 Bit mode */
934 else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
935 {
936 /* Transmit data in 16 Bit mode */
937 while (hspi->TxXferCount > 0UL)
938 {
939 /* Wait until TXP flag is set to send data */
940 if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP))
941 {
942 if ((hspi->TxXferCount > 1UL) && (hspi->Init.FifoThreshold > SPI_FIFO_THRESHOLD_01DATA))
943 {
944 *((__IO uint32_t *)&hspi->Instance->TXDR) = *((const uint32_t *)hspi->pTxBuffPtr);
945 hspi->pTxBuffPtr += sizeof(uint32_t);
946 hspi->TxXferCount -= (uint16_t)2UL;
947 }
948 else
949 {
950 #if defined (__GNUC__)
951 *ptxdr_16bits = *((const uint16_t *)hspi->pTxBuffPtr);
952 #else
953 *((__IO uint16_t *)&hspi->Instance->TXDR) = *((const uint16_t *)hspi->pTxBuffPtr);
954 #endif /* __GNUC__ */
955 hspi->pTxBuffPtr += sizeof(uint16_t);
956 hspi->TxXferCount--;
957 }
958 }
959 else
960 {
961 /* Timeout management */
962 if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
963 {
964 /* Call standard close procedure with error check */
965 SPI_CloseTransfer(hspi);
966
967 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
968 hspi->State = HAL_SPI_STATE_READY;
969
970 /* Unlock the process */
971 __HAL_UNLOCK(hspi);
972
973 return HAL_TIMEOUT;
974 }
975 }
976 }
977 }
978 /* Transmit data in 8 Bit mode */
979 else
980 {
981 while (hspi->TxXferCount > 0UL)
982 {
983 /* Wait until TXP flag is set to send data */
984 if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP))
985 {
986 if ((hspi->TxXferCount > 3UL) && (hspi->Init.FifoThreshold > SPI_FIFO_THRESHOLD_03DATA))
987 {
988 *((__IO uint32_t *)&hspi->Instance->TXDR) = *((const uint32_t *)hspi->pTxBuffPtr);
989 hspi->pTxBuffPtr += sizeof(uint32_t);
990 hspi->TxXferCount -= (uint16_t)4UL;
991 }
992 else if ((hspi->TxXferCount > 1UL) && (hspi->Init.FifoThreshold > SPI_FIFO_THRESHOLD_01DATA))
993 {
994 #if defined (__GNUC__)
995 *ptxdr_16bits = *((const uint16_t *)hspi->pTxBuffPtr);
996 #else
997 *((__IO uint16_t *)&hspi->Instance->TXDR) = *((const uint16_t *)hspi->pTxBuffPtr);
998 #endif /* __GNUC__ */
999 hspi->pTxBuffPtr += sizeof(uint16_t);
1000 hspi->TxXferCount -= (uint16_t)2UL;
1001 }
1002 else
1003 {
1004 *((__IO uint8_t *)&hspi->Instance->TXDR) = *((const uint8_t *)hspi->pTxBuffPtr);
1005 hspi->pTxBuffPtr += sizeof(uint8_t);
1006 hspi->TxXferCount--;
1007 }
1008 }
1009 else
1010 {
1011 /* Timeout management */
1012 if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
1013 {
1014 /* Call standard close procedure with error check */
1015 SPI_CloseTransfer(hspi);
1016
1017 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
1018 hspi->State = HAL_SPI_STATE_READY;
1019
1020 /* Unlock the process */
1021 __HAL_UNLOCK(hspi);
1022
1023 return HAL_TIMEOUT;
1024 }
1025 }
1026 }
1027 }
1028
1029 /* Wait for Tx (and CRC) data to be sent */
1030 if (SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_EOT, RESET, Timeout, tickstart) != HAL_OK)
1031 {
1032 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
1033 }
1034
1035 /* Call standard close procedure with error check */
1036 SPI_CloseTransfer(hspi);
1037
1038 hspi->State = HAL_SPI_STATE_READY;
1039
1040 /* Unlock the process */
1041 __HAL_UNLOCK(hspi);
1042
1043 if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
1044 {
1045 return HAL_ERROR;
1046 }
1047 else
1048 {
1049 return HAL_OK;
1050 }
1051 }
1052
1053 /**
1054 * @brief Receive an amount of data in blocking mode.
1055 * @param hspi : pointer to a SPI_HandleTypeDef structure that contains
1056 * the configuration information for SPI module.
1057 * @param pData : pointer to data buffer
1058 * @param Size : amount of data to be received
1059 * @param Timeout: Timeout duration
1060 * @retval HAL status
1061 */
HAL_SPI_Receive(SPI_HandleTypeDef * hspi,uint8_t * pData,uint16_t Size,uint32_t Timeout)1062 HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
1063 {
1064 uint32_t tickstart;
1065 uint32_t temp_sr_reg;
1066 uint16_t init_max_data_in_fifo;
1067 init_max_data_in_fifo = (((uint16_t)(hspi->Init.FifoThreshold >> 5U) + 1U));
1068 #if defined (__GNUC__)
1069 __IO uint16_t *prxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->RXDR));
1070 #endif /* __GNUC__ */
1071
1072 /* Check Direction parameter */
1073 assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_RXONLY(hspi->Init.Direction));
1074
1075 /* Init tickstart for timeout management*/
1076 tickstart = HAL_GetTick();
1077
1078 if (hspi->State != HAL_SPI_STATE_READY)
1079 {
1080 return HAL_BUSY;
1081 }
1082
1083 if ((pData == NULL) || (Size == 0UL))
1084 {
1085 return HAL_ERROR;
1086 }
1087
1088 /* Lock the process */
1089 __HAL_LOCK(hspi);
1090
1091 /* Set the transaction information */
1092 hspi->State = HAL_SPI_STATE_BUSY_RX;
1093 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
1094 hspi->pRxBuffPtr = (uint8_t *)pData;
1095 hspi->RxXferSize = Size;
1096 hspi->RxXferCount = Size;
1097
1098 /*Init field not used in handle to zero */
1099 hspi->pTxBuffPtr = NULL;
1100 hspi->TxXferSize = (uint16_t) 0UL;
1101 hspi->TxXferCount = (uint16_t) 0UL;
1102 hspi->RxISR = NULL;
1103 hspi->TxISR = NULL;
1104
1105 /* Configure communication direction: 1Line */
1106 if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
1107 {
1108 SPI_1LINE_RX(hspi);
1109 }
1110 else
1111 {
1112 SPI_2LINES_RX(hspi);
1113 }
1114
1115 /* Set the number of data at current transfer */
1116 MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size);
1117
1118 /* Enable SPI peripheral */
1119 __HAL_SPI_ENABLE(hspi);
1120
1121 if (hspi->Init.Mode == SPI_MODE_MASTER)
1122 {
1123 /* Master transfer start */
1124 SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART);
1125 }
1126
1127 /* Receive data in 32 Bit mode */
1128 if ((hspi->Init.DataSize > SPI_DATASIZE_16BIT) && (IS_SPI_FULL_INSTANCE(hspi->Instance)))
1129 {
1130 /* Transfer loop */
1131 while (hspi->RxXferCount > 0UL)
1132 {
1133 /* Evaluate state of SR register */
1134 temp_sr_reg = hspi->Instance->SR;
1135
1136 /* Check the RXP flag */
1137 if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXP))
1138 {
1139 *((uint32_t *)hspi->pRxBuffPtr) = *((__IO uint32_t *)&hspi->Instance->RXDR);
1140 hspi->pRxBuffPtr += sizeof(uint32_t);
1141 hspi->RxXferCount--;
1142 }
1143 /* Check RXWNE flag if RXP cannot be reached */
1144 else if ((hspi->RxXferCount < init_max_data_in_fifo) && ((temp_sr_reg & SPI_SR_RXWNE_Msk) != 0UL))
1145 {
1146 *((uint32_t *)hspi->pRxBuffPtr) = *((__IO uint32_t *)&hspi->Instance->RXDR);
1147 hspi->pRxBuffPtr += sizeof(uint32_t);
1148 hspi->RxXferCount--;
1149 }
1150 else
1151 {
1152 /* Timeout management */
1153 if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
1154 {
1155 /* Call standard close procedure with error check */
1156 SPI_CloseTransfer(hspi);
1157
1158 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
1159 hspi->State = HAL_SPI_STATE_READY;
1160
1161 /* Unlock the process */
1162 __HAL_UNLOCK(hspi);
1163
1164 return HAL_TIMEOUT;
1165 }
1166 }
1167 }
1168 }
1169 /* Receive data in 16 Bit mode */
1170 else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
1171 {
1172 /* Transfer loop */
1173 while (hspi->RxXferCount > 0UL)
1174 {
1175 /* Evaluate state of SR register */
1176 temp_sr_reg = hspi->Instance->SR;
1177
1178 /* Check the RXP flag */
1179 if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXP))
1180 {
1181 #if defined (__GNUC__)
1182 *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits;
1183 #else
1184 *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
1185 #endif /* __GNUC__ */
1186 hspi->pRxBuffPtr += sizeof(uint16_t);
1187 hspi->RxXferCount--;
1188 }
1189 /* Check RXWNE flag if RXP cannot be reached */
1190 else if ((hspi->RxXferCount < init_max_data_in_fifo) && ((temp_sr_reg & SPI_SR_RXWNE_Msk) != 0UL))
1191 {
1192 #if defined (__GNUC__)
1193 *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits;
1194 #else
1195 *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
1196 #endif /* __GNUC__ */
1197 hspi->pRxBuffPtr += sizeof(uint16_t);
1198 #if defined (__GNUC__)
1199 *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits;
1200 #else
1201 *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
1202 #endif /* __GNUC__ */
1203 hspi->pRxBuffPtr += sizeof(uint16_t);
1204 hspi->RxXferCount -= (uint16_t)2UL;
1205 }
1206 /* Check RXPLVL flags when RXWNE cannot be reached */
1207 else if ((hspi->RxXferCount == 1UL) && ((temp_sr_reg & SPI_SR_RXPLVL_0) != 0UL))
1208 {
1209 #if defined (__GNUC__)
1210 *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits;
1211 #else
1212 *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
1213 #endif /* __GNUC__ */
1214 hspi->pRxBuffPtr += sizeof(uint16_t);
1215 hspi->RxXferCount--;
1216 }
1217 else
1218 {
1219 /* Timeout management */
1220 if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
1221 {
1222 /* Call standard close procedure with error check */
1223 SPI_CloseTransfer(hspi);
1224
1225 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
1226 hspi->State = HAL_SPI_STATE_READY;
1227
1228 /* Unlock the process */
1229 __HAL_UNLOCK(hspi);
1230
1231 return HAL_TIMEOUT;
1232 }
1233 }
1234 }
1235 }
1236 /* Receive data in 8 Bit mode */
1237 else
1238 {
1239 /* Transfer loop */
1240 while (hspi->RxXferCount > 0UL)
1241 {
1242 /* Evaluate state of SR register */
1243 temp_sr_reg = hspi->Instance->SR;
1244
1245 /* Check the RXP flag */
1246 if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXP))
1247 {
1248 *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
1249 hspi->pRxBuffPtr += sizeof(uint8_t);
1250 hspi->RxXferCount--;
1251 }
1252 /* Check RXWNE flag if RXP cannot be reached */
1253 else if ((hspi->RxXferCount < init_max_data_in_fifo) && ((temp_sr_reg & SPI_SR_RXWNE_Msk) != 0UL))
1254 {
1255 *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
1256 hspi->pRxBuffPtr += sizeof(uint8_t);
1257 *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
1258 hspi->pRxBuffPtr += sizeof(uint8_t);
1259 *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
1260 hspi->pRxBuffPtr += sizeof(uint8_t);
1261 *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
1262 hspi->pRxBuffPtr += sizeof(uint8_t);
1263 hspi->RxXferCount -= (uint16_t)4UL;
1264 }
1265 /* Check RXPLVL flags when RXWNE cannot be reached */
1266 else if ((hspi->RxXferCount < 4UL) && ((temp_sr_reg & SPI_SR_RXPLVL_Msk) != 0UL))
1267 {
1268 *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
1269 hspi->pRxBuffPtr += sizeof(uint8_t);
1270 hspi->RxXferCount--;
1271 }
1272 else
1273 {
1274 /* Timeout management */
1275 if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
1276 {
1277 /* Call standard close procedure with error check */
1278 SPI_CloseTransfer(hspi);
1279
1280 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
1281 hspi->State = HAL_SPI_STATE_READY;
1282
1283 /* Unlock the process */
1284 __HAL_UNLOCK(hspi);
1285
1286 return HAL_TIMEOUT;
1287 }
1288 }
1289 }
1290 }
1291
1292 #if (USE_SPI_CRC != 0UL)
1293 if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
1294 {
1295 /* Wait for crc data to be received */
1296 if (SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_EOT, RESET, Timeout, tickstart) != HAL_OK)
1297 {
1298 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
1299 }
1300 }
1301 #endif /* USE_SPI_CRC */
1302
1303 /* Call standard close procedure with error check */
1304 SPI_CloseTransfer(hspi);
1305
1306 hspi->State = HAL_SPI_STATE_READY;
1307
1308 /* Unlock the process */
1309 __HAL_UNLOCK(hspi);
1310
1311
1312 if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
1313 {
1314 return HAL_ERROR;
1315 }
1316 else
1317 {
1318 return HAL_OK;
1319 }
1320 }
1321
1322 /**
1323 * @brief Transmit and Receive an amount of data in blocking mode.
1324 * @param hspi : pointer to a SPI_HandleTypeDef structure that contains
1325 * the configuration information for SPI module.
1326 * @param pTxData: pointer to transmission data buffer
1327 * @param pRxData: pointer to reception data buffer
1328 * @param Size : amount of data to be sent and received
1329 * @param Timeout: Timeout duration
1330 * @retval HAL status
1331 */
HAL_SPI_TransmitReceive(SPI_HandleTypeDef * hspi,const uint8_t * pTxData,uint8_t * pRxData,uint16_t Size,uint32_t Timeout)1332 HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, const uint8_t *pTxData, uint8_t *pRxData,
1333 uint16_t Size, uint32_t Timeout)
1334 {
1335 #if defined (__GNUC__)
1336 __IO uint16_t *ptxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->TXDR));
1337 __IO uint16_t *prxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->RXDR));
1338 #endif /* __GNUC__ */
1339
1340 uint32_t tickstart;
1341 uint32_t fifo_length;
1342 uint32_t temp_sr_reg;
1343 uint16_t initial_TxXferCount;
1344 uint16_t initial_RxXferCount;
1345 uint16_t init_max_data_in_fifo;
1346 init_max_data_in_fifo = (((uint16_t)(hspi->Init.FifoThreshold >> 5U) + 1U));
1347
1348 /* Check Direction parameter */
1349 assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));
1350
1351 /* Init tickstart for timeout management*/
1352 tickstart = HAL_GetTick();
1353
1354 initial_TxXferCount = Size;
1355 initial_RxXferCount = Size;
1356
1357 if (hspi->State != HAL_SPI_STATE_READY)
1358 {
1359 return HAL_BUSY;
1360 }
1361
1362 if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0UL))
1363 {
1364 return HAL_ERROR;
1365 }
1366
1367 /* Lock the process */
1368 __HAL_LOCK(hspi);
1369
1370 /* Set the transaction information */
1371 hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
1372 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
1373 hspi->pRxBuffPtr = (uint8_t *)pRxData;
1374 hspi->RxXferCount = Size;
1375 hspi->RxXferSize = Size;
1376 hspi->pTxBuffPtr = (const uint8_t *)pTxData;
1377 hspi->TxXferCount = Size;
1378 hspi->TxXferSize = Size;
1379
1380 /*Init field not used in handle to zero */
1381 hspi->RxISR = NULL;
1382 hspi->TxISR = NULL;
1383
1384 /* Set Full-Duplex mode */
1385 SPI_2LINES(hspi);
1386
1387 /* Initialize FIFO length */
1388 if (IS_SPI_FULL_INSTANCE(hspi->Instance))
1389 {
1390 fifo_length = SPI_HIGHEND_FIFO_SIZE;
1391 }
1392 else
1393 {
1394 fifo_length = SPI_LOWEND_FIFO_SIZE;
1395 }
1396
1397 /* Set the number of data at current transfer */
1398 MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size);
1399
1400 __HAL_SPI_ENABLE(hspi);
1401
1402 if (hspi->Init.Mode == SPI_MODE_MASTER)
1403 {
1404 /* Master transfer start */
1405 SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART);
1406 }
1407
1408 /* Transmit and Receive data in 32 Bit mode */
1409 if ((hspi->Init.DataSize > SPI_DATASIZE_16BIT) && (IS_SPI_FULL_INSTANCE(hspi->Instance)))
1410 {
1411 /* Adapt fifo length to 32bits data width */
1412 fifo_length = (fifo_length / 4UL);
1413
1414 while ((initial_TxXferCount > 0UL) || (initial_RxXferCount > 0UL))
1415 {
1416 /* Check TXP flag */
1417 if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP)) && (initial_TxXferCount > 0UL) &&
1418 (initial_RxXferCount < (initial_TxXferCount + fifo_length)))
1419 {
1420 *((__IO uint32_t *)&hspi->Instance->TXDR) = *((const uint32_t *)hspi->pTxBuffPtr);
1421 hspi->pTxBuffPtr += sizeof(uint32_t);
1422 hspi->TxXferCount --;
1423 initial_TxXferCount = hspi->TxXferCount;
1424 }
1425
1426 /* Evaluate state of SR register */
1427 temp_sr_reg = hspi->Instance->SR;
1428
1429 if (initial_RxXferCount > 0UL)
1430 {
1431 /* Check the RXP flag */
1432 if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXP))
1433 {
1434 *((uint32_t *)hspi->pRxBuffPtr) = *((__IO uint32_t *)&hspi->Instance->RXDR);
1435 hspi->pRxBuffPtr += sizeof(uint32_t);
1436 hspi->RxXferCount--;
1437 initial_RxXferCount = hspi->RxXferCount;
1438 }
1439 /* Check RXWNE flag if RXP cannot be reached */
1440 else if ((initial_RxXferCount < init_max_data_in_fifo) && ((temp_sr_reg & SPI_SR_RXWNE_Msk) != 0UL))
1441 {
1442 *((uint32_t *)hspi->pRxBuffPtr) = *((__IO uint32_t *)&hspi->Instance->RXDR);
1443 hspi->pRxBuffPtr += sizeof(uint32_t);
1444 hspi->RxXferCount--;
1445 initial_RxXferCount = hspi->RxXferCount;
1446 }
1447 else
1448 {
1449 /* Timeout management */
1450 if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
1451 {
1452 /* Call standard close procedure with error check */
1453 SPI_CloseTransfer(hspi);
1454
1455 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
1456 hspi->State = HAL_SPI_STATE_READY;
1457
1458 /* Unlock the process */
1459 __HAL_UNLOCK(hspi);
1460
1461 return HAL_TIMEOUT;
1462 }
1463 }
1464 }
1465 }
1466 }
1467 /* Transmit and Receive data in 16 Bit mode */
1468 else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
1469 {
1470 /* Adapt fifo length to 16bits data width */
1471 fifo_length = (fifo_length / 2UL);
1472
1473 while ((initial_TxXferCount > 0UL) || (initial_RxXferCount > 0UL))
1474 {
1475 /* Check the TXP flag */
1476 if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP)) && (initial_TxXferCount > 0UL) &&
1477 (initial_RxXferCount < (initial_TxXferCount + fifo_length)))
1478 {
1479 #if defined (__GNUC__)
1480 *ptxdr_16bits = *((const uint16_t *)hspi->pTxBuffPtr);
1481 #else
1482 *((__IO uint16_t *)&hspi->Instance->TXDR) = *((const uint16_t *)hspi->pTxBuffPtr);
1483 #endif /* __GNUC__ */
1484 hspi->pTxBuffPtr += sizeof(uint16_t);
1485 hspi->TxXferCount--;
1486 initial_TxXferCount = hspi->TxXferCount;
1487 }
1488
1489 /* Evaluate state of SR register */
1490 temp_sr_reg = hspi->Instance->SR;
1491
1492 if (initial_RxXferCount > 0UL)
1493 {
1494 /* Check the RXP flag */
1495 if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXP))
1496 {
1497 #if defined (__GNUC__)
1498 *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits;
1499 #else
1500 *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
1501 #endif /* __GNUC__ */
1502 hspi->pRxBuffPtr += sizeof(uint16_t);
1503 hspi->RxXferCount--;
1504 initial_RxXferCount = hspi->RxXferCount;
1505 }
1506 /* Check RXWNE flag if RXP cannot be reached */
1507 else if ((initial_RxXferCount < init_max_data_in_fifo) && ((temp_sr_reg & SPI_SR_RXWNE_Msk) != 0UL))
1508 {
1509 #if defined (__GNUC__)
1510 *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits;
1511 #else
1512 *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
1513 #endif /* __GNUC__ */
1514 hspi->pRxBuffPtr += sizeof(uint16_t);
1515 #if defined (__GNUC__)
1516 *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits;
1517 #else
1518 *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
1519 #endif /* __GNUC__ */
1520 hspi->pRxBuffPtr += sizeof(uint16_t);
1521 hspi->RxXferCount -= (uint16_t)2UL;
1522 initial_RxXferCount = hspi->RxXferCount;
1523 }
1524 /* Check RXPLVL flags when RXWNE cannot be reached */
1525 else if ((initial_RxXferCount == 1UL) && ((temp_sr_reg & SPI_SR_RXPLVL_0) != 0UL))
1526 {
1527 #if defined (__GNUC__)
1528 *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits;
1529 #else
1530 *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
1531 #endif /* __GNUC__ */
1532 hspi->pRxBuffPtr += sizeof(uint16_t);
1533 hspi->RxXferCount--;
1534 initial_RxXferCount = hspi->RxXferCount;
1535 }
1536 else
1537 {
1538 /* Timeout management */
1539 if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
1540 {
1541 /* Call standard close procedure with error check */
1542 SPI_CloseTransfer(hspi);
1543
1544 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
1545 hspi->State = HAL_SPI_STATE_READY;
1546
1547 /* Unlock the process */
1548 __HAL_UNLOCK(hspi);
1549
1550 return HAL_TIMEOUT;
1551 }
1552 }
1553 }
1554 }
1555 }
1556 /* Transmit and Receive data in 8 Bit mode */
1557 else
1558 {
1559 while ((initial_TxXferCount > 0UL) || (initial_RxXferCount > 0UL))
1560 {
1561 /* Check the TXP flag */
1562 if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP)) && (initial_TxXferCount > 0UL) &&
1563 (initial_RxXferCount < (initial_TxXferCount + fifo_length)))
1564 {
1565 *((__IO uint8_t *)&hspi->Instance->TXDR) = *((const uint8_t *)hspi->pTxBuffPtr);
1566 hspi->pTxBuffPtr += sizeof(uint8_t);
1567 hspi->TxXferCount--;
1568 initial_TxXferCount = hspi->TxXferCount;
1569 }
1570
1571 /* Evaluate state of SR register */
1572 temp_sr_reg = hspi->Instance->SR;
1573
1574 if (initial_RxXferCount > 0UL)
1575 {
1576 /* Check the RXP flag */
1577 if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXP))
1578 {
1579 *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
1580 hspi->pRxBuffPtr += sizeof(uint8_t);
1581 hspi->RxXferCount--;
1582 initial_RxXferCount = hspi->RxXferCount;
1583 }
1584 /* Check RXWNE flag if RXP cannot be reached */
1585 else if ((initial_RxXferCount < init_max_data_in_fifo) && ((temp_sr_reg & SPI_SR_RXWNE_Msk) != 0UL))
1586 {
1587 *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
1588 hspi->pRxBuffPtr += sizeof(uint8_t);
1589 *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
1590 hspi->pRxBuffPtr += sizeof(uint8_t);
1591 *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
1592 hspi->pRxBuffPtr += sizeof(uint8_t);
1593 *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
1594 hspi->pRxBuffPtr += sizeof(uint8_t);
1595 hspi->RxXferCount -= (uint16_t)4UL;
1596 initial_RxXferCount = hspi->RxXferCount;
1597 }
1598 /* Check RXPLVL flags when RXWNE cannot be reached */
1599 else if ((initial_RxXferCount < 4UL) && ((temp_sr_reg & SPI_SR_RXPLVL_Msk) != 0UL))
1600 {
1601 *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
1602 hspi->pRxBuffPtr += sizeof(uint8_t);
1603 hspi->RxXferCount--;
1604 initial_RxXferCount = hspi->RxXferCount;
1605 }
1606 else
1607 {
1608 /* Timeout management */
1609 if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
1610 {
1611 /* Call standard close procedure with error check */
1612 SPI_CloseTransfer(hspi);
1613
1614 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
1615 hspi->State = HAL_SPI_STATE_READY;
1616
1617 /* Unlock the process */
1618 __HAL_UNLOCK(hspi);
1619
1620 return HAL_TIMEOUT;
1621 }
1622 }
1623 }
1624 }
1625 }
1626
1627 /* Wait for Tx/Rx (and CRC) data to be sent/received */
1628 if (SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_EOT, RESET, Timeout, tickstart) != HAL_OK)
1629 {
1630 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
1631 }
1632
1633 /* Call standard close procedure with error check */
1634 SPI_CloseTransfer(hspi);
1635
1636 hspi->State = HAL_SPI_STATE_READY;
1637
1638 /* Unlock the process */
1639 __HAL_UNLOCK(hspi);
1640
1641 if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
1642 {
1643 return HAL_ERROR;
1644 }
1645 else
1646 {
1647 return HAL_OK;
1648 }
1649 }
1650
1651 /**
1652 * @brief Transmit an amount of data in non-blocking mode with Interrupt.
1653 * @param hspi : pointer to a SPI_HandleTypeDef structure that contains
1654 * the configuration information for SPI module.
1655 * @param pData: pointer to data buffer
1656 * @param Size : amount of data to be sent
1657 * @retval HAL status
1658 */
HAL_SPI_Transmit_IT(SPI_HandleTypeDef * hspi,const uint8_t * pData,uint16_t Size)1659 HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, const uint8_t *pData, uint16_t Size)
1660 {
1661 /* Check Direction parameter */
1662 assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_TXONLY(hspi->Init.Direction));
1663
1664 if ((pData == NULL) || (Size == 0UL))
1665 {
1666 return HAL_ERROR;
1667 }
1668
1669 if (hspi->State != HAL_SPI_STATE_READY)
1670 {
1671 return HAL_BUSY;
1672 }
1673
1674 /* Lock the process */
1675 __HAL_LOCK(hspi);
1676
1677 /* Set the transaction information */
1678 hspi->State = HAL_SPI_STATE_BUSY_TX;
1679 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
1680 hspi->pTxBuffPtr = (const uint8_t *)pData;
1681 hspi->TxXferSize = Size;
1682 hspi->TxXferCount = Size;
1683
1684 /* Init field not used in handle to zero */
1685 hspi->pRxBuffPtr = NULL;
1686 hspi->RxXferSize = (uint16_t) 0UL;
1687 hspi->RxXferCount = (uint16_t) 0UL;
1688 hspi->RxISR = NULL;
1689
1690 /* Set the function for IT treatment */
1691 if ((hspi->Init.DataSize > SPI_DATASIZE_16BIT) && (IS_SPI_FULL_INSTANCE(hspi->Instance)))
1692 {
1693 hspi->TxISR = SPI_TxISR_32BIT;
1694 }
1695 else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
1696 {
1697 hspi->TxISR = SPI_TxISR_16BIT;
1698 }
1699 else
1700 {
1701 hspi->TxISR = SPI_TxISR_8BIT;
1702 }
1703
1704 /* Configure communication direction : 1Line */
1705 if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
1706 {
1707 SPI_1LINE_TX(hspi);
1708 }
1709 else
1710 {
1711 SPI_2LINES_TX(hspi);
1712 }
1713
1714 /* Set the number of data at current transfer */
1715 MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size);
1716
1717 /* Enable SPI peripheral */
1718 __HAL_SPI_ENABLE(hspi);
1719
1720 /* Unlock the process */
1721 __HAL_UNLOCK(hspi);
1722
1723 /* Enable EOT, TXP, FRE, MODF and UDR interrupts */
1724 __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_EOT | SPI_IT_TXP | SPI_IT_UDR | SPI_IT_FRE | SPI_IT_MODF));
1725
1726 if (hspi->Init.Mode == SPI_MODE_MASTER)
1727 {
1728 /* Master transfer start */
1729 SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART);
1730 }
1731
1732 return HAL_OK;
1733 }
1734
1735 /**
1736 * @brief Receive an amount of data in non-blocking mode with Interrupt.
1737 * @param hspi : pointer to a SPI_HandleTypeDef structure that contains
1738 * the configuration information for SPI module.
1739 * @param pData: pointer to data buffer
1740 * @param Size : amount of data to be sent
1741 * @retval HAL status
1742 */
HAL_SPI_Receive_IT(SPI_HandleTypeDef * hspi,uint8_t * pData,uint16_t Size)1743 HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
1744 {
1745 /* Check Direction parameter */
1746 assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_RXONLY(hspi->Init.Direction));
1747
1748 if (hspi->State != HAL_SPI_STATE_READY)
1749 {
1750 return HAL_BUSY;
1751 }
1752
1753 if ((pData == NULL) || (Size == 0UL))
1754 {
1755 return HAL_ERROR;
1756 }
1757
1758 /* Lock the process */
1759 __HAL_LOCK(hspi);
1760
1761 /* Set the transaction information */
1762 hspi->State = HAL_SPI_STATE_BUSY_RX;
1763 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
1764 hspi->pRxBuffPtr = (uint8_t *)pData;
1765 hspi->RxXferSize = Size;
1766 hspi->RxXferCount = Size;
1767
1768 /* Init field not used in handle to zero */
1769 hspi->pTxBuffPtr = NULL;
1770 hspi->TxXferSize = (uint16_t) 0UL;
1771 hspi->TxXferCount = (uint16_t) 0UL;
1772 hspi->TxISR = NULL;
1773
1774 /* Set the function for IT treatment */
1775 if ((hspi->Init.DataSize > SPI_DATASIZE_16BIT) && (IS_SPI_FULL_INSTANCE(hspi->Instance)))
1776 {
1777 hspi->RxISR = SPI_RxISR_32BIT;
1778 }
1779 else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
1780 {
1781 hspi->RxISR = SPI_RxISR_16BIT;
1782 }
1783 else
1784 {
1785 hspi->RxISR = SPI_RxISR_8BIT;
1786 }
1787
1788 /* Configure communication direction : 1Line */
1789 if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
1790 {
1791 SPI_1LINE_RX(hspi);
1792 }
1793 else
1794 {
1795 SPI_2LINES_RX(hspi);
1796 }
1797
1798 /* Note : The SPI must be enabled after unlocking current process
1799 to avoid the risk of SPI interrupt handle execution before current
1800 process unlock */
1801
1802 /* Set the number of data at current transfer */
1803 MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size);
1804
1805 /* Enable SPI peripheral */
1806 __HAL_SPI_ENABLE(hspi);
1807
1808 /* Unlock the process */
1809 __HAL_UNLOCK(hspi);
1810
1811 /* Enable EOT, RXP, OVR, FRE and MODF interrupts */
1812 __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_EOT | SPI_IT_RXP | SPI_IT_OVR | SPI_IT_FRE | SPI_IT_MODF));
1813
1814 if (hspi->Init.Mode == SPI_MODE_MASTER)
1815 {
1816 /* Master transfer start */
1817 SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART);
1818 }
1819
1820 return HAL_OK;
1821 }
1822
1823 /**
1824 * @brief Transmit and Receive an amount of data in non-blocking mode with Interrupt.
1825 * @param hspi : pointer to a SPI_HandleTypeDef structure that contains
1826 * the configuration information for SPI module.
1827 * @param pTxData: pointer to transmission data buffer
1828 * @param pRxData: pointer to reception data buffer
1829 * @param Size : amount of data to be sent and received
1830 * @retval HAL status
1831 */
HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef * hspi,const uint8_t * pTxData,uint8_t * pRxData,uint16_t Size)1832 HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, const uint8_t *pTxData, uint8_t *pRxData,
1833 uint16_t Size)
1834 {
1835 uint32_t tmp_TxXferCount;
1836 #if defined (__GNUC__)
1837 __IO uint16_t *ptxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->TXDR));
1838 #endif /* __GNUC__ */
1839
1840 /* Check Direction parameter */
1841 assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));
1842
1843 if (hspi->State != HAL_SPI_STATE_READY)
1844 {
1845 return HAL_BUSY;
1846 }
1847
1848 if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0UL))
1849 {
1850 return HAL_ERROR;
1851 }
1852
1853 /* Lock the process */
1854 __HAL_LOCK(hspi);
1855
1856 /* Set the transaction information */
1857 hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
1858 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
1859 hspi->pTxBuffPtr = (const uint8_t *)pTxData;
1860 hspi->TxXferSize = Size;
1861 hspi->TxXferCount = Size;
1862 hspi->pRxBuffPtr = (uint8_t *)pRxData;
1863 hspi->RxXferSize = Size;
1864 hspi->RxXferCount = Size;
1865 tmp_TxXferCount = hspi->TxXferCount;
1866
1867 /* Set the function for IT treatment */
1868 if ((hspi->Init.DataSize > SPI_DATASIZE_16BIT) && (IS_SPI_FULL_INSTANCE(hspi->Instance)))
1869 {
1870 hspi->TxISR = SPI_TxISR_32BIT;
1871 hspi->RxISR = SPI_RxISR_32BIT;
1872 }
1873 else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
1874 {
1875 hspi->RxISR = SPI_RxISR_16BIT;
1876 hspi->TxISR = SPI_TxISR_16BIT;
1877 }
1878 else
1879 {
1880 hspi->RxISR = SPI_RxISR_8BIT;
1881 hspi->TxISR = SPI_TxISR_8BIT;
1882 }
1883
1884 /* Set Full-Duplex mode */
1885 SPI_2LINES(hspi);
1886
1887 /* Set the number of data at current transfer */
1888 MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size);
1889
1890 /* Enable SPI peripheral */
1891 __HAL_SPI_ENABLE(hspi);
1892
1893 /* Fill in the TxFIFO */
1894 while ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP)) && (tmp_TxXferCount != 0UL))
1895 {
1896 /* Transmit data in 32 Bit mode */
1897 if (hspi->Init.DataSize > SPI_DATASIZE_16BIT)
1898 {
1899 *((__IO uint32_t *)&hspi->Instance->TXDR) = *((const uint32_t *)hspi->pTxBuffPtr);
1900 hspi->pTxBuffPtr += sizeof(uint32_t);
1901 hspi->TxXferCount--;
1902 tmp_TxXferCount = hspi->TxXferCount;
1903 }
1904 /* Transmit data in 16 Bit mode */
1905 else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
1906 {
1907 #if defined (__GNUC__)
1908 *ptxdr_16bits = *((const uint16_t *)hspi->pTxBuffPtr);
1909 #else
1910 *((__IO uint16_t *)&hspi->Instance->TXDR) = *((const uint16_t *)hspi->pTxBuffPtr);
1911 #endif /* __GNUC__ */
1912 hspi->pTxBuffPtr += sizeof(uint16_t);
1913 hspi->TxXferCount--;
1914 tmp_TxXferCount = hspi->TxXferCount;
1915 }
1916 /* Transmit data in 8 Bit mode */
1917 else
1918 {
1919 *((__IO uint8_t *)&hspi->Instance->TXDR) = *((const uint8_t *)hspi->pTxBuffPtr);
1920 hspi->pTxBuffPtr += sizeof(uint8_t);
1921 hspi->TxXferCount--;
1922 tmp_TxXferCount = hspi->TxXferCount;
1923 }
1924 }
1925
1926 /* Unlock the process */
1927 __HAL_UNLOCK(hspi);
1928
1929 /* Enable EOT, DXP, UDR, OVR, FRE and MODF interrupts */
1930 __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_EOT | SPI_IT_DXP | SPI_IT_UDR | SPI_IT_OVR | SPI_IT_FRE | SPI_IT_MODF));
1931
1932 if (hspi->Init.Mode == SPI_MODE_MASTER)
1933 {
1934 /* Start Master transfer */
1935 SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART);
1936 }
1937
1938 return HAL_OK;
1939 }
1940
1941
1942
1943
1944 /**
1945 * @brief Transmit an amount of data in non-blocking mode with DMA.
1946 * @param hspi : pointer to a SPI_HandleTypeDef structure that contains
1947 * the configuration information for SPI module.
1948 * @param pData: pointer to data buffer
1949 * @param Size : amount of data to be sent
1950 * @retval HAL status
1951 */
HAL_SPI_Transmit_DMA(SPI_HandleTypeDef * hspi,const uint8_t * pData,uint16_t Size)1952 HAL_StatusTypeDef HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, const uint8_t *pData, uint16_t Size)
1953 {
1954 HAL_StatusTypeDef status;
1955
1956 /* Check Direction parameter */
1957 assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_TXONLY(hspi->Init.Direction));
1958
1959 if (hspi->State != HAL_SPI_STATE_READY)
1960 {
1961 return HAL_BUSY;
1962 }
1963
1964 if ((pData == NULL) || (Size == 0UL))
1965 {
1966 return HAL_ERROR;
1967 }
1968
1969 /* Lock the process */
1970 __HAL_LOCK(hspi);
1971
1972 /* Set the transaction information */
1973 hspi->State = HAL_SPI_STATE_BUSY_TX;
1974 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
1975 hspi->pTxBuffPtr = (const uint8_t *)pData;
1976 hspi->TxXferSize = Size;
1977 hspi->TxXferCount = Size;
1978
1979 /* Init field not used in handle to zero */
1980 hspi->pRxBuffPtr = NULL;
1981 hspi->TxISR = NULL;
1982 hspi->RxISR = NULL;
1983 hspi->RxXferSize = (uint16_t)0UL;
1984 hspi->RxXferCount = (uint16_t)0UL;
1985
1986 /* Configure communication direction : 1Line */
1987 if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
1988 {
1989 SPI_1LINE_TX(hspi);
1990 }
1991 else
1992 {
1993 SPI_2LINES_TX(hspi);
1994 }
1995
1996 /* Packing mode management is enabled by the DMA settings */
1997 if (((hspi->Init.DataSize > SPI_DATASIZE_16BIT) && (hspi->hdmatx->Init.SrcDataWidth != DMA_SRC_DATAWIDTH_WORD) && \
1998 (IS_SPI_FULL_INSTANCE(hspi->Instance))) || \
1999 ((hspi->Init.DataSize > SPI_DATASIZE_8BIT) && (hspi->hdmatx->Init.SrcDataWidth == DMA_SRC_DATAWIDTH_BYTE)))
2000 {
2001 /* Restriction the DMA data received is not allowed in this mode */
2002 __HAL_UNLOCK(hspi);
2003 return HAL_ERROR;
2004 }
2005
2006 /* Adjust XferCount according to DMA alignment / Data size */
2007 if (hspi->Init.DataSize <= SPI_DATASIZE_8BIT)
2008 {
2009 if (hspi->hdmatx->Init.SrcDataWidth == DMA_SRC_DATAWIDTH_HALFWORD)
2010 {
2011 hspi->TxXferCount = (hspi->TxXferCount + (uint16_t) 1UL) >> 1UL;
2012 }
2013 if (hspi->hdmatx->Init.SrcDataWidth == DMA_SRC_DATAWIDTH_WORD)
2014 {
2015 hspi->TxXferCount = (hspi->TxXferCount + (uint16_t) 3UL) >> 2UL;
2016 }
2017 }
2018 else if (hspi->Init.DataSize <= SPI_DATASIZE_16BIT)
2019 {
2020 if (hspi->hdmatx->Init.SrcDataWidth == DMA_SRC_DATAWIDTH_WORD)
2021 {
2022 hspi->TxXferCount = (hspi->TxXferCount + (uint16_t) 1UL) >> 1UL;
2023 }
2024 }
2025 else
2026 {
2027 /* Adjustment done */
2028 }
2029
2030 /* Set the SPI TxDMA Half transfer complete callback */
2031 hspi->hdmatx->XferHalfCpltCallback = SPI_DMAHalfTransmitCplt;
2032
2033 /* Set the SPI TxDMA transfer complete callback */
2034 hspi->hdmatx->XferCpltCallback = SPI_DMATransmitCplt;
2035
2036 /* Set the DMA error callback */
2037 hspi->hdmatx->XferErrorCallback = SPI_DMAError;
2038
2039 /* Set the DMA AbortCpltCallback */
2040 hspi->hdmatx->XferAbortCallback = NULL;
2041
2042 /* Clear TXDMAEN bit*/
2043 CLEAR_BIT(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN);
2044
2045 if (hspi->Init.DataSize <= SPI_DATASIZE_8BIT)
2046 {
2047 hspi->TxXferCount = Size;
2048 }
2049 else if (hspi->Init.DataSize <= SPI_DATASIZE_16BIT)
2050 {
2051 hspi->TxXferCount = Size * 2U;
2052 }
2053 else
2054 {
2055 hspi->TxXferCount = Size * 4U;
2056 }
2057
2058 /* Enable the Tx DMA Stream/Channel */
2059 if ((hspi->hdmatx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
2060 {
2061 if (hspi->hdmatx->LinkedListQueue != NULL)
2062 {
2063 /* Set DMA data size */
2064 hspi->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hspi->TxXferCount;
2065
2066 /* Set DMA source address */
2067 hspi->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)hspi->pTxBuffPtr;
2068
2069 /* Set DMA destination address */
2070 hspi->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)&hspi->Instance->TXDR;
2071
2072 status = HAL_DMAEx_List_Start_IT(hspi->hdmatx);
2073 }
2074 else
2075 {
2076 status = HAL_ERROR;
2077 }
2078 }
2079 else
2080 {
2081 status = HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->TXDR,
2082 hspi->TxXferCount);
2083 }
2084
2085 /* Check status */
2086 if (status != HAL_OK)
2087 {
2088 /* Update SPI error code */
2089 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
2090 hspi->State = HAL_SPI_STATE_READY;
2091
2092 /* Unlock the process */
2093 __HAL_UNLOCK(hspi);
2094
2095 return HAL_ERROR;
2096 }
2097
2098 /* Set the number of data at current transfer */
2099 if (hspi->hdmatx->Mode == DMA_LINKEDLIST_CIRCULAR)
2100 {
2101 MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, 0UL);
2102 }
2103 else
2104 {
2105 MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size);
2106 }
2107
2108 /* Enable Tx DMA Request */
2109 SET_BIT(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN);
2110
2111 /* Enable the SPI Error Interrupt Bit */
2112 __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_UDR | SPI_IT_FRE | SPI_IT_MODF));
2113
2114 /* Enable SPI peripheral */
2115 __HAL_SPI_ENABLE(hspi);
2116
2117 if (hspi->Init.Mode == SPI_MODE_MASTER)
2118 {
2119 /* Master transfer start */
2120 SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART);
2121 }
2122
2123 /* Unlock the process */
2124 __HAL_UNLOCK(hspi);
2125
2126 return HAL_OK;
2127 }
2128
2129 /**
2130 * @brief Receive an amount of data in non-blocking mode with DMA.
2131 * @param hspi : pointer to a SPI_HandleTypeDef structure that contains
2132 * the configuration information for SPI module.
2133 * @param pData: pointer to data buffer
2134 * @param Size : amount of data to be sent
2135 * @note When the CRC feature is enabled the pData Length must be Size + 1.
2136 * @retval HAL status
2137 */
HAL_SPI_Receive_DMA(SPI_HandleTypeDef * hspi,uint8_t * pData,uint16_t Size)2138 HAL_StatusTypeDef HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
2139 {
2140 HAL_StatusTypeDef status;
2141
2142 /* Check Direction parameter */
2143 assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_RXONLY(hspi->Init.Direction));
2144
2145
2146 if (hspi->State != HAL_SPI_STATE_READY)
2147 {
2148 __HAL_UNLOCK(hspi);
2149 return HAL_BUSY;
2150 }
2151
2152 if ((pData == NULL) || (Size == 0UL))
2153 {
2154 __HAL_UNLOCK(hspi);
2155 return HAL_ERROR;
2156 }
2157
2158 /* Lock the process */
2159 __HAL_LOCK(hspi);
2160
2161 /* Set the transaction information */
2162 hspi->State = HAL_SPI_STATE_BUSY_RX;
2163 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
2164 hspi->pRxBuffPtr = (uint8_t *)pData;
2165 hspi->RxXferSize = Size;
2166 hspi->RxXferCount = Size;
2167
2168 /*Init field not used in handle to zero */
2169 hspi->RxISR = NULL;
2170 hspi->TxISR = NULL;
2171 hspi->TxXferSize = (uint16_t) 0UL;
2172 hspi->TxXferCount = (uint16_t) 0UL;
2173
2174 /* Configure communication direction : 1Line */
2175 if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
2176 {
2177 SPI_1LINE_RX(hspi);
2178 }
2179 else
2180 {
2181 SPI_2LINES_RX(hspi);
2182 }
2183
2184 /* Packing mode management is enabled by the DMA settings */
2185 if (((hspi->Init.DataSize > SPI_DATASIZE_16BIT) && (hspi->hdmarx->Init.DestDataWidth != DMA_DEST_DATAWIDTH_WORD) && \
2186 (IS_SPI_FULL_INSTANCE(hspi->Instance))) || \
2187 ((hspi->Init.DataSize > SPI_DATASIZE_8BIT) && (hspi->hdmarx->Init.DestDataWidth == DMA_DEST_DATAWIDTH_BYTE)))
2188 {
2189 /* Restriction the DMA data received is not allowed in this mode */
2190 __HAL_UNLOCK(hspi);
2191 return HAL_ERROR;
2192 }
2193
2194 /* Clear RXDMAEN bit */
2195 CLEAR_BIT(hspi->Instance->CFG1, SPI_CFG1_RXDMAEN);
2196
2197 /* Adjust XferCount according to DMA alignment / Data size */
2198 if (hspi->Init.DataSize <= SPI_DATASIZE_8BIT)
2199 {
2200 if (hspi->hdmarx->Init.DestDataWidth == DMA_DEST_DATAWIDTH_HALFWORD)
2201 {
2202 hspi->RxXferCount = (hspi->RxXferCount + (uint16_t) 1UL) >> 1UL;
2203 }
2204 if (hspi->hdmarx->Init.DestDataWidth == DMA_DEST_DATAWIDTH_WORD)
2205 {
2206 hspi->RxXferCount = (hspi->RxXferCount + (uint16_t) 3UL) >> 2UL;
2207 }
2208 }
2209 else if (hspi->Init.DataSize <= SPI_DATASIZE_16BIT)
2210 {
2211 if (hspi->hdmarx->Init.DestDataWidth == DMA_DEST_DATAWIDTH_WORD)
2212 {
2213 hspi->RxXferCount = (hspi->RxXferCount + (uint16_t) 1UL) >> 1UL;
2214 }
2215 }
2216 else
2217 {
2218 /* Adjustment done */
2219 }
2220
2221 /* Set the SPI RxDMA Half transfer complete callback */
2222 hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfReceiveCplt;
2223
2224 /* Set the SPI Rx DMA transfer complete callback */
2225 hspi->hdmarx->XferCpltCallback = SPI_DMAReceiveCplt;
2226
2227 /* Set the DMA error callback */
2228 hspi->hdmarx->XferErrorCallback = SPI_DMAError;
2229
2230 /* Set the DMA AbortCpltCallback */
2231 hspi->hdmarx->XferAbortCallback = NULL;
2232
2233 if (hspi->Init.DataSize <= SPI_DATASIZE_8BIT)
2234 {
2235 hspi->RxXferCount = Size;
2236 }
2237 else if (hspi->Init.DataSize <= SPI_DATASIZE_16BIT)
2238 {
2239 hspi->RxXferCount = Size * 2U;
2240 }
2241 else
2242 {
2243 hspi->RxXferCount = Size * 4U;
2244 }
2245
2246 /* Enable the Rx DMA Stream/Channel */
2247 if ((hspi->hdmarx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
2248 {
2249 if (hspi->hdmarx->LinkedListQueue != NULL)
2250 {
2251 /* Set DMA data size */
2252 hspi->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hspi->RxXferCount;
2253
2254 /* Set DMA source address */
2255 hspi->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)&hspi->Instance->RXDR;
2256
2257 /* Set DMA destination address */
2258 hspi->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)hspi->pRxBuffPtr;
2259
2260 status = HAL_DMAEx_List_Start_IT(hspi->hdmarx);
2261 }
2262 else
2263 {
2264 status = HAL_ERROR;
2265 }
2266 }
2267 else
2268 {
2269 status = HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->RXDR, (uint32_t)hspi->pRxBuffPtr,
2270 hspi->RxXferCount);
2271 }
2272
2273 /* Check status */
2274 if (status != HAL_OK)
2275 {
2276 /* Update SPI error code */
2277 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
2278 hspi->State = HAL_SPI_STATE_READY;
2279
2280 /* Unlock the process */
2281 __HAL_UNLOCK(hspi);
2282
2283 return HAL_ERROR;
2284 }
2285
2286 /* Set the number of data at current transfer */
2287 if (hspi->hdmarx->Mode == DMA_LINKEDLIST_CIRCULAR)
2288 {
2289 MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, 0UL);
2290 }
2291 else
2292 {
2293 MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size);
2294 }
2295
2296 /* Enable Rx DMA Request */
2297 SET_BIT(hspi->Instance->CFG1, SPI_CFG1_RXDMAEN);
2298
2299 /* Enable the SPI Error Interrupt Bit */
2300 __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_OVR | SPI_IT_FRE | SPI_IT_MODF));
2301
2302 /* Enable SPI peripheral */
2303 __HAL_SPI_ENABLE(hspi);
2304
2305 if (hspi->Init.Mode == SPI_MODE_MASTER)
2306 {
2307 /* Master transfer start */
2308 SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART);
2309 }
2310
2311 /* Unlock the process */
2312 __HAL_UNLOCK(hspi);
2313
2314 return HAL_OK;
2315 }
2316
2317 /**
2318 * @brief Transmit and Receive an amount of data in non-blocking mode with DMA.
2319 * @param hspi : pointer to a SPI_HandleTypeDef structure that contains
2320 * the configuration information for SPI module.
2321 * @param pTxData: pointer to transmission data buffer
2322 * @param pRxData: pointer to reception data buffer
2323 * @param Size : amount of data to be sent
2324 * @note When the CRC feature is enabled the pRxData Length must be Size + 1
2325 * @retval HAL status
2326 */
HAL_SPI_TransmitReceive_DMA(SPI_HandleTypeDef * hspi,const uint8_t * pTxData,uint8_t * pRxData,uint16_t Size)2327 HAL_StatusTypeDef HAL_SPI_TransmitReceive_DMA(SPI_HandleTypeDef *hspi, const uint8_t *pTxData, uint8_t *pRxData,
2328 uint16_t Size)
2329 {
2330 HAL_StatusTypeDef status;
2331
2332 /* Check Direction parameter */
2333 assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));
2334
2335 if (hspi->State != HAL_SPI_STATE_READY)
2336 {
2337 return HAL_BUSY;
2338 }
2339
2340 if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0UL))
2341 {
2342 return HAL_ERROR;
2343 }
2344
2345 /* Lock the process */
2346 __HAL_LOCK(hspi);
2347
2348 /* Set the transaction information */
2349 hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
2350 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
2351 hspi->pTxBuffPtr = (const uint8_t *)pTxData;
2352 hspi->TxXferSize = Size;
2353 hspi->TxXferCount = Size;
2354 hspi->pRxBuffPtr = (uint8_t *)pRxData;
2355 hspi->RxXferSize = Size;
2356 hspi->RxXferCount = Size;
2357
2358 /* Init field not used in handle to zero */
2359 hspi->RxISR = NULL;
2360 hspi->TxISR = NULL;
2361
2362 /* Set Full-Duplex mode */
2363 SPI_2LINES(hspi);
2364
2365 /* Reset the Tx/Rx DMA bits */
2366 CLEAR_BIT(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN | SPI_CFG1_RXDMAEN);
2367
2368 /* Packing mode management is enabled by the DMA settings */
2369 if (((hspi->Init.DataSize > SPI_DATASIZE_16BIT) && (hspi->hdmarx->Init.DestDataWidth != DMA_DEST_DATAWIDTH_WORD) && \
2370 (IS_SPI_FULL_INSTANCE(hspi->Instance))) || \
2371 ((hspi->Init.DataSize > SPI_DATASIZE_8BIT) && (hspi->hdmarx->Init.DestDataWidth == DMA_DEST_DATAWIDTH_BYTE)))
2372 {
2373 /* Restriction the DMA data received is not allowed in this mode */
2374 /* Unlock the process */
2375 __HAL_UNLOCK(hspi);
2376 return HAL_ERROR;
2377 }
2378
2379 /* Adjust XferCount according to DMA alignment / Data size */
2380 if (hspi->Init.DataSize <= SPI_DATASIZE_8BIT)
2381 {
2382 if (hspi->hdmatx->Init.SrcDataWidth == DMA_SRC_DATAWIDTH_HALFWORD)
2383 {
2384 hspi->TxXferCount = (hspi->TxXferCount + (uint16_t) 1UL) >> 1UL;
2385 }
2386 if (hspi->hdmatx->Init.SrcDataWidth == DMA_SRC_DATAWIDTH_WORD)
2387 {
2388 hspi->TxXferCount = (hspi->TxXferCount + (uint16_t) 3UL) >> 2UL;
2389 }
2390 if (hspi->hdmarx->Init.DestDataWidth == DMA_DEST_DATAWIDTH_HALFWORD)
2391 {
2392 hspi->RxXferCount = (hspi->RxXferCount + (uint16_t) 1UL) >> 1UL;
2393 }
2394 if (hspi->hdmarx->Init.DestDataWidth == DMA_DEST_DATAWIDTH_WORD)
2395 {
2396 hspi->RxXferCount = (hspi->RxXferCount + (uint16_t) 3UL) >> 2UL;
2397 }
2398 }
2399 else if (hspi->Init.DataSize <= SPI_DATASIZE_16BIT)
2400 {
2401 if (hspi->hdmatx->Init.SrcDataWidth == DMA_SRC_DATAWIDTH_WORD)
2402 {
2403 hspi->TxXferCount = (hspi->TxXferCount + (uint16_t) 1UL) >> 1UL;
2404 }
2405 if (hspi->hdmarx->Init.DestDataWidth == DMA_DEST_DATAWIDTH_WORD)
2406 {
2407 hspi->RxXferCount = (hspi->RxXferCount + (uint16_t) 1UL) >> 1UL;
2408 }
2409 }
2410 else
2411 {
2412 /* Adjustment done */
2413 }
2414
2415 /* Set the SPI Tx/Rx DMA Half transfer complete callback */
2416 hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfTransmitReceiveCplt;
2417 hspi->hdmarx->XferCpltCallback = SPI_DMATransmitReceiveCplt;
2418
2419 /* Set the DMA error callback */
2420 hspi->hdmarx->XferErrorCallback = SPI_DMAError;
2421
2422 /* Set the DMA AbortCallback */
2423 hspi->hdmarx->XferAbortCallback = NULL;
2424
2425 if (hspi->Init.DataSize <= SPI_DATASIZE_8BIT)
2426 {
2427 hspi->RxXferCount = Size;
2428 }
2429 else if (hspi->Init.DataSize <= SPI_DATASIZE_16BIT)
2430 {
2431 hspi->RxXferCount = Size * 2U;
2432 }
2433 else
2434 {
2435 hspi->RxXferCount = Size * 4U;
2436 }
2437 /* Enable the Rx DMA Stream/Channel */
2438 if ((hspi->hdmarx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
2439 {
2440 if (hspi->hdmarx->LinkedListQueue != NULL)
2441 {
2442 /* Set DMA data size */
2443 hspi->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hspi->RxXferCount;
2444
2445 /* Set DMA source address */
2446 hspi->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)&hspi->Instance->RXDR;
2447
2448 /* Set DMA destination address */
2449 hspi->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)hspi->pRxBuffPtr;
2450
2451 status = HAL_DMAEx_List_Start_IT(hspi->hdmarx);
2452 }
2453 else
2454 {
2455 status = HAL_ERROR;
2456 }
2457 }
2458 else
2459 {
2460 status = HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->RXDR, (uint32_t)hspi->pRxBuffPtr,
2461 hspi->RxXferCount);
2462 }
2463
2464 /* Check status */
2465 if (status != HAL_OK)
2466 {
2467 /* Update SPI error code */
2468 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
2469 hspi->State = HAL_SPI_STATE_READY;
2470
2471 /* Unlock the process */
2472 __HAL_UNLOCK(hspi);
2473
2474 return HAL_ERROR;
2475 }
2476
2477 /* Enable Rx DMA Request */
2478 SET_BIT(hspi->Instance->CFG1, SPI_CFG1_RXDMAEN);
2479
2480 /* Set the SPI Tx DMA transfer complete callback as NULL because the communication closing
2481 is performed in DMA reception complete callback */
2482 hspi->hdmatx->XferHalfCpltCallback = NULL;
2483 hspi->hdmatx->XferCpltCallback = NULL;
2484 hspi->hdmatx->XferAbortCallback = NULL;
2485
2486 /* Set the DMA error callback */
2487 hspi->hdmatx->XferErrorCallback = SPI_DMAError;
2488
2489 if (hspi->Init.DataSize <= SPI_DATASIZE_8BIT)
2490 {
2491 hspi->TxXferCount = Size;
2492 }
2493 else if (hspi->Init.DataSize <= SPI_DATASIZE_16BIT)
2494 {
2495 hspi->TxXferCount = Size * 2U;
2496 }
2497 else
2498 {
2499 hspi->TxXferCount = Size * 4U;
2500 }
2501
2502 /* Enable the Tx DMA Stream/Channel */
2503 if ((hspi->hdmatx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
2504 {
2505 if (hspi->hdmatx->LinkedListQueue != NULL)
2506 {
2507 /* Set DMA data size */
2508 hspi->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hspi->TxXferCount;
2509
2510 /* Set DMA source address */
2511 hspi->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)hspi->pTxBuffPtr;
2512
2513 /* Set DMA destination address */
2514 hspi->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)&hspi->Instance->TXDR;
2515
2516 status = HAL_DMAEx_List_Start_IT(hspi->hdmatx);
2517 }
2518 else
2519 {
2520 status = HAL_ERROR;
2521 }
2522 }
2523 else
2524 {
2525 status = HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->TXDR,
2526 hspi->TxXferCount);
2527 }
2528
2529 /* Check status */
2530 if (status != HAL_OK)
2531 {
2532 /* Abort Rx DMA Channel already started */
2533 (void)HAL_DMA_Abort(hspi->hdmarx);
2534
2535 /* Update SPI error code */
2536 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
2537 hspi->State = HAL_SPI_STATE_READY;
2538
2539 /* Unlock the process */
2540 __HAL_UNLOCK(hspi);
2541
2542 return HAL_ERROR;
2543 }
2544
2545 if ((hspi->hdmarx->Mode == DMA_LINKEDLIST_CIRCULAR) && (hspi->hdmatx->Mode == DMA_LINKEDLIST_CIRCULAR))
2546 {
2547 MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, 0UL);
2548 }
2549 else
2550 {
2551 MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size);
2552 }
2553
2554 /* Enable Tx DMA Request */
2555 SET_BIT(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN);
2556
2557 /* Enable the SPI Error Interrupt Bit */
2558 __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_OVR | SPI_IT_UDR | SPI_IT_FRE | SPI_IT_MODF));
2559
2560 /* Enable SPI peripheral */
2561 __HAL_SPI_ENABLE(hspi);
2562
2563 if (hspi->Init.Mode == SPI_MODE_MASTER)
2564 {
2565 /* Master transfer start */
2566 SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART);
2567 }
2568
2569 /* Unlock the process */
2570 __HAL_UNLOCK(hspi);
2571
2572 return HAL_OK;
2573 }
2574
2575 /**
2576 * @brief Abort ongoing transfer (blocking mode).
2577 * @param hspi SPI handle.
2578 * @note This procedure could be used for aborting any ongoing transfer (Tx and Rx),
2579 * started in Interrupt or DMA mode.
2580 * @note This procedure performs following operations :
2581 * + Disable SPI Interrupts (depending of transfer direction)
2582 * + Disable the DMA transfer in the peripheral register (if enabled)
2583 * + Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
2584 * + Set handle State to READY.
2585 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
2586 * @retval HAL status
2587 */
HAL_SPI_Abort(SPI_HandleTypeDef * hspi)2588 HAL_StatusTypeDef HAL_SPI_Abort(SPI_HandleTypeDef *hspi)
2589 {
2590 HAL_StatusTypeDef errorcode;
2591
2592 __IO uint32_t count;
2593
2594 /* Lock the process */
2595 __HAL_LOCK(hspi);
2596
2597 /* Set hspi->state to aborting to avoid any interaction */
2598 hspi->State = HAL_SPI_STATE_ABORT;
2599
2600 /* Initialized local variable */
2601 errorcode = HAL_OK;
2602 count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24UL / 1000UL);
2603
2604 /* If master communication on going, make sure current frame is done before closing the connection */
2605 if (HAL_IS_BIT_SET(hspi->Instance->CR1, SPI_CR1_CSTART))
2606 {
2607 /* Disable EOT interrupt */
2608 __HAL_SPI_DISABLE_IT(hspi, SPI_IT_EOT);
2609 do
2610 {
2611 count--;
2612 if (count == 0UL)
2613 {
2614 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
2615 break;
2616 }
2617 } while (HAL_IS_BIT_SET(hspi->Instance->IER, SPI_IT_EOT));
2618
2619 /* Request a Suspend transfer */
2620 SET_BIT(hspi->Instance->CR1, SPI_CR1_CSUSP);
2621 do
2622 {
2623 count--;
2624 if (count == 0UL)
2625 {
2626 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
2627 break;
2628 }
2629 } while (HAL_IS_BIT_SET(hspi->Instance->CR1, SPI_CR1_CSTART));
2630
2631 /* Clear SUSP flag */
2632 __HAL_SPI_CLEAR_SUSPFLAG(hspi);
2633 do
2634 {
2635 count--;
2636 if (count == 0UL)
2637 {
2638 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
2639 break;
2640 }
2641 } while (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_SUSP));
2642 }
2643
2644 /* Disable the SPI DMA Tx request if enabled */
2645 if (HAL_IS_BIT_SET(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN))
2646 {
2647 if (hspi->hdmatx != NULL)
2648 {
2649 /* Abort the SPI DMA Tx Stream/Channel : use blocking DMA Abort API (no callback) */
2650 hspi->hdmatx->XferAbortCallback = NULL;
2651
2652 /* Abort DMA Tx Handle linked to SPI Peripheral */
2653 if (HAL_DMA_Abort(hspi->hdmatx) != HAL_OK)
2654 {
2655 if (HAL_DMA_GetError(hspi->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
2656 {
2657 hspi->ErrorCode = HAL_SPI_ERROR_ABORT;
2658 }
2659 }
2660 }
2661 }
2662
2663 /* Disable the SPI DMA Rx request if enabled */
2664 if (HAL_IS_BIT_SET(hspi->Instance->CFG1, SPI_CFG1_RXDMAEN))
2665 {
2666 if (hspi->hdmarx != NULL)
2667 {
2668 /* Abort the SPI DMA Rx Stream/Channel : use blocking DMA Abort API (no callback) */
2669 hspi->hdmarx->XferAbortCallback = NULL;
2670
2671 /* Abort DMA Rx Handle linked to SPI Peripheral */
2672 if (HAL_DMA_Abort(hspi->hdmarx) != HAL_OK)
2673 {
2674 if (HAL_DMA_GetError(hspi->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
2675 {
2676 hspi->ErrorCode = HAL_SPI_ERROR_ABORT;
2677 }
2678 }
2679 }
2680 }
2681
2682 /* Proceed with abort procedure */
2683 SPI_AbortTransfer(hspi);
2684
2685 /* Check error during Abort procedure */
2686 if (HAL_IS_BIT_SET(hspi->ErrorCode, HAL_SPI_ERROR_ABORT))
2687 {
2688 /* return HAL_Error in case of error during Abort procedure */
2689 errorcode = HAL_ERROR;
2690 }
2691 else
2692 {
2693 /* Reset errorCode */
2694 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
2695 }
2696
2697 /* Restore hspi->state to ready */
2698 hspi->State = HAL_SPI_STATE_READY;
2699
2700 /* Unlock the process */
2701 __HAL_UNLOCK(hspi);
2702
2703 return errorcode;
2704 }
2705
2706 /**
2707 * @brief Abort ongoing transfer (Interrupt mode).
2708 * @param hspi SPI handle.
2709 * @note This procedure could be used for aborting any ongoing transfer (Tx and Rx),
2710 * started in Interrupt or DMA mode.
2711 * @note This procedure performs following operations :
2712 * + Disable SPI Interrupts (depending of transfer direction)
2713 * + Disable the DMA transfer in the peripheral register (if enabled)
2714 * + Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
2715 * + Set handle State to READY
2716 * + At abort completion, call user abort complete callback.
2717 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
2718 * considered as completed only when user abort complete callback is executed (not when exiting function).
2719 * @retval HAL status
2720 */
HAL_SPI_Abort_IT(SPI_HandleTypeDef * hspi)2721 HAL_StatusTypeDef HAL_SPI_Abort_IT(SPI_HandleTypeDef *hspi)
2722 {
2723 HAL_StatusTypeDef errorcode;
2724 __IO uint32_t count;
2725 uint32_t dma_tx_abort_done = 1UL;
2726 uint32_t dma_rx_abort_done = 1UL;
2727
2728 /* Set hspi->state to aborting to avoid any interaction */
2729 hspi->State = HAL_SPI_STATE_ABORT;
2730
2731 /* Initialized local variable */
2732 errorcode = HAL_OK;
2733 count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24UL / 1000UL);
2734
2735 /* If master communication on going, make sure current frame is done before closing the connection */
2736 if (HAL_IS_BIT_SET(hspi->Instance->CR1, SPI_CR1_CSTART))
2737 {
2738 /* Disable EOT interrupt */
2739 __HAL_SPI_DISABLE_IT(hspi, SPI_IT_EOT);
2740 do
2741 {
2742 count--;
2743 if (count == 0UL)
2744 {
2745 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
2746 break;
2747 }
2748 } while (HAL_IS_BIT_SET(hspi->Instance->IER, SPI_IT_EOT));
2749
2750 /* Request a Suspend transfer */
2751 SET_BIT(hspi->Instance->CR1, SPI_CR1_CSUSP);
2752 do
2753 {
2754 count--;
2755 if (count == 0UL)
2756 {
2757 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
2758 break;
2759 }
2760 } while (HAL_IS_BIT_SET(hspi->Instance->CR1, SPI_CR1_CSTART));
2761
2762 /* Clear SUSP flag */
2763 __HAL_SPI_CLEAR_SUSPFLAG(hspi);
2764 do
2765 {
2766 count--;
2767 if (count == 0UL)
2768 {
2769 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
2770 break;
2771 }
2772 } while (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_SUSP));
2773 }
2774
2775 /* If DMA Tx and/or DMA Rx Handles are associated to SPI Handle, DMA Abort complete callbacks should be initialized
2776 before any call to DMA Abort functions */
2777
2778 if (hspi->hdmatx != NULL)
2779 {
2780 if (HAL_IS_BIT_SET(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN))
2781 {
2782 /* Set DMA Abort Complete callback if SPI DMA Tx request if enabled */
2783 hspi->hdmatx->XferAbortCallback = SPI_DMATxAbortCallback;
2784
2785 dma_tx_abort_done = 0UL;
2786
2787 /* Abort DMA Tx Handle linked to SPI Peripheral */
2788 if (HAL_DMA_Abort_IT(hspi->hdmatx) != HAL_OK)
2789 {
2790 if (HAL_DMA_GetError(hspi->hdmatx) == HAL_DMA_ERROR_NO_XFER)
2791 {
2792 dma_tx_abort_done = 1UL;
2793 hspi->hdmatx->XferAbortCallback = NULL;
2794 }
2795 }
2796 }
2797 else
2798 {
2799 hspi->hdmatx->XferAbortCallback = NULL;
2800 }
2801 }
2802
2803 if (hspi->hdmarx != NULL)
2804 {
2805 if (HAL_IS_BIT_SET(hspi->Instance->CFG1, SPI_CFG1_RXDMAEN))
2806 {
2807 /* Set DMA Abort Complete callback if SPI DMA Rx request if enabled */
2808 hspi->hdmarx->XferAbortCallback = SPI_DMARxAbortCallback;
2809
2810 dma_rx_abort_done = 0UL;
2811
2812 /* Abort DMA Rx Handle linked to SPI Peripheral */
2813 if (HAL_DMA_Abort_IT(hspi->hdmarx) != HAL_OK)
2814 {
2815 if (HAL_DMA_GetError(hspi->hdmarx) == HAL_DMA_ERROR_NO_XFER)
2816 {
2817 dma_rx_abort_done = 1UL;
2818 hspi->hdmarx->XferAbortCallback = NULL;
2819 }
2820 }
2821 }
2822 else
2823 {
2824 hspi->hdmarx->XferAbortCallback = NULL;
2825 }
2826 }
2827
2828 /* If no running DMA transfer, finish cleanup and call callbacks */
2829 if ((dma_tx_abort_done == 1UL) && (dma_rx_abort_done == 1UL))
2830 {
2831 /* Proceed with abort procedure */
2832 SPI_AbortTransfer(hspi);
2833
2834 /* Check error during Abort procedure */
2835 if (HAL_IS_BIT_SET(hspi->ErrorCode, HAL_SPI_ERROR_ABORT))
2836 {
2837 /* return HAL_Error in case of error during Abort procedure */
2838 errorcode = HAL_ERROR;
2839 }
2840 else
2841 {
2842 /* Reset errorCode */
2843 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
2844 }
2845
2846 /* Restore hspi->state to ready */
2847 hspi->State = HAL_SPI_STATE_READY;
2848
2849 /* Call user Abort complete callback */
2850 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
2851 hspi->AbortCpltCallback(hspi);
2852 #else
2853 HAL_SPI_AbortCpltCallback(hspi);
2854 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
2855 }
2856
2857 return errorcode;
2858 }
2859
2860 /**
2861 * @brief Pause the DMA Transfer.
2862 * This API is not supported, it is maintained for backward compatibility.
2863 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
2864 * the configuration information for the specified SPI module.
2865 * @retval HAL_ERROR
2866 */
HAL_SPI_DMAPause(SPI_HandleTypeDef * hspi)2867 HAL_StatusTypeDef HAL_SPI_DMAPause(SPI_HandleTypeDef *hspi)
2868 {
2869 /* Set error code to not supported */
2870 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_NOT_SUPPORTED);
2871
2872 return HAL_ERROR;
2873 }
2874
2875 /**
2876 * @brief Resume the DMA Transfer.
2877 * This API is not supported, it is maintained for backward compatibility.
2878 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
2879 * the configuration information for the specified SPI module.
2880 * @retval HAL_ERROR
2881 */
HAL_SPI_DMAResume(SPI_HandleTypeDef * hspi)2882 HAL_StatusTypeDef HAL_SPI_DMAResume(SPI_HandleTypeDef *hspi)
2883 {
2884 /* Set error code to not supported */
2885 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_NOT_SUPPORTED);
2886
2887 return HAL_ERROR;
2888 }
2889
2890 /**
2891 * @brief Stop the DMA Transfer.
2892 * This API is not supported, it is maintained for backward compatibility.
2893 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
2894 * the configuration information for the specified SPI module.
2895 * @retval HAL_ERROR
2896 */
HAL_SPI_DMAStop(SPI_HandleTypeDef * hspi)2897 HAL_StatusTypeDef HAL_SPI_DMAStop(SPI_HandleTypeDef *hspi)
2898 {
2899 /* Set error code to not supported */
2900 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_NOT_SUPPORTED);
2901
2902 return HAL_ERROR;
2903 }
2904
2905 /**
2906 * @brief Handle SPI interrupt request.
2907 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
2908 * the configuration information for the specified SPI module.
2909 * @retval None
2910 */
HAL_SPI_IRQHandler(SPI_HandleTypeDef * hspi)2911 void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi)
2912 {
2913 uint32_t itsource = hspi->Instance->IER;
2914 uint32_t itflag = hspi->Instance->SR;
2915 uint32_t trigger = itsource & itflag;
2916 uint32_t cfg1 = hspi->Instance->CFG1;
2917 uint32_t handled = 0UL;
2918
2919 HAL_SPI_StateTypeDef State = hspi->State;
2920 #if defined (__GNUC__)
2921 __IO uint16_t *prxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->RXDR));
2922 #endif /* __GNUC__ */
2923
2924 /* SPI in SUSPEND mode ----------------------------------------------------*/
2925 if (HAL_IS_BIT_SET(itflag, SPI_FLAG_SUSP) && HAL_IS_BIT_SET(itsource, SPI_FLAG_EOT))
2926 {
2927 /* Clear the Suspend flag */
2928 __HAL_SPI_CLEAR_SUSPFLAG(hspi);
2929
2930 /* Suspend on going, Call the Suspend callback */
2931 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
2932 hspi->SuspendCallback(hspi);
2933 #else
2934 HAL_SPI_SuspendCallback(hspi);
2935 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
2936 return;
2937 }
2938
2939 /* SPI in mode Transmitter and Receiver ------------------------------------*/
2940 if (HAL_IS_BIT_CLR(trigger, SPI_FLAG_OVR) && HAL_IS_BIT_CLR(trigger, SPI_FLAG_UDR) && \
2941 HAL_IS_BIT_SET(trigger, SPI_FLAG_DXP))
2942 {
2943 hspi->TxISR(hspi);
2944 hspi->RxISR(hspi);
2945 handled = 1UL;
2946 }
2947
2948 /* SPI in mode Receiver ----------------------------------------------------*/
2949 if (HAL_IS_BIT_CLR(trigger, SPI_FLAG_OVR) && HAL_IS_BIT_SET(trigger, SPI_FLAG_RXP) && \
2950 HAL_IS_BIT_CLR(trigger, SPI_FLAG_DXP))
2951 {
2952 hspi->RxISR(hspi);
2953 handled = 1UL;
2954 }
2955
2956 /* SPI in mode Transmitter -------------------------------------------------*/
2957 if (HAL_IS_BIT_CLR(trigger, SPI_FLAG_UDR) && HAL_IS_BIT_SET(trigger, SPI_FLAG_TXP) && \
2958 HAL_IS_BIT_CLR(trigger, SPI_FLAG_DXP))
2959 {
2960 hspi->TxISR(hspi);
2961 handled = 1UL;
2962 }
2963
2964 if (handled != 0UL)
2965 {
2966 return;
2967 }
2968
2969 /* SPI End Of Transfer: DMA or IT based transfer */
2970 if (HAL_IS_BIT_SET(trigger, SPI_FLAG_EOT))
2971 {
2972 /* Clear EOT/TXTF/SUSP flag */
2973 __HAL_SPI_CLEAR_EOTFLAG(hspi);
2974 __HAL_SPI_CLEAR_TXTFFLAG(hspi);
2975 __HAL_SPI_CLEAR_SUSPFLAG(hspi);
2976
2977 /* Disable EOT interrupt */
2978 __HAL_SPI_DISABLE_IT(hspi, SPI_IT_EOT);
2979
2980 /* For the IT based receive extra polling maybe required for last packet */
2981 if (HAL_IS_BIT_CLR(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN | SPI_CFG1_RXDMAEN))
2982 {
2983 /* Pooling remaining data */
2984 while (hspi->RxXferCount != 0UL)
2985 {
2986 /* Receive data in 32 Bit mode */
2987 if (hspi->Init.DataSize > SPI_DATASIZE_16BIT)
2988 {
2989 *((uint32_t *)hspi->pRxBuffPtr) = *((__IO uint32_t *)&hspi->Instance->RXDR);
2990 hspi->pRxBuffPtr += sizeof(uint32_t);
2991 }
2992 /* Receive data in 16 Bit mode */
2993 else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
2994 {
2995 #if defined (__GNUC__)
2996 *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits;
2997 #else
2998 *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
2999 #endif /* __GNUC__ */
3000 hspi->pRxBuffPtr += sizeof(uint16_t);
3001 }
3002 /* Receive data in 8 Bit mode */
3003 else
3004 {
3005 *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
3006 hspi->pRxBuffPtr += sizeof(uint8_t);
3007 }
3008
3009 hspi->RxXferCount--;
3010 }
3011 }
3012
3013 /* Call SPI Standard close procedure */
3014 SPI_CloseTransfer(hspi);
3015
3016 hspi->State = HAL_SPI_STATE_READY;
3017 if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
3018 {
3019 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
3020 hspi->ErrorCallback(hspi);
3021 #else
3022 HAL_SPI_ErrorCallback(hspi);
3023 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
3024 return;
3025 }
3026
3027 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
3028 /* Call appropriate user callback */
3029 if (State == HAL_SPI_STATE_BUSY_TX_RX)
3030 {
3031 hspi->TxRxCpltCallback(hspi);
3032 }
3033 else if (State == HAL_SPI_STATE_BUSY_RX)
3034 {
3035 hspi->RxCpltCallback(hspi);
3036 }
3037 else if (State == HAL_SPI_STATE_BUSY_TX)
3038 {
3039 hspi->TxCpltCallback(hspi);
3040 }
3041 #else
3042 /* Call appropriate user callback */
3043 if (State == HAL_SPI_STATE_BUSY_TX_RX)
3044 {
3045 HAL_SPI_TxRxCpltCallback(hspi);
3046 }
3047 else if (State == HAL_SPI_STATE_BUSY_RX)
3048 {
3049 HAL_SPI_RxCpltCallback(hspi);
3050 }
3051 else if (State == HAL_SPI_STATE_BUSY_TX)
3052 {
3053 HAL_SPI_TxCpltCallback(hspi);
3054 }
3055 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
3056 else
3057 {
3058 /* End of the appropriate call */
3059 }
3060
3061 return;
3062 }
3063
3064 /* SPI in Error Treatment --------------------------------------------------*/
3065 if ((trigger & (SPI_FLAG_MODF | SPI_FLAG_OVR | SPI_FLAG_FRE | SPI_FLAG_UDR)) != 0UL)
3066 {
3067 /* SPI Overrun error interrupt occurred ----------------------------------*/
3068 if ((trigger & SPI_FLAG_OVR) != 0UL)
3069 {
3070 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_OVR);
3071 __HAL_SPI_CLEAR_OVRFLAG(hspi);
3072 }
3073
3074 /* SPI Mode Fault error interrupt occurred -------------------------------*/
3075 if ((trigger & SPI_FLAG_MODF) != 0UL)
3076 {
3077 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_MODF);
3078 __HAL_SPI_CLEAR_MODFFLAG(hspi);
3079 }
3080
3081 /* SPI Frame error interrupt occurred ------------------------------------*/
3082 if ((trigger & SPI_FLAG_FRE) != 0UL)
3083 {
3084 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FRE);
3085 __HAL_SPI_CLEAR_FREFLAG(hspi);
3086 }
3087
3088 /* SPI Underrun error interrupt occurred ------------------------------------*/
3089 if ((trigger & SPI_FLAG_UDR) != 0UL)
3090 {
3091 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_UDR);
3092 __HAL_SPI_CLEAR_UDRFLAG(hspi);
3093 }
3094
3095 if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
3096 {
3097 /* Disable SPI peripheral */
3098 __HAL_SPI_DISABLE(hspi);
3099
3100 /* Disable all interrupts */
3101 __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_EOT | SPI_IT_RXP | SPI_IT_TXP | SPI_IT_MODF |
3102 SPI_IT_OVR | SPI_IT_FRE | SPI_IT_UDR));
3103
3104 /* Disable the SPI DMA requests if enabled */
3105 if (HAL_IS_BIT_SET(cfg1, SPI_CFG1_TXDMAEN | SPI_CFG1_RXDMAEN))
3106 {
3107 /* Disable the SPI DMA requests */
3108 CLEAR_BIT(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN | SPI_CFG1_RXDMAEN);
3109
3110 /* Abort the SPI DMA Rx channel */
3111 if (hspi->hdmarx != NULL)
3112 {
3113 /* Set the SPI DMA Abort callback :
3114 will lead to call HAL_SPI_ErrorCallback() at end of DMA abort procedure */
3115 hspi->hdmarx->XferAbortCallback = SPI_DMAAbortOnError;
3116 if (HAL_OK != HAL_DMA_Abort_IT(hspi->hdmarx))
3117 {
3118 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
3119 }
3120 }
3121 /* Abort the SPI DMA Tx channel */
3122 if (hspi->hdmatx != NULL)
3123 {
3124 /* Set the SPI DMA Abort callback :
3125 will lead to call HAL_SPI_ErrorCallback() at end of DMA abort procedure */
3126 hspi->hdmatx->XferAbortCallback = SPI_DMAAbortOnError;
3127 if (HAL_OK != HAL_DMA_Abort_IT(hspi->hdmatx))
3128 {
3129 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
3130 }
3131 }
3132 }
3133 else
3134 {
3135 /* Restore hspi->State to Ready */
3136 hspi->State = HAL_SPI_STATE_READY;
3137
3138 /* Call user error callback */
3139 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
3140 hspi->ErrorCallback(hspi);
3141 #else
3142 HAL_SPI_ErrorCallback(hspi);
3143 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
3144 }
3145 }
3146 return;
3147 }
3148 }
3149
3150 /**
3151 * @brief Tx Transfer completed callback.
3152 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3153 * the configuration information for SPI module.
3154 * @retval None
3155 */
HAL_SPI_TxCpltCallback(SPI_HandleTypeDef * hspi)3156 __weak void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */
3157 {
3158 /* Prevent unused argument(s) compilation warning */
3159 UNUSED(hspi);
3160
3161 /* NOTE : This function should not be modified, when the callback is needed,
3162 the HAL_SPI_TxCpltCallback should be implemented in the user file
3163 */
3164 }
3165
3166 /**
3167 * @brief Rx Transfer completed callback.
3168 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3169 * the configuration information for SPI module.
3170 * @retval None
3171 */
HAL_SPI_RxCpltCallback(SPI_HandleTypeDef * hspi)3172 __weak void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */
3173 {
3174 /* Prevent unused argument(s) compilation warning */
3175 UNUSED(hspi);
3176
3177 /* NOTE : This function should not be modified, when the callback is needed,
3178 the HAL_SPI_RxCpltCallback should be implemented in the user file
3179 */
3180 }
3181
3182 /**
3183 * @brief Tx and Rx Transfer completed callback.
3184 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3185 * the configuration information for SPI module.
3186 * @retval None
3187 */
HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef * hspi)3188 __weak void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */
3189 {
3190 /* Prevent unused argument(s) compilation warning */
3191 UNUSED(hspi);
3192
3193 /* NOTE : This function should not be modified, when the callback is needed,
3194 the HAL_SPI_TxRxCpltCallback should be implemented in the user file
3195 */
3196 }
3197
3198 /**
3199 * @brief Tx Half Transfer completed callback.
3200 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3201 * the configuration information for SPI module.
3202 * @retval None
3203 */
HAL_SPI_TxHalfCpltCallback(SPI_HandleTypeDef * hspi)3204 __weak void HAL_SPI_TxHalfCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */
3205 {
3206 /* Prevent unused argument(s) compilation warning */
3207 UNUSED(hspi);
3208
3209 /* NOTE : This function should not be modified, when the callback is needed,
3210 the HAL_SPI_TxHalfCpltCallback should be implemented in the user file
3211 */
3212 }
3213
3214 /**
3215 * @brief Rx Half Transfer completed callback.
3216 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3217 * the configuration information for SPI module.
3218 * @retval None
3219 */
HAL_SPI_RxHalfCpltCallback(SPI_HandleTypeDef * hspi)3220 __weak void HAL_SPI_RxHalfCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */
3221 {
3222 /* Prevent unused argument(s) compilation warning */
3223 UNUSED(hspi);
3224
3225 /* NOTE : This function should not be modified, when the callback is needed,
3226 the HAL_SPI_RxHalfCpltCallback() should be implemented in the user file
3227 */
3228 }
3229
3230 /**
3231 * @brief Tx and Rx Half Transfer callback.
3232 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3233 * the configuration information for SPI module.
3234 * @retval None
3235 */
HAL_SPI_TxRxHalfCpltCallback(SPI_HandleTypeDef * hspi)3236 __weak void HAL_SPI_TxRxHalfCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */
3237 {
3238 /* Prevent unused argument(s) compilation warning */
3239 UNUSED(hspi);
3240
3241 /* NOTE : This function should not be modified, when the callback is needed,
3242 the HAL_SPI_TxRxHalfCpltCallback() should be implemented in the user file
3243 */
3244 }
3245
3246 /**
3247 * @brief SPI error callback.
3248 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3249 * the configuration information for SPI module.
3250 * @retval None
3251 */
HAL_SPI_ErrorCallback(SPI_HandleTypeDef * hspi)3252 __weak void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */
3253 {
3254 /* Prevent unused argument(s) compilation warning */
3255 UNUSED(hspi);
3256
3257 /* NOTE : This function should not be modified, when the callback is needed,
3258 the HAL_SPI_ErrorCallback should be implemented in the user file
3259 */
3260 /* NOTE : The ErrorCode parameter in the hspi handle is updated by the SPI processes
3261 and user can use HAL_SPI_GetError() API to check the latest error occurred
3262 */
3263 }
3264
3265 /**
3266 * @brief SPI Abort Complete callback.
3267 * @param hspi SPI handle.
3268 * @retval None
3269 */
HAL_SPI_AbortCpltCallback(SPI_HandleTypeDef * hspi)3270 __weak void HAL_SPI_AbortCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */
3271 {
3272 /* Prevent unused argument(s) compilation warning */
3273 UNUSED(hspi);
3274
3275 /* NOTE : This function should not be modified, when the callback is needed,
3276 the HAL_SPI_AbortCpltCallback can be implemented in the user file.
3277 */
3278 }
3279
3280 /**
3281 * @brief SPI Suspend callback.
3282 * @param hspi SPI handle.
3283 * @retval None
3284 */
HAL_SPI_SuspendCallback(SPI_HandleTypeDef * hspi)3285 __weak void HAL_SPI_SuspendCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */
3286 {
3287 /* Prevent unused argument(s) compilation warning */
3288 UNUSED(hspi);
3289
3290 /* NOTE : This function should not be modified, when the callback is needed,
3291 the HAL_SPI_SuspendCallback can be implemented in the user file.
3292 */
3293 }
3294
3295 /**
3296 * @}
3297 */
3298
3299 /** @defgroup SPI_Exported_Functions_Group3 Peripheral State and Errors functions
3300 * @brief SPI control functions
3301 *
3302 @verbatim
3303 ===============================================================================
3304 ##### Peripheral State and Errors functions #####
3305 ===============================================================================
3306 [..]
3307 This subsection provides a set of functions allowing to control the SPI.
3308 (+) HAL_SPI_GetState() API can be helpful to check in run-time the state of the SPI peripheral
3309 (+) HAL_SPI_GetError() check in run-time Errors occurring during communication
3310 @endverbatim
3311 * @{
3312 */
3313
3314 /**
3315 * @brief Return the SPI handle state.
3316 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3317 * the configuration information for SPI module.
3318 * @retval SPI state
3319 */
HAL_SPI_GetState(const SPI_HandleTypeDef * hspi)3320 HAL_SPI_StateTypeDef HAL_SPI_GetState(const SPI_HandleTypeDef *hspi)
3321 {
3322 /* Return SPI handle state */
3323 return hspi->State;
3324 }
3325
3326 /**
3327 * @brief Return the SPI error code.
3328 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3329 * the configuration information for SPI module.
3330 * @retval SPI error code in bitmap format
3331 */
HAL_SPI_GetError(const SPI_HandleTypeDef * hspi)3332 uint32_t HAL_SPI_GetError(const SPI_HandleTypeDef *hspi)
3333 {
3334 /* Return SPI ErrorCode */
3335 return hspi->ErrorCode;
3336 }
3337
3338 /**
3339 * @}
3340 */
3341
3342 /**
3343 * @}
3344 */
3345
3346 /** @addtogroup SPI_Private_Functions
3347 * @brief Private functions
3348 * @{
3349 */
3350
3351 /**
3352 * @brief DMA SPI transmit process complete callback.
3353 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
3354 * the configuration information for the specified DMA module.
3355 * @retval None
3356 */
SPI_DMATransmitCplt(DMA_HandleTypeDef * hdma)3357 static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma)
3358 {
3359 SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
3360
3361 if (hspi->State != HAL_SPI_STATE_ABORT)
3362 {
3363 if (hspi->hdmatx->Mode == DMA_LINKEDLIST_CIRCULAR)
3364 {
3365 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
3366 hspi->TxCpltCallback(hspi);
3367 #else
3368 HAL_SPI_TxCpltCallback(hspi);
3369 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
3370 }
3371 else
3372 {
3373 /* Enable EOT interrupt */
3374 __HAL_SPI_ENABLE_IT(hspi, SPI_IT_EOT);
3375 }
3376 }
3377 }
3378
3379 /**
3380 * @brief DMA SPI receive process complete callback.
3381 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
3382 * the configuration information for the specified DMA module.
3383 * @retval None
3384 */
SPI_DMAReceiveCplt(DMA_HandleTypeDef * hdma)3385 static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
3386 {
3387 SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
3388
3389 if (hspi->State != HAL_SPI_STATE_ABORT)
3390 {
3391 if (hspi->hdmarx->Mode == DMA_LINKEDLIST_CIRCULAR)
3392 {
3393 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
3394 hspi->RxCpltCallback(hspi);
3395 #else
3396 HAL_SPI_RxCpltCallback(hspi);
3397 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
3398 }
3399 else
3400 {
3401 /* Enable EOT interrupt */
3402 __HAL_SPI_ENABLE_IT(hspi, SPI_IT_EOT);
3403 }
3404 }
3405 }
3406
3407 /**
3408 * @brief DMA SPI transmit receive process complete callback.
3409 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
3410 * the configuration information for the specified DMA module.
3411 * @retval None
3412 */
SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef * hdma)3413 static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma)
3414 {
3415 SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
3416
3417 if (hspi->State != HAL_SPI_STATE_ABORT)
3418 {
3419 if ((hspi->hdmarx->Mode == DMA_LINKEDLIST_CIRCULAR) &&
3420 (hspi->hdmatx->Mode == DMA_LINKEDLIST_CIRCULAR))
3421 {
3422 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
3423 hspi->TxRxCpltCallback(hspi);
3424 #else
3425 HAL_SPI_TxRxCpltCallback(hspi);
3426 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
3427 }
3428 else
3429 {
3430 /* Enable EOT interrupt */
3431 __HAL_SPI_ENABLE_IT(hspi, SPI_IT_EOT);
3432 }
3433 }
3434 }
3435
3436 /**
3437 * @brief DMA SPI half transmit process complete callback.
3438 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
3439 * the configuration information for the specified DMA module.
3440 * @retval None
3441 */
SPI_DMAHalfTransmitCplt(DMA_HandleTypeDef * hdma)3442 static void SPI_DMAHalfTransmitCplt(DMA_HandleTypeDef *hdma) /* Derogation MISRAC2012-Rule-8.13 */
3443 {
3444 SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)
3445 ((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-8.13 */
3446
3447 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
3448 hspi->TxHalfCpltCallback(hspi);
3449 #else
3450 HAL_SPI_TxHalfCpltCallback(hspi);
3451 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
3452 }
3453
3454 /**
3455 * @brief DMA SPI half receive process complete callback
3456 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
3457 * the configuration information for the specified DMA module.
3458 * @retval None
3459 */
SPI_DMAHalfReceiveCplt(DMA_HandleTypeDef * hdma)3460 static void SPI_DMAHalfReceiveCplt(DMA_HandleTypeDef *hdma) /* Derogation MISRAC2012-Rule-8.13 */
3461 {
3462 SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)
3463 ((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-8.13 */
3464
3465 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
3466 hspi->RxHalfCpltCallback(hspi);
3467 #else
3468 HAL_SPI_RxHalfCpltCallback(hspi);
3469 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
3470 }
3471
3472 /**
3473 * @brief DMA SPI half transmit receive process complete callback.
3474 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
3475 * the configuration information for the specified DMA module.
3476 * @retval None
3477 */
SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef * hdma)3478 static void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma) /* Derogation MISRAC2012-Rule-8.13 */
3479 {
3480 SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)
3481 ((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-8.13 */
3482
3483 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
3484 hspi->TxRxHalfCpltCallback(hspi);
3485 #else
3486 HAL_SPI_TxRxHalfCpltCallback(hspi);
3487 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
3488 }
3489
3490 /**
3491 * @brief DMA SPI communication error callback.
3492 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
3493 * the configuration information for the specified DMA module.
3494 * @retval None
3495 */
SPI_DMAError(DMA_HandleTypeDef * hdma)3496 static void SPI_DMAError(DMA_HandleTypeDef *hdma)
3497 {
3498 SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
3499
3500 /* if DMA error is FIFO error ignore it */
3501 if (HAL_DMA_GetError(hdma) != HAL_DMA_ERROR_NONE)
3502 {
3503 /* Call SPI standard close procedure */
3504 SPI_CloseTransfer(hspi);
3505
3506 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
3507 hspi->State = HAL_SPI_STATE_READY;
3508 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
3509 hspi->ErrorCallback(hspi);
3510 #else
3511 HAL_SPI_ErrorCallback(hspi);
3512 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
3513 }
3514 }
3515
3516 /**
3517 * @brief DMA SPI communication abort callback, when initiated by HAL services on Error
3518 * (To be called at end of DMA Abort procedure following error occurrence).
3519 * @param hdma DMA handle.
3520 * @retval None
3521 */
SPI_DMAAbortOnError(DMA_HandleTypeDef * hdma)3522 static void SPI_DMAAbortOnError(DMA_HandleTypeDef *hdma)
3523 {
3524 SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
3525 hspi->RxXferCount = (uint16_t) 0UL;
3526 hspi->TxXferCount = (uint16_t) 0UL;
3527
3528 /* Restore hspi->State to Ready */
3529 hspi->State = HAL_SPI_STATE_READY;
3530
3531 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
3532 hspi->ErrorCallback(hspi);
3533 #else
3534 HAL_SPI_ErrorCallback(hspi);
3535 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
3536 }
3537
3538 /**
3539 * @brief DMA SPI Tx communication abort callback, when initiated by user
3540 * (To be called at end of DMA Tx Abort procedure following user abort request).
3541 * @note When this callback is executed, User Abort complete call back is called only if no
3542 * Abort still ongoing for Rx DMA Handle.
3543 * @param hdma DMA handle.
3544 * @retval None
3545 */
SPI_DMATxAbortCallback(DMA_HandleTypeDef * hdma)3546 static void SPI_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
3547 {
3548 SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
3549
3550 hspi->hdmatx->XferAbortCallback = NULL;
3551
3552 /* Check if an Abort process is still ongoing */
3553 if (hspi->hdmarx != NULL)
3554 {
3555 if (hspi->hdmarx->XferAbortCallback != NULL)
3556 {
3557 return;
3558 }
3559 }
3560
3561 /* Call the Abort procedure */
3562 SPI_AbortTransfer(hspi);
3563
3564 /* Restore hspi->State to Ready */
3565 hspi->State = HAL_SPI_STATE_READY;
3566
3567 /* Call user Abort complete callback */
3568 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
3569 hspi->AbortCpltCallback(hspi);
3570 #else
3571 HAL_SPI_AbortCpltCallback(hspi);
3572 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
3573 }
3574
3575 /**
3576 * @brief DMA SPI Rx communication abort callback, when initiated by user
3577 * (To be called at end of DMA Rx Abort procedure following user abort request).
3578 * @note When this callback is executed, User Abort complete call back is called only if no
3579 * Abort still ongoing for Tx DMA Handle.
3580 * @param hdma DMA handle.
3581 * @retval None
3582 */
SPI_DMARxAbortCallback(DMA_HandleTypeDef * hdma)3583 static void SPI_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
3584 {
3585 SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
3586
3587 hspi->hdmarx->XferAbortCallback = NULL;
3588
3589 /* Check if an Abort process is still ongoing */
3590 if (hspi->hdmatx != NULL)
3591 {
3592 if (hspi->hdmatx->XferAbortCallback != NULL)
3593 {
3594 return;
3595 }
3596 }
3597
3598 /* Call the Abort procedure */
3599 SPI_AbortTransfer(hspi);
3600
3601 /* Restore hspi->State to Ready */
3602 hspi->State = HAL_SPI_STATE_READY;
3603
3604 /* Call user Abort complete callback */
3605 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
3606 hspi->AbortCpltCallback(hspi);
3607 #else
3608 HAL_SPI_AbortCpltCallback(hspi);
3609 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
3610 }
3611
3612 /**
3613 * @brief Manage the receive 8-bit in Interrupt context.
3614 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3615 * the configuration information for SPI module.
3616 * @retval None
3617 */
SPI_RxISR_8BIT(SPI_HandleTypeDef * hspi)3618 static void SPI_RxISR_8BIT(SPI_HandleTypeDef *hspi)
3619 {
3620 /* Receive data in 8 Bit mode */
3621 *((uint8_t *)hspi->pRxBuffPtr) = (*(__IO uint8_t *)&hspi->Instance->RXDR);
3622 hspi->pRxBuffPtr += sizeof(uint8_t);
3623 hspi->RxXferCount--;
3624
3625 /* Disable IT if no more data excepted */
3626 if (hspi->RxXferCount == 0UL)
3627 {
3628 /* Disable RXP interrupts */
3629 __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXP);
3630 }
3631 }
3632
3633
3634 /**
3635 * @brief Manage the 16-bit receive in Interrupt context.
3636 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3637 * the configuration information for SPI module.
3638 * @retval None
3639 */
SPI_RxISR_16BIT(SPI_HandleTypeDef * hspi)3640 static void SPI_RxISR_16BIT(SPI_HandleTypeDef *hspi)
3641 {
3642 /* Receive data in 16 Bit mode */
3643 #if defined (__GNUC__)
3644 __IO uint16_t *prxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->RXDR));
3645
3646 *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits;
3647 #else
3648 *((uint16_t *)hspi->pRxBuffPtr) = (*(__IO uint16_t *)&hspi->Instance->RXDR);
3649 #endif /* __GNUC__ */
3650 hspi->pRxBuffPtr += sizeof(uint16_t);
3651 hspi->RxXferCount--;
3652
3653 /* Disable IT if no more data excepted */
3654 if (hspi->RxXferCount == 0UL)
3655 {
3656 /* Disable RXP interrupts */
3657 __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXP);
3658 }
3659 }
3660
3661
3662 /**
3663 * @brief Manage the 32-bit receive in Interrupt context.
3664 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3665 * the configuration information for SPI module.
3666 * @retval None
3667 */
SPI_RxISR_32BIT(SPI_HandleTypeDef * hspi)3668 static void SPI_RxISR_32BIT(SPI_HandleTypeDef *hspi)
3669 {
3670 /* Receive data in 32 Bit mode */
3671 *((uint32_t *)hspi->pRxBuffPtr) = (*(__IO uint32_t *)&hspi->Instance->RXDR);
3672 hspi->pRxBuffPtr += sizeof(uint32_t);
3673 hspi->RxXferCount--;
3674
3675 /* Disable IT if no more data excepted */
3676 if (hspi->RxXferCount == 0UL)
3677 {
3678 /* Disable RXP interrupts */
3679 __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXP);
3680 }
3681 }
3682
3683
3684 /**
3685 * @brief Handle the data 8-bit transmit in Interrupt mode.
3686 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3687 * the configuration information for SPI module.
3688 * @retval None
3689 */
SPI_TxISR_8BIT(SPI_HandleTypeDef * hspi)3690 static void SPI_TxISR_8BIT(SPI_HandleTypeDef *hspi)
3691 {
3692 /* Transmit data in 8 Bit mode */
3693 *(__IO uint8_t *)&hspi->Instance->TXDR = *((const uint8_t *)hspi->pTxBuffPtr);
3694 hspi->pTxBuffPtr += sizeof(uint8_t);
3695 hspi->TxXferCount--;
3696
3697 /* Disable IT if no more data excepted */
3698 if (hspi->TxXferCount == 0UL)
3699 {
3700 /* Disable TXP interrupts */
3701 __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXP);
3702 }
3703 }
3704
3705 /**
3706 * @brief Handle the data 16-bit transmit in Interrupt mode.
3707 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3708 * the configuration information for SPI module.
3709 * @retval None
3710 */
SPI_TxISR_16BIT(SPI_HandleTypeDef * hspi)3711 static void SPI_TxISR_16BIT(SPI_HandleTypeDef *hspi)
3712 {
3713 /* Transmit data in 16 Bit mode */
3714 #if defined (__GNUC__)
3715 __IO uint16_t *ptxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->TXDR));
3716
3717 *ptxdr_16bits = *((const uint16_t *)hspi->pTxBuffPtr);
3718 #else
3719 *((__IO uint16_t *)&hspi->Instance->TXDR) = *((const uint16_t *)hspi->pTxBuffPtr);
3720 #endif /* __GNUC__ */
3721 hspi->pTxBuffPtr += sizeof(uint16_t);
3722 hspi->TxXferCount--;
3723
3724 /* Disable IT if no more data excepted */
3725 if (hspi->TxXferCount == 0UL)
3726 {
3727 /* Disable TXP interrupts */
3728 __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXP);
3729 }
3730 }
3731
3732 /**
3733 * @brief Handle the data 32-bit transmit in Interrupt mode.
3734 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3735 * the configuration information for SPI module.
3736 * @retval None
3737 */
SPI_TxISR_32BIT(SPI_HandleTypeDef * hspi)3738 static void SPI_TxISR_32BIT(SPI_HandleTypeDef *hspi)
3739 {
3740 /* Transmit data in 32 Bit mode */
3741 *((__IO uint32_t *)&hspi->Instance->TXDR) = *((const uint32_t *)hspi->pTxBuffPtr);
3742 hspi->pTxBuffPtr += sizeof(uint32_t);
3743 hspi->TxXferCount--;
3744
3745 /* Disable IT if no more data excepted */
3746 if (hspi->TxXferCount == 0UL)
3747 {
3748 /* Disable TXP interrupts */
3749 __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXP);
3750 }
3751 }
3752
3753 /**
3754 * @brief Abort Transfer and clear flags.
3755 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3756 * the configuration information for SPI module.
3757 * @retval None
3758 */
SPI_AbortTransfer(SPI_HandleTypeDef * hspi)3759 static void SPI_AbortTransfer(SPI_HandleTypeDef *hspi)
3760 {
3761 /* Disable SPI peripheral */
3762 __HAL_SPI_DISABLE(hspi);
3763
3764 /* Disable ITs */
3765 __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_EOT | SPI_IT_TXP | SPI_IT_RXP | SPI_IT_DXP | SPI_IT_UDR | SPI_IT_OVR | \
3766 SPI_IT_FRE | SPI_IT_MODF));
3767
3768 /* Clear the Status flags in the SR register */
3769 __HAL_SPI_CLEAR_EOTFLAG(hspi);
3770 __HAL_SPI_CLEAR_TXTFFLAG(hspi);
3771
3772 /* Disable Tx DMA Request */
3773 CLEAR_BIT(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN | SPI_CFG1_RXDMAEN);
3774
3775 /* Clear the Error flags in the SR register */
3776 __HAL_SPI_CLEAR_OVRFLAG(hspi);
3777 __HAL_SPI_CLEAR_UDRFLAG(hspi);
3778 __HAL_SPI_CLEAR_FREFLAG(hspi);
3779 __HAL_SPI_CLEAR_MODFFLAG(hspi);
3780 __HAL_SPI_CLEAR_SUSPFLAG(hspi);
3781
3782 #if (USE_SPI_CRC != 0U)
3783 __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
3784 #endif /* USE_SPI_CRC */
3785
3786 hspi->TxXferCount = (uint16_t)0UL;
3787 hspi->RxXferCount = (uint16_t)0UL;
3788 }
3789
3790
3791 /**
3792 * @brief Close Transfer and clear flags.
3793 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3794 * the configuration information for SPI module.
3795 * @retval HAL_ERROR: if any error detected
3796 * HAL_OK: if nothing detected
3797 */
SPI_CloseTransfer(SPI_HandleTypeDef * hspi)3798 static void SPI_CloseTransfer(SPI_HandleTypeDef *hspi)
3799 {
3800 uint32_t itflag = hspi->Instance->SR;
3801
3802 __HAL_SPI_CLEAR_EOTFLAG(hspi);
3803 __HAL_SPI_CLEAR_TXTFFLAG(hspi);
3804
3805 /* Disable SPI peripheral */
3806 __HAL_SPI_DISABLE(hspi);
3807
3808 /* Disable ITs */
3809 __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_EOT | SPI_IT_TXP | SPI_IT_RXP | SPI_IT_DXP | SPI_IT_UDR | SPI_IT_OVR | \
3810 SPI_IT_FRE | SPI_IT_MODF));
3811
3812 /* Disable Tx DMA Request */
3813 CLEAR_BIT(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN | SPI_CFG1_RXDMAEN);
3814
3815 /* Report UnderRun error for non RX Only communication */
3816 if (hspi->State != HAL_SPI_STATE_BUSY_RX)
3817 {
3818 if ((itflag & SPI_FLAG_UDR) != 0UL)
3819 {
3820 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_UDR);
3821 __HAL_SPI_CLEAR_UDRFLAG(hspi);
3822 }
3823 }
3824
3825 /* Report OverRun error for non TX Only communication */
3826 if (hspi->State != HAL_SPI_STATE_BUSY_TX)
3827 {
3828 if ((itflag & SPI_FLAG_OVR) != 0UL)
3829 {
3830 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_OVR);
3831 __HAL_SPI_CLEAR_OVRFLAG(hspi);
3832 }
3833
3834 #if (USE_SPI_CRC != 0UL)
3835 /* Check if CRC error occurred */
3836 if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
3837 {
3838 if ((itflag & SPI_FLAG_CRCERR) != 0UL)
3839 {
3840 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
3841 __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
3842 }
3843 }
3844 #endif /* USE_SPI_CRC */
3845 }
3846
3847 /* SPI Mode Fault error interrupt occurred -------------------------------*/
3848 if ((itflag & SPI_FLAG_MODF) != 0UL)
3849 {
3850 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_MODF);
3851 __HAL_SPI_CLEAR_MODFFLAG(hspi);
3852 }
3853
3854 /* SPI Frame error interrupt occurred ------------------------------------*/
3855 if ((itflag & SPI_FLAG_FRE) != 0UL)
3856 {
3857 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FRE);
3858 __HAL_SPI_CLEAR_FREFLAG(hspi);
3859 }
3860
3861 hspi->TxXferCount = (uint16_t)0UL;
3862 hspi->RxXferCount = (uint16_t)0UL;
3863 }
3864
3865 /**
3866 * @brief Handle SPI Communication Timeout.
3867 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3868 * the configuration information for SPI module.
3869 * @param Flag: SPI flag to check
3870 * @param Status: flag state to check
3871 * @param Timeout: Timeout duration
3872 * @param Tickstart: Tick start value
3873 * @retval HAL status
3874 */
SPI_WaitOnFlagUntilTimeout(const SPI_HandleTypeDef * hspi,uint32_t Flag,FlagStatus Status,uint32_t Timeout,uint32_t Tickstart)3875 static HAL_StatusTypeDef SPI_WaitOnFlagUntilTimeout(const SPI_HandleTypeDef *hspi, uint32_t Flag, FlagStatus Status,
3876 uint32_t Timeout, uint32_t Tickstart)
3877 {
3878 /* Wait until flag is set */
3879 while ((__HAL_SPI_GET_FLAG(hspi, Flag) ? SET : RESET) == Status)
3880 {
3881 /* Check for the Timeout */
3882 if ((((HAL_GetTick() - Tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
3883 {
3884 return HAL_TIMEOUT;
3885 }
3886 }
3887 return HAL_OK;
3888 }
3889
3890 /**
3891 * @brief Compute configured packet size from fifo perspective.
3892 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3893 * the configuration information for SPI module.
3894 * @retval Packet size occupied in the fifo
3895 */
SPI_GetPacketSize(const SPI_HandleTypeDef * hspi)3896 static uint32_t SPI_GetPacketSize(const SPI_HandleTypeDef *hspi)
3897 {
3898 uint32_t fifo_threashold = (hspi->Init.FifoThreshold >> SPI_CFG1_FTHLV_Pos) + 1UL;
3899 uint32_t data_size = (hspi->Init.DataSize >> SPI_CFG1_DSIZE_Pos) + 1UL;
3900
3901 /* Convert data size to Byte */
3902 data_size = (data_size + 7UL) / 8UL;
3903
3904 return data_size * fifo_threashold;
3905 }
3906
3907 /**
3908 * @}
3909 */
3910
3911 #endif /* HAL_SPI_MODULE_ENABLED */
3912
3913 /**
3914 * @}
3915 */
3916
3917 /**
3918 * @}
3919 */
3920