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