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