]> git.gir.st - tmk_keyboard.git/blob - tool/mbed/mbed-sdk/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_STM32F1/stm32f1xx_hal_spi.c
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[tmk_keyboard.git] / tool / mbed / mbed-sdk / libraries / mbed / targets / cmsis / TARGET_STM / TARGET_STM32F1 / stm32f1xx_hal_spi.c
1 /**
2 ******************************************************************************
3 * @file stm32f1xx_hal_spi.c
4 * @author MCD Application Team
5 * @version V1.0.0
6 * @date 15-December-2014
7 * @brief SPI HAL module driver.
8 *
9 * This file provides firmware functions to manage the following
10 * functionalities of the Serial Peripheral Interface (SPI) peripheral:
11 * + Initialization and de-initialization functions
12 * + IO operation functions
13 * + Peripheral Control functions
14 * + Peripheral State functions
15 @verbatim
16 ==============================================================================
17 ##### How to use this driver #####
18 ==============================================================================
19 [..]
20 The SPI HAL driver can be used as follows:
21
22 (#) Declare a SPI_HandleTypeDef handle structure, for example:
23 SPI_HandleTypeDef hspi;
24
25 (#)Initialize the SPI low level resources by implementing the HAL_SPI_MspInit ()API:
26 (##) Enable the SPIx interface clock
27 (##) SPI pins configuration
28 (+++) Enable the clock for the SPI GPIOs
29 (+++) Configure these SPI pins as alternate function push-pull
30 (##) NVIC configuration if you need to use interrupt process
31 (+++) Configure the SPIx interrupt priority
32 (+++) Enable the NVIC SPI IRQ handle
33 (##) DMA Configuration if you need to use DMA process
34 (+++) Declare a DMA_HandleTypeDef handle structure for the transmit or receive Channel
35 (+++) Enable the DMAx clock
36 (+++) Configure the DMA handle parameters
37 (+++) Configure the DMA Tx or Rx Channel
38 (+++) Associate the initilalized hdma_tx(or _rx) handle to the hspi DMA Tx (or Rx) handle
39 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx or Rx Channel
40
41 (#) Program the Mode, Direction , Data size, Baudrate Prescaler, NSS
42 management, Clock polarity and phase, FirstBit and CRC configuration in the hspi Init structure.
43
44 (#) Initialize the SPI registers by calling the HAL_SPI_Init() API:
45 (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
46 by calling the customed HAL_SPI_MspInit() API.
47 [..]
48 Circular mode restriction:
49 (#) The DMA circular mode cannot be used when the SPI is configured in these modes:
50 (##) Master 2Lines RxOnly
51 (##) Master 1Line Rx
52 (#) The CRC feature is not managed when the DMA circular mode is enabled
53 (#) When the SPI DMA Pause/Stop features are used, we must use the following APIs
54 the HAL_SPI_DMAPause()/ HAL_SPI_DMAStop() only under the SPI callbacks
55
56 [..]
57 Using the HAL it is not possible to reach all supported SPI frequency with the differents SPI Modes,
58 the following table resume the max SPI frequency reached with data size 8bits/16bits,
59 according to frequency used on APBx Peripheral Clock (fPCLK) used by the SPI instance :
60
61 For 8 bits SPI data size transfers :
62 +--------------------------------------------------------------------------------------------------+
63 | | | 2Lines Fullduplex | 2Lines RxOnly | 1Line |
64 | Process | Tranfert mode |-----------------------|-----------------------|-----------------------|
65 | | | Master | Slave | Master | Slave | Master | Slave |
66 |==================================================================================================|
67 | T | Polling | fPCLK/8 | fPCLK/8 | NA | NA | NA | NA |
68 | X |----------------|-----------|-----------|-----------|-----------|-----------|-----------|
69 | / | Interrupt | fPCLK/32 | fPCLK/32 | NA | NA | NA | NA |
70 | R |----------------|-----------|-----------|-----------|-----------|-----------|-----------|
71 | X | DMA | fPCLK/2 | fPCLK/4 | NA | NA | NA | NA |
72 |=========|================|===========|===========|===========|===========|===========|===========|
73 | | Polling | fPCLK/4 | fPCLK/8 | fPCLK/128 | fPCLK/16 | fPCLK/128 | fPCLK/8 |
74 | |----------------|-----------|-----------|-----------|-----------|-----------|-----------|
75 | R | Interrupt | fPCLK/32 | fPCLK/16 | fPCLK/128 | fPCLK/16 | fPCLK/128 | fPCLK/16 |
76 | X |----------------|-----------|-----------|-----------|-----------|-----------|-----------|
77 | | DMA | fPCLK/2 | fPCLK/2 | fPCLK/128 | fPCLK/16 | fPCLK/128 | fPCLK/2 |
78 |=========|================|===========|===========|===========|===========|===========|===========|
79 | | Polling | fPCLK/4 | fPCLK/4 | NA | NA | fPCLK/4 | fPCLK/64 |
80 | |----------------|-----------|-----------|-----------|-----------|-----------|-----------|
81 | T | Interrupt | fPCLK/8 | fPCLK/16 | NA | NA | fPCLK/8 | fPCLK/128 |
82 | X |----------------|-----------|-----------|-----------|-----------|-----------|-----------|
83 | | DMA | fPCLK/2 | fPCLK/4 | NA | NA | fPCLK/2 | fPCLK/64 |
84 +--------------------------------------------------------------------------------------------------+
85
86 For 16 bits SPI data size transfers :
87 +--------------------------------------------------------------------------------------------------+
88 | | | 2Lines Fullduplex | 2Lines RxOnly | 1Line |
89 | Process | Tranfert mode |-----------------------|-----------------------|-----------------------|
90 | | | Master | Slave | Master | Slave | Master | Slave |
91 |==================================================================================================|
92 | T | Polling | fPCLK/2 | fPCLK/4 | NA | NA | NA | NA |
93 | X |----------------|-----------|-----------|-----------|-----------|-----------|-----------|
94 | / | Interrupt | fPCLK/16 | fPCLK/16 | NA | NA | NA | NA |
95 | R |----------------|-----------|-----------|-----------|-----------|-----------|-----------|
96 | X | DMA | fPCLK/2 | fPCLK/4 | NA | NA | NA | NA |
97 |=========|================|===========|===========|===========|===========|===========|===========|
98 | | Polling | fPCLK/2 | fPCLK/4 | fPCLK/64 | fPCLK/8 | fPCLK/64 | fPCLK/4 |
99 | |----------------|-----------|-----------|-----------|-----------|-----------|-----------|
100 | R | Interrupt | fPCLK/16 | fPCLK/8 | fPCLK/128 | fPCLK/8 | fPCLK/128 | fPCLK/8 |
101 | X |----------------|-----------|-----------|-----------|-----------|-----------|-----------|
102 | | DMA | fPCLK/2 | fPCLK/2 | fPCLK/128 | fPCLK/8 | fPCLK/128 | fPCLK/2 |
103 |=========|================|===========|===========|===========|===========|===========|===========|
104 | | Polling | fPCLK/2 | fPCLK/4 | NA | NA | fPCLK/2 | fPCLK/64 |
105 | |----------------|-----------|-----------|-----------|-----------|-----------|-----------|
106 | T | Interrupt | fPCLK/4 | fPCLK/8 | NA | NA | fPCLK/4 | fPCLK/256 |
107 | X |----------------|-----------|-----------|-----------|-----------|-----------|-----------|
108 | | DMA | fPCLK/2 | fPCLK/4 | NA | NA | fPCLK/2 | fPCLK/32 |
109 +--------------------------------------------------------------------------------------------------+
110
111 @note The max SPI frequency depend on SPI data size (8bits, 16bits),
112 SPI mode(2 Lines fullduplex, 2 lines RxOnly, 1 line TX/RX) and Process mode (Polling, IT, DMA).
113 @note
114 (#) TX/RX processes are HAL_SPI_TransmitReceive(), HAL_SPI_TransmitReceive_IT() and HAL_SPI_TransmitReceive_DMA()
115 (#) RX processes are HAL_SPI_Receive(), HAL_SPI_Receive_IT() and HAL_SPI_Receive_DMA()
116 (#) TX processes are HAL_SPI_Transmit(), HAL_SPI_Transmit_IT() and HAL_SPI_Transmit_DMA()
117
118 @endverbatim
119 ******************************************************************************
120 * @attention
121 *
122 * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
123 *
124 * Redistribution and use in source and binary forms, with or without modification,
125 * are permitted provided that the following conditions are met:
126 * 1. Redistributions of source code must retain the above copyright notice,
127 * this list of conditions and the following disclaimer.
128 * 2. Redistributions in binary form must reproduce the above copyright notice,
129 * this list of conditions and the following disclaimer in the documentation
130 * and/or other materials provided with the distribution.
131 * 3. Neither the name of STMicroelectronics nor the names of its contributors
132 * may be used to endorse or promote products derived from this software
133 * without specific prior written permission.
134 *
135 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
136 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
137 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
138 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
139 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
140 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
141 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
142 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
143 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145 *
146 ******************************************************************************
147 */
148
149 /* Includes ------------------------------------------------------------------*/
150 #include "stm32f1xx_hal.h"
151
152 /** @addtogroup STM32F1xx_HAL_Driver
153 * @{
154 */
155
156 /** @defgroup SPI SPI
157 * @brief SPI HAL module driver
158 * @{
159 */
160
161 #ifdef HAL_SPI_MODULE_ENABLED
162
163 /* Private typedef -----------------------------------------------------------*/
164 /* Private define ------------------------------------------------------------*/
165 /** @defgroup SPI_Private_Constants SPI Private Constants
166 * @{
167 */
168 #define SPI_TIMEOUT_VALUE 10
169 /**
170 * @}
171 */
172
173 /* Private macro -------------------------------------------------------------*/
174 /* Private variables ---------------------------------------------------------*/
175 /* Private function prototypes -----------------------------------------------*/
176 /** @defgroup SPI_Private_Functions SPI Private Functions
177 * @{
178 */
179 static void SPI_TxCloseIRQHandler(SPI_HandleTypeDef *hspi);
180 static void SPI_TxISR(SPI_HandleTypeDef *hspi);
181 static void SPI_RxCloseIRQHandler(SPI_HandleTypeDef *hspi);
182 static void SPI_2LinesRxISR(SPI_HandleTypeDef *hspi);
183 static void SPI_RxISR(SPI_HandleTypeDef *hspi);
184 static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma);
185 static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
186 static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma);
187 static void SPI_DMAHalfTransmitCplt(DMA_HandleTypeDef *hdma);
188 static void SPI_DMAHalfReceiveCplt(DMA_HandleTypeDef *hdma);
189 static void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma);
190 static void SPI_DMAError(DMA_HandleTypeDef *hdma);
191 static HAL_StatusTypeDef SPI_WaitOnFlagUntilTimeout(SPI_HandleTypeDef *hspi, uint32_t Flag, FlagStatus Status, uint32_t Timeout);
192 /**
193 * @}
194 */
195
196 /* Exported functions ---------------------------------------------------------*/
197
198 /** @defgroup SPI_Exported_Functions SPI Exported Functions
199 * @{
200 */
201
202 /** @defgroup SPI_Exported_Functions_Group1 Initialization and de-initialization functions
203 * @brief Initialization and Configuration functions
204 *
205 @verbatim
206 ===============================================================================
207 ##### Initialization and de-initialization functions #####
208 ===============================================================================
209 [..] This subsection provides a set of functions allowing to initialize and
210 de-initialiaze the SPIx peripheral:
211
212 (+) User must implement HAL_SPI_MspInit() function in which he configures
213 all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
214
215 (+) Call the function HAL_SPI_Init() to configure the selected device with
216 the selected configuration:
217 (++) Mode
218 (++) Direction
219 (++) Data Size
220 (++) Clock Polarity and Phase
221 (++) NSS Management
222 (++) BaudRate Prescaler
223 (++) FirstBit
224 (++) TIMode
225 (++) CRC Calculation
226 (++) CRC Polynomial if CRC enabled
227
228 (+) Call the function HAL_SPI_DeInit() to restore the default configuration
229 of the selected SPIx periperal.
230
231 @endverbatim
232 * @{
233 */
234
235 /**
236 * @brief Initializes the SPI according to the specified parameters
237 * in the SPI_InitTypeDef and create the associated handle.
238 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
239 * the configuration information for SPI module.
240 * @retval HAL status
241 */
242 __weak HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi)
243 {
244 /* Check the SPI handle allocation */
245 if(hspi == NULL)
246 {
247 return HAL_ERROR;
248 }
249
250 /* Check the parameters */
251 assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance));
252 assert_param(IS_SPI_MODE(hspi->Init.Mode));
253 assert_param(IS_SPI_DIRECTION_MODE(hspi->Init.Direction));
254 assert_param(IS_SPI_DATASIZE(hspi->Init.DataSize));
255 assert_param(IS_SPI_CPOL(hspi->Init.CLKPolarity));
256 assert_param(IS_SPI_CPHA(hspi->Init.CLKPhase));
257 assert_param(IS_SPI_NSS(hspi->Init.NSS));
258 assert_param(IS_SPI_BAUDRATE_PRESCALER(hspi->Init.BaudRatePrescaler));
259 assert_param(IS_SPI_FIRST_BIT(hspi->Init.FirstBit));
260 assert_param(IS_SPI_TIMODE(hspi->Init.TIMode));
261 assert_param(IS_SPI_CRC_CALCULATION(hspi->Init.CRCCalculation));
262 assert_param(IS_SPI_CRC_POLYNOMIAL(hspi->Init.CRCPolynomial));
263
264 if(hspi->State == HAL_SPI_STATE_RESET)
265 {
266 /* Allocate lock resource and initialize it */
267 hspi-> Lock = HAL_UNLOCKED;
268
269 /* Init the low level hardware : GPIO, CLOCK, NVIC... */
270 HAL_SPI_MspInit(hspi);
271 }
272
273 hspi->State = HAL_SPI_STATE_BUSY;
274
275 /* Disble the selected SPI peripheral */
276 __HAL_SPI_DISABLE(hspi);
277
278 /*----------------------- SPIx CR1 & CR2 Configuration ---------------------*/
279 /* Configure : SPI Mode, Communication Mode, Data size, Clock polarity and phase, NSS management,
280 Communication speed, First bit and CRC calculation state */
281 WRITE_REG(hspi->Instance->CR1, (hspi->Init.Mode | hspi->Init.Direction | hspi->Init.DataSize |
282 hspi->Init.CLKPolarity | hspi->Init.CLKPhase | (hspi->Init.NSS & SPI_CR1_SSM) |
283 hspi->Init.BaudRatePrescaler | hspi->Init.FirstBit | hspi->Init.CRCCalculation) );
284
285 /* Configure : NSS management */
286 WRITE_REG(hspi->Instance->CR2, (((hspi->Init.NSS >> 16) & SPI_CR2_SSOE) | hspi->Init.TIMode));
287
288 /*---------------------------- SPIx CRCPOLY Configuration ------------------*/
289 /* Configure : CRC Polynomial */
290 WRITE_REG(hspi->Instance->CRCPR, hspi->Init.CRCPolynomial);
291
292 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
293 hspi->State = HAL_SPI_STATE_READY;
294
295 return HAL_OK;
296 }
297
298 /**
299 * @brief DeInitializes the SPI peripheral
300 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
301 * the configuration information for SPI module.
302 * @retval HAL status
303 */
304 HAL_StatusTypeDef HAL_SPI_DeInit(SPI_HandleTypeDef *hspi)
305 {
306 /* Check the SPI handle allocation */
307 if(hspi == NULL)
308 {
309 return HAL_ERROR;
310 }
311
312 hspi->State = HAL_SPI_STATE_BUSY;
313
314 /* Disable the SPI Peripheral Clock */
315 __HAL_SPI_DISABLE(hspi);
316
317 /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
318 HAL_SPI_MspDeInit(hspi);
319
320 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
321 hspi->State = HAL_SPI_STATE_RESET;
322
323 /* Release Lock */
324 __HAL_UNLOCK(hspi);
325
326 return HAL_OK;
327 }
328
329 /**
330 * @brief SPI MSP Init
331 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
332 * the configuration information for SPI module.
333 * @retval None
334 */
335 __weak void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
336 {
337 /* NOTE : This function Should not be modified, when the callback is needed,
338 the HAL_SPI_MspInit could be implenetd in the user file
339 */
340 }
341
342 /**
343 * @brief SPI MSP DeInit
344 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
345 * the configuration information for SPI module.
346 * @retval None
347 */
348 __weak void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi)
349 {
350 /* NOTE : This function Should not be modified, when the callback is needed,
351 the HAL_SPI_MspDeInit could be implenetd in the user file
352 */
353 }
354
355 /**
356 * @}
357 */
358
359 /** @defgroup SPI_Exported_Functions_Group2 IO operation functions
360 * @brief Data transfers functions
361 *
362 @verbatim
363 ==============================================================================
364 ##### IO operation functions #####
365 ===============================================================================
366 This subsection provides a set of functions allowing to manage the SPI
367 data transfers.
368
369 [..] The SPI supports master and slave mode :
370
371 (#) There are two modes of transfer:
372 (++) Blocking mode: The communication is performed in polling mode.
373 The HAL status of all data processing is returned by the same function
374 after finishing transfer.
375 (++) No-Blocking mode: The communication is performed using Interrupts
376 or DMA, These APIs return the HAL status.
377 The end of the data processing will be indicated through the
378 dedicated SPI IRQ when using Interrupt mode or the DMA IRQ when
379 using DMA mode.
380 The HAL_SPI_TxCpltCallback(), HAL_SPI_RxCpltCallback() and HAL_SPI_TxRxCpltCallback() user callbacks
381 will be executed respectivelly at the end of the transmit or Receive process
382 The HAL_SPI_ErrorCallback()user callback will be executed when a communication error is detected
383
384 (#) APIs provided for these 2 transfer modes (Blocking mode or Non blocking mode using either Interrupt or DMA)
385 exist for 1Line (simplex) and 2Lines (full duplex) modes.
386
387 @endverbatim
388 * @{
389 */
390
391 /**
392 * @brief Transmit an amount of data in blocking mode
393 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
394 * the configuration information for SPI module.
395 * @param pData: pointer to data buffer
396 * @param Size: amount of data to be sent
397 * @param Timeout: Timeout duration
398 * @retval HAL status
399 */
400 HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
401 {
402
403 if(hspi->State == HAL_SPI_STATE_READY)
404 {
405 if((pData == NULL ) || (Size == 0))
406 {
407 return HAL_ERROR;
408 }
409
410 /* Check the parameters */
411 assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction));
412
413 /* Process Locked */
414 __HAL_LOCK(hspi);
415
416 /* Configure communication */
417 hspi->State = HAL_SPI_STATE_BUSY_TX;
418 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
419
420 hspi->pTxBuffPtr = pData;
421 hspi->TxXferSize = Size;
422 hspi->TxXferCount = Size;
423
424 /*Init field not used in handle to zero */
425 hspi->TxISR = 0;
426 hspi->RxISR = 0;
427 hspi->pRxBuffPtr = NULL;
428 hspi->RxXferSize = 0;
429 hspi->RxXferCount = 0;
430
431 /* Reset CRC Calculation */
432 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
433 {
434 SPI_RESET_CRC(hspi);
435 }
436
437 if(hspi->Init.Direction == SPI_DIRECTION_1LINE)
438 {
439 /* Configure communication direction : 1Line */
440 SPI_1LINE_TX(hspi);
441 }
442
443 /* Check if the SPI is already enabled */
444 if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
445 {
446 /* Enable SPI peripheral */
447 __HAL_SPI_ENABLE(hspi);
448 }
449
450 /* Transmit data in 8 Bit mode */
451 if(hspi->Init.DataSize == SPI_DATASIZE_8BIT)
452 {
453 if((hspi->Init.Mode == SPI_MODE_SLAVE)|| (hspi->TxXferCount == 0x01))
454 {
455 hspi->Instance->DR = (*hspi->pTxBuffPtr++);
456 hspi->TxXferCount--;
457 }
458
459 while(hspi->TxXferCount > 0)
460 {
461 /* Wait until TXE flag is set to send data */
462 if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_TXE, RESET, Timeout) != HAL_OK)
463 {
464 return HAL_TIMEOUT;
465 }
466 hspi->Instance->DR = (*hspi->pTxBuffPtr++);
467 hspi->TxXferCount--;
468 }
469 /* Enable CRC Transmission */
470 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
471 {
472 SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
473 }
474 }
475 /* Transmit data in 16 Bit mode */
476 else
477 {
478 if((hspi->Init.Mode == SPI_MODE_SLAVE) || (hspi->TxXferCount == 0x01))
479 {
480 hspi->Instance->DR = *((uint16_t*)hspi->pTxBuffPtr);
481 hspi->pTxBuffPtr+=2;
482 hspi->TxXferCount--;
483 }
484
485 while(hspi->TxXferCount > 0)
486 {
487 /* Wait until TXE flag is set to send data */
488 if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_TXE, RESET, Timeout) != HAL_OK)
489 {
490 return HAL_TIMEOUT;
491 }
492 hspi->Instance->DR = *((uint16_t*)hspi->pTxBuffPtr);
493 hspi->pTxBuffPtr+=2;
494 hspi->TxXferCount--;
495 }
496 /* Enable CRC Transmission */
497 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
498 {
499 SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
500 }
501 }
502
503 /* Wait until TXE flag is set to send data */
504 if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_TXE, RESET, Timeout) != HAL_OK)
505 {
506 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
507 return HAL_TIMEOUT;
508 }
509
510 /* Wait until Busy flag is reset before disabling SPI */
511 if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_BSY, SET, Timeout) != HAL_OK)
512 {
513 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
514 return HAL_TIMEOUT;
515 }
516
517 /* Clear OVERUN flag in 2 Lines communication mode because received is not read */
518 if(hspi->Init.Direction == SPI_DIRECTION_2LINES)
519 {
520 __HAL_SPI_CLEAR_OVRFLAG(hspi);
521 }
522
523 hspi->State = HAL_SPI_STATE_READY;
524
525 /* Process Unlocked */
526 __HAL_UNLOCK(hspi);
527
528 return HAL_OK;
529 }
530 else
531 {
532 return HAL_BUSY;
533 }
534 }
535
536 /**
537 * @brief Receive an amount of data in blocking mode
538 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
539 * the configuration information for SPI module.
540 * @param pData: pointer to data buffer
541 * @param Size: amount of data to be sent
542 * @param Timeout: Timeout duration
543 * @retval HAL status
544 */
545 HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
546 {
547 __IO uint16_t tmpreg = 0;
548
549 if(hspi->State == HAL_SPI_STATE_READY)
550 {
551 if((pData == NULL ) || (Size == 0))
552 {
553 return HAL_ERROR;
554 }
555
556 /* Process Locked */
557 __HAL_LOCK(hspi);
558
559 /* Configure communication */
560 hspi->State = HAL_SPI_STATE_BUSY_RX;
561 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
562
563 hspi->pRxBuffPtr = pData;
564 hspi->RxXferSize = Size;
565 hspi->RxXferCount = Size;
566
567 /*Init field not used in handle to zero */
568 hspi->RxISR = 0;
569 hspi->TxISR = 0;
570 hspi->pTxBuffPtr = NULL;
571 hspi->TxXferSize = 0;
572 hspi->TxXferCount = 0;
573
574 /* Configure communication direction : 1Line */
575 if(hspi->Init.Direction == SPI_DIRECTION_1LINE)
576 {
577 SPI_1LINE_RX(hspi);
578 }
579
580 /* Reset CRC Calculation */
581 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
582 {
583 SPI_RESET_CRC(hspi);
584 }
585
586 if((hspi->Init.Mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES))
587 {
588 /* Process Unlocked */
589 __HAL_UNLOCK(hspi);
590
591 /* Call transmit-receive function to send Dummy data on Tx line and generate clock on CLK line */
592 return HAL_SPI_TransmitReceive(hspi, pData, pData, Size, Timeout);
593 }
594
595 /* Check if the SPI is already enabled */
596 if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
597 {
598 /* Enable SPI peripheral */
599 __HAL_SPI_ENABLE(hspi);
600 }
601
602 /* Receive data in 8 Bit mode */
603 if(hspi->Init.DataSize == SPI_DATASIZE_8BIT)
604 {
605 while(hspi->RxXferCount > 1)
606 {
607 /* Wait until RXNE flag is set */
608 if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK)
609 {
610 return HAL_TIMEOUT;
611 }
612
613 (*hspi->pRxBuffPtr++) = hspi->Instance->DR;
614 hspi->RxXferCount--;
615 }
616 /* Enable CRC Reception */
617 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
618 {
619 SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
620 }
621 }
622 /* Receive data in 16 Bit mode */
623 else
624 {
625 while(hspi->RxXferCount > 1)
626 {
627 /* Wait until RXNE flag is set to read data */
628 if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK)
629 {
630 return HAL_TIMEOUT;
631 }
632
633 *((uint16_t*)hspi->pRxBuffPtr) = hspi->Instance->DR;
634 hspi->pRxBuffPtr+=2;
635 hspi->RxXferCount--;
636 }
637 /* Enable CRC Reception */
638 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
639 {
640 SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
641 }
642 }
643
644 /* Wait until RXNE flag is set */
645 if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK)
646 {
647 return HAL_TIMEOUT;
648 }
649
650 /* Receive last data in 8 Bit mode */
651 if(hspi->Init.DataSize == SPI_DATASIZE_8BIT)
652 {
653 (*hspi->pRxBuffPtr++) = hspi->Instance->DR;
654 }
655 /* Receive last data in 16 Bit mode */
656 else
657 {
658 *((uint16_t*)hspi->pRxBuffPtr) = hspi->Instance->DR;
659 hspi->pRxBuffPtr+=2;
660 }
661 hspi->RxXferCount--;
662
663 /* If CRC computation is enabled */
664 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
665 {
666 /* Wait until RXNE flag is set: CRC Received */
667 if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK)
668 {
669 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
670 return HAL_TIMEOUT;
671 }
672
673 /* Read CRC to clear RXNE flag */
674 tmpreg = hspi->Instance->DR;
675 UNUSED(tmpreg);
676 }
677
678 if((hspi->Init.Mode == SPI_MODE_MASTER)&&((hspi->Init.Direction == SPI_DIRECTION_1LINE)||(hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY)))
679 {
680 /* Disable SPI peripheral */
681 __HAL_SPI_DISABLE(hspi);
682 }
683
684 hspi->State = HAL_SPI_STATE_READY;
685
686 /* Check if CRC error occurred */
687 if((hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET))
688 {
689 /* Check if CRC error is valid or not (workaround to be applied or not) */
690 if (SPI_ISCRCErrorValid(hspi) == SPI_VALID_CRC_ERROR)
691 {
692 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
693
694 /* Reset CRC Calculation */
695 SPI_RESET_CRC(hspi);
696
697 /* Process Unlocked */
698 __HAL_UNLOCK(hspi);
699
700 return HAL_ERROR;
701 }
702 else
703 {
704 __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
705 }
706 }
707
708 /* Process Unlocked */
709 __HAL_UNLOCK(hspi);
710
711 return HAL_OK;
712 }
713 else
714 {
715 return HAL_BUSY;
716 }
717 }
718
719 /**
720 * @brief Transmit and Receive an amount of data in blocking mode
721 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
722 * the configuration information for SPI module.
723 * @param pTxData: pointer to transmission data buffer
724 * @param pRxData: pointer to reception data buffer to be
725 * @param Size: amount of data to be sent
726 * @param Timeout: Timeout duration
727 * @retval HAL status
728 */
729 HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
730 {
731 __IO uint16_t tmpreg = 0;
732
733 if((hspi->State == HAL_SPI_STATE_READY) || (hspi->State == HAL_SPI_STATE_BUSY_RX))
734 {
735 if((pTxData == NULL ) || (pRxData == NULL ) || (Size == 0))
736 {
737 return HAL_ERROR;
738 }
739
740 /* Check the parameters */
741 assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));
742
743 /* Process Locked */
744 __HAL_LOCK(hspi);
745
746 /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */
747 if(hspi->State == HAL_SPI_STATE_READY)
748 {
749 hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
750 }
751
752 /* Configure communication */
753 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
754
755 hspi->pRxBuffPtr = pRxData;
756 hspi->RxXferSize = Size;
757 hspi->RxXferCount = Size;
758
759 hspi->pTxBuffPtr = pTxData;
760 hspi->TxXferSize = Size;
761 hspi->TxXferCount = Size;
762
763 /*Init field not used in handle to zero */
764 hspi->RxISR = 0;
765 hspi->TxISR = 0;
766
767 /* Reset CRC Calculation */
768 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
769 {
770 SPI_RESET_CRC(hspi);
771 }
772
773 /* Check if the SPI is already enabled */
774 if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
775 {
776 /* Enable SPI peripheral */
777 __HAL_SPI_ENABLE(hspi);
778 }
779
780 /* Transmit and Receive data in 16 Bit mode */
781 if(hspi->Init.DataSize == SPI_DATASIZE_16BIT)
782 {
783 if((hspi->Init.Mode == SPI_MODE_SLAVE) || ((hspi->Init.Mode == SPI_MODE_MASTER) && (hspi->TxXferCount == 0x01)))
784 {
785 hspi->Instance->DR = *((uint16_t*)hspi->pTxBuffPtr);
786 hspi->pTxBuffPtr+=2;
787 hspi->TxXferCount--;
788 }
789 if(hspi->TxXferCount == 0)
790 {
791 /* Enable CRC Transmission */
792 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
793 {
794 SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
795 }
796
797 /* Wait until RXNE flag is set */
798 if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK)
799 {
800 return HAL_TIMEOUT;
801 }
802
803 *((uint16_t*)hspi->pRxBuffPtr) = hspi->Instance->DR;
804 hspi->pRxBuffPtr+=2;
805 hspi->RxXferCount--;
806 }
807 else
808 {
809 while(hspi->TxXferCount > 0)
810 {
811 /* Wait until TXE flag is set to send data */
812 if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_TXE, RESET, Timeout) != HAL_OK)
813 {
814 return HAL_TIMEOUT;
815 }
816
817 hspi->Instance->DR = *((uint16_t*)hspi->pTxBuffPtr);
818 hspi->pTxBuffPtr+=2;
819 hspi->TxXferCount--;
820
821 /* Enable CRC Transmission */
822 if((hspi->TxXferCount == 0) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE))
823 {
824 SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
825 }
826
827 /* Wait until RXNE flag is set */
828 if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK)
829 {
830 return HAL_TIMEOUT;
831 }
832
833 *((uint16_t*)hspi->pRxBuffPtr) = hspi->Instance->DR;
834 hspi->pRxBuffPtr+=2;
835 hspi->RxXferCount--;
836 }
837 /* Receive the last byte */
838 if(hspi->Init.Mode == SPI_MODE_SLAVE)
839 {
840 /* Wait until RXNE flag is set */
841 if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK)
842 {
843 return HAL_TIMEOUT;
844 }
845
846 *((uint16_t*)hspi->pRxBuffPtr) = hspi->Instance->DR;
847 hspi->pRxBuffPtr+=2;
848 hspi->RxXferCount--;
849 }
850 }
851 }
852 /* Transmit and Receive data in 8 Bit mode */
853 else
854 {
855 if((hspi->Init.Mode == SPI_MODE_SLAVE) || ((hspi->Init.Mode == SPI_MODE_MASTER) && (hspi->TxXferCount == 0x01)))
856 {
857 hspi->Instance->DR = (*hspi->pTxBuffPtr++);
858 hspi->TxXferCount--;
859 }
860 if(hspi->TxXferCount == 0)
861 {
862 /* Enable CRC Transmission */
863 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
864 {
865 SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
866 }
867
868 /* Wait until RXNE flag is set */
869 if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK)
870 {
871 return HAL_TIMEOUT;
872 }
873
874 (*hspi->pRxBuffPtr) = hspi->Instance->DR;
875 hspi->RxXferCount--;
876 }
877 else
878 {
879 while(hspi->TxXferCount > 0)
880 {
881 /* Wait until TXE flag is set to send data */
882 if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_TXE, RESET, Timeout) != HAL_OK)
883 {
884 return HAL_TIMEOUT;
885 }
886
887 hspi->Instance->DR = (*hspi->pTxBuffPtr++);
888 hspi->TxXferCount--;
889
890 /* Enable CRC Transmission */
891 if((hspi->TxXferCount == 0) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE))
892 {
893 SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
894 }
895
896 /* Wait until RXNE flag is set */
897 if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK)
898 {
899 return HAL_TIMEOUT;
900 }
901
902 (*hspi->pRxBuffPtr++) = hspi->Instance->DR;
903 hspi->RxXferCount--;
904 }
905 if(hspi->Init.Mode == SPI_MODE_SLAVE)
906 {
907 /* Wait until RXNE flag is set */
908 if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK)
909 {
910 return HAL_TIMEOUT;
911 }
912
913 (*hspi->pRxBuffPtr++) = hspi->Instance->DR;
914 hspi->RxXferCount--;
915 }
916 }
917 }
918
919 /* Read CRC from DR to close CRC calculation process */
920 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
921 {
922 /* Wait until RXNE flag is set */
923 if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK)
924 {
925 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
926 return HAL_TIMEOUT;
927 }
928 /* Read CRC */
929 tmpreg = hspi->Instance->DR;
930 UNUSED(tmpreg);
931 }
932
933 /* Wait until Busy flag is reset before disabling SPI */
934 if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_BSY, SET, Timeout) != HAL_OK)
935 {
936 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
937 return HAL_TIMEOUT;
938 }
939
940 hspi->State = HAL_SPI_STATE_READY;
941
942 /* Check if CRC error occurred */
943 if((hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET))
944 {
945 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
946
947 SPI_RESET_CRC(hspi);
948
949 /* Process Unlocked */
950 __HAL_UNLOCK(hspi);
951
952 return HAL_ERROR;
953 }
954
955 /* Process Unlocked */
956 __HAL_UNLOCK(hspi);
957
958 return HAL_OK;
959 }
960 else
961 {
962 return HAL_BUSY;
963 }
964 }
965
966 /**
967 * @brief Transmit an amount of data in no-blocking mode with Interrupt
968 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
969 * the configuration information for SPI module.
970 * @param pData: pointer to data buffer
971 * @param Size: amount of data to be sent
972 * @retval HAL status
973 */
974 HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
975 {
976 if(hspi->State == HAL_SPI_STATE_READY)
977 {
978 if((pData == NULL) || (Size == 0))
979 {
980 return HAL_ERROR;
981 }
982
983 /* Check the parameters */
984 assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction));
985
986 /* Process Locked */
987 __HAL_LOCK(hspi);
988
989 /* Configure communication */
990 hspi->State = HAL_SPI_STATE_BUSY_TX;
991 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
992
993 hspi->TxISR = &SPI_TxISR;
994 hspi->pTxBuffPtr = pData;
995 hspi->TxXferSize = Size;
996 hspi->TxXferCount = Size;
997
998 /*Init field not used in handle to zero */
999 hspi->RxISR = 0;
1000 hspi->pRxBuffPtr = NULL;
1001 hspi->RxXferSize = 0;
1002 hspi->RxXferCount = 0;
1003
1004 /* Configure communication direction : 1Line */
1005 if(hspi->Init.Direction == SPI_DIRECTION_1LINE)
1006 {
1007 SPI_1LINE_TX(hspi);
1008 }
1009
1010 /* Reset CRC Calculation */
1011 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
1012 {
1013 SPI_RESET_CRC(hspi);
1014 }
1015
1016 if (hspi->Init.Direction == SPI_DIRECTION_2LINES)
1017 {
1018 __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TXE));
1019 }
1020 else
1021 {
1022 /* Enable TXE and ERR interrupt */
1023 __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_ERR));
1024 }
1025 /* Process Unlocked */
1026 __HAL_UNLOCK(hspi);
1027
1028 /* Check if the SPI is already enabled */
1029 if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
1030 {
1031 /* Enable SPI peripheral */
1032 __HAL_SPI_ENABLE(hspi);
1033 }
1034
1035 return HAL_OK;
1036 }
1037 else
1038 {
1039 return HAL_BUSY;
1040 }
1041 }
1042
1043 /**
1044 * @brief Receive an amount of data in no-blocking mode with Interrupt
1045 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
1046 * the configuration information for SPI module.
1047 * @param pData: pointer to data buffer
1048 * @param Size: amount of data to be sent
1049 * @retval HAL status
1050 */
1051 HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
1052 {
1053 if(hspi->State == HAL_SPI_STATE_READY)
1054 {
1055 if((pData == NULL) || (Size == 0))
1056 {
1057 return HAL_ERROR;
1058 }
1059
1060 /* Process Locked */
1061 __HAL_LOCK(hspi);
1062
1063 /* Configure communication */
1064 hspi->State = HAL_SPI_STATE_BUSY_RX;
1065 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
1066
1067 hspi->RxISR = &SPI_RxISR;
1068 hspi->pRxBuffPtr = pData;
1069 hspi->RxXferSize = Size;
1070 hspi->RxXferCount = Size ;
1071
1072 /*Init field not used in handle to zero */
1073 hspi->TxISR = 0;
1074 hspi->pTxBuffPtr = NULL;
1075 hspi->TxXferSize = 0;
1076 hspi->TxXferCount = 0;
1077
1078 /* Configure communication direction : 1Line */
1079 if(hspi->Init.Direction == SPI_DIRECTION_1LINE)
1080 {
1081 SPI_1LINE_RX(hspi);
1082 }
1083 else if((hspi->Init.Direction == SPI_DIRECTION_2LINES) && (hspi->Init.Mode == SPI_MODE_MASTER))
1084 {
1085 /* Process Unlocked */
1086 __HAL_UNLOCK(hspi);
1087
1088 /* Call transmit-receive function to send Dummy data on Tx line and generate clock on CLK line */
1089 return HAL_SPI_TransmitReceive_IT(hspi, pData, pData, Size);
1090 }
1091
1092 /* Reset CRC Calculation */
1093 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
1094 {
1095 SPI_RESET_CRC(hspi);
1096 }
1097
1098 /* Enable TXE and ERR interrupt */
1099 __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR));
1100
1101 /* Process Unlocked */
1102 __HAL_UNLOCK(hspi);
1103
1104 /* Note : The SPI must be enabled after unlocking current process
1105 to avoid the risk of SPI interrupt handle execution before current
1106 process unlock */
1107
1108 /* Check if the SPI is already enabled */
1109 if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
1110 {
1111 /* Enable SPI peripheral */
1112 __HAL_SPI_ENABLE(hspi);
1113 }
1114
1115 return HAL_OK;
1116 }
1117 else
1118 {
1119 return HAL_BUSY;
1120 }
1121 }
1122
1123 /**
1124 * @brief Transmit and Receive an amount of data in no-blocking mode with Interrupt
1125 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
1126 * the configuration information for SPI module.
1127 * @param pTxData: pointer to transmission data buffer
1128 * @param pRxData: pointer to reception data buffer to be
1129 * @param Size: amount of data to be sent
1130 * @retval HAL status
1131 */
1132 HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
1133 {
1134
1135 if((hspi->State == HAL_SPI_STATE_READY) || \
1136 ((hspi->Init.Mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (hspi->State == HAL_SPI_STATE_BUSY_RX)))
1137 {
1138 if((pTxData == NULL ) || (pRxData == NULL ) || (Size == 0))
1139 {
1140 return HAL_ERROR;
1141 }
1142
1143 /* Check the parameters */
1144 assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));
1145
1146 /* Process locked */
1147 __HAL_LOCK(hspi);
1148
1149 /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */
1150 if(hspi->State != HAL_SPI_STATE_BUSY_RX)
1151 {
1152 hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
1153 }
1154
1155 /* Configure communication */
1156 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
1157
1158 hspi->TxISR = &SPI_TxISR;
1159 hspi->pTxBuffPtr = pTxData;
1160 hspi->TxXferSize = Size;
1161 hspi->TxXferCount = Size;
1162
1163 hspi->RxISR = &SPI_2LinesRxISR;
1164 hspi->pRxBuffPtr = pRxData;
1165 hspi->RxXferSize = Size;
1166 hspi->RxXferCount = Size;
1167
1168 /* Reset CRC Calculation */
1169 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
1170 {
1171 SPI_RESET_CRC(hspi);
1172 }
1173
1174 /* Enable TXE, RXNE and ERR interrupt */
1175 __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR));
1176
1177 /* Process Unlocked */
1178 __HAL_UNLOCK(hspi);
1179
1180 /* Check if the SPI is already enabled */
1181 if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
1182 {
1183 /* Enable SPI peripheral */
1184 __HAL_SPI_ENABLE(hspi);
1185 }
1186
1187 return HAL_OK;
1188 }
1189 else
1190 {
1191 return HAL_BUSY;
1192 }
1193 }
1194
1195 /**
1196 * @brief Transmit an amount of data in no-blocking mode with DMA
1197 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
1198 * the configuration information for SPI module.
1199 * @param pData: pointer to data buffer
1200 * @param Size: amount of data to be sent
1201 * @retval HAL status
1202 */
1203 HAL_StatusTypeDef HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
1204 {
1205 if(hspi->State == HAL_SPI_STATE_READY)
1206 {
1207 if((pData == NULL) || (Size == 0))
1208 {
1209 return HAL_ERROR;
1210 }
1211
1212 /* Check the parameters */
1213 assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction));
1214
1215 /* Process Locked */
1216 __HAL_LOCK(hspi);
1217
1218 /* Configure communication */
1219 hspi->State = HAL_SPI_STATE_BUSY_TX;
1220 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
1221
1222 hspi->pTxBuffPtr = pData;
1223 hspi->TxXferSize = Size;
1224 hspi->TxXferCount = Size;
1225
1226 /*Init field not used in handle to zero */
1227 hspi->TxISR = 0;
1228 hspi->RxISR = 0;
1229 hspi->pRxBuffPtr = NULL;
1230 hspi->RxXferSize = 0;
1231 hspi->RxXferCount = 0;
1232
1233 /* Configure communication direction : 1Line */
1234 if(hspi->Init.Direction == SPI_DIRECTION_1LINE)
1235 {
1236 SPI_1LINE_TX(hspi);
1237 }
1238
1239 /* Reset CRC Calculation */
1240 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
1241 {
1242 SPI_RESET_CRC(hspi);
1243 }
1244
1245 /* Set the SPI TxDMA Half transfer complete callback */
1246 hspi->hdmatx->XferHalfCpltCallback = SPI_DMAHalfTransmitCplt;
1247
1248 /* Set the SPI TxDMA transfer complete callback */
1249 hspi->hdmatx->XferCpltCallback = SPI_DMATransmitCplt;
1250
1251 /* Set the DMA error callback */
1252 hspi->hdmatx->XferErrorCallback = SPI_DMAError;
1253
1254 /* Reset content of SPI RxDMA descriptor */
1255 hspi->hdmarx->XferHalfCpltCallback = 0;
1256 hspi->hdmarx->XferCpltCallback = 0;
1257 hspi->hdmarx->XferErrorCallback = 0;
1258
1259 /* Enable the Tx DMA Channel */
1260 HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->DR, hspi->TxXferCount);
1261
1262 /* Enable Tx DMA Request */
1263 SET_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN);
1264
1265 /* Process Unlocked */
1266 __HAL_UNLOCK(hspi);
1267
1268 /* Check if the SPI is already enabled */
1269 if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
1270 {
1271 /* Enable SPI peripheral */
1272 __HAL_SPI_ENABLE(hspi);
1273 }
1274
1275 return HAL_OK;
1276 }
1277 else
1278 {
1279 return HAL_BUSY;
1280 }
1281 }
1282
1283 /**
1284 * @brief Receive an amount of data in no-blocking mode with DMA
1285 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
1286 * the configuration information for SPI module.
1287 * @param pData: pointer to data buffer
1288 * @note When the CRC feature is enabled the pData Length must be Size + 1.
1289 * @param Size: amount of data to be sent
1290 * @retval HAL status
1291 */
1292 HAL_StatusTypeDef HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
1293 {
1294 if(hspi->State == HAL_SPI_STATE_READY)
1295 {
1296 if((pData == NULL) || (Size == 0))
1297 {
1298 return HAL_ERROR;
1299 }
1300
1301 /* Process Locked */
1302 __HAL_LOCK(hspi);
1303
1304 /* Configure communication */
1305 hspi->State = HAL_SPI_STATE_BUSY_RX;
1306 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
1307
1308 hspi->pRxBuffPtr = pData;
1309 hspi->RxXferSize = Size;
1310 hspi->RxXferCount = Size;
1311
1312 /*Init field not used in handle to zero */
1313 hspi->RxISR = 0;
1314 hspi->TxISR = 0;
1315 hspi->pTxBuffPtr = NULL;
1316 hspi->TxXferSize = 0;
1317 hspi->TxXferCount = 0;
1318
1319 /* Configure communication direction : 1Line */
1320 if(hspi->Init.Direction == SPI_DIRECTION_1LINE)
1321 {
1322 SPI_1LINE_RX(hspi);
1323 }
1324 else if((hspi->Init.Direction == SPI_DIRECTION_2LINES)&&(hspi->Init.Mode == SPI_MODE_MASTER))
1325 {
1326 /* Process Unlocked */
1327 __HAL_UNLOCK(hspi);
1328
1329 /* Call transmit-receive function to send Dummy data on Tx line and generate clock on CLK line */
1330 return HAL_SPI_TransmitReceive_DMA(hspi, pData, pData, Size);
1331 }
1332
1333 /* Reset CRC Calculation */
1334 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
1335 {
1336 SPI_RESET_CRC(hspi);
1337 }
1338
1339 /* Set the SPI RxDMA Half transfer complete callback */
1340 hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfReceiveCplt;
1341
1342 /* Set the SPI Rx DMA transfer complete callback */
1343 hspi->hdmarx->XferCpltCallback = SPI_DMAReceiveCplt;
1344
1345 /* Set the DMA error callback */
1346 hspi->hdmarx->XferErrorCallback = SPI_DMAError;
1347
1348 /* Reset content of SPI TxDMA descriptor */
1349 hspi->hdmatx->XferHalfCpltCallback = 0;
1350 hspi->hdmatx->XferCpltCallback = 0;
1351 hspi->hdmatx->XferErrorCallback = 0;
1352
1353 /* Enable the Rx DMA Channel */
1354 HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->DR, (uint32_t)hspi->pRxBuffPtr, hspi->RxXferCount);
1355
1356 /* Enable Rx DMA Request */
1357 SET_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN);
1358
1359 /* Process Unlocked */
1360 __HAL_UNLOCK(hspi);
1361
1362 /* Check if the SPI is already enabled */
1363 if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
1364 {
1365 /* Enable SPI peripheral */
1366 __HAL_SPI_ENABLE(hspi);
1367 }
1368
1369 return HAL_OK;
1370 }
1371 else
1372 {
1373 return HAL_BUSY;
1374 }
1375 }
1376
1377 /**
1378 * @brief Transmit and Receive an amount of data in no-blocking mode with DMA
1379 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
1380 * the configuration information for SPI module.
1381 * @param pTxData: pointer to transmission data buffer
1382 * @param pRxData: pointer to reception data buffer
1383 * @note When the CRC feature is enabled the pRxData Length must be Size + 1
1384 * @param Size: amount of data to be sent
1385 * @retval HAL status
1386 */
1387 HAL_StatusTypeDef HAL_SPI_TransmitReceive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
1388 {
1389 if((hspi->State == HAL_SPI_STATE_READY) || \
1390 ((hspi->Init.Mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (hspi->State == HAL_SPI_STATE_BUSY_RX)))
1391 {
1392 if((pTxData == NULL ) || (pRxData == NULL ) || (Size == 0))
1393 {
1394 return HAL_ERROR;
1395 }
1396
1397 /* Check the parameters */
1398 assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));
1399
1400 /* Process locked */
1401 __HAL_LOCK(hspi);
1402
1403 /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */
1404 if(hspi->State != HAL_SPI_STATE_BUSY_RX)
1405 {
1406 hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
1407 }
1408
1409 /* Configure communication */
1410 hspi->ErrorCode = HAL_SPI_ERROR_NONE;
1411
1412 hspi->pTxBuffPtr = (uint8_t*)pTxData;
1413 hspi->TxXferSize = Size;
1414 hspi->TxXferCount = Size;
1415
1416 hspi->pRxBuffPtr = (uint8_t*)pRxData;
1417 hspi->RxXferSize = Size;
1418 hspi->RxXferCount = Size;
1419
1420 /*Init field not used in handle to zero */
1421 hspi->RxISR = 0;
1422 hspi->TxISR = 0;
1423
1424 /* Reset CRC Calculation */
1425 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
1426 {
1427 SPI_RESET_CRC(hspi);
1428 }
1429
1430 /* Check if we are in Rx only or in Rx/Tx Mode and configure the DMA transfer complete callback */
1431 if(hspi->State == HAL_SPI_STATE_BUSY_RX)
1432 {
1433 /* Set the SPI Rx DMA Half transfer complete callback */
1434 hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfReceiveCplt;
1435
1436 hspi->hdmarx->XferCpltCallback = SPI_DMAReceiveCplt;
1437 }
1438 else
1439 {
1440 /* Set the SPI Tx/Rx DMA Half transfer complete callback */
1441 hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfTransmitReceiveCplt;
1442
1443 hspi->hdmarx->XferCpltCallback = SPI_DMATransmitReceiveCplt;
1444 }
1445
1446 /* Set the DMA error callback */
1447 hspi->hdmarx->XferErrorCallback = SPI_DMAError;
1448
1449 /* Enable the Rx DMA Channel */
1450 HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->DR, (uint32_t)hspi->pRxBuffPtr, hspi->RxXferCount);
1451
1452 /* Enable Rx DMA Request */
1453 SET_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN);
1454
1455 /* Set the SPI Tx DMA transfer complete callback as NULL because the communication closing
1456 is performed in DMA reception complete callback */
1457 if(hspi->State == HAL_SPI_STATE_BUSY_TX_RX)
1458 {
1459 /* Set the DMA error callback */
1460 hspi->hdmatx->XferErrorCallback = SPI_DMAError;
1461 }
1462 else
1463 {
1464 hspi->hdmatx->XferErrorCallback = NULL;
1465 }
1466
1467 /* Enable the Tx DMA Channel */
1468 HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->DR, hspi->TxXferCount);
1469
1470 /* Check if the SPI is already enabled */
1471 if((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
1472 {
1473 /* Enable SPI peripheral */
1474 __HAL_SPI_ENABLE(hspi);
1475 }
1476
1477 /* Enable Tx DMA Request */
1478 SET_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN);
1479
1480 /* Process Unlocked */
1481 __HAL_UNLOCK(hspi);
1482
1483 return HAL_OK;
1484 }
1485 else
1486 {
1487 return HAL_BUSY;
1488 }
1489 }
1490
1491
1492 /**
1493 * @brief Pauses the DMA Transfer.
1494 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
1495 * the configuration information for the specified SPI module.
1496 * @retval HAL status
1497 */
1498 HAL_StatusTypeDef HAL_SPI_DMAPause(SPI_HandleTypeDef *hspi)
1499 {
1500 /* Process Locked */
1501 __HAL_LOCK(hspi);
1502
1503 /* Disable the SPI DMA Tx & Rx requests */
1504 CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN);
1505 CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN);
1506
1507 /* Process Unlocked */
1508 __HAL_UNLOCK(hspi);
1509
1510 return HAL_OK;
1511 }
1512
1513 /**
1514 * @brief Resumes the DMA Transfer.
1515 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
1516 * the configuration information for the specified SPI module.
1517 * @retval HAL status
1518 */
1519 HAL_StatusTypeDef HAL_SPI_DMAResume(SPI_HandleTypeDef *hspi)
1520 {
1521 /* Process Locked */
1522 __HAL_LOCK(hspi);
1523
1524 /* Enable the SPI DMA Tx & Rx requests */
1525 SET_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN);
1526 SET_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN);
1527
1528 /* Process Unlocked */
1529 __HAL_UNLOCK(hspi);
1530
1531 return HAL_OK;
1532 }
1533
1534 /**
1535 * @brief Stops the DMA Transfer.
1536 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
1537 * the configuration information for the specified SPI module.
1538 * @retval HAL status
1539 */
1540 HAL_StatusTypeDef HAL_SPI_DMAStop(SPI_HandleTypeDef *hspi)
1541 {
1542 /* The Lock is not implemented on this API to allow the user application
1543 to call the HAL SPI API under callbacks HAL_SPI_TxCpltCallback() or HAL_SPI_RxCpltCallback() or HAL_SPI_TxRxCpltCallback():
1544 when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated
1545 and the correspond call back is executed HAL_SPI_TxCpltCallback() or HAL_SPI_RxCpltCallback() or HAL_SPI_TxRxCpltCallback()
1546 */
1547
1548 /* Abort the SPI DMA tx Channel */
1549 if(hspi->hdmatx != NULL)
1550 {
1551 HAL_DMA_Abort(hspi->hdmatx);
1552 }
1553 /* Abort the SPI DMA rx Channel */
1554 if(hspi->hdmarx != NULL)
1555 {
1556 HAL_DMA_Abort(hspi->hdmarx);
1557 }
1558
1559 /* Disable the SPI DMA Tx & Rx requests */
1560 CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN);
1561 CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN);
1562
1563 hspi->State = HAL_SPI_STATE_READY;
1564
1565 return HAL_OK;
1566 }
1567
1568 /**
1569 * @brief This function handles SPI interrupt request.
1570 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
1571 * the configuration information for SPI module.
1572 * @retval None
1573 */
1574 void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi)
1575 {
1576 /* SPI in mode Receiver and Overrun not occurred ---------------------------*/
1577 if((__HAL_SPI_GET_IT_SOURCE(hspi, SPI_IT_RXNE) != RESET) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE) != RESET) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_OVR) == RESET))
1578 {
1579 hspi->RxISR(hspi);
1580 return;
1581 }
1582
1583 /* SPI in mode Tramitter ---------------------------------------------------*/
1584 if((__HAL_SPI_GET_IT_SOURCE(hspi, SPI_IT_TXE) != RESET) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE) != RESET))
1585 {
1586 hspi->TxISR(hspi);
1587 return;
1588 }
1589
1590 if(__HAL_SPI_GET_IT_SOURCE(hspi, SPI_IT_ERR) != RESET)
1591 {
1592 /* SPI CRC error interrupt occurred ---------------------------------------*/
1593 if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)
1594 {
1595 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
1596 __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
1597 }
1598 /* SPI Mode Fault error interrupt occurred --------------------------------*/
1599 if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_MODF) != RESET)
1600 {
1601 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_MODF);
1602 __HAL_SPI_CLEAR_MODFFLAG(hspi);
1603 }
1604
1605 /* SPI Overrun error interrupt occurred -----------------------------------*/
1606 if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_OVR) != RESET)
1607 {
1608 if(hspi->State != HAL_SPI_STATE_BUSY_TX)
1609 {
1610 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_OVR);
1611 __HAL_SPI_CLEAR_OVRFLAG(hspi);
1612 }
1613 }
1614
1615 /* Call the Error call Back in case of Errors */
1616 if(hspi->ErrorCode!=HAL_SPI_ERROR_NONE)
1617 {
1618 __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXNE | SPI_IT_TXE | SPI_IT_ERR);
1619 hspi->State = HAL_SPI_STATE_READY;
1620 HAL_SPI_ErrorCallback(hspi);
1621 }
1622 }
1623 }
1624
1625 /**
1626 * @brief Tx Transfer completed callbacks
1627 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
1628 * the configuration information for SPI module.
1629 * @retval None
1630 */
1631 __weak void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
1632 {
1633 /* NOTE : This function Should not be modified, when the callback is needed,
1634 the HAL_SPI_TxCpltCallback could be implenetd in the user file
1635 */
1636 }
1637
1638 /**
1639 * @brief Rx Transfer completed callbacks
1640 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
1641 * the configuration information for SPI module.
1642 * @retval None
1643 */
1644 __weak void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
1645 {
1646 /* NOTE : This function Should not be modified, when the callback is needed,
1647 the HAL_SPI_RxCpltCallback() could be implenetd in the user file
1648 */
1649 }
1650
1651 /**
1652 * @brief Tx and Rx Transfer completed callbacks
1653 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
1654 * the configuration information for SPI module.
1655 * @retval None
1656 */
1657 __weak void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
1658 {
1659 /* NOTE : This function Should not be modified, when the callback is needed,
1660 the HAL_SPI_TxRxCpltCallback() could be implenetd in the user file
1661 */
1662 }
1663
1664 /**
1665 * @brief Tx Half Transfer completed callbacks
1666 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
1667 * the configuration information for SPI module.
1668 * @retval None
1669 */
1670 __weak void HAL_SPI_TxHalfCpltCallback(SPI_HandleTypeDef *hspi)
1671 {
1672 /* NOTE : This function Should not be modified, when the callback is needed,
1673 the HAL_SPI_TxHalfCpltCallback could be implenetd in the user file
1674 */
1675 }
1676
1677 /**
1678 * @brief Rx Half Transfer completed callbacks
1679 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
1680 * the configuration information for SPI module.
1681 * @retval None
1682 */
1683 __weak void HAL_SPI_RxHalfCpltCallback(SPI_HandleTypeDef *hspi)
1684 {
1685 /* NOTE : This function Should not be modified, when the callback is needed,
1686 the HAL_SPI_RxHalfCpltCallback() could be implenetd in the user file
1687 */
1688 }
1689
1690 /**
1691 * @brief Tx and Rx Transfer completed callbacks
1692 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
1693 * the configuration information for SPI module.
1694 * @retval None
1695 */
1696 __weak void HAL_SPI_TxRxHalfCpltCallback(SPI_HandleTypeDef *hspi)
1697 {
1698 /* NOTE : This function Should not be modified, when the callback is needed,
1699 the HAL_SPI_TxRxHalfCpltCallback() could be implenetd in the user file
1700 */
1701 }
1702
1703 /**
1704 * @brief SPI error callbacks
1705 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
1706 * the configuration information for SPI module.
1707 * @retval None
1708 */
1709 __weak void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi)
1710 {
1711 /* NOTE : - This function Should not be modified, when the callback is needed,
1712 the HAL_SPI_ErrorCallback() could be implenetd in the user file.
1713 - The ErrorCode parameter in the hspi handle is updated by the SPI processes
1714 and user can use HAL_SPI_GetError() API to check the latest error occurred.
1715 */
1716 }
1717
1718 /**
1719 * @}
1720 */
1721
1722 /** @defgroup SPI_Exported_Functions_Group3 Peripheral State and Errors functions
1723 * @brief SPI control functions
1724 *
1725 @verbatim
1726 ===============================================================================
1727 ##### Peripheral State and Errors functions #####
1728 ===============================================================================
1729 [..]
1730 This subsection provides a set of functions allowing to control the SPI.
1731 (+) HAL_SPI_GetState() API can be helpful to check in run-time the state of the SPI peripheral
1732 (+) HAL_SPI_GetError() check in run-time Errors occurring during communication
1733 @endverbatim
1734 * @{
1735 */
1736
1737 /**
1738 * @brief Return the SPI state
1739 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
1740 * the configuration information for SPI module.
1741 * @retval SPI state
1742 */
1743 HAL_SPI_StateTypeDef HAL_SPI_GetState(SPI_HandleTypeDef *hspi)
1744 {
1745 return hspi->State;
1746 }
1747
1748 /**
1749 * @brief Return the SPI error code
1750 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
1751 * the configuration information for SPI module.
1752 * @retval SPI Error Code
1753 */
1754 uint32_t HAL_SPI_GetError(SPI_HandleTypeDef *hspi)
1755 {
1756 return hspi->ErrorCode;
1757 }
1758
1759 /**
1760 * @}
1761 */
1762
1763 /**
1764 * @}
1765 */
1766
1767
1768
1769 /** @addtogroup SPI_Private_Functions
1770 * @{
1771 */
1772
1773
1774 /**
1775 * @brief Interrupt Handler to close Tx transfer
1776 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
1777 * the configuration information for SPI module.
1778 * @retval None
1779 */
1780 static void SPI_TxCloseIRQHandler(SPI_HandleTypeDef *hspi)
1781 {
1782 /* Wait until TXE flag is set to send data */
1783 if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_TXE, RESET, SPI_TIMEOUT_VALUE) != HAL_OK)
1784 {
1785 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
1786 }
1787
1788 /* Disable TXE interrupt */
1789 __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE));
1790
1791 /* Disable ERR interrupt if Receive process is finished */
1792 if(__HAL_SPI_GET_IT_SOURCE(hspi, SPI_IT_RXNE) == RESET)
1793 {
1794 __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_ERR));
1795
1796 /* Wait until Busy flag is reset before disabling SPI */
1797 if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_BSY, SET, SPI_TIMEOUT_VALUE) != HAL_OK)
1798 {
1799 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
1800 }
1801
1802 /* Clear OVERUN flag in 2 Lines communication mode because received is not read */
1803 if(hspi->Init.Direction == SPI_DIRECTION_2LINES)
1804 {
1805 __HAL_SPI_CLEAR_OVRFLAG(hspi);
1806 }
1807
1808 /* Check if Errors has been detected during transfer */
1809 if(hspi->ErrorCode == HAL_SPI_ERROR_NONE)
1810 {
1811 /* Check if we are in Tx or in Rx/Tx Mode */
1812 if(hspi->State == HAL_SPI_STATE_BUSY_TX_RX)
1813 {
1814 /* Set state to READY before run the Callback Complete */
1815 hspi->State = HAL_SPI_STATE_READY;
1816 HAL_SPI_TxRxCpltCallback(hspi);
1817 }
1818 else
1819 {
1820 /* Set state to READY before run the Callback Complete */
1821 hspi->State = HAL_SPI_STATE_READY;
1822 HAL_SPI_TxCpltCallback(hspi);
1823 }
1824 }
1825 else
1826 {
1827 /* Set state to READY before run the Callback Complete */
1828 hspi->State = HAL_SPI_STATE_READY;
1829 /* Call Error call back in case of Error */
1830 HAL_SPI_ErrorCallback(hspi);
1831 }
1832 }
1833 }
1834
1835 /**
1836 * @brief Interrupt Handler to transmit amount of data in no-blocking mode
1837 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
1838 * the configuration information for SPI module.
1839 * @retval None
1840 */
1841 static void SPI_TxISR(SPI_HandleTypeDef *hspi)
1842 {
1843 /* Transmit data in 8 Bit mode */
1844 if(hspi->Init.DataSize == SPI_DATASIZE_8BIT)
1845 {
1846 hspi->Instance->DR = (*hspi->pTxBuffPtr++);
1847 }
1848 /* Transmit data in 16 Bit mode */
1849 else
1850 {
1851 hspi->Instance->DR = *((uint16_t*)hspi->pTxBuffPtr);
1852 hspi->pTxBuffPtr+=2;
1853 }
1854 hspi->TxXferCount--;
1855
1856 if(hspi->TxXferCount == 0)
1857 {
1858 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
1859 {
1860 /* calculate and transfer CRC on Tx line */
1861 SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
1862 }
1863 SPI_TxCloseIRQHandler(hspi);
1864 }
1865 }
1866
1867 /**
1868 * @brief Interrupt Handler to close Rx transfer
1869 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
1870 * the configuration information for SPI module.
1871 * @retval None
1872 */
1873 static void SPI_RxCloseIRQHandler(SPI_HandleTypeDef *hspi)
1874 {
1875 __IO uint16_t tmpreg = 0;
1876
1877 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
1878 {
1879 /* Wait until RXNE flag is set to read CRC data */
1880 if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, SPI_TIMEOUT_VALUE) != HAL_OK)
1881 {
1882 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
1883 }
1884
1885 /* Read CRC to reset RXNE flag */
1886 tmpreg = hspi->Instance->DR;
1887 UNUSED(tmpreg);
1888
1889 /* Wait until RXNE flag is reset */
1890 if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, SET, SPI_TIMEOUT_VALUE) != HAL_OK)
1891 {
1892 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
1893 }
1894
1895 /* Check if CRC error occurred */
1896 if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)
1897 {
1898 /* Check if CRC error is valid or not (workaround to be applied or not) */
1899 if ( (hspi->State != HAL_SPI_STATE_BUSY_RX)
1900 || (SPI_ISCRCErrorValid(hspi) == SPI_VALID_CRC_ERROR) )
1901 {
1902 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
1903
1904 /* Reset CRC Calculation */
1905 SPI_RESET_CRC(hspi);
1906 }
1907 else
1908 {
1909 __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
1910 }
1911 }
1912 }
1913
1914 /* Disable RXNE interrupt */
1915 __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE));
1916
1917 /* if Transmit process is finished */
1918 if(__HAL_SPI_GET_IT_SOURCE(hspi, SPI_IT_TXE) == RESET)
1919 {
1920 /* Disable ERR interrupt */
1921 __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_ERR));
1922
1923 if((hspi->Init.Mode == SPI_MODE_MASTER)&&((hspi->Init.Direction == SPI_DIRECTION_1LINE)||(hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY)))
1924 {
1925 /* Disable SPI peripheral */
1926 __HAL_SPI_DISABLE(hspi);
1927 }
1928
1929 /* Check if Errors has been detected during transfer */
1930 if(hspi->ErrorCode == HAL_SPI_ERROR_NONE)
1931 {
1932 /* Check if we are in Rx or in Rx/Tx Mode */
1933 if(hspi->State == HAL_SPI_STATE_BUSY_TX_RX)
1934 {
1935 /* Set state to READY before run the Callback Complete */
1936 hspi->State = HAL_SPI_STATE_READY;
1937 HAL_SPI_TxRxCpltCallback(hspi);
1938 }
1939 else
1940 {
1941 /* Set state to READY before run the Callback Complete */
1942 hspi->State = HAL_SPI_STATE_READY;
1943 HAL_SPI_RxCpltCallback(hspi);
1944 }
1945 }
1946 else
1947 {
1948 /* Set state to READY before run the Callback Complete */
1949 hspi->State = HAL_SPI_STATE_READY;
1950 /* Call Error call back in case of Error */
1951 HAL_SPI_ErrorCallback(hspi);
1952 }
1953 }
1954 }
1955
1956 /**
1957 * @brief Interrupt Handler to receive amount of data in 2Lines mode
1958 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
1959 * the configuration information for SPI module.
1960 * @retval None
1961 */
1962 static void SPI_2LinesRxISR(SPI_HandleTypeDef *hspi)
1963 {
1964 /* Receive data in 8 Bit mode */
1965 if(hspi->Init.DataSize == SPI_DATASIZE_8BIT)
1966 {
1967 (*hspi->pRxBuffPtr++) = hspi->Instance->DR;
1968 }
1969 /* Receive data in 16 Bit mode */
1970 else
1971 {
1972 *((uint16_t*)hspi->pRxBuffPtr) = hspi->Instance->DR;
1973 hspi->pRxBuffPtr+=2;
1974 }
1975 hspi->RxXferCount--;
1976
1977 if(hspi->RxXferCount==0)
1978 {
1979 SPI_RxCloseIRQHandler(hspi);
1980 }
1981 }
1982
1983 /**
1984 * @brief Interrupt Handler to receive amount of data in no-blocking mode
1985 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
1986 * the configuration information for SPI module.
1987 * @retval None
1988 */
1989 static void SPI_RxISR(SPI_HandleTypeDef *hspi)
1990 {
1991 /* Receive data in 8 Bit mode */
1992 if(hspi->Init.DataSize == SPI_DATASIZE_8BIT)
1993 {
1994 (*hspi->pRxBuffPtr++) = hspi->Instance->DR;
1995 }
1996 /* Receive data in 16 Bit mode */
1997 else
1998 {
1999 *((uint16_t*)hspi->pRxBuffPtr) = hspi->Instance->DR;
2000 hspi->pRxBuffPtr+=2;
2001 }
2002 hspi->RxXferCount--;
2003
2004 /* Enable CRC Transmission */
2005 if((hspi->RxXferCount == 1) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE))
2006 {
2007 /* Set CRC Next to calculate CRC on Rx side */
2008 SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
2009 }
2010
2011 if(hspi->RxXferCount == 0)
2012 {
2013 SPI_RxCloseIRQHandler(hspi);
2014 }
2015 }
2016
2017 /**
2018 * @brief DMA SPI transmit process complete callback
2019 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
2020 * the configuration information for the specified DMA module.
2021 * @retval None
2022 */
2023 static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma)
2024 {
2025 SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
2026
2027 /* DMA Normal Mode */
2028 if((hdma->Instance->CCR & DMA_CIRCULAR) == 0)
2029 {
2030 /* Wait until TXE flag is set to send data */
2031 if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_TXE, RESET, SPI_TIMEOUT_VALUE) != HAL_OK)
2032 {
2033 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
2034 }
2035
2036 /* Disable Tx DMA Request */
2037 CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN);
2038
2039 /* Wait until Busy flag is reset before disabling SPI */
2040 if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_BSY, SET, SPI_TIMEOUT_VALUE) != HAL_OK)
2041 {
2042 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
2043 }
2044
2045 hspi->TxXferCount = 0;
2046 hspi->State = HAL_SPI_STATE_READY;
2047 }
2048
2049 /* Clear OVERUN flag in 2 Lines communication mode because received is not read */
2050 if(hspi->Init.Direction == SPI_DIRECTION_2LINES)
2051 {
2052 __HAL_SPI_CLEAR_OVRFLAG(hspi);
2053 }
2054
2055 /* Check if Errors has been detected during transfer */
2056 if(hspi->ErrorCode != HAL_SPI_ERROR_NONE)
2057 {
2058 HAL_SPI_ErrorCallback(hspi);
2059 }
2060 else
2061 {
2062 HAL_SPI_TxCpltCallback(hspi);
2063 }
2064 }
2065
2066 /**
2067 * @brief DMA SPI receive process complete callback
2068 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
2069 * the configuration information for the specified DMA module.
2070 * @retval None
2071 */
2072 static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
2073 {
2074 __IO uint16_t tmpreg = 0;
2075 SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
2076
2077 /* DMA Normal mode */
2078 if((hdma->Instance->CCR & DMA_CIRCULAR) == 0)
2079 {
2080 /* Disable Rx DMA Request */
2081 CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN);
2082
2083 /* Disable Tx DMA Request (done by default to handle the case Master RX direction 2 lines) */
2084 CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN);
2085
2086 /* CRC Calculation handling */
2087 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
2088 {
2089 /* Wait until RXNE flag is set (CRC ready) */
2090 if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, SPI_TIMEOUT_VALUE) != HAL_OK)
2091 {
2092 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
2093 }
2094
2095 /* Read CRC */
2096 tmpreg = hspi->Instance->DR;
2097 UNUSED(tmpreg);
2098
2099 /* Wait until RXNE flag is reset */
2100 if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, SET, SPI_TIMEOUT_VALUE) != HAL_OK)
2101 {
2102 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
2103 }
2104
2105 /* Check if CRC error occurred */
2106 if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)
2107 {
2108 /* Check if CRC error is valid or not (workaround to be applied or not) */
2109 if (SPI_ISCRCErrorValid(hspi) == SPI_VALID_CRC_ERROR)
2110 {
2111 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
2112
2113 /* Reset CRC Calculation */
2114 SPI_RESET_CRC(hspi);
2115 }
2116 __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
2117 }
2118 }
2119
2120 if((hspi->Init.Mode == SPI_MODE_MASTER)&&((hspi->Init.Direction == SPI_DIRECTION_1LINE)||(hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY)))
2121 {
2122 /* Disable SPI peripheral */
2123 __HAL_SPI_DISABLE(hspi);
2124 }
2125
2126 hspi->RxXferCount = 0;
2127 hspi->State = HAL_SPI_STATE_READY;
2128
2129 /* Check if Errors has been detected during transfer */
2130 if(hspi->ErrorCode != HAL_SPI_ERROR_NONE)
2131 {
2132 HAL_SPI_ErrorCallback(hspi);
2133 }
2134 else
2135 {
2136 HAL_SPI_RxCpltCallback(hspi);
2137 }
2138 }
2139 else
2140 {
2141 HAL_SPI_RxCpltCallback(hspi);
2142 }
2143 }
2144
2145 /**
2146 * @brief DMA SPI transmit receive process complete callback
2147 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
2148 * the configuration information for the specified DMA module.
2149 * @retval None
2150 */
2151 static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma)
2152 {
2153 __IO uint16_t tmpreg = 0;
2154
2155 SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
2156
2157 if((hdma->Instance->CCR & DMA_CIRCULAR) == 0)
2158 {
2159 /* CRC Calculation handling */
2160 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
2161 {
2162 /* Check if CRC is done on going (RXNE flag set) */
2163 if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, SET, SPI_TIMEOUT_VALUE) == HAL_OK)
2164 {
2165 /* Wait until RXNE flag is set to send data */
2166 if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, SPI_TIMEOUT_VALUE) != HAL_OK)
2167 {
2168 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
2169 }
2170 }
2171 /* Read CRC */
2172 tmpreg = hspi->Instance->DR;
2173 UNUSED(tmpreg);
2174
2175 /* Check if CRC error occurred */
2176 if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)
2177 {
2178 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
2179 __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
2180 }
2181 }
2182
2183 /* Wait until TXE flag is set to send data */
2184 if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_TXE, RESET, SPI_TIMEOUT_VALUE) != HAL_OK)
2185 {
2186 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
2187 }
2188
2189 /* Disable Tx DMA Request */
2190 CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN);
2191
2192 /* Wait until Busy flag is reset before disabling SPI */
2193 if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_BSY, SET, SPI_TIMEOUT_VALUE) != HAL_OK)
2194 {
2195 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
2196 }
2197
2198 /* Disable Rx DMA Request */
2199 CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN);
2200
2201 hspi->TxXferCount = 0;
2202 hspi->RxXferCount = 0;
2203
2204 hspi->State = HAL_SPI_STATE_READY;
2205
2206 /* Check if Errors has been detected during transfer */
2207 if(hspi->ErrorCode != HAL_SPI_ERROR_NONE)
2208 {
2209 HAL_SPI_ErrorCallback(hspi);
2210 }
2211 else
2212 {
2213 HAL_SPI_TxRxCpltCallback(hspi);
2214 }
2215 }
2216 else
2217 {
2218 HAL_SPI_TxRxCpltCallback(hspi);
2219 }
2220 }
2221
2222 /**
2223 * @brief DMA SPI half transmit process complete callback
2224 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
2225 * the configuration information for the specified DMA module.
2226 * @retval None
2227 */
2228 static void SPI_DMAHalfTransmitCplt(DMA_HandleTypeDef *hdma)
2229 {
2230 SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
2231
2232 HAL_SPI_TxHalfCpltCallback(hspi);
2233 }
2234
2235 /**
2236 * @brief DMA SPI half receive process complete callback
2237 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
2238 * the configuration information for the specified DMA module.
2239 * @retval None
2240 */
2241 static void SPI_DMAHalfReceiveCplt(DMA_HandleTypeDef *hdma)
2242 {
2243 SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
2244
2245 HAL_SPI_RxHalfCpltCallback(hspi);
2246 }
2247
2248 /**
2249 * @brief DMA SPI Half transmit receive process complete callback
2250 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
2251 * the configuration information for the specified DMA module.
2252 * @retval None
2253 */
2254 static void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma)
2255 {
2256 SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
2257
2258 HAL_SPI_TxRxHalfCpltCallback(hspi);
2259 }
2260
2261 /**
2262 * @brief DMA SPI communication error callback
2263 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
2264 * the configuration information for the specified DMA module.
2265 * @retval None
2266 */
2267 static void SPI_DMAError(DMA_HandleTypeDef *hdma)
2268 {
2269 SPI_HandleTypeDef* hspi = (SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
2270 hspi->TxXferCount = 0;
2271 hspi->RxXferCount = 0;
2272 hspi->State= HAL_SPI_STATE_READY;
2273 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
2274 HAL_SPI_ErrorCallback(hspi);
2275 }
2276
2277 /**
2278 * @brief This function handles SPI Communication Timeout.
2279 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
2280 * the configuration information for SPI module.
2281 * @param Flag: SPI flag to check
2282 * @param Status: Flag status to check: RESET or set
2283 * @param Timeout: Timeout duration
2284 * @retval HAL status
2285 */
2286 static HAL_StatusTypeDef SPI_WaitOnFlagUntilTimeout(SPI_HandleTypeDef *hspi, uint32_t Flag, FlagStatus Status, uint32_t Timeout)
2287 {
2288 uint32_t tickstart = 0;
2289
2290 /* Get tick */
2291 tickstart = HAL_GetTick();
2292
2293 /* Wait until flag is set */
2294 if(Status == RESET)
2295 {
2296 while(__HAL_SPI_GET_FLAG(hspi, Flag) == RESET)
2297 {
2298 if(Timeout != HAL_MAX_DELAY)
2299 {
2300 if((Timeout == 0) || ((HAL_GetTick() - tickstart ) > Timeout))
2301 {
2302 /* Disable the SPI and reset the CRC: the CRC value should be cleared
2303 on both master and slave sides in order to resynchronize the master
2304 and slave for their respective CRC calculation */
2305
2306 /* Disable TXE, RXNE and ERR interrupts for the interrupt process */
2307 __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR));
2308
2309 /* Disable SPI peripheral */
2310 __HAL_SPI_DISABLE(hspi);
2311
2312 /* Reset CRC Calculation */
2313 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
2314 {
2315 SPI_RESET_CRC(hspi);
2316 }
2317
2318 hspi->State= HAL_SPI_STATE_READY;
2319
2320 /* Process Unlocked */
2321 __HAL_UNLOCK(hspi);
2322
2323 return HAL_TIMEOUT;
2324 }
2325 }
2326 }
2327 }
2328 else
2329 {
2330 while(__HAL_SPI_GET_FLAG(hspi, Flag) != RESET)
2331 {
2332 if(Timeout != HAL_MAX_DELAY)
2333 {
2334 if((Timeout == 0) || ((HAL_GetTick() - tickstart ) > Timeout))
2335 {
2336 /* Disable the SPI and reset the CRC: the CRC value should be cleared
2337 on both master and slave sides in order to resynchronize the master
2338 and slave for their respective CRC calculation */
2339
2340 /* Disable TXE, RXNE and ERR interrupts for the interrupt process */
2341 __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR));
2342
2343 /* Disable SPI peripheral */
2344 __HAL_SPI_DISABLE(hspi);
2345
2346 /* Reset CRC Calculation */
2347 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
2348 {
2349 SPI_RESET_CRC(hspi);
2350 }
2351
2352 hspi->State= HAL_SPI_STATE_READY;
2353
2354 /* Process Unlocked */
2355 __HAL_UNLOCK(hspi);
2356
2357 return HAL_TIMEOUT;
2358 }
2359 }
2360 }
2361 }
2362 return HAL_OK;
2363 }
2364
2365 /**
2366 * @}
2367 */
2368
2369 /** @addtogroup SPI_Private_Functions
2370 * @{
2371 */
2372
2373 /**
2374 * @brief Checks if encountered CRC error could be corresponding to wrongly detected errors
2375 * according to SPI instance, Device type, and revision ID.
2376 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
2377 * the configuration information for SPI module.
2378 * @retval CRC error validity (SPI_INVALID_CRC_ERROR or SPI_VALID_CRC_ERROR).
2379 */
2380 __weak uint8_t SPI_ISCRCErrorValid(SPI_HandleTypeDef *hspi)
2381 {
2382 return (SPI_VALID_CRC_ERROR);
2383 }
2384 /**
2385 * @}
2386 */
2387
2388
2389 #endif /* HAL_SPI_MODULE_ENABLED */
2390 /**
2391 * @}
2392 */
2393
2394 /**
2395 * @}
2396 */
2397
2398 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Imprint / Impressum