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