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