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