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