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