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