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