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