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