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