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