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