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