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