source: S-port/trunk/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c

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