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