source: asp3_wo_tecs/trunk/arch/arm_m_gcc/stm32f4xx_stm32cube/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c@ 303

Last change on this file since 303 was 303, checked in by ertl-honda, 7 years ago

nucleo_f401re依存部の追加

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