Merge maintenance-8.x.x fixes into master
[inav.git] / lib / main / STM32H7 / Drivers / STM32H7xx_HAL_Driver / Src / stm32h7xx_hal_spi.c
blobe0571e0d963681c44a8fe726351ce8d210e10589
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
13 ******************************************************************************
14 * @attention
16 * Copyright (c) 2017 STMicroelectronics.
17 * All rights reserved.
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.
23 ******************************************************************************
24 @verbatim
25 ==============================================================================
26 ##### How to use this driver #####
27 ==============================================================================
28 [..]
29 The SPI HAL driver can be used as follows:
31 (#) Declare a SPI_HandleTypeDef handle structure, for example:
32 SPI_HandleTypeDef hspi;
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
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.
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:
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.
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.
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
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.
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.
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.
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.
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.
132 @endverbatim
135 /* Includes ------------------------------------------------------------------*/
136 #include "stm32h7xx_hal.h"
138 /** @addtogroup STM32H7xx_HAL_Driver
139 * @{
142 /** @defgroup SPI SPI
143 * @brief SPI HAL module driver
144 * @{
146 #ifdef HAL_SPI_MODULE_ENABLED
148 /* Private typedef -----------------------------------------------------------*/
149 /* Private defines -----------------------------------------------------------*/
150 /** @defgroup SPI_Private_Constants SPI Private Constants
151 * @{
153 #define SPI_DEFAULT_TIMEOUT 100UL
155 * @}
158 /* Private macros ------------------------------------------------------------*/
159 /* Private variables ---------------------------------------------------------*/
160 /* Private function prototypes -----------------------------------------------*/
161 /** @defgroup SPI_Private_Functions SPI Private Functions
162 * @{
164 static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma);
165 static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
166 static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma);
167 static void SPI_DMAHalfTransmitCplt(DMA_HandleTypeDef *hdma);
168 static void SPI_DMAHalfReceiveCplt(DMA_HandleTypeDef *hdma);
169 static void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma);
170 static void SPI_DMAError(DMA_HandleTypeDef *hdma);
171 static void SPI_DMAAbortOnError(DMA_HandleTypeDef *hdma);
172 static void SPI_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
173 static void SPI_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
174 static HAL_StatusTypeDef SPI_WaitOnFlagUntilTimeout(const SPI_HandleTypeDef *hspi, uint32_t Flag,
175 FlagStatus FlagStatus, uint32_t Timeout, uint32_t Tickstart);
176 static void SPI_TxISR_8BIT(SPI_HandleTypeDef *hspi);
177 static void SPI_TxISR_16BIT(SPI_HandleTypeDef *hspi);
178 static void SPI_TxISR_32BIT(SPI_HandleTypeDef *hspi);
179 static void SPI_RxISR_8BIT(SPI_HandleTypeDef *hspi);
180 static void SPI_RxISR_16BIT(SPI_HandleTypeDef *hspi);
181 static void SPI_RxISR_32BIT(SPI_HandleTypeDef *hspi);
182 static void SPI_AbortTransfer(SPI_HandleTypeDef *hspi);
183 static void SPI_CloseTransfer(SPI_HandleTypeDef *hspi);
184 static uint32_t SPI_GetPacketSize(const SPI_HandleTypeDef *hspi);
188 * @}
191 /* Exported functions --------------------------------------------------------*/
192 /** @defgroup SPI_Exported_Functions SPI Exported Functions
193 * @{
196 /** @defgroup SPI_Exported_Functions_Group1 Initialization and de-initialization functions
197 * @brief Initialization and Configuration functions
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:
206 (+) User must implement HAL_SPI_MspInit() function in which he configures
207 all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
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
225 (+) Call the function HAL_SPI_DeInit() to restore the default configuration
226 of the selected SPIx peripheral.
228 @endverbatim
229 * @{
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
239 HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi)
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 */
247 /* Check the SPI handle allocation */
248 if (hspi == NULL)
250 return HAL_ERROR;
253 /* Check the parameters */
254 assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance));
255 assert_param(IS_SPI_MODE(hspi->Init.Mode));
256 assert_param(IS_SPI_DIRECTION(hspi->Init.Direction));
257 assert_param(IS_SPI_DATASIZE(hspi->Init.DataSize));
258 assert_param(IS_SPI_FIFOTHRESHOLD(hspi->Init.FifoThreshold));
259 assert_param(IS_SPI_NSS(hspi->Init.NSS));
260 assert_param(IS_SPI_NSSP(hspi->Init.NSSPMode));
261 assert_param(IS_SPI_BAUDRATE_PRESCALER(hspi->Init.BaudRatePrescaler));
262 assert_param(IS_SPI_FIRST_BIT(hspi->Init.FirstBit));
263 assert_param(IS_SPI_TIMODE(hspi->Init.TIMode));
264 if (hspi->Init.TIMode == SPI_TIMODE_DISABLE)
266 assert_param(IS_SPI_CPOL(hspi->Init.CLKPolarity));
267 assert_param(IS_SPI_CPHA(hspi->Init.CLKPhase));
269 #if (USE_SPI_CRC != 0UL)
270 assert_param(IS_SPI_CRC_CALCULATION(hspi->Init.CRCCalculation));
271 if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
273 assert_param(IS_SPI_CRC_LENGTH(hspi->Init.CRCLength));
274 assert_param(IS_SPI_CRC_POLYNOMIAL(hspi->Init.CRCPolynomial));
275 assert_param(IS_SPI_CRC_INITIALIZATION_PATTERN(hspi->Init.TxCRCInitializationPattern));
276 assert_param(IS_SPI_CRC_INITIALIZATION_PATTERN(hspi->Init.RxCRCInitializationPattern));
278 #else
279 hspi->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
280 #endif /* USE_SPI_CRC */
282 /* Verify that the SPI instance supports Data Size higher than 16bits */
283 if ((!IS_SPI_HIGHEND_INSTANCE(hspi->Instance)) && (hspi->Init.DataSize > SPI_DATASIZE_16BIT))
285 return HAL_ERROR;
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)))
293 return HAL_ERROR;
296 #if (USE_SPI_CRC != 0UL)
297 if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
299 /* Verify that the SPI instance supports CRC Length higher than 16bits */
300 if ((!IS_SPI_HIGHEND_INSTANCE(hspi->Instance)) && (hspi->Init.CRCLength > SPI_CRC_LENGTH_16BIT))
302 return HAL_ERROR;
305 /* Align the CRC Length on the data size */
306 if (hspi->Init.CRCLength == SPI_CRC_LENGTH_DATASIZE)
308 crc_length = (hspi->Init.DataSize >> SPI_CFG1_DSIZE_Pos) << SPI_CFG1_CRCSIZE_Pos;
310 else
312 crc_length = hspi->Init.CRCLength;
315 /* Verify the correctness of polynom size */
316 assert_param(IS_SPI_CRC_POLYNOMIAL_SIZE(hspi->Init.CRCPolynomial, crc_length));
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))
321 return HAL_ERROR;
324 else
326 crc_length = hspi->Init.DataSize << SPI_CFG1_CRCSIZE_Pos;
328 #endif /* USE_SPI_CRC */
330 if (hspi->State == HAL_SPI_STATE_RESET)
332 /* Allocate lock resource and initialize it */
333 hspi->Lock = HAL_UNLOCKED;
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 */
347 if (hspi->MspInitCallback == NULL)
349 hspi->MspInitCallback = HAL_SPI_MspInit; /* Legacy weak MspInit */
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 */
360 hspi->State = HAL_SPI_STATE_BUSY;
362 /* Disable the selected SPI peripheral */
363 __HAL_SPI_DISABLE(hspi);
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 */
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 */
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) && \
378 (hspi->Init.NSSPolarity == SPI_NSS_POLARITY_HIGH))))
380 SET_BIT(hspi->Instance->CR1, SPI_CR1_SSI);
383 /* SPIx Master Rx Auto Suspend Configuration */
384 if (((hspi->Init.Mode & SPI_MODE_MASTER) == SPI_MODE_MASTER) && (hspi->Init.DataSize >= SPI_DATASIZE_8BIT))
386 MODIFY_REG(hspi->Instance->CR1, SPI_CR1_MASRX, hspi->Init.MasterReceiverAutoSusp);
388 else
390 CLEAR_BIT(hspi->Instance->CR1, SPI_CR1_MASRX);
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));
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 |
402 hspi->Init.MasterInterDataIdleness | hspi->Init.Direction |
403 hspi->Init.MasterSSIdleness | hspi->Init.IOSwap));
405 #if (USE_SPI_CRC != 0UL)
406 /*---------------------------- SPIx CRCPOLY Configuration ------------------*/
407 /* Configure : CRC Polynomial */
408 if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
410 /* Initialize TXCRC Pattern Initial Value */
411 if (hspi->Init.TxCRCInitializationPattern == SPI_CRC_INITIALIZATION_ALL_ONE_PATTERN)
413 SET_BIT(hspi->Instance->CR1, SPI_CR1_TCRCINI);
415 else
417 CLEAR_BIT(hspi->Instance->CR1, SPI_CR1_TCRCINI);
420 /* Initialize RXCRC Pattern Initial Value */
421 if (hspi->Init.RxCRCInitializationPattern == SPI_CRC_INITIALIZATION_ALL_ONE_PATTERN)
423 SET_BIT(hspi->Instance->CR1, SPI_CR1_RCRCINI);
425 else
427 CLEAR_BIT(hspi->Instance->CR1, SPI_CR1_RCRCINI);
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)))
434 /* Set SPI_CR1_CRC33_17 bit */
435 SET_BIT(hspi->Instance->CR1, SPI_CR1_CRC33_17);
436 /* Write CRC polynomial in SPI Register */
437 WRITE_REG(hspi->Instance->CRCPOLY, hspi->Init.CRCPolynomial);
439 else
441 /* Clear SPI_CR1_CRC33_17 bit */
442 CLEAR_BIT(hspi->Instance->CR1, SPI_CR1_CRC33_17);
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);
450 #endif /* USE_SPI_CRC */
452 /* Insure that Underrun configuration is managed only by Salve */
453 if (hspi->Init.Mode == SPI_MODE_SLAVE)
455 /* Set Default Underrun configuration */
456 #if (USE_SPI_CRC != 0UL)
457 if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_DISABLE)
458 #endif /* USE_SPI_CRC */
460 MODIFY_REG(hspi->Instance->CFG1, SPI_CFG1_UDRDET, SPI_CFG1_UDRDET_0);
462 MODIFY_REG(hspi->Instance->CFG1, SPI_CFG1_UDRCFG, SPI_CFG1_UDRCFG_1);
465 #if defined(SPI_I2SCFGR_I2SMOD)
466 /* Activate the SPI mode (Make sure that I2SMOD bit in I2SCFGR register is reset) */
467 CLEAR_BIT(hspi->Instance->I2SCFGR, SPI_I2SCFGR_I2SMOD);
468 #endif /* SPI_I2SCFGR_I2SMOD */
470 /* Insure that AFCNTR is managed only by Master */
471 if ((hspi->Init.Mode & SPI_MODE_MASTER) == SPI_MODE_MASTER)
473 /* Alternate function GPIOs control */
474 MODIFY_REG(hspi->Instance->CFG2, SPI_CFG2_AFCNTR, (hspi->Init.MasterKeepIOState));
477 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
478 hspi->State = HAL_SPI_STATE_READY;
480 return HAL_OK;
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
489 HAL_StatusTypeDef HAL_SPI_DeInit(SPI_HandleTypeDef *hspi)
491 /* Check the SPI handle allocation */
492 if (hspi == NULL)
494 return HAL_ERROR;
497 /* Check SPI Instance parameter */
498 assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance));
500 hspi->State = HAL_SPI_STATE_BUSY;
502 /* Disable the SPI Peripheral Clock */
503 __HAL_SPI_DISABLE(hspi);
505 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
506 if (hspi->MspDeInitCallback == NULL)
508 hspi->MspDeInitCallback = HAL_SPI_MspDeInit; /* Legacy weak MspDeInit */
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 */
518 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
519 hspi->State = HAL_SPI_STATE_RESET;
521 /* Release Lock */
522 __HAL_UNLOCK(hspi);
524 return HAL_OK;
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
533 __weak void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
535 /* Prevent unused argument(s) compilation warning */
536 UNUSED(hspi);
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
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
549 __weak void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi)
551 /* Prevent unused argument(s) compilation warning */
552 UNUSED(hspi);
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
559 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
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
571 HAL_StatusTypeDef HAL_SPI_RegisterCallback(SPI_HandleTypeDef *hspi, HAL_SPI_CallbackIDTypeDef CallbackID,
572 pSPI_CallbackTypeDef pCallback)
574 HAL_StatusTypeDef status = HAL_OK;
576 if (pCallback == NULL)
578 /* Update the error code */
579 hspi->ErrorCode |= HAL_SPI_ERROR_INVALID_CALLBACK;
581 return HAL_ERROR;
584 if (HAL_SPI_STATE_READY == hspi->State)
586 switch (CallbackID)
588 case HAL_SPI_TX_COMPLETE_CB_ID :
589 hspi->TxCpltCallback = pCallback;
590 break;
592 case HAL_SPI_RX_COMPLETE_CB_ID :
593 hspi->RxCpltCallback = pCallback;
594 break;
596 case HAL_SPI_TX_RX_COMPLETE_CB_ID :
597 hspi->TxRxCpltCallback = pCallback;
598 break;
600 case HAL_SPI_TX_HALF_COMPLETE_CB_ID :
601 hspi->TxHalfCpltCallback = pCallback;
602 break;
604 case HAL_SPI_RX_HALF_COMPLETE_CB_ID :
605 hspi->RxHalfCpltCallback = pCallback;
606 break;
608 case HAL_SPI_TX_RX_HALF_COMPLETE_CB_ID :
609 hspi->TxRxHalfCpltCallback = pCallback;
610 break;
612 case HAL_SPI_ERROR_CB_ID :
613 hspi->ErrorCallback = pCallback;
614 break;
616 case HAL_SPI_ABORT_CB_ID :
617 hspi->AbortCpltCallback = pCallback;
618 break;
620 case HAL_SPI_SUSPEND_CB_ID :
621 hspi->SuspendCallback = pCallback;
622 break;
624 case HAL_SPI_MSPINIT_CB_ID :
625 hspi->MspInitCallback = pCallback;
626 break;
628 case HAL_SPI_MSPDEINIT_CB_ID :
629 hspi->MspDeInitCallback = pCallback;
630 break;
632 default :
633 /* Update the error code */
634 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK);
636 /* Return error status */
637 status = HAL_ERROR;
638 break;
641 else if (HAL_SPI_STATE_RESET == hspi->State)
643 switch (CallbackID)
645 case HAL_SPI_MSPINIT_CB_ID :
646 hspi->MspInitCallback = pCallback;
647 break;
649 case HAL_SPI_MSPDEINIT_CB_ID :
650 hspi->MspDeInitCallback = pCallback;
651 break;
653 default :
654 /* Update the error code */
655 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK);
657 /* Return error status */
658 status = HAL_ERROR;
659 break;
662 else
664 /* Update the error code */
665 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK);
667 /* Return error status */
668 status = HAL_ERROR;
671 return status;
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
684 HAL_StatusTypeDef HAL_SPI_UnRegisterCallback(SPI_HandleTypeDef *hspi, HAL_SPI_CallbackIDTypeDef CallbackID)
686 HAL_StatusTypeDef status = HAL_OK;
688 if (HAL_SPI_STATE_READY == hspi->State)
690 switch (CallbackID)
692 case HAL_SPI_TX_COMPLETE_CB_ID :
693 hspi->TxCpltCallback = HAL_SPI_TxCpltCallback; /* Legacy weak TxCpltCallback */
694 break;
696 case HAL_SPI_RX_COMPLETE_CB_ID :
697 hspi->RxCpltCallback = HAL_SPI_RxCpltCallback; /* Legacy weak RxCpltCallback */
698 break;
700 case HAL_SPI_TX_RX_COMPLETE_CB_ID :
701 hspi->TxRxCpltCallback = HAL_SPI_TxRxCpltCallback; /* Legacy weak TxRxCpltCallback */
702 break;
704 case HAL_SPI_TX_HALF_COMPLETE_CB_ID :
705 hspi->TxHalfCpltCallback = HAL_SPI_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
706 break;
708 case HAL_SPI_RX_HALF_COMPLETE_CB_ID :
709 hspi->RxHalfCpltCallback = HAL_SPI_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
710 break;
712 case HAL_SPI_TX_RX_HALF_COMPLETE_CB_ID :
713 hspi->TxRxHalfCpltCallback = HAL_SPI_TxRxHalfCpltCallback; /* Legacy weak TxRxHalfCpltCallback */
714 break;
716 case HAL_SPI_ERROR_CB_ID :
717 hspi->ErrorCallback = HAL_SPI_ErrorCallback; /* Legacy weak ErrorCallback */
718 break;
720 case HAL_SPI_ABORT_CB_ID :
721 hspi->AbortCpltCallback = HAL_SPI_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
722 break;
724 case HAL_SPI_SUSPEND_CB_ID :
725 hspi->SuspendCallback = HAL_SPI_SuspendCallback; /* Legacy weak SuspendCallback */
726 break;
728 case HAL_SPI_MSPINIT_CB_ID :
729 hspi->MspInitCallback = HAL_SPI_MspInit; /* Legacy weak MspInit */
730 break;
732 case HAL_SPI_MSPDEINIT_CB_ID :
733 hspi->MspDeInitCallback = HAL_SPI_MspDeInit; /* Legacy weak MspDeInit */
734 break;
736 default :
737 /* Update the error code */
738 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK);
740 /* Return error status */
741 status = HAL_ERROR;
742 break;
745 else if (HAL_SPI_STATE_RESET == hspi->State)
747 switch (CallbackID)
749 case HAL_SPI_MSPINIT_CB_ID :
750 hspi->MspInitCallback = HAL_SPI_MspInit; /* Legacy weak MspInit */
751 break;
753 case HAL_SPI_MSPDEINIT_CB_ID :
754 hspi->MspDeInitCallback = HAL_SPI_MspDeInit; /* Legacy weak MspDeInit */
755 break;
757 default :
758 /* Update the error code */
759 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK);
761 /* Return error status */
762 status = HAL_ERROR;
763 break;
766 else
768 /* Update the error code */
769 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK);
771 /* Return error status */
772 status = HAL_ERROR;
775 return status;
777 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
779 * @}
782 /** @defgroup SPI_Exported_Functions_Group2 IO operation functions
783 * @brief Data transfers functions
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.
793 [..] The SPI supports master and slave mode :
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
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.
811 @endverbatim
812 * @{
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
824 HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, const uint8_t *pData, uint16_t Size, uint32_t Timeout)
826 #if defined (__GNUC__)
827 __IO uint16_t *ptxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->TXDR));
828 #endif /* __GNUC__ */
830 uint32_t tickstart;
832 /* Check Direction parameter */
833 assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_TXONLY(hspi->Init.Direction));
835 /* Init tickstart for timeout management*/
836 tickstart = HAL_GetTick();
838 if (hspi->State != HAL_SPI_STATE_READY)
840 return HAL_BUSY;
843 if ((pData == NULL) || (Size == 0UL))
845 return HAL_ERROR;
848 /* Lock the process */
849 __HAL_LOCK(hspi);
851 /* Set the transaction information */
852 hspi->State = HAL_SPI_STATE_BUSY_TX;
853 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
854 hspi->pTxBuffPtr = (const uint8_t *)pData;
855 hspi->TxXferSize = Size;
856 hspi->TxXferCount = Size;
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;
865 /* Configure communication direction : 1Line */
866 if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
868 SPI_1LINE_TX(hspi);
870 else
872 SPI_2LINES_TX(hspi);
875 /* Set the number of data at current transfer */
876 MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size);
878 /* Enable SPI peripheral */
879 __HAL_SPI_ENABLE(hspi);
881 if (hspi->Init.Mode == SPI_MODE_MASTER)
883 /* Master transfer start */
884 SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART);
887 /* Transmit data in 32 Bit mode */
888 if (hspi->Init.DataSize > SPI_DATASIZE_16BIT)
890 /* Transmit data in 32 Bit mode */
891 while (hspi->TxXferCount > 0UL)
893 /* Wait until TXP flag is set to send data */
894 if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP))
896 *((__IO uint32_t *)&hspi->Instance->TXDR) = *((const uint32_t *)hspi->pTxBuffPtr);
897 hspi->pTxBuffPtr += sizeof(uint32_t);
898 hspi->TxXferCount--;
900 else
902 /* Timeout management */
903 if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
905 /* Call standard close procedure with error check */
906 SPI_CloseTransfer(hspi);
908 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
909 hspi->State = HAL_SPI_STATE_READY;
911 /* Unlock the process */
912 __HAL_UNLOCK(hspi);
914 return HAL_TIMEOUT;
919 /* Transmit data in 16 Bit mode */
920 else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
922 /* Transmit data in 16 Bit mode */
923 while (hspi->TxXferCount > 0UL)
925 /* Wait until TXP flag is set to send data */
926 if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP))
928 if ((hspi->TxXferCount > 1UL) && (hspi->Init.FifoThreshold > SPI_FIFO_THRESHOLD_01DATA))
930 *((__IO uint32_t *)&hspi->Instance->TXDR) = *((const uint32_t *)hspi->pTxBuffPtr);
931 hspi->pTxBuffPtr += sizeof(uint32_t);
932 hspi->TxXferCount -= (uint16_t)2UL;
934 else
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--;
945 else
947 /* Timeout management */
948 if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
950 /* Call standard close procedure with error check */
951 SPI_CloseTransfer(hspi);
953 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
954 hspi->State = HAL_SPI_STATE_READY;
956 /* Unlock the process */
957 __HAL_UNLOCK(hspi);
959 return HAL_TIMEOUT;
964 /* Transmit data in 8 Bit mode */
965 else
967 while (hspi->TxXferCount > 0UL)
969 /* Wait until TXP flag is set to send data */
970 if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP))
972 if ((hspi->TxXferCount > 3UL) && (hspi->Init.FifoThreshold > SPI_FIFO_THRESHOLD_03DATA))
974 *((__IO uint32_t *)&hspi->Instance->TXDR) = *((const uint32_t *)hspi->pTxBuffPtr);
975 hspi->pTxBuffPtr += sizeof(uint32_t);
976 hspi->TxXferCount -= (uint16_t)4UL;
978 else if ((hspi->TxXferCount > 1UL) && (hspi->Init.FifoThreshold > SPI_FIFO_THRESHOLD_01DATA))
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;
988 else
990 *((__IO uint8_t *)&hspi->Instance->TXDR) = *((const uint8_t *)hspi->pTxBuffPtr);
991 hspi->pTxBuffPtr += sizeof(uint8_t);
992 hspi->TxXferCount--;
995 else
997 /* Timeout management */
998 if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
1000 /* Call standard close procedure with error check */
1001 SPI_CloseTransfer(hspi);
1003 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
1004 hspi->State = HAL_SPI_STATE_READY;
1006 /* Unlock the process */
1007 __HAL_UNLOCK(hspi);
1009 return HAL_TIMEOUT;
1015 /* Wait for Tx (and CRC) data to be sent */
1016 if (SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_EOT, RESET, Timeout, tickstart) != HAL_OK)
1018 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
1021 /* Call standard close procedure with error check */
1022 SPI_CloseTransfer(hspi);
1024 hspi->State = HAL_SPI_STATE_READY;
1026 /* Unlock the process */
1027 __HAL_UNLOCK(hspi);
1029 if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
1031 return HAL_ERROR;
1033 else
1035 return HAL_OK;
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
1048 HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
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__ */
1058 /* Check Direction parameter */
1059 assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_RXONLY(hspi->Init.Direction));
1061 /* Init tickstart for timeout management*/
1062 tickstart = HAL_GetTick();
1064 if (hspi->State != HAL_SPI_STATE_READY)
1066 return HAL_BUSY;
1069 if ((pData == NULL) || (Size == 0UL))
1071 return HAL_ERROR;
1074 /* Lock the process */
1075 __HAL_LOCK(hspi);
1077 /* Set the transaction information */
1078 hspi->State = HAL_SPI_STATE_BUSY_RX;
1079 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
1080 hspi->pRxBuffPtr = (uint8_t *)pData;
1081 hspi->RxXferSize = Size;
1082 hspi->RxXferCount = Size;
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;
1091 /* Configure communication direction: 1Line */
1092 if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
1094 SPI_1LINE_RX(hspi);
1096 else
1098 SPI_2LINES_RX(hspi);
1101 /* Set the number of data at current transfer */
1102 MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size);
1104 /* Enable SPI peripheral */
1105 __HAL_SPI_ENABLE(hspi);
1107 if (hspi->Init.Mode == SPI_MODE_MASTER)
1109 /* Master transfer start */
1110 SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART);
1113 /* Receive data in 32 Bit mode */
1114 if (hspi->Init.DataSize > SPI_DATASIZE_16BIT)
1116 /* Transfer loop */
1117 while (hspi->RxXferCount > 0UL)
1119 /* Evaluate state of SR register */
1120 temp_sr_reg = hspi->Instance->SR;
1122 /* Check the RXP flag */
1123 if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXP))
1125 *((uint32_t *)hspi->pRxBuffPtr) = *((__IO uint32_t *)&hspi->Instance->RXDR);
1126 hspi->pRxBuffPtr += sizeof(uint32_t);
1127 hspi->RxXferCount--;
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))
1132 *((uint32_t *)hspi->pRxBuffPtr) = *((__IO uint32_t *)&hspi->Instance->RXDR);
1133 hspi->pRxBuffPtr += sizeof(uint32_t);
1134 hspi->RxXferCount--;
1136 else
1138 /* Timeout management */
1139 if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
1141 /* Call standard close procedure with error check */
1142 SPI_CloseTransfer(hspi);
1144 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
1145 hspi->State = HAL_SPI_STATE_READY;
1147 /* Unlock the process */
1148 __HAL_UNLOCK(hspi);
1150 return HAL_TIMEOUT;
1155 /* Receive data in 16 Bit mode */
1156 else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
1158 /* Transfer loop */
1159 while (hspi->RxXferCount > 0UL)
1161 /* Evaluate state of SR register */
1162 temp_sr_reg = hspi->Instance->SR;
1164 /* Check the RXP flag */
1165 if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXP))
1167 #if defined (__GNUC__)
1168 *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits;
1169 #else
1170 *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
1171 #endif /* __GNUC__ */
1172 hspi->pRxBuffPtr += sizeof(uint16_t);
1173 hspi->RxXferCount--;
1175 /* Check RXWNE flag if RXP cannot be reached */
1176 else if ((hspi->RxXferCount < init_max_data_in_fifo) && ((temp_sr_reg & SPI_SR_RXWNE_Msk) != 0UL))
1178 #if defined (__GNUC__)
1179 *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits;
1180 #else
1181 *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
1182 #endif /* __GNUC__ */
1183 hspi->pRxBuffPtr += sizeof(uint16_t);
1184 #if defined (__GNUC__)
1185 *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits;
1186 #else
1187 *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
1188 #endif /* __GNUC__ */
1189 hspi->pRxBuffPtr += sizeof(uint16_t);
1190 hspi->RxXferCount -= (uint16_t)2UL;
1192 /* Check RXPLVL flags when RXWNE cannot be reached */
1193 else if ((hspi->RxXferCount == 1UL) && ((temp_sr_reg & SPI_SR_RXPLVL_0) != 0UL))
1195 #if defined (__GNUC__)
1196 *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits;
1197 #else
1198 *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
1199 #endif /* __GNUC__ */
1200 hspi->pRxBuffPtr += sizeof(uint16_t);
1201 hspi->RxXferCount--;
1203 else
1205 /* Timeout management */
1206 if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
1208 /* Call standard close procedure with error check */
1209 SPI_CloseTransfer(hspi);
1211 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
1212 hspi->State = HAL_SPI_STATE_READY;
1214 /* Unlock the process */
1215 __HAL_UNLOCK(hspi);
1217 return HAL_TIMEOUT;
1222 /* Receive data in 8 Bit mode */
1223 else
1225 /* Transfer loop */
1226 while (hspi->RxXferCount > 0UL)
1228 /* Evaluate state of SR register */
1229 temp_sr_reg = hspi->Instance->SR;
1231 /* Check the RXP flag */
1232 if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXP))
1234 *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
1235 hspi->pRxBuffPtr += sizeof(uint8_t);
1236 hspi->RxXferCount--;
1238 /* Check RXWNE flag if RXP cannot be reached */
1239 else if ((hspi->RxXferCount < init_max_data_in_fifo) && ((temp_sr_reg & SPI_SR_RXWNE_Msk) != 0UL))
1241 *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
1242 hspi->pRxBuffPtr += sizeof(uint8_t);
1243 *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
1244 hspi->pRxBuffPtr += sizeof(uint8_t);
1245 *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
1246 hspi->pRxBuffPtr += sizeof(uint8_t);
1247 *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
1248 hspi->pRxBuffPtr += sizeof(uint8_t);
1249 hspi->RxXferCount -= (uint16_t)4UL;
1251 /* Check RXPLVL flags when RXWNE cannot be reached */
1252 else if ((hspi->RxXferCount < 4UL) && ((temp_sr_reg & SPI_SR_RXPLVL_Msk) != 0UL))
1254 *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
1255 hspi->pRxBuffPtr += sizeof(uint8_t);
1256 hspi->RxXferCount--;
1258 else
1260 /* Timeout management */
1261 if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
1263 /* Call standard close procedure with error check */
1264 SPI_CloseTransfer(hspi);
1266 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
1267 hspi->State = HAL_SPI_STATE_READY;
1269 /* Unlock the process */
1270 __HAL_UNLOCK(hspi);
1272 return HAL_TIMEOUT;
1278 #if (USE_SPI_CRC != 0UL)
1279 if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
1281 /* Wait for crc data to be received */
1282 if (SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_EOT, RESET, Timeout, tickstart) != HAL_OK)
1284 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
1287 #endif /* USE_SPI_CRC */
1289 /* Call standard close procedure with error check */
1290 SPI_CloseTransfer(hspi);
1292 hspi->State = HAL_SPI_STATE_READY;
1294 /* Unlock the process */
1295 __HAL_UNLOCK(hspi);
1298 if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
1300 return HAL_ERROR;
1302 else
1304 return HAL_OK;
1309 * @brief Transmit and Receive an amount of data in blocking mode.
1310 * @param hspi : pointer to a SPI_HandleTypeDef structure that contains
1311 * the configuration information for SPI module.
1312 * @param pTxData: pointer to transmission data buffer
1313 * @param pRxData: pointer to reception data buffer
1314 * @param Size : amount of data to be sent and received
1315 * @param Timeout: Timeout duration
1316 * @retval HAL status
1318 HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, const uint8_t *pTxData, uint8_t *pRxData,
1319 uint16_t Size, uint32_t Timeout)
1321 #if defined (__GNUC__)
1322 __IO uint16_t *ptxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->TXDR));
1323 __IO uint16_t *prxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->RXDR));
1324 #endif /* __GNUC__ */
1326 uint32_t tickstart;
1327 uint32_t fifo_length;
1328 uint32_t temp_sr_reg;
1329 uint16_t initial_TxXferCount;
1330 uint16_t initial_RxXferCount;
1331 uint16_t init_max_data_in_fifo;
1332 init_max_data_in_fifo = (((uint16_t)(hspi->Init.FifoThreshold >> 5U) + 1U));
1334 /* Check Direction parameter */
1335 assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));
1337 /* Init tickstart for timeout management*/
1338 tickstart = HAL_GetTick();
1340 initial_TxXferCount = Size;
1341 initial_RxXferCount = Size;
1343 if (hspi->State != HAL_SPI_STATE_READY)
1345 return HAL_BUSY;
1348 if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0UL))
1350 return HAL_ERROR;
1353 /* Lock the process */
1354 __HAL_LOCK(hspi);
1356 /* Set the transaction information */
1357 hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
1358 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
1359 hspi->pRxBuffPtr = (uint8_t *)pRxData;
1360 hspi->RxXferCount = Size;
1361 hspi->RxXferSize = Size;
1362 hspi->pTxBuffPtr = (const uint8_t *)pTxData;
1363 hspi->TxXferCount = Size;
1364 hspi->TxXferSize = Size;
1366 /*Init field not used in handle to zero */
1367 hspi->RxISR = NULL;
1368 hspi->TxISR = NULL;
1370 /* Set Full-Duplex mode */
1371 SPI_2LINES(hspi);
1373 /* Initialize FIFO length */
1374 if (IS_SPI_HIGHEND_INSTANCE(hspi->Instance))
1376 fifo_length = SPI_HIGHEND_FIFO_SIZE;
1378 else
1380 fifo_length = SPI_LOWEND_FIFO_SIZE;
1383 /* Set the number of data at current transfer */
1384 MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size);
1386 __HAL_SPI_ENABLE(hspi);
1388 if (hspi->Init.Mode == SPI_MODE_MASTER)
1390 /* Master transfer start */
1391 SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART);
1394 /* Transmit and Receive data in 32 Bit mode */
1395 if (hspi->Init.DataSize > SPI_DATASIZE_16BIT)
1397 /* Adapt fifo length to 32bits data width */
1398 fifo_length = (fifo_length / 4UL);
1400 while ((initial_TxXferCount > 0UL) || (initial_RxXferCount > 0UL))
1402 /* Check TXP flag */
1403 if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP)) && (initial_TxXferCount > 0UL) &&
1404 (initial_RxXferCount < (initial_TxXferCount + fifo_length)))
1406 *((__IO uint32_t *)&hspi->Instance->TXDR) = *((const uint32_t *)hspi->pTxBuffPtr);
1407 hspi->pTxBuffPtr += sizeof(uint32_t);
1408 hspi->TxXferCount --;
1409 initial_TxXferCount = hspi->TxXferCount;
1412 /* Evaluate state of SR register */
1413 temp_sr_reg = hspi->Instance->SR;
1415 if (initial_RxXferCount > 0UL)
1417 /* Check the RXP flag */
1418 if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXP))
1420 *((uint32_t *)hspi->pRxBuffPtr) = *((__IO uint32_t *)&hspi->Instance->RXDR);
1421 hspi->pRxBuffPtr += sizeof(uint32_t);
1422 hspi->RxXferCount--;
1423 initial_RxXferCount = hspi->RxXferCount;
1425 /* Check RXWNE flag if RXP cannot be reached */
1426 else if ((initial_RxXferCount < init_max_data_in_fifo) && ((temp_sr_reg & SPI_SR_RXWNE_Msk) != 0UL))
1428 *((uint32_t *)hspi->pRxBuffPtr) = *((__IO uint32_t *)&hspi->Instance->RXDR);
1429 hspi->pRxBuffPtr += sizeof(uint32_t);
1430 hspi->RxXferCount--;
1431 initial_RxXferCount = hspi->RxXferCount;
1433 else
1435 /* Timeout management */
1436 if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
1438 /* Call standard close procedure with error check */
1439 SPI_CloseTransfer(hspi);
1441 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
1442 hspi->State = HAL_SPI_STATE_READY;
1444 /* Unlock the process */
1445 __HAL_UNLOCK(hspi);
1447 return HAL_TIMEOUT;
1453 /* Transmit and Receive data in 16 Bit mode */
1454 else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
1456 /* Adapt fifo length to 16bits data width */
1457 fifo_length = (fifo_length / 2UL);
1459 while ((initial_TxXferCount > 0UL) || (initial_RxXferCount > 0UL))
1461 /* Check the TXP flag */
1462 if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP)) && (initial_TxXferCount > 0UL) &&
1463 (initial_RxXferCount < (initial_TxXferCount + fifo_length)))
1465 #if defined (__GNUC__)
1466 *ptxdr_16bits = *((const uint16_t *)hspi->pTxBuffPtr);
1467 #else
1468 *((__IO uint16_t *)&hspi->Instance->TXDR) = *((const uint16_t *)hspi->pTxBuffPtr);
1469 #endif /* __GNUC__ */
1470 hspi->pTxBuffPtr += sizeof(uint16_t);
1471 hspi->TxXferCount--;
1472 initial_TxXferCount = hspi->TxXferCount;
1475 /* Evaluate state of SR register */
1476 temp_sr_reg = hspi->Instance->SR;
1478 if (initial_RxXferCount > 0UL)
1480 /* Check the RXP flag */
1481 if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXP))
1483 #if defined (__GNUC__)
1484 *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits;
1485 #else
1486 *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
1487 #endif /* __GNUC__ */
1488 hspi->pRxBuffPtr += sizeof(uint16_t);
1489 hspi->RxXferCount--;
1490 initial_RxXferCount = hspi->RxXferCount;
1492 /* Check RXWNE flag if RXP cannot be reached */
1493 else if ((initial_RxXferCount < init_max_data_in_fifo) && ((temp_sr_reg & SPI_SR_RXWNE_Msk) != 0UL))
1495 #if defined (__GNUC__)
1496 *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits;
1497 #else
1498 *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
1499 #endif /* __GNUC__ */
1500 hspi->pRxBuffPtr += sizeof(uint16_t);
1501 #if defined (__GNUC__)
1502 *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits;
1503 #else
1504 *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
1505 #endif /* __GNUC__ */
1506 hspi->pRxBuffPtr += sizeof(uint16_t);
1507 hspi->RxXferCount -= (uint16_t)2UL;
1508 initial_RxXferCount = hspi->RxXferCount;
1510 /* Check RXPLVL flags when RXWNE cannot be reached */
1511 else if ((initial_RxXferCount == 1UL) && ((temp_sr_reg & SPI_SR_RXPLVL_0) != 0UL))
1513 #if defined (__GNUC__)
1514 *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits;
1515 #else
1516 *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
1517 #endif /* __GNUC__ */
1518 hspi->pRxBuffPtr += sizeof(uint16_t);
1519 hspi->RxXferCount--;
1520 initial_RxXferCount = hspi->RxXferCount;
1522 else
1524 /* Timeout management */
1525 if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
1527 /* Call standard close procedure with error check */
1528 SPI_CloseTransfer(hspi);
1530 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
1531 hspi->State = HAL_SPI_STATE_READY;
1533 /* Unlock the process */
1534 __HAL_UNLOCK(hspi);
1536 return HAL_TIMEOUT;
1542 /* Transmit and Receive data in 8 Bit mode */
1543 else
1545 while ((initial_TxXferCount > 0UL) || (initial_RxXferCount > 0UL))
1547 /* Check the TXP flag */
1548 if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP)) && (initial_TxXferCount > 0UL) &&
1549 (initial_RxXferCount < (initial_TxXferCount + fifo_length)))
1551 *((__IO uint8_t *)&hspi->Instance->TXDR) = *((const uint8_t *)hspi->pTxBuffPtr);
1552 hspi->pTxBuffPtr += sizeof(uint8_t);
1553 hspi->TxXferCount--;
1554 initial_TxXferCount = hspi->TxXferCount;
1557 /* Evaluate state of SR register */
1558 temp_sr_reg = hspi->Instance->SR;
1560 if (initial_RxXferCount > 0UL)
1562 /* Check the RXP flag */
1563 if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXP))
1565 *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
1566 hspi->pRxBuffPtr += sizeof(uint8_t);
1567 hspi->RxXferCount--;
1568 initial_RxXferCount = hspi->RxXferCount;
1570 /* Check RXWNE flag if RXP cannot be reached */
1571 else if ((initial_RxXferCount < init_max_data_in_fifo) && ((temp_sr_reg & SPI_SR_RXWNE_Msk) != 0UL))
1573 *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
1574 hspi->pRxBuffPtr += sizeof(uint8_t);
1575 *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
1576 hspi->pRxBuffPtr += sizeof(uint8_t);
1577 *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
1578 hspi->pRxBuffPtr += sizeof(uint8_t);
1579 *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
1580 hspi->pRxBuffPtr += sizeof(uint8_t);
1581 hspi->RxXferCount -= (uint16_t)4UL;
1582 initial_RxXferCount = hspi->RxXferCount;
1584 /* Check RXPLVL flags when RXWNE cannot be reached */
1585 else if ((initial_RxXferCount < 4UL) && ((temp_sr_reg & SPI_SR_RXPLVL_Msk) != 0UL))
1587 *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
1588 hspi->pRxBuffPtr += sizeof(uint8_t);
1589 hspi->RxXferCount--;
1590 initial_RxXferCount = hspi->RxXferCount;
1592 else
1594 /* Timeout management */
1595 if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
1597 /* Call standard close procedure with error check */
1598 SPI_CloseTransfer(hspi);
1600 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
1601 hspi->State = HAL_SPI_STATE_READY;
1603 /* Unlock the process */
1604 __HAL_UNLOCK(hspi);
1606 return HAL_TIMEOUT;
1613 /* Wait for Tx/Rx (and CRC) data to be sent/received */
1614 if (SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_EOT, RESET, Timeout, tickstart) != HAL_OK)
1616 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
1619 /* Call standard close procedure with error check */
1620 SPI_CloseTransfer(hspi);
1622 hspi->State = HAL_SPI_STATE_READY;
1624 /* Unlock the process */
1625 __HAL_UNLOCK(hspi);
1627 if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
1629 return HAL_ERROR;
1631 else
1633 return HAL_OK;
1638 * @brief Transmit an amount of data in non-blocking mode with Interrupt.
1639 * @param hspi : pointer to a SPI_HandleTypeDef structure that contains
1640 * the configuration information for SPI module.
1641 * @param pData: pointer to data buffer
1642 * @param Size : amount of data to be sent
1643 * @retval HAL status
1645 HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, const uint8_t *pData, uint16_t Size)
1647 /* Check Direction parameter */
1648 assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_TXONLY(hspi->Init.Direction));
1650 if ((pData == NULL) || (Size == 0UL))
1652 return HAL_ERROR;
1655 if (hspi->State != HAL_SPI_STATE_READY)
1657 return HAL_BUSY;
1660 /* Lock the process */
1661 __HAL_LOCK(hspi);
1663 /* Set the transaction information */
1664 hspi->State = HAL_SPI_STATE_BUSY_TX;
1665 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
1666 hspi->pTxBuffPtr = (const uint8_t *)pData;
1667 hspi->TxXferSize = Size;
1668 hspi->TxXferCount = Size;
1670 /* Init field not used in handle to zero */
1671 hspi->pRxBuffPtr = NULL;
1672 hspi->RxXferSize = (uint16_t) 0UL;
1673 hspi->RxXferCount = (uint16_t) 0UL;
1674 hspi->RxISR = NULL;
1676 #if defined(USE_SPI_RELOAD_TRANSFER)
1677 hspi->Reload.Requested = 0UL;
1678 hspi->Reload.pTxBuffPtr = NULL;
1679 hspi->Reload.TxXferSize = NULL;
1680 #endif /* USE_SPI_RELOAD_TRANSFER */
1682 /* Set the function for IT treatment */
1683 if (hspi->Init.DataSize > SPI_DATASIZE_16BIT)
1685 hspi->TxISR = SPI_TxISR_32BIT;
1687 else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
1689 hspi->TxISR = SPI_TxISR_16BIT;
1691 else
1693 hspi->TxISR = SPI_TxISR_8BIT;
1696 /* Configure communication direction : 1Line */
1697 if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
1699 SPI_1LINE_TX(hspi);
1701 else
1703 SPI_2LINES_TX(hspi);
1706 /* Set the number of data at current transfer */
1707 MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size);
1709 /* Enable SPI peripheral */
1710 __HAL_SPI_ENABLE(hspi);
1712 /* Unlock the process */
1713 __HAL_UNLOCK(hspi);
1715 /* Enable EOT, TXP, FRE, MODF, UDR and TSERF interrupts */
1716 __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_EOT | SPI_IT_TXP | SPI_IT_UDR | SPI_IT_FRE | SPI_IT_MODF | SPI_IT_TSERF));
1718 if (hspi->Init.Mode == SPI_MODE_MASTER)
1720 /* Master transfer start */
1721 SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART);
1724 return HAL_OK;
1728 * @brief Receive an amount of data in non-blocking mode with Interrupt.
1729 * @param hspi : pointer to a SPI_HandleTypeDef structure that contains
1730 * the configuration information for SPI module.
1731 * @param pData: pointer to data buffer
1732 * @param Size : amount of data to be sent
1733 * @retval HAL status
1735 HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
1737 /* Check Direction parameter */
1738 assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_RXONLY(hspi->Init.Direction));
1740 if (hspi->State != HAL_SPI_STATE_READY)
1742 return HAL_BUSY;
1745 if ((pData == NULL) || (Size == 0UL))
1747 return HAL_ERROR;
1750 /* Lock the process */
1751 __HAL_LOCK(hspi);
1753 /* Set the transaction information */
1754 hspi->State = HAL_SPI_STATE_BUSY_RX;
1755 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
1756 hspi->pRxBuffPtr = (uint8_t *)pData;
1757 hspi->RxXferSize = Size;
1758 hspi->RxXferCount = Size;
1760 /* Init field not used in handle to zero */
1761 hspi->pTxBuffPtr = NULL;
1762 hspi->TxXferSize = (uint16_t) 0UL;
1763 hspi->TxXferCount = (uint16_t) 0UL;
1764 hspi->TxISR = NULL;
1766 #if defined(USE_SPI_RELOAD_TRANSFER)
1767 hspi->Reload.Requested = 0UL;
1768 hspi->Reload.pRxBuffPtr = NULL;
1769 hspi->Reload.RxXferSize = NULL;
1770 #endif /* USE_SPI_RELOAD_TRANSFER */
1772 /* Set the function for IT treatment */
1773 if (hspi->Init.DataSize > SPI_DATASIZE_16BIT)
1775 hspi->RxISR = SPI_RxISR_32BIT;
1777 else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
1779 hspi->RxISR = SPI_RxISR_16BIT;
1781 else
1783 hspi->RxISR = SPI_RxISR_8BIT;
1786 /* Configure communication direction : 1Line */
1787 if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
1789 SPI_1LINE_RX(hspi);
1791 else
1793 SPI_2LINES_RX(hspi);
1796 /* Note : The SPI must be enabled after unlocking current process
1797 to avoid the risk of SPI interrupt handle execution before current
1798 process unlock */
1800 /* Set the number of data at current transfer */
1801 MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size);
1803 /* Enable SPI peripheral */
1804 __HAL_SPI_ENABLE(hspi);
1806 /* Unlock the process */
1807 __HAL_UNLOCK(hspi);
1809 /* Enable EOT, RXP, OVR, FRE, MODF and TSERF interrupts */
1810 __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_EOT | SPI_IT_RXP | SPI_IT_OVR | SPI_IT_FRE | SPI_IT_MODF | SPI_IT_TSERF));
1812 if (hspi->Init.Mode == SPI_MODE_MASTER)
1814 /* Master transfer start */
1815 SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART);
1818 return HAL_OK;
1822 * @brief Transmit and Receive an amount of data in non-blocking mode with Interrupt.
1823 * @param hspi : pointer to a SPI_HandleTypeDef structure that contains
1824 * the configuration information for SPI module.
1825 * @param pTxData: pointer to transmission data buffer
1826 * @param pRxData: pointer to reception data buffer
1827 * @param Size : amount of data to be sent and received
1828 * @retval HAL status
1830 HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, const uint8_t *pTxData, uint8_t *pRxData,
1831 uint16_t Size)
1833 uint32_t tmp_TxXferCount;
1834 #if defined (__GNUC__)
1835 __IO uint16_t *ptxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->TXDR));
1836 #endif /* __GNUC__ */
1838 /* Check Direction parameter */
1839 assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));
1841 if (hspi->State != HAL_SPI_STATE_READY)
1843 return HAL_BUSY;
1846 if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0UL))
1848 return HAL_ERROR;
1851 /* Lock the process */
1852 __HAL_LOCK(hspi);
1854 /* Set the transaction information */
1855 hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
1856 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
1857 hspi->pTxBuffPtr = (const uint8_t *)pTxData;
1858 hspi->TxXferSize = Size;
1859 hspi->TxXferCount = Size;
1860 hspi->pRxBuffPtr = (uint8_t *)pRxData;
1861 hspi->RxXferSize = Size;
1862 hspi->RxXferCount = Size;
1863 tmp_TxXferCount = hspi->TxXferCount;
1865 #if defined(USE_SPI_RELOAD_TRANSFER)
1866 hspi->Reload.Requested = 0UL;
1867 hspi->Reload.pRxBuffPtr = NULL;
1868 hspi->Reload.RxXferSize = NULL;
1869 hspi->Reload.pTxBuffPtr = NULL;
1870 hspi->Reload.TxXferSize = NULL;
1871 #endif /* USE_SPI_RELOAD_TRANSFER */
1873 /* Set the function for IT treatment */
1874 if (hspi->Init.DataSize > SPI_DATASIZE_16BIT)
1876 hspi->TxISR = SPI_TxISR_32BIT;
1877 hspi->RxISR = SPI_RxISR_32BIT;
1879 else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
1881 hspi->RxISR = SPI_RxISR_16BIT;
1882 hspi->TxISR = SPI_TxISR_16BIT;
1884 else
1886 hspi->RxISR = SPI_RxISR_8BIT;
1887 hspi->TxISR = SPI_TxISR_8BIT;
1890 /* Set Full-Duplex mode */
1891 SPI_2LINES(hspi);
1893 /* Set the number of data at current transfer */
1894 MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size);
1896 /* Enable SPI peripheral */
1897 __HAL_SPI_ENABLE(hspi);
1899 /* Fill in the TxFIFO */
1900 while ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP)) && (tmp_TxXferCount != 0UL))
1902 /* Transmit data in 32 Bit mode */
1903 if (hspi->Init.DataSize > SPI_DATASIZE_16BIT)
1905 *((__IO uint32_t *)&hspi->Instance->TXDR) = *((const uint32_t *)hspi->pTxBuffPtr);
1906 hspi->pTxBuffPtr += sizeof(uint32_t);
1907 hspi->TxXferCount--;
1908 tmp_TxXferCount = hspi->TxXferCount;
1910 /* Transmit data in 16 Bit mode */
1911 else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
1913 #if defined (__GNUC__)
1914 *ptxdr_16bits = *((const uint16_t *)hspi->pTxBuffPtr);
1915 #else
1916 *((__IO uint16_t *)&hspi->Instance->TXDR) = *((const uint16_t *)hspi->pTxBuffPtr);
1917 #endif /* __GNUC__ */
1918 hspi->pTxBuffPtr += sizeof(uint16_t);
1919 hspi->TxXferCount--;
1920 tmp_TxXferCount = hspi->TxXferCount;
1922 /* Transmit data in 8 Bit mode */
1923 else
1925 *((__IO uint8_t *)&hspi->Instance->TXDR) = *((const uint8_t *)hspi->pTxBuffPtr);
1926 hspi->pTxBuffPtr += sizeof(uint8_t);
1927 hspi->TxXferCount--;
1928 tmp_TxXferCount = hspi->TxXferCount;
1932 /* Unlock the process */
1933 __HAL_UNLOCK(hspi);
1935 /* Enable EOT, DXP, UDR, OVR, FRE, MODF and TSERF interrupts */
1936 __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_EOT | SPI_IT_DXP | SPI_IT_UDR | SPI_IT_OVR |
1937 SPI_IT_FRE | SPI_IT_MODF | SPI_IT_TSERF));
1939 if (hspi->Init.Mode == SPI_MODE_MASTER)
1941 /* Start Master transfer */
1942 SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART);
1945 return HAL_OK;
1948 #if defined(USE_SPI_RELOAD_TRANSFER)
1950 * @brief Transmit an additional amount of data in blocking mode.
1951 * @param hspi : pointer to a SPI_HandleTypeDef structure that contains
1952 * the configuration information for SPI module.
1953 * @param pData: pointer to data buffer
1954 * @param Size : amount of data to be sent
1955 * @retval HAL status
1957 HAL_StatusTypeDef HAL_SPI_Reload_Transmit_IT(SPI_HandleTypeDef *hspi, const uint8_t *pData, uint16_t Size)
1959 /* check if there is already a request to reload */
1960 if ((hspi->Reload.Requested == 1UL) || (pData == NULL) || (Size == 0UL))
1962 return HAL_ERROR;
1965 if (hspi->State == HAL_SPI_STATE_BUSY_TX)
1967 /* Lock the process */
1968 __HAL_LOCK(hspi);
1970 /* Insert the new number of data to be sent just after the current one */
1971 MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSER, (Size & 0xFFFFFFFFUL) << 16UL);
1973 /* Set the transaction information */
1974 hspi->Reload.Requested = 1UL;
1975 hspi->Reload.pTxBuffPtr = (const uint8_t *)pData;
1976 hspi->Reload.TxXferSize = Size;
1978 /* Unlock the process */
1979 __HAL_UNLOCK(hspi);
1981 return HAL_OK;
1983 else
1985 return HAL_ERROR;
1988 #endif /* USE_SPI_RELOAD_TRANSFER */
1990 #if defined(USE_SPI_RELOAD_TRANSFER)
1992 * @brief Receive an additional amount of data in blocking mode.
1993 * @param hspi : pointer to a SPI_HandleTypeDef structure that contains
1994 * the configuration information for SPI module.
1995 * @param pData: pointer to data buffer
1996 * @param Size : amount of data to be sent
1997 * @retval HAL status
1999 HAL_StatusTypeDef HAL_SPI_Reload_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
2001 /* check if there is already a request to reload */
2002 if ((hspi->Reload.Requested == 1UL) || (pData == NULL) || (Size == 0UL))
2004 return HAL_ERROR;
2007 if (hspi->State == HAL_SPI_STATE_BUSY_RX)
2009 /* Lock the process */
2010 __HAL_LOCK(hspi);
2012 /* Insert the new number of data that will be received just after the current one */
2013 MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSER, (Size & 0xFFFFFFFFUL) << 16UL);
2015 /* Set the transaction information */
2016 hspi->Reload.Requested = 1UL;
2017 hspi->Reload.pRxBuffPtr = (uint8_t *)pData;
2018 hspi->Reload.RxXferSize = Size;
2020 /* Unlock the process */
2021 __HAL_UNLOCK(hspi);
2023 return HAL_OK;
2025 else
2027 return HAL_ERROR;
2030 #endif /* USE_SPI_RELOAD_TRANSFER */
2032 #if defined(USE_SPI_RELOAD_TRANSFER)
2034 * @brief Transmit and receive an additional amount of data in blocking mode.
2035 * @param hspi : pointer to a SPI_HandleTypeDef structure that contains
2036 * the configuration information for SPI module.
2037 * @param pTxData: pointer to transmission data buffer
2038 * @param pRxData: pointer to reception data buffer
2039 * @param Size : amount of data to be sent and received
2040 * @retval HAL status
2042 HAL_StatusTypeDef HAL_SPI_Reload_TransmitReceive_IT(SPI_HandleTypeDef *hspi, const uint8_t *pTxData,
2043 uint8_t *pRxData, uint16_t Size)
2045 /* check if there is already a request to reload */
2046 if ((hspi->Reload.Requested == 1UL) || (pTxData == NULL) || (pRxData == NULL) || (Size == 0UL))
2048 return HAL_ERROR;
2051 if (hspi->State == HAL_SPI_STATE_BUSY_TX_RX)
2053 /* Lock the process */
2054 __HAL_LOCK(hspi);
2056 /* Insert the new number of data that will be sent and received just after the current one */
2057 MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSER, (Size & 0xFFFFFFFFUL) << 16UL);
2059 /* Set the transaction information */
2060 hspi->Reload.Requested = 1UL;
2061 hspi->Reload.pTxBuffPtr = (const uint8_t *)pTxData;
2062 hspi->Reload.TxXferSize = Size;
2063 hspi->Reload.pRxBuffPtr = (uint8_t *)pRxData;
2064 hspi->Reload.RxXferSize = Size;
2066 /* Unlock the process */
2067 __HAL_UNLOCK(hspi);
2069 return HAL_OK;
2071 else
2073 return HAL_ERROR;
2076 #endif /* USE_SPI_RELOAD_TRANSFER */
2079 * @brief Transmit an amount of data in non-blocking mode with DMA.
2080 * @param hspi : pointer to a SPI_HandleTypeDef structure that contains
2081 * the configuration information for SPI module.
2082 * @param pData: pointer to data buffer
2083 * @param Size : amount of data to be sent
2084 * @retval HAL status
2086 HAL_StatusTypeDef HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, const uint8_t *pData, uint16_t Size)
2089 /* Check Direction parameter */
2090 assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_TXONLY(hspi->Init.Direction));
2092 if (hspi->State != HAL_SPI_STATE_READY)
2094 return HAL_BUSY;
2097 if ((pData == NULL) || (Size == 0UL))
2099 return HAL_ERROR;
2102 /* Lock the process */
2103 __HAL_LOCK(hspi);
2105 /* Set the transaction information */
2106 hspi->State = HAL_SPI_STATE_BUSY_TX;
2107 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
2108 hspi->pTxBuffPtr = (const uint8_t *)pData;
2109 hspi->TxXferSize = Size;
2110 hspi->TxXferCount = Size;
2112 /* Init field not used in handle to zero */
2113 hspi->pRxBuffPtr = NULL;
2114 hspi->TxISR = NULL;
2115 hspi->RxISR = NULL;
2116 hspi->RxXferSize = (uint16_t)0UL;
2117 hspi->RxXferCount = (uint16_t)0UL;
2119 /* Configure communication direction : 1Line */
2120 if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
2122 SPI_1LINE_TX(hspi);
2124 else
2126 SPI_2LINES_TX(hspi);
2129 /* Packing mode management is enabled by the DMA settings */
2130 if (((hspi->Init.DataSize > SPI_DATASIZE_16BIT) && (hspi->hdmatx->Init.MemDataAlignment != DMA_MDATAALIGN_WORD)) || \
2131 ((hspi->Init.DataSize > SPI_DATASIZE_8BIT) && ((hspi->hdmatx->Init.MemDataAlignment != DMA_MDATAALIGN_HALFWORD) && \
2132 (hspi->hdmatx->Init.MemDataAlignment != DMA_MDATAALIGN_WORD))))
2134 /* Restriction the DMA data received is not allowed in this mode */
2135 __HAL_UNLOCK(hspi);
2136 return HAL_ERROR;
2139 /* Adjust XferCount according to DMA alignment / Data size */
2140 if (hspi->Init.DataSize <= SPI_DATASIZE_8BIT)
2142 if (hspi->hdmatx->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD)
2144 hspi->TxXferCount = (hspi->TxXferCount + (uint16_t) 1UL) >> 1UL;
2146 if (hspi->hdmatx->Init.MemDataAlignment == DMA_MDATAALIGN_WORD)
2148 hspi->TxXferCount = (hspi->TxXferCount + (uint16_t) 3UL) >> 2UL;
2151 else if (hspi->Init.DataSize <= SPI_DATASIZE_16BIT)
2153 if (hspi->hdmatx->Init.MemDataAlignment == DMA_MDATAALIGN_WORD)
2155 hspi->TxXferCount = (hspi->TxXferCount + (uint16_t) 1UL) >> 1UL;
2158 else
2160 /* Adjustment done */
2163 /* Set the SPI TxDMA Half transfer complete callback */
2164 hspi->hdmatx->XferHalfCpltCallback = SPI_DMAHalfTransmitCplt;
2166 /* Set the SPI TxDMA transfer complete callback */
2167 hspi->hdmatx->XferCpltCallback = SPI_DMATransmitCplt;
2169 /* Set the DMA error callback */
2170 hspi->hdmatx->XferErrorCallback = SPI_DMAError;
2172 /* Set the DMA AbortCpltCallback */
2173 hspi->hdmatx->XferAbortCallback = NULL;
2175 /* Clear TXDMAEN bit*/
2176 CLEAR_BIT(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN);
2178 /* Enable the Tx DMA Stream/Channel */
2179 if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->TXDR,
2180 hspi->TxXferCount))
2182 /* Update SPI error code */
2183 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
2184 hspi->State = HAL_SPI_STATE_READY;
2186 /* Unlock the process */
2187 __HAL_UNLOCK(hspi);
2189 return HAL_ERROR;
2192 /* Set the number of data at current transfer */
2193 if (hspi->hdmatx->Init.Mode == DMA_CIRCULAR)
2195 MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, 0UL);
2197 else
2199 MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size);
2202 /* Enable Tx DMA Request */
2203 SET_BIT(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN);
2205 /* Enable the SPI Error Interrupt Bit */
2206 __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_UDR | SPI_IT_FRE | SPI_IT_MODF));
2208 /* Enable SPI peripheral */
2209 __HAL_SPI_ENABLE(hspi);
2211 if (hspi->Init.Mode == SPI_MODE_MASTER)
2213 /* Master transfer start */
2214 SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART);
2217 /* Unlock the process */
2218 __HAL_UNLOCK(hspi);
2220 return HAL_OK;
2224 * @brief Receive an amount of data in non-blocking mode with DMA.
2225 * @param hspi : pointer to a SPI_HandleTypeDef structure that contains
2226 * the configuration information for SPI module.
2227 * @param pData: pointer to data buffer
2228 * @param Size : amount of data to be sent
2229 * @note When the CRC feature is enabled the pData Length must be Size + 1.
2230 * @retval HAL status
2232 HAL_StatusTypeDef HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
2235 /* Check Direction parameter */
2236 assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_RXONLY(hspi->Init.Direction));
2238 if (hspi->State != HAL_SPI_STATE_READY)
2240 __HAL_UNLOCK(hspi);
2241 return HAL_BUSY;
2244 if ((pData == NULL) || (Size == 0UL))
2246 __HAL_UNLOCK(hspi);
2247 return HAL_ERROR;
2250 /* Lock the process */
2251 __HAL_LOCK(hspi);
2253 /* Set the transaction information */
2254 hspi->State = HAL_SPI_STATE_BUSY_RX;
2255 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
2256 hspi->pRxBuffPtr = (uint8_t *)pData;
2257 hspi->RxXferSize = Size;
2258 hspi->RxXferCount = Size;
2260 /*Init field not used in handle to zero */
2261 hspi->RxISR = NULL;
2262 hspi->TxISR = NULL;
2263 hspi->TxXferSize = (uint16_t) 0UL;
2264 hspi->TxXferCount = (uint16_t) 0UL;
2266 /* Configure communication direction : 1Line */
2267 if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
2269 SPI_1LINE_RX(hspi);
2271 else
2273 SPI_2LINES_RX(hspi);
2276 /* Packing mode management is enabled by the DMA settings */
2277 if (((hspi->Init.DataSize > SPI_DATASIZE_16BIT) && (hspi->hdmarx->Init.MemDataAlignment != DMA_MDATAALIGN_WORD)) || \
2278 ((hspi->Init.DataSize > SPI_DATASIZE_8BIT) && ((hspi->hdmarx->Init.MemDataAlignment != DMA_MDATAALIGN_HALFWORD) && \
2279 (hspi->hdmarx->Init.MemDataAlignment != DMA_MDATAALIGN_WORD))))
2281 /* Restriction the DMA data received is not allowed in this mode */
2282 __HAL_UNLOCK(hspi);
2283 return HAL_ERROR;
2286 /* Clear RXDMAEN bit */
2287 CLEAR_BIT(hspi->Instance->CFG1, SPI_CFG1_RXDMAEN);
2289 /* Adjust XferCount according to DMA alignment / Data size */
2290 if (hspi->Init.DataSize <= SPI_DATASIZE_8BIT)
2292 if (hspi->hdmarx->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD)
2294 hspi->RxXferCount = (hspi->RxXferCount + (uint16_t) 1UL) >> 1UL;
2296 if (hspi->hdmarx->Init.MemDataAlignment == DMA_MDATAALIGN_WORD)
2298 hspi->RxXferCount = (hspi->RxXferCount + (uint16_t) 3UL) >> 2UL;
2301 else if (hspi->Init.DataSize <= SPI_DATASIZE_16BIT)
2303 if (hspi->hdmarx->Init.MemDataAlignment == DMA_MDATAALIGN_WORD)
2305 hspi->RxXferCount = (hspi->RxXferCount + (uint16_t) 1UL) >> 1UL;
2308 else
2310 /* Adjustment done */
2313 /* Set the SPI RxDMA Half transfer complete callback */
2314 hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfReceiveCplt;
2316 /* Set the SPI Rx DMA transfer complete callback */
2317 hspi->hdmarx->XferCpltCallback = SPI_DMAReceiveCplt;
2319 /* Set the DMA error callback */
2320 hspi->hdmarx->XferErrorCallback = SPI_DMAError;
2322 /* Set the DMA AbortCpltCallback */
2323 hspi->hdmarx->XferAbortCallback = NULL;
2325 /* Enable the Rx DMA Stream/Channel */
2326 if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->RXDR, (uint32_t)hspi->pRxBuffPtr,
2327 hspi->RxXferCount))
2329 /* Update SPI error code */
2330 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
2331 hspi->State = HAL_SPI_STATE_READY;
2333 /* Unlock the process */
2334 __HAL_UNLOCK(hspi);
2336 return HAL_ERROR;
2339 /* Set the number of data at current transfer */
2340 if (hspi->hdmarx->Init.Mode == DMA_CIRCULAR)
2342 MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, 0UL);
2344 else
2346 MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size);
2349 /* Enable Rx DMA Request */
2350 SET_BIT(hspi->Instance->CFG1, SPI_CFG1_RXDMAEN);
2352 /* Enable the SPI Error Interrupt Bit */
2353 __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_OVR | SPI_IT_FRE | SPI_IT_MODF));
2355 /* Enable SPI peripheral */
2356 __HAL_SPI_ENABLE(hspi);
2358 if (hspi->Init.Mode == SPI_MODE_MASTER)
2360 /* Master transfer start */
2361 SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART);
2364 /* Unlock the process */
2365 __HAL_UNLOCK(hspi);
2367 return HAL_OK;
2371 * @brief Transmit and Receive an amount of data in non-blocking mode with DMA.
2372 * @param hspi : pointer to a SPI_HandleTypeDef structure that contains
2373 * the configuration information for SPI module.
2374 * @param pTxData: pointer to transmission data buffer
2375 * @param pRxData: pointer to reception data buffer
2376 * @param Size : amount of data to be sent
2377 * @note When the CRC feature is enabled the pRxData Length must be Size + 1
2378 * @retval HAL status
2380 HAL_StatusTypeDef HAL_SPI_TransmitReceive_DMA(SPI_HandleTypeDef *hspi, const uint8_t *pTxData, uint8_t *pRxData,
2381 uint16_t Size)
2383 /* Check Direction parameter */
2384 assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));
2386 if (hspi->State != HAL_SPI_STATE_READY)
2388 return HAL_BUSY;
2391 if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0UL))
2393 return HAL_ERROR;
2396 /* Lock the process */
2397 __HAL_LOCK(hspi);
2399 /* Set the transaction information */
2400 hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
2401 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
2402 hspi->pTxBuffPtr = (const uint8_t *)pTxData;
2403 hspi->TxXferSize = Size;
2404 hspi->TxXferCount = Size;
2405 hspi->pRxBuffPtr = (uint8_t *)pRxData;
2406 hspi->RxXferSize = Size;
2407 hspi->RxXferCount = Size;
2409 /* Init field not used in handle to zero */
2410 hspi->RxISR = NULL;
2411 hspi->TxISR = NULL;
2413 /* Set Full-Duplex mode */
2414 SPI_2LINES(hspi);
2416 /* Reset the Tx/Rx DMA bits */
2417 CLEAR_BIT(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN | SPI_CFG1_RXDMAEN);
2419 /* Packing mode management is enabled by the DMA settings */
2420 if (((hspi->Init.DataSize > SPI_DATASIZE_16BIT) && \
2421 ((hspi->hdmarx->Init.MemDataAlignment != DMA_MDATAALIGN_WORD) || \
2422 (hspi->hdmatx->Init.MemDataAlignment != DMA_MDATAALIGN_WORD))) || \
2423 ((hspi->Init.DataSize > SPI_DATASIZE_8BIT) && \
2424 (((hspi->hdmarx->Init.MemDataAlignment != DMA_MDATAALIGN_HALFWORD) && \
2425 (hspi->hdmarx->Init.MemDataAlignment != DMA_MDATAALIGN_WORD)) || \
2426 ((hspi->hdmatx->Init.MemDataAlignment != DMA_MDATAALIGN_HALFWORD) && \
2427 (hspi->hdmatx->Init.MemDataAlignment != DMA_MDATAALIGN_WORD)))))
2429 /* Restriction the DMA data received is not allowed in this mode */
2430 /* Unlock the process */
2431 __HAL_UNLOCK(hspi);
2432 return HAL_ERROR;
2435 /* Adjust XferCount according to DMA alignment / Data size */
2436 if (hspi->Init.DataSize <= SPI_DATASIZE_8BIT)
2438 if (hspi->hdmatx->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD)
2440 hspi->TxXferCount = (hspi->TxXferCount + (uint16_t) 1UL) >> 1UL;
2442 if (hspi->hdmatx->Init.MemDataAlignment == DMA_MDATAALIGN_WORD)
2444 hspi->TxXferCount = (hspi->TxXferCount + (uint16_t) 3UL) >> 2UL;
2446 if (hspi->hdmarx->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD)
2448 hspi->RxXferCount = (hspi->RxXferCount + (uint16_t) 1UL) >> 1UL;
2450 if (hspi->hdmarx->Init.MemDataAlignment == DMA_MDATAALIGN_WORD)
2452 hspi->RxXferCount = (hspi->RxXferCount + (uint16_t) 3UL) >> 2UL;
2455 else if (hspi->Init.DataSize <= SPI_DATASIZE_16BIT)
2457 if (hspi->hdmatx->Init.MemDataAlignment == DMA_MDATAALIGN_WORD)
2459 hspi->TxXferCount = (hspi->TxXferCount + (uint16_t) 1UL) >> 1UL;
2461 if (hspi->hdmarx->Init.MemDataAlignment == DMA_MDATAALIGN_WORD)
2463 hspi->RxXferCount = (hspi->RxXferCount + (uint16_t) 1UL) >> 1UL;
2466 else
2468 /* Adjustment done */
2471 /* Set the SPI Tx/Rx DMA Half transfer complete callback */
2472 hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfTransmitReceiveCplt;
2473 hspi->hdmarx->XferCpltCallback = SPI_DMATransmitReceiveCplt;
2475 /* Set the DMA error callback */
2476 hspi->hdmarx->XferErrorCallback = SPI_DMAError;
2478 /* Set the DMA AbortCallback */
2479 hspi->hdmarx->XferAbortCallback = NULL;
2481 /* Enable the Rx DMA Stream/Channel */
2482 if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->RXDR, (uint32_t)hspi->pRxBuffPtr,
2483 hspi->RxXferCount))
2485 /* Update SPI error code */
2486 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
2487 hspi->State = HAL_SPI_STATE_READY;
2489 /* Unlock the process */
2490 __HAL_UNLOCK(hspi);
2492 return HAL_ERROR;
2495 /* Enable Rx DMA Request */
2496 SET_BIT(hspi->Instance->CFG1, SPI_CFG1_RXDMAEN);
2498 /* Set the SPI Tx DMA transfer complete callback as NULL because the communication closing
2499 is performed in DMA reception complete callback */
2500 hspi->hdmatx->XferHalfCpltCallback = NULL;
2501 hspi->hdmatx->XferCpltCallback = NULL;
2502 hspi->hdmatx->XferAbortCallback = NULL;
2504 /* Set the DMA error callback */
2505 hspi->hdmatx->XferErrorCallback = SPI_DMAError;
2507 /* Enable the Tx DMA Stream/Channel */
2508 if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->TXDR,
2509 hspi->TxXferCount))
2511 /* Abort Rx DMA Channel already started */
2512 (void)HAL_DMA_Abort(hspi->hdmarx);
2514 /* Update SPI error code */
2515 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
2516 hspi->State = HAL_SPI_STATE_READY;
2518 /* Unlock the process */
2519 __HAL_UNLOCK(hspi);
2521 return HAL_ERROR;
2524 if (hspi->hdmatx->Init.Mode == DMA_CIRCULAR)
2526 MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, 0UL);
2528 else
2530 MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size);
2533 /* Enable Tx DMA Request */
2534 SET_BIT(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN);
2536 /* Enable the SPI Error Interrupt Bit */
2537 __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_OVR | SPI_IT_UDR | SPI_IT_FRE | SPI_IT_MODF));
2539 /* Enable SPI peripheral */
2540 __HAL_SPI_ENABLE(hspi);
2542 if (hspi->Init.Mode == SPI_MODE_MASTER)
2544 /* Master transfer start */
2545 SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART);
2548 /* Unlock the process */
2549 __HAL_UNLOCK(hspi);
2551 return HAL_OK;
2555 * @brief Abort ongoing transfer (blocking mode).
2556 * @param hspi SPI handle.
2557 * @note This procedure could be used for aborting any ongoing transfer (Tx and Rx),
2558 * started in Interrupt or DMA mode.
2559 * @note This procedure performs following operations :
2560 * + Disable SPI Interrupts (depending of transfer direction)
2561 * + Disable the DMA transfer in the peripheral register (if enabled)
2562 * + Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
2563 * + Set handle State to READY.
2564 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
2565 * @retval HAL status
2567 HAL_StatusTypeDef HAL_SPI_Abort(SPI_HandleTypeDef *hspi)
2569 HAL_StatusTypeDef errorcode;
2571 __IO uint32_t count;
2573 /* Lock the process */
2574 __HAL_LOCK(hspi);
2576 /* Set hspi->state to aborting to avoid any interaction */
2577 hspi->State = HAL_SPI_STATE_ABORT;
2579 /* Initialized local variable */
2580 errorcode = HAL_OK;
2581 count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24UL / 1000UL);
2583 /* If master communication on going, make sure current frame is done before closing the connection */
2584 if (HAL_IS_BIT_SET(hspi->Instance->CR1, SPI_CR1_CSTART))
2586 /* Disable EOT interrupt */
2587 __HAL_SPI_DISABLE_IT(hspi, SPI_IT_EOT);
2590 count--;
2591 if (count == 0UL)
2593 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
2594 break;
2596 } while (HAL_IS_BIT_SET(hspi->Instance->IER, SPI_IT_EOT));
2598 /* Request a Suspend transfer */
2599 SET_BIT(hspi->Instance->CR1, SPI_CR1_CSUSP);
2602 count--;
2603 if (count == 0UL)
2605 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
2606 break;
2608 } while (HAL_IS_BIT_SET(hspi->Instance->CR1, SPI_CR1_CSTART));
2610 /* Clear SUSP flag */
2611 __HAL_SPI_CLEAR_SUSPFLAG(hspi);
2614 count--;
2615 if (count == 0UL)
2617 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
2618 break;
2620 } while (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_SUSP));
2623 /* Disable the SPI DMA Tx request if enabled */
2624 if (HAL_IS_BIT_SET(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN))
2626 if (hspi->hdmatx != NULL)
2628 /* Abort the SPI DMA Tx Stream/Channel : use blocking DMA Abort API (no callback) */
2629 hspi->hdmatx->XferAbortCallback = NULL;
2631 /* Abort DMA Tx Handle linked to SPI Peripheral */
2632 if (HAL_DMA_Abort(hspi->hdmatx) != HAL_OK)
2634 if (HAL_DMA_GetError(hspi->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
2636 hspi->ErrorCode = HAL_SPI_ERROR_ABORT;
2642 /* Disable the SPI DMA Rx request if enabled */
2643 if (HAL_IS_BIT_SET(hspi->Instance->CFG1, SPI_CFG1_RXDMAEN))
2645 if (hspi->hdmarx != NULL)
2647 /* Abort the SPI DMA Rx Stream/Channel : use blocking DMA Abort API (no callback) */
2648 hspi->hdmarx->XferAbortCallback = NULL;
2650 /* Abort DMA Rx Handle linked to SPI Peripheral */
2651 if (HAL_DMA_Abort(hspi->hdmarx) != HAL_OK)
2653 if (HAL_DMA_GetError(hspi->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
2655 hspi->ErrorCode = HAL_SPI_ERROR_ABORT;
2661 /* Proceed with abort procedure */
2662 SPI_AbortTransfer(hspi);
2664 /* Check error during Abort procedure */
2665 if (HAL_IS_BIT_SET(hspi->ErrorCode, HAL_SPI_ERROR_ABORT))
2667 /* return HAL_Error in case of error during Abort procedure */
2668 errorcode = HAL_ERROR;
2670 else
2672 /* Reset errorCode */
2673 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
2676 /* Restore hspi->state to ready */
2677 hspi->State = HAL_SPI_STATE_READY;
2679 /* Unlock the process */
2680 __HAL_UNLOCK(hspi);
2682 return errorcode;
2686 * @brief Abort ongoing transfer (Interrupt mode).
2687 * @param hspi SPI handle.
2688 * @note This procedure could be used for aborting any ongoing transfer (Tx and Rx),
2689 * started in Interrupt or DMA mode.
2690 * @note This procedure performs following operations :
2691 * + Disable SPI Interrupts (depending of transfer direction)
2692 * + Disable the DMA transfer in the peripheral register (if enabled)
2693 * + Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
2694 * + Set handle State to READY
2695 * + At abort completion, call user abort complete callback.
2696 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
2697 * considered as completed only when user abort complete callback is executed (not when exiting function).
2698 * @retval HAL status
2700 HAL_StatusTypeDef HAL_SPI_Abort_IT(SPI_HandleTypeDef *hspi)
2702 HAL_StatusTypeDef errorcode;
2703 __IO uint32_t count;
2704 uint32_t dma_tx_abort_done = 1UL;
2705 uint32_t dma_rx_abort_done = 1UL;
2707 /* Set hspi->state to aborting to avoid any interaction */
2708 hspi->State = HAL_SPI_STATE_ABORT;
2710 /* Initialized local variable */
2711 errorcode = HAL_OK;
2712 count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24UL / 1000UL);
2714 /* If master communication on going, make sure current frame is done before closing the connection */
2715 if (HAL_IS_BIT_SET(hspi->Instance->CR1, SPI_CR1_CSTART))
2717 /* Disable EOT interrupt */
2718 __HAL_SPI_DISABLE_IT(hspi, SPI_IT_EOT);
2721 count--;
2722 if (count == 0UL)
2724 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
2725 break;
2727 } while (HAL_IS_BIT_SET(hspi->Instance->IER, SPI_IT_EOT));
2729 /* Request a Suspend transfer */
2730 SET_BIT(hspi->Instance->CR1, SPI_CR1_CSUSP);
2733 count--;
2734 if (count == 0UL)
2736 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
2737 break;
2739 } while (HAL_IS_BIT_SET(hspi->Instance->CR1, SPI_CR1_CSTART));
2741 /* Clear SUSP flag */
2742 __HAL_SPI_CLEAR_SUSPFLAG(hspi);
2745 count--;
2746 if (count == 0UL)
2748 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
2749 break;
2751 } while (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_SUSP));
2754 /* If DMA Tx and/or DMA Rx Handles are associated to SPI Handle, DMA Abort complete callbacks should be initialized
2755 before any call to DMA Abort functions */
2757 if (hspi->hdmatx != NULL)
2759 if (HAL_IS_BIT_SET(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN))
2761 /* Set DMA Abort Complete callback if SPI DMA Tx request if enabled */
2762 hspi->hdmatx->XferAbortCallback = SPI_DMATxAbortCallback;
2764 dma_tx_abort_done = 0UL;
2766 /* Abort DMA Tx Handle linked to SPI Peripheral */
2767 if (HAL_DMA_Abort_IT(hspi->hdmatx) != HAL_OK)
2769 if (HAL_DMA_GetError(hspi->hdmatx) == HAL_DMA_ERROR_NO_XFER)
2771 dma_tx_abort_done = 1UL;
2772 hspi->hdmatx->XferAbortCallback = NULL;
2776 else
2778 hspi->hdmatx->XferAbortCallback = NULL;
2782 if (hspi->hdmarx != NULL)
2784 if (HAL_IS_BIT_SET(hspi->Instance->CFG1, SPI_CFG1_RXDMAEN))
2786 /* Set DMA Abort Complete callback if SPI DMA Rx request if enabled */
2787 hspi->hdmarx->XferAbortCallback = SPI_DMARxAbortCallback;
2789 dma_rx_abort_done = 0UL;
2791 /* Abort DMA Rx Handle linked to SPI Peripheral */
2792 if (HAL_DMA_Abort_IT(hspi->hdmarx) != HAL_OK)
2794 if (HAL_DMA_GetError(hspi->hdmarx) == HAL_DMA_ERROR_NO_XFER)
2796 dma_rx_abort_done = 1UL;
2797 hspi->hdmarx->XferAbortCallback = NULL;
2801 else
2803 hspi->hdmarx->XferAbortCallback = NULL;
2807 /* If no running DMA transfer, finish cleanup and call callbacks */
2808 if ((dma_tx_abort_done == 1UL) && (dma_rx_abort_done == 1UL))
2810 /* Proceed with abort procedure */
2811 SPI_AbortTransfer(hspi);
2813 /* Check error during Abort procedure */
2814 if (HAL_IS_BIT_SET(hspi->ErrorCode, HAL_SPI_ERROR_ABORT))
2816 /* return HAL_Error in case of error during Abort procedure */
2817 errorcode = HAL_ERROR;
2819 else
2821 /* Reset errorCode */
2822 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
2825 /* Restore hspi->state to ready */
2826 hspi->State = HAL_SPI_STATE_READY;
2828 /* Call user Abort complete callback */
2829 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
2830 hspi->AbortCpltCallback(hspi);
2831 #else
2832 HAL_SPI_AbortCpltCallback(hspi);
2833 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
2836 return errorcode;
2840 * @brief Pause the DMA Transfer.
2841 * This API is not supported, it is maintained for backward compatibility.
2842 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
2843 * the configuration information for the specified SPI module.
2844 * @retval HAL_ERROR
2846 HAL_StatusTypeDef HAL_SPI_DMAPause(SPI_HandleTypeDef *hspi)
2848 /* Set error code to not supported */
2849 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_NOT_SUPPORTED);
2851 return HAL_ERROR;
2855 * @brief Resume the DMA Transfer.
2856 * This API is not supported, it is maintained for backward compatibility.
2857 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
2858 * the configuration information for the specified SPI module.
2859 * @retval HAL_ERROR
2861 HAL_StatusTypeDef HAL_SPI_DMAResume(SPI_HandleTypeDef *hspi)
2863 /* Set error code to not supported */
2864 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_NOT_SUPPORTED);
2866 return HAL_ERROR;
2870 * @brief Stop the DMA Transfer.
2871 * This API is not supported, it is maintained for backward compatibility.
2872 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
2873 * the configuration information for the specified SPI module.
2874 * @retval HAL_ERROR
2876 HAL_StatusTypeDef HAL_SPI_DMAStop(SPI_HandleTypeDef *hspi)
2878 /* Set error code to not supported */
2879 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_NOT_SUPPORTED);
2881 return HAL_ERROR;
2885 * @brief Handle SPI interrupt request.
2886 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
2887 * the configuration information for the specified SPI module.
2888 * @retval None
2890 void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi)
2892 uint32_t itsource = hspi->Instance->IER;
2893 uint32_t itflag = hspi->Instance->SR;
2894 uint32_t trigger = itsource & itflag;
2895 uint32_t cfg1 = hspi->Instance->CFG1;
2896 uint32_t handled = 0UL;
2898 HAL_SPI_StateTypeDef State = hspi->State;
2899 #if defined (__GNUC__)
2900 __IO uint16_t *prxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->RXDR));
2901 #endif /* __GNUC__ */
2903 /* SPI in SUSPEND mode ----------------------------------------------------*/
2904 if (HAL_IS_BIT_SET(itflag, SPI_FLAG_SUSP) && HAL_IS_BIT_SET(itsource, SPI_FLAG_EOT))
2906 /* Clear the Suspend flag */
2907 __HAL_SPI_CLEAR_SUSPFLAG(hspi);
2909 /* Suspend on going, Call the Suspend callback */
2910 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
2911 hspi->SuspendCallback(hspi);
2912 #else
2913 HAL_SPI_SuspendCallback(hspi);
2914 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
2915 return;
2918 /* SPI in mode Transmitter and Receiver ------------------------------------*/
2919 if (HAL_IS_BIT_CLR(trigger, SPI_FLAG_OVR) && HAL_IS_BIT_CLR(trigger, SPI_FLAG_UDR) && \
2920 HAL_IS_BIT_SET(trigger, SPI_FLAG_DXP))
2922 hspi->TxISR(hspi);
2923 hspi->RxISR(hspi);
2924 handled = 1UL;
2927 /* SPI in mode Receiver ----------------------------------------------------*/
2928 if (HAL_IS_BIT_CLR(trigger, SPI_FLAG_OVR) && HAL_IS_BIT_SET(trigger, SPI_FLAG_RXP) && \
2929 HAL_IS_BIT_CLR(trigger, SPI_FLAG_DXP))
2931 hspi->RxISR(hspi);
2932 handled = 1UL;
2935 /* SPI in mode Transmitter -------------------------------------------------*/
2936 if (HAL_IS_BIT_CLR(trigger, SPI_FLAG_UDR) && HAL_IS_BIT_SET(trigger, SPI_FLAG_TXP) && \
2937 HAL_IS_BIT_CLR(trigger, SPI_FLAG_DXP))
2939 hspi->TxISR(hspi);
2940 handled = 1UL;
2943 #if defined(USE_SPI_RELOAD_TRANSFER)
2944 /* SPI Reload -------------------------------------------------*/
2945 if (HAL_IS_BIT_SET(trigger, SPI_FLAG_TSERF))
2947 __HAL_SPI_CLEAR_TSERFFLAG(hspi);
2949 #endif /* USE_SPI_RELOAD_TRANSFER */
2951 if (handled != 0UL)
2953 return;
2956 /* SPI End Of Transfer: DMA or IT based transfer */
2957 if (HAL_IS_BIT_SET(trigger, SPI_FLAG_EOT))
2959 /* Clear EOT/TXTF/SUSP flag */
2960 __HAL_SPI_CLEAR_EOTFLAG(hspi);
2961 __HAL_SPI_CLEAR_TXTFFLAG(hspi);
2962 __HAL_SPI_CLEAR_SUSPFLAG(hspi);
2964 /* Disable EOT interrupt */
2965 __HAL_SPI_DISABLE_IT(hspi, SPI_IT_EOT);
2967 /* For the IT based receive extra polling maybe required for last packet */
2968 if (HAL_IS_BIT_CLR(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN | SPI_CFG1_RXDMAEN))
2970 /* Pooling remaining data */
2971 while (hspi->RxXferCount != 0UL)
2973 /* Receive data in 32 Bit mode */
2974 if (hspi->Init.DataSize > SPI_DATASIZE_16BIT)
2976 *((uint32_t *)hspi->pRxBuffPtr) = *((__IO uint32_t *)&hspi->Instance->RXDR);
2977 hspi->pRxBuffPtr += sizeof(uint32_t);
2979 /* Receive data in 16 Bit mode */
2980 else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
2982 #if defined (__GNUC__)
2983 *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits;
2984 #else
2985 *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
2986 #endif /* __GNUC__ */
2987 hspi->pRxBuffPtr += sizeof(uint16_t);
2989 /* Receive data in 8 Bit mode */
2990 else
2992 *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
2993 hspi->pRxBuffPtr += sizeof(uint8_t);
2996 hspi->RxXferCount--;
3000 /* Call SPI Standard close procedure */
3001 SPI_CloseTransfer(hspi);
3003 hspi->State = HAL_SPI_STATE_READY;
3004 if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
3006 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
3007 hspi->ErrorCallback(hspi);
3008 #else
3009 HAL_SPI_ErrorCallback(hspi);
3010 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
3011 return;
3014 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
3015 /* Call appropriate user callback */
3016 if (State == HAL_SPI_STATE_BUSY_TX_RX)
3018 hspi->TxRxCpltCallback(hspi);
3020 else if (State == HAL_SPI_STATE_BUSY_RX)
3022 hspi->RxCpltCallback(hspi);
3024 else if (State == HAL_SPI_STATE_BUSY_TX)
3026 hspi->TxCpltCallback(hspi);
3028 #else
3029 /* Call appropriate user callback */
3030 if (State == HAL_SPI_STATE_BUSY_TX_RX)
3032 HAL_SPI_TxRxCpltCallback(hspi);
3034 else if (State == HAL_SPI_STATE_BUSY_RX)
3036 HAL_SPI_RxCpltCallback(hspi);
3038 else if (State == HAL_SPI_STATE_BUSY_TX)
3040 HAL_SPI_TxCpltCallback(hspi);
3042 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
3043 else
3045 /* End of the appropriate call */
3048 return;
3051 /* SPI in Error Treatment --------------------------------------------------*/
3052 if ((trigger & (SPI_FLAG_MODF | SPI_FLAG_OVR | SPI_FLAG_FRE | SPI_FLAG_UDR)) != 0UL)
3054 /* SPI Overrun error interrupt occurred ----------------------------------*/
3055 if ((trigger & SPI_FLAG_OVR) != 0UL)
3057 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_OVR);
3058 __HAL_SPI_CLEAR_OVRFLAG(hspi);
3061 /* SPI Mode Fault error interrupt occurred -------------------------------*/
3062 if ((trigger & SPI_FLAG_MODF) != 0UL)
3064 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_MODF);
3065 __HAL_SPI_CLEAR_MODFFLAG(hspi);
3068 /* SPI Frame error interrupt occurred ------------------------------------*/
3069 if ((trigger & SPI_FLAG_FRE) != 0UL)
3071 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FRE);
3072 __HAL_SPI_CLEAR_FREFLAG(hspi);
3075 /* SPI Underrun error interrupt occurred ------------------------------------*/
3076 if ((trigger & SPI_FLAG_UDR) != 0UL)
3078 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_UDR);
3079 __HAL_SPI_CLEAR_UDRFLAG(hspi);
3082 if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
3084 /* Disable SPI peripheral */
3085 __HAL_SPI_DISABLE(hspi);
3087 /* Disable all interrupts */
3088 __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_EOT | SPI_IT_RXP | SPI_IT_TXP | SPI_IT_MODF |
3089 SPI_IT_OVR | SPI_IT_FRE | SPI_IT_UDR));
3091 /* Disable the SPI DMA requests if enabled */
3092 if (HAL_IS_BIT_SET(cfg1, SPI_CFG1_TXDMAEN | SPI_CFG1_RXDMAEN))
3094 /* Disable the SPI DMA requests */
3095 CLEAR_BIT(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN | SPI_CFG1_RXDMAEN);
3097 /* Abort the SPI DMA Rx channel */
3098 if (hspi->hdmarx != NULL)
3100 /* Set the SPI DMA Abort callback :
3101 will lead to call HAL_SPI_ErrorCallback() at end of DMA abort procedure */
3102 hspi->hdmarx->XferAbortCallback = SPI_DMAAbortOnError;
3103 if (HAL_OK != HAL_DMA_Abort_IT(hspi->hdmarx))
3105 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
3108 /* Abort the SPI DMA Tx channel */
3109 if (hspi->hdmatx != NULL)
3111 /* Set the SPI DMA Abort callback :
3112 will lead to call HAL_SPI_ErrorCallback() at end of DMA abort procedure */
3113 hspi->hdmatx->XferAbortCallback = SPI_DMAAbortOnError;
3114 if (HAL_OK != HAL_DMA_Abort_IT(hspi->hdmatx))
3116 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
3120 else
3122 /* Restore hspi->State to Ready */
3123 hspi->State = HAL_SPI_STATE_READY;
3125 /* Call user error callback */
3126 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
3127 hspi->ErrorCallback(hspi);
3128 #else
3129 HAL_SPI_ErrorCallback(hspi);
3130 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
3133 return;
3138 * @brief Tx Transfer completed callback.
3139 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3140 * the configuration information for SPI module.
3141 * @retval None
3143 __weak void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */
3145 /* Prevent unused argument(s) compilation warning */
3146 UNUSED(hspi);
3148 /* NOTE : This function should not be modified, when the callback is needed,
3149 the HAL_SPI_TxCpltCallback should be implemented in the user file
3154 * @brief Rx Transfer completed callback.
3155 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3156 * the configuration information for SPI module.
3157 * @retval None
3159 __weak void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */
3161 /* Prevent unused argument(s) compilation warning */
3162 UNUSED(hspi);
3164 /* NOTE : This function should not be modified, when the callback is needed,
3165 the HAL_SPI_RxCpltCallback should be implemented in the user file
3170 * @brief Tx and Rx Transfer completed callback.
3171 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3172 * the configuration information for SPI module.
3173 * @retval None
3175 __weak void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */
3177 /* Prevent unused argument(s) compilation warning */
3178 UNUSED(hspi);
3180 /* NOTE : This function should not be modified, when the callback is needed,
3181 the HAL_SPI_TxRxCpltCallback should be implemented in the user file
3186 * @brief Tx Half Transfer completed callback.
3187 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3188 * the configuration information for SPI module.
3189 * @retval None
3191 __weak void HAL_SPI_TxHalfCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */
3193 /* Prevent unused argument(s) compilation warning */
3194 UNUSED(hspi);
3196 /* NOTE : This function should not be modified, when the callback is needed,
3197 the HAL_SPI_TxHalfCpltCallback should be implemented in the user file
3202 * @brief Rx Half Transfer completed callback.
3203 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3204 * the configuration information for SPI module.
3205 * @retval None
3207 __weak void HAL_SPI_RxHalfCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */
3209 /* Prevent unused argument(s) compilation warning */
3210 UNUSED(hspi);
3212 /* NOTE : This function should not be modified, when the callback is needed,
3213 the HAL_SPI_RxHalfCpltCallback() should be implemented in the user file
3218 * @brief Tx and Rx Half Transfer callback.
3219 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3220 * the configuration information for SPI module.
3221 * @retval None
3223 __weak void HAL_SPI_TxRxHalfCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */
3225 /* Prevent unused argument(s) compilation warning */
3226 UNUSED(hspi);
3228 /* NOTE : This function should not be modified, when the callback is needed,
3229 the HAL_SPI_TxRxHalfCpltCallback() should be implemented in the user file
3234 * @brief SPI error callback.
3235 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3236 * the configuration information for SPI module.
3237 * @retval None
3239 __weak void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */
3241 /* Prevent unused argument(s) compilation warning */
3242 UNUSED(hspi);
3244 /* NOTE : This function should not be modified, when the callback is needed,
3245 the HAL_SPI_ErrorCallback should be implemented in the user file
3247 /* NOTE : The ErrorCode parameter in the hspi handle is updated by the SPI processes
3248 and user can use HAL_SPI_GetError() API to check the latest error occurred
3253 * @brief SPI Abort Complete callback.
3254 * @param hspi SPI handle.
3255 * @retval None
3257 __weak void HAL_SPI_AbortCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */
3259 /* Prevent unused argument(s) compilation warning */
3260 UNUSED(hspi);
3262 /* NOTE : This function should not be modified, when the callback is needed,
3263 the HAL_SPI_AbortCpltCallback can be implemented in the user file.
3268 * @brief SPI Suspend callback.
3269 * @param hspi SPI handle.
3270 * @retval None
3272 __weak void HAL_SPI_SuspendCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */
3274 /* Prevent unused argument(s) compilation warning */
3275 UNUSED(hspi);
3277 /* NOTE : This function should not be modified, when the callback is needed,
3278 the HAL_SPI_SuspendCallback can be implemented in the user file.
3283 * @}
3286 /** @defgroup SPI_Exported_Functions_Group3 Peripheral State and Errors functions
3287 * @brief SPI control functions
3289 @verbatim
3290 ===============================================================================
3291 ##### Peripheral State and Errors functions #####
3292 ===============================================================================
3293 [..]
3294 This subsection provides a set of functions allowing to control the SPI.
3295 (+) HAL_SPI_GetState() API can be helpful to check in run-time the state of the SPI peripheral
3296 (+) HAL_SPI_GetError() check in run-time Errors occurring during communication
3297 @endverbatim
3298 * @{
3302 * @brief Return the SPI handle state.
3303 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3304 * the configuration information for SPI module.
3305 * @retval SPI state
3307 HAL_SPI_StateTypeDef HAL_SPI_GetState(const SPI_HandleTypeDef *hspi)
3309 /* Return SPI handle state */
3310 return hspi->State;
3314 * @brief Return the SPI error code.
3315 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3316 * the configuration information for SPI module.
3317 * @retval SPI error code in bitmap format
3319 uint32_t HAL_SPI_GetError(const SPI_HandleTypeDef *hspi)
3321 /* Return SPI ErrorCode */
3322 return hspi->ErrorCode;
3326 * @}
3330 * @}
3333 /** @addtogroup SPI_Private_Functions
3334 * @brief Private functions
3335 * @{
3339 * @brief DMA SPI transmit process complete callback.
3340 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
3341 * the configuration information for the specified DMA module.
3342 * @retval None
3344 static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma)
3346 SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
3348 if (hspi->State != HAL_SPI_STATE_ABORT)
3350 if (hspi->hdmatx->Init.Mode == DMA_CIRCULAR)
3352 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
3353 hspi->TxCpltCallback(hspi);
3354 #else
3355 HAL_SPI_TxCpltCallback(hspi);
3356 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
3358 else
3360 /* Enable EOT interrupt */
3361 __HAL_SPI_ENABLE_IT(hspi, SPI_IT_EOT);
3367 * @brief DMA SPI receive process complete callback.
3368 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
3369 * the configuration information for the specified DMA module.
3370 * @retval None
3372 static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
3374 SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
3376 if (hspi->State != HAL_SPI_STATE_ABORT)
3378 if (hspi->hdmarx->Init.Mode == DMA_CIRCULAR)
3380 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
3381 hspi->RxCpltCallback(hspi);
3382 #else
3383 HAL_SPI_RxCpltCallback(hspi);
3384 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
3386 else
3388 /* Enable EOT interrupt */
3389 __HAL_SPI_ENABLE_IT(hspi, SPI_IT_EOT);
3395 * @brief DMA SPI transmit receive process complete callback.
3396 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
3397 * the configuration information for the specified DMA module.
3398 * @retval None
3400 static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma)
3402 SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
3404 if (hspi->State != HAL_SPI_STATE_ABORT)
3406 if (hspi->hdmatx->Init.Mode == DMA_CIRCULAR)
3408 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
3409 hspi->TxRxCpltCallback(hspi);
3410 #else
3411 HAL_SPI_TxRxCpltCallback(hspi);
3412 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
3414 else
3416 /* Enable EOT interrupt */
3417 __HAL_SPI_ENABLE_IT(hspi, SPI_IT_EOT);
3423 * @brief DMA SPI half transmit process complete callback.
3424 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
3425 * the configuration information for the specified DMA module.
3426 * @retval None
3428 static void SPI_DMAHalfTransmitCplt(DMA_HandleTypeDef *hdma) /* Derogation MISRAC2012-Rule-8.13 */
3430 SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)
3431 ((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-8.13 */
3433 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
3434 hspi->TxHalfCpltCallback(hspi);
3435 #else
3436 HAL_SPI_TxHalfCpltCallback(hspi);
3437 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
3441 * @brief DMA SPI half receive process complete callback
3442 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
3443 * the configuration information for the specified DMA module.
3444 * @retval None
3446 static void SPI_DMAHalfReceiveCplt(DMA_HandleTypeDef *hdma) /* Derogation MISRAC2012-Rule-8.13 */
3448 SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)
3449 ((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-8.13 */
3451 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
3452 hspi->RxHalfCpltCallback(hspi);
3453 #else
3454 HAL_SPI_RxHalfCpltCallback(hspi);
3455 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
3459 * @brief DMA SPI half transmit receive 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
3464 static void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma) /* Derogation MISRAC2012-Rule-8.13 */
3466 SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)
3467 ((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-8.13 */
3469 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
3470 hspi->TxRxHalfCpltCallback(hspi);
3471 #else
3472 HAL_SPI_TxRxHalfCpltCallback(hspi);
3473 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
3477 * @brief DMA SPI communication error callback.
3478 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
3479 * the configuration information for the specified DMA module.
3480 * @retval None
3482 static void SPI_DMAError(DMA_HandleTypeDef *hdma)
3484 SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
3486 /* if DMA error is FIFO error ignore it */
3487 if (HAL_DMA_GetError(hdma) != HAL_DMA_ERROR_FE)
3489 /* Call SPI standard close procedure */
3490 SPI_CloseTransfer(hspi);
3492 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
3493 hspi->State = HAL_SPI_STATE_READY;
3494 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
3495 hspi->ErrorCallback(hspi);
3496 #else
3497 HAL_SPI_ErrorCallback(hspi);
3498 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
3503 * @brief DMA SPI communication abort callback, when initiated by HAL services on Error
3504 * (To be called at end of DMA Abort procedure following error occurrence).
3505 * @param hdma DMA handle.
3506 * @retval None
3508 static void SPI_DMAAbortOnError(DMA_HandleTypeDef *hdma)
3510 SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
3511 hspi->RxXferCount = (uint16_t) 0UL;
3512 hspi->TxXferCount = (uint16_t) 0UL;
3514 /* Restore hspi->State to Ready */
3515 hspi->State = HAL_SPI_STATE_READY;
3517 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
3518 hspi->ErrorCallback(hspi);
3519 #else
3520 HAL_SPI_ErrorCallback(hspi);
3521 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
3525 * @brief DMA SPI Tx communication abort callback, when initiated by user
3526 * (To be called at end of DMA Tx Abort procedure following user abort request).
3527 * @note When this callback is executed, User Abort complete call back is called only if no
3528 * Abort still ongoing for Rx DMA Handle.
3529 * @param hdma DMA handle.
3530 * @retval None
3532 static void SPI_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
3534 SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
3536 hspi->hdmatx->XferAbortCallback = NULL;
3538 /* Check if an Abort process is still ongoing */
3539 if (hspi->hdmarx != NULL)
3541 if (hspi->hdmarx->XferAbortCallback != NULL)
3543 return;
3547 /* Call the Abort procedure */
3548 SPI_AbortTransfer(hspi);
3550 /* Restore hspi->State to Ready */
3551 hspi->State = HAL_SPI_STATE_READY;
3553 /* Call user Abort complete callback */
3554 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
3555 hspi->AbortCpltCallback(hspi);
3556 #else
3557 HAL_SPI_AbortCpltCallback(hspi);
3558 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
3562 * @brief DMA SPI Rx communication abort callback, when initiated by user
3563 * (To be called at end of DMA Rx Abort procedure following user abort request).
3564 * @note When this callback is executed, User Abort complete call back is called only if no
3565 * Abort still ongoing for Tx DMA Handle.
3566 * @param hdma DMA handle.
3567 * @retval None
3569 static void SPI_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
3571 SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
3573 hspi->hdmarx->XferAbortCallback = NULL;
3575 /* Check if an Abort process is still ongoing */
3576 if (hspi->hdmatx != NULL)
3578 if (hspi->hdmatx->XferAbortCallback != NULL)
3580 return;
3584 /* Call the Abort procedure */
3585 SPI_AbortTransfer(hspi);
3587 /* Restore hspi->State to Ready */
3588 hspi->State = HAL_SPI_STATE_READY;
3590 /* Call user Abort complete callback */
3591 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
3592 hspi->AbortCpltCallback(hspi);
3593 #else
3594 HAL_SPI_AbortCpltCallback(hspi);
3595 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
3599 * @brief Manage the receive 8-bit in Interrupt context.
3600 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3601 * the configuration information for SPI module.
3602 * @retval None
3604 static void SPI_RxISR_8BIT(SPI_HandleTypeDef *hspi)
3606 /* Receive data in 8 Bit mode */
3607 *((uint8_t *)hspi->pRxBuffPtr) = (*(__IO uint8_t *)&hspi->Instance->RXDR);
3608 hspi->pRxBuffPtr += sizeof(uint8_t);
3609 hspi->RxXferCount--;
3611 /* Disable IT if no more data excepted */
3612 if (hspi->RxXferCount == 0UL)
3614 #if defined(USE_SPI_RELOAD_TRANSFER)
3615 /* Check if there is any request to reload */
3616 if (hspi->Reload.Requested == 1UL)
3618 hspi->RxXferSize = hspi->Reload.RxXferSize;
3619 hspi->RxXferCount = hspi->Reload.RxXferSize;
3620 hspi->pRxBuffPtr = hspi->Reload.pRxBuffPtr;
3621 hspi->Reload.Requested = 0UL;
3623 else
3625 /* Disable RXP interrupts */
3626 __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXP);
3628 #else
3629 /* Disable RXP interrupts */
3630 __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXP);
3631 #endif /* USE_SPI_RELOAD_TRANSFER */
3637 * @brief Manage the 16-bit receive in Interrupt context.
3638 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3639 * the configuration information for SPI module.
3640 * @retval None
3642 static void SPI_RxISR_16BIT(SPI_HandleTypeDef *hspi)
3644 /* Receive data in 16 Bit mode */
3645 #if defined (__GNUC__)
3646 __IO uint16_t *prxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->RXDR));
3648 *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits;
3649 #else
3650 *((uint16_t *)hspi->pRxBuffPtr) = (*(__IO uint16_t *)&hspi->Instance->RXDR);
3651 #endif /* __GNUC__ */
3652 hspi->pRxBuffPtr += sizeof(uint16_t);
3653 hspi->RxXferCount--;
3655 /* Disable IT if no more data excepted */
3656 if (hspi->RxXferCount == 0UL)
3658 #if defined(USE_SPI_RELOAD_TRANSFER)
3659 /* Check if there is any request to reload */
3660 if (hspi->Reload.Requested == 1UL)
3662 hspi->RxXferSize = hspi->Reload.RxXferSize;
3663 hspi->RxXferCount = hspi->Reload.RxXferSize;
3664 hspi->pRxBuffPtr = hspi->Reload.pRxBuffPtr;
3665 hspi->Reload.Requested = 0UL;
3667 else
3669 /* Disable RXP interrupts */
3670 __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXP);
3672 #else
3673 /* Disable RXP interrupts */
3674 __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXP);
3675 #endif /* USE_SPI_RELOAD_TRANSFER */
3681 * @brief Manage the 32-bit receive in Interrupt context.
3682 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3683 * the configuration information for SPI module.
3684 * @retval None
3686 static void SPI_RxISR_32BIT(SPI_HandleTypeDef *hspi)
3688 /* Receive data in 32 Bit mode */
3689 *((uint32_t *)hspi->pRxBuffPtr) = (*(__IO uint32_t *)&hspi->Instance->RXDR);
3690 hspi->pRxBuffPtr += sizeof(uint32_t);
3691 hspi->RxXferCount--;
3693 /* Disable IT if no more data excepted */
3694 if (hspi->RxXferCount == 0UL)
3696 #if defined(USE_SPI_RELOAD_TRANSFER)
3697 /* Check if there is any request to reload */
3698 if (hspi->Reload.Requested == 1UL)
3700 hspi->RxXferSize = hspi->Reload.RxXferSize;
3701 hspi->RxXferCount = hspi->Reload.RxXferSize;
3702 hspi->pRxBuffPtr = hspi->Reload.pRxBuffPtr;
3703 hspi->Reload.Requested = 0UL;
3705 else
3707 /* Disable RXP interrupts */
3708 __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXP);
3710 #else
3711 /* Disable RXP interrupts */
3712 __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXP);
3713 #endif /* USE_SPI_RELOAD_TRANSFER */
3719 * @brief Handle the data 8-bit transmit in Interrupt mode.
3720 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3721 * the configuration information for SPI module.
3722 * @retval None
3724 static void SPI_TxISR_8BIT(SPI_HandleTypeDef *hspi)
3726 /* Transmit data in 8 Bit mode */
3727 *(__IO uint8_t *)&hspi->Instance->TXDR = *((const uint8_t *)hspi->pTxBuffPtr);
3728 hspi->pTxBuffPtr += sizeof(uint8_t);
3729 hspi->TxXferCount--;
3731 /* Disable IT if no more data excepted */
3732 if (hspi->TxXferCount == 0UL)
3734 #if defined(USE_SPI_RELOAD_TRANSFER)
3735 /* Check if there is any request to reload */
3736 if (hspi->Reload.Requested == 1UL)
3738 hspi->TxXferSize = hspi->Reload.TxXferSize;
3739 hspi->TxXferCount = hspi->Reload.TxXferSize;
3740 hspi->pTxBuffPtr = hspi->Reload.pTxBuffPtr;
3742 /* In full duplex mode the reload request is reset in RX side */
3743 if (hspi->State == HAL_SPI_STATE_BUSY_TX)
3745 hspi->Reload.Requested = 0UL;
3748 else
3750 /* Disable TXP interrupts */
3751 __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXP);
3753 #else
3754 /* Disable TXP interrupts */
3755 __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXP);
3756 #endif /* USE_SPI_RELOAD_TRANSFER */
3761 * @brief Handle the data 16-bit transmit in Interrupt mode.
3762 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3763 * the configuration information for SPI module.
3764 * @retval None
3766 static void SPI_TxISR_16BIT(SPI_HandleTypeDef *hspi)
3768 /* Transmit data in 16 Bit mode */
3769 #if defined (__GNUC__)
3770 __IO uint16_t *ptxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->TXDR));
3772 *ptxdr_16bits = *((const uint16_t *)hspi->pTxBuffPtr);
3773 #else
3774 *((__IO uint16_t *)&hspi->Instance->TXDR) = *((const uint16_t *)hspi->pTxBuffPtr);
3775 #endif /* __GNUC__ */
3776 hspi->pTxBuffPtr += sizeof(uint16_t);
3777 hspi->TxXferCount--;
3779 /* Disable IT if no more data excepted */
3780 if (hspi->TxXferCount == 0UL)
3782 #if defined(USE_SPI_RELOAD_TRANSFER)
3783 /* Check if there is any request to reload */
3784 if (hspi->Reload.Requested == 1UL)
3786 hspi->TxXferSize = hspi->Reload.TxXferSize;
3787 hspi->TxXferCount = hspi->Reload.TxXferSize;
3788 hspi->pTxBuffPtr = hspi->Reload.pTxBuffPtr;
3790 /* In full duplex mode the reload request is reset in RX side */
3791 if (hspi->State == HAL_SPI_STATE_BUSY_TX)
3793 hspi->Reload.Requested = 0UL;
3796 else
3798 /* Disable TXP interrupts */
3799 __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXP);
3801 #else
3802 /* Disable TXP interrupts */
3803 __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXP);
3804 #endif /* USE_SPI_RELOAD_TRANSFER */
3809 * @brief Handle the data 32-bit transmit in Interrupt mode.
3810 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3811 * the configuration information for SPI module.
3812 * @retval None
3814 static void SPI_TxISR_32BIT(SPI_HandleTypeDef *hspi)
3816 /* Transmit data in 32 Bit mode */
3817 *((__IO uint32_t *)&hspi->Instance->TXDR) = *((const uint32_t *)hspi->pTxBuffPtr);
3818 hspi->pTxBuffPtr += sizeof(uint32_t);
3819 hspi->TxXferCount--;
3821 /* Disable IT if no more data excepted */
3822 if (hspi->TxXferCount == 0UL)
3824 #if defined(USE_SPI_RELOAD_TRANSFER)
3825 /* Check if there is any request to reload */
3826 if (hspi->Reload.Requested == 1UL)
3828 hspi->TxXferSize = hspi->Reload.TxXferSize;
3829 hspi->TxXferCount = hspi->Reload.TxXferSize;
3830 hspi->pTxBuffPtr = hspi->Reload.pTxBuffPtr;
3832 /* In full duplex mode the reload request is reset in RX side */
3833 if (hspi->State == HAL_SPI_STATE_BUSY_TX)
3835 hspi->Reload.Requested = 0UL;
3838 else
3840 /* Disable TXP interrupts */
3841 __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXP);
3843 #else
3844 /* Disable TXP interrupts */
3845 __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXP);
3846 #endif /* USE_SPI_RELOAD_TRANSFER */
3851 * @brief Abort Transfer and clear flags.
3852 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3853 * the configuration information for SPI module.
3854 * @retval None
3856 static void SPI_AbortTransfer(SPI_HandleTypeDef *hspi)
3858 /* Disable SPI peripheral */
3859 __HAL_SPI_DISABLE(hspi);
3861 /* Disable ITs */
3862 __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_EOT | SPI_IT_TXP | SPI_IT_RXP | SPI_IT_DXP | SPI_IT_UDR | SPI_IT_OVR | \
3863 SPI_IT_FRE | SPI_IT_MODF));
3865 /* Clear the Status flags in the SR register */
3866 __HAL_SPI_CLEAR_EOTFLAG(hspi);
3867 __HAL_SPI_CLEAR_TXTFFLAG(hspi);
3869 /* Disable Tx DMA Request */
3870 CLEAR_BIT(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN | SPI_CFG1_RXDMAEN);
3872 /* Clear the Error flags in the SR register */
3873 __HAL_SPI_CLEAR_OVRFLAG(hspi);
3874 __HAL_SPI_CLEAR_UDRFLAG(hspi);
3875 __HAL_SPI_CLEAR_FREFLAG(hspi);
3876 __HAL_SPI_CLEAR_MODFFLAG(hspi);
3877 __HAL_SPI_CLEAR_SUSPFLAG(hspi);
3879 #if (USE_SPI_CRC != 0U)
3880 __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
3881 #endif /* USE_SPI_CRC */
3883 hspi->TxXferCount = (uint16_t)0UL;
3884 hspi->RxXferCount = (uint16_t)0UL;
3889 * @brief Close Transfer and clear flags.
3890 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3891 * the configuration information for SPI module.
3892 * @retval HAL_ERROR: if any error detected
3893 * HAL_OK: if nothing detected
3895 static void SPI_CloseTransfer(SPI_HandleTypeDef *hspi)
3897 uint32_t itflag = hspi->Instance->SR;
3899 __HAL_SPI_CLEAR_EOTFLAG(hspi);
3900 __HAL_SPI_CLEAR_TXTFFLAG(hspi);
3902 /* Disable SPI peripheral */
3903 __HAL_SPI_DISABLE(hspi);
3905 /* Disable ITs */
3906 __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_EOT | SPI_IT_TXP | SPI_IT_RXP | SPI_IT_DXP | SPI_IT_UDR | SPI_IT_OVR | \
3907 SPI_IT_FRE | SPI_IT_MODF));
3909 /* Disable Tx DMA Request */
3910 CLEAR_BIT(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN | SPI_CFG1_RXDMAEN);
3912 /* Report UnderRun error for non RX Only communication */
3913 if (hspi->State != HAL_SPI_STATE_BUSY_RX)
3915 if ((itflag & SPI_FLAG_UDR) != 0UL)
3917 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_UDR);
3918 __HAL_SPI_CLEAR_UDRFLAG(hspi);
3922 /* Report OverRun error for non TX Only communication */
3923 if (hspi->State != HAL_SPI_STATE_BUSY_TX)
3925 if ((itflag & SPI_FLAG_OVR) != 0UL)
3927 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_OVR);
3928 __HAL_SPI_CLEAR_OVRFLAG(hspi);
3931 #if (USE_SPI_CRC != 0UL)
3932 /* Check if CRC error occurred */
3933 if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
3935 if ((itflag & SPI_FLAG_CRCERR) != 0UL)
3937 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
3938 __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
3941 #endif /* USE_SPI_CRC */
3944 /* SPI Mode Fault error interrupt occurred -------------------------------*/
3945 if ((itflag & SPI_FLAG_MODF) != 0UL)
3947 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_MODF);
3948 __HAL_SPI_CLEAR_MODFFLAG(hspi);
3951 /* SPI Frame error interrupt occurred ------------------------------------*/
3952 if ((itflag & SPI_FLAG_FRE) != 0UL)
3954 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FRE);
3955 __HAL_SPI_CLEAR_FREFLAG(hspi);
3958 hspi->TxXferCount = (uint16_t)0UL;
3959 hspi->RxXferCount = (uint16_t)0UL;
3963 * @brief Handle SPI Communication Timeout.
3964 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3965 * the configuration information for SPI module.
3966 * @param Flag: SPI flag to check
3967 * @param Status: flag state to check
3968 * @param Timeout: Timeout duration
3969 * @param Tickstart: Tick start value
3970 * @retval HAL status
3972 static HAL_StatusTypeDef SPI_WaitOnFlagUntilTimeout(const SPI_HandleTypeDef *hspi, uint32_t Flag, FlagStatus Status,
3973 uint32_t Timeout, uint32_t Tickstart)
3975 /* Wait until flag is set */
3976 while ((__HAL_SPI_GET_FLAG(hspi, Flag) ? SET : RESET) == Status)
3978 /* Check for the Timeout */
3979 if ((((HAL_GetTick() - Tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
3981 return HAL_TIMEOUT;
3984 return HAL_OK;
3988 * @brief Compute configured packet size from fifo perspective.
3989 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
3990 * the configuration information for SPI module.
3991 * @retval Packet size occupied in the fifo
3993 static uint32_t SPI_GetPacketSize(const SPI_HandleTypeDef *hspi)
3995 uint32_t fifo_threashold = (hspi->Init.FifoThreshold >> SPI_CFG1_FTHLV_Pos) + 1UL;
3996 uint32_t data_size = (hspi->Init.DataSize >> SPI_CFG1_DSIZE_Pos) + 1UL;
3998 /* Convert data size to Byte */
3999 data_size = (data_size + 7UL) / 8UL;
4001 return data_size * fifo_threashold;
4005 * @}
4008 #endif /* HAL_SPI_MODULE_ENABLED */
4011 * @}
4015 * @}