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