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