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