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