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