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