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