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