38
|
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****/
|