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