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