Mercurial > public > ostc4
comparison Common/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c @ 128:c78bcbd5deda FlipDisplay
Added current STM32 standandard libraries in version independend folder structure
author | Ideenmodellierer |
---|---|
date | Sun, 17 Feb 2019 21:12:22 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
127:1369f8660eaa | 128:c78bcbd5deda |
---|---|
1 /** | |
2 ****************************************************************************** | |
3 * @file stm32f4xx_hal_spi.c | |
4 * @author MCD Application Team | |
5 * @brief SPI HAL module driver. | |
6 * This file provides firmware functions to manage the following | |
7 * functionalities of the Serial Peripheral Interface (SPI) peripheral: | |
8 * + Initialization and de-initialization functions | |
9 * + IO operation functions | |
10 * + Peripheral Control functions | |
11 * + Peripheral State functions | |
12 * | |
13 @verbatim | |
14 ============================================================================== | |
15 ##### How to use this driver ##### | |
16 ============================================================================== | |
17 [..] | |
18 The SPI HAL driver can be used as follows: | |
19 | |
20 (#) Declare a SPI_HandleTypeDef handle structure, for example: | |
21 SPI_HandleTypeDef hspi; | |
22 | |
23 (#)Initialize the SPI low level resources by implementing the HAL_SPI_MspInit() API: | |
24 (##) Enable the SPIx interface clock | |
25 (##) SPI pins configuration | |
26 (+++) Enable the clock for the SPI GPIOs | |
27 (+++) Configure these SPI pins as alternate function push-pull | |
28 (##) NVIC configuration if you need to use interrupt process | |
29 (+++) Configure the SPIx interrupt priority | |
30 (+++) Enable the NVIC SPI IRQ handle | |
31 (##) DMA Configuration if you need to use DMA process | |
32 (+++) Declare a DMA_HandleTypeDef handle structure for the transmit or receive stream | |
33 (+++) Enable the DMAx clock | |
34 (+++) Configure the DMA handle parameters | |
35 (+++) Configure the DMA Tx or Rx stream | |
36 (+++) Associate the initialized hdma_tx handle to the hspi DMA Tx or Rx handle | |
37 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx or Rx stream | |
38 | |
39 (#) Program the Mode, BidirectionalMode , Data size, Baudrate Prescaler, NSS | |
40 management, Clock polarity and phase, FirstBit and CRC configuration in the hspi Init structure. | |
41 | |
42 (#) Initialize the SPI registers by calling the HAL_SPI_Init() API: | |
43 (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc) | |
44 by calling the customized HAL_SPI_MspInit() API. | |
45 [..] | |
46 Circular mode restriction: | |
47 (#) The DMA circular mode cannot be used when the SPI is configured in these modes: | |
48 (##) Master 2Lines RxOnly | |
49 (##) Master 1Line Rx | |
50 (#) The CRC feature is not managed when the DMA circular mode is enabled | |
51 (#) When the SPI DMA Pause/Stop features are used, we must use the following APIs | |
52 the HAL_SPI_DMAPause()/ HAL_SPI_DMAStop() only under the SPI callbacks | |
53 [..] | |
54 Master Receive mode restriction: | |
55 (#) In Master unidirectional receive-only mode (MSTR =1, BIDIMODE=0, RXONLY=0) or | |
56 bidirectional receive mode (MSTR=1, BIDIMODE=1, BIDIOE=0), to ensure that the SPI | |
57 does not initiate a new transfer the following procedure has to be respected: | |
58 (##) HAL_SPI_DeInit() | |
59 (##) HAL_SPI_Init() | |
60 | |
61 @endverbatim | |
62 | |
63 Using the HAL it is not possible to reach all supported SPI frequency with the differents SPI Modes, | |
64 the following tables resume the max SPI frequency reached with data size 8bits/16bits, | |
65 according to frequency used on APBx Peripheral Clock (fPCLK) used by the SPI instance : | |
66 | |
67 DataSize = SPI_DATASIZE_8BIT: | |
68 +----------------------------------------------------------------------------------------------+ | |
69 | | | 2Lines Fullduplex | 2Lines RxOnly | 1Line | | |
70 | Process | Tranfert mode |---------------------|----------------------|----------------------| | |
71 | | | Master | Slave | Master | Slave | Master | Slave | | |
72 |==============================================================================================| | |
73 | T | Polling | Fpclk/2 | Fpclk/2 | NA | NA | NA | NA | | |
74 | X |----------------|----------|----------|-----------|----------|-----------|----------| | |
75 | / | Interrupt | Fpclk/4 | Fpclk/8 | NA | NA | NA | NA | | |
76 | R |----------------|----------|----------|-----------|----------|-----------|----------| | |
77 | X | DMA | Fpclk/2 | Fpclk/2 | NA | NA | NA | NA | | |
78 |=========|================|==========|==========|===========|==========|===========|==========| | |
79 | | Polling | Fpclk/2 | Fpclk/2 | Fpclk/64 | Fpclk/2 | Fpclk/64 | Fpclk/2 | | |
80 | |----------------|----------|----------|-----------|----------|-----------|----------| | |
81 | R | Interrupt | Fpclk/8 | Fpclk/8 | Fpclk/64 | Fpclk/2 | Fpclk/64 | Fpclk/2 | | |
82 | X |----------------|----------|----------|-----------|----------|-----------|----------| | |
83 | | DMA | Fpclk/2 | Fpclk/2 | Fpclk/64 | Fpclk/2 | Fpclk/128 | Fpclk/2 | | |
84 |=========|================|==========|==========|===========|==========|===========|==========| | |
85 | | Polling | Fpclk/2 | Fpclk/4 | NA | NA | Fpclk/2 | Fpclk/64 | | |
86 | |----------------|----------|----------|-----------|----------|-----------|----------| | |
87 | T | Interrupt | Fpclk/2 | Fpclk/4 | NA | NA | Fpclk/2 | Fpclk/64 | | |
88 | X |----------------|----------|----------|-----------|----------|-----------|----------| | |
89 | | DMA | Fpclk/2 | Fpclk/2 | NA | NA | Fpclk/2 | Fpclk/128| | |
90 +----------------------------------------------------------------------------------------------+ | |
91 | |
92 DataSize = SPI_DATASIZE_16BIT: | |
93 +----------------------------------------------------------------------------------------------+ | |
94 | | | 2Lines Fullduplex | 2Lines RxOnly | 1Line | | |
95 | Process | Tranfert mode |---------------------|----------------------|----------------------| | |
96 | | | Master | Slave | Master | Slave | Master | Slave | | |
97 |==============================================================================================| | |
98 | T | Polling | Fpclk/2 | Fpclk/2 | NA | NA | NA | NA | | |
99 | X |----------------|----------|----------|-----------|----------|-----------|----------| | |
100 | / | Interrupt | Fpclk/4 | Fpclk/4 | NA | NA | NA | NA | | |
101 | R |----------------|----------|----------|-----------|----------|-----------|----------| | |
102 | X | DMA | Fpclk/2 | Fpclk/2 | NA | NA | NA | NA | | |
103 |=========|================|==========|==========|===========|==========|===========|==========| | |
104 | | Polling | Fpclk/2 | Fpclk/2 | Fpclk/64 | Fpclk/2 | Fpclk/32 | Fpclk/2 | | |
105 | |----------------|----------|----------|-----------|----------|-----------|----------| | |
106 | R | Interrupt | Fpclk/4 | Fpclk/4 | Fpclk/64 | Fpclk/2 | Fpclk/64 | Fpclk/2 | | |
107 | X |----------------|----------|----------|-----------|----------|-----------|----------| | |
108 | | DMA | Fpclk/2 | Fpclk/2 | Fpclk/64 | Fpclk/2 | Fpclk/128 | Fpclk/2 | | |
109 |=========|================|==========|==========|===========|==========|===========|==========| | |
110 | | Polling | Fpclk/2 | Fpclk/2 | NA | NA | Fpclk/2 | Fpclk/32 | | |
111 | |----------------|----------|----------|-----------|----------|-----------|----------| | |
112 | T | Interrupt | Fpclk/2 | Fpclk/2 | NA | NA | Fpclk/2 | Fpclk/64 | | |
113 | X |----------------|----------|----------|-----------|----------|-----------|----------| | |
114 | | DMA | Fpclk/2 | Fpclk/2 | NA | NA | Fpclk/2 | Fpclk/128| | |
115 +----------------------------------------------------------------------------------------------+ | |
116 [..] | |
117 (@) The max SPI frequency depend on SPI data size (8bits, 16bits), | |
118 SPI mode(2 Lines fullduplex, 2 lines RxOnly, 1 line TX/RX) and Process mode (Polling, IT, DMA). | |
119 (@) | |
120 (+@) TX/RX processes are HAL_SPI_TransmitReceive(), HAL_SPI_TransmitReceive_IT() and HAL_SPI_TransmitReceive_DMA() | |
121 (+@) RX processes are HAL_SPI_Receive(), HAL_SPI_Receive_IT() and HAL_SPI_Receive_DMA() | |
122 (+@) TX processes are HAL_SPI_Transmit(), HAL_SPI_Transmit_IT() and HAL_SPI_Transmit_DMA() | |
123 ****************************************************************************** | |
124 * @attention | |
125 * | |
126 * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2> | |
127 * | |
128 * Redistribution and use in source and binary forms, with or without modification, | |
129 * are permitted provided that the following conditions are met: | |
130 * 1. Redistributions of source code must retain the above copyright notice, | |
131 * this list of conditions and the following disclaimer. | |
132 * 2. Redistributions in binary form must reproduce the above copyright notice, | |
133 * this list of conditions and the following disclaimer in the documentation | |
134 * and/or other materials provided with the distribution. | |
135 * 3. Neither the name of STMicroelectronics nor the names of its contributors | |
136 * may be used to endorse or promote products derived from this software | |
137 * without specific prior written permission. | |
138 * | |
139 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
140 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
141 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
142 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | |
143 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
144 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
145 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |
146 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |
147 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
148 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
149 * | |
150 ****************************************************************************** | |
151 */ | |
152 | |
153 /* Includes ------------------------------------------------------------------*/ | |
154 #include "stm32f4xx_hal.h" | |
155 | |
156 /** @addtogroup STM32F4xx_HAL_Driver | |
157 * @{ | |
158 */ | |
159 /** @defgroup SPI SPI | |
160 * @brief SPI HAL module driver | |
161 * @{ | |
162 */ | |
163 #ifdef HAL_SPI_MODULE_ENABLED | |
164 | |
165 /* Private typedef -----------------------------------------------------------*/ | |
166 /* Private defines -----------------------------------------------------------*/ | |
167 /** @defgroup SPI_Private_Constants SPI Private Constants | |
168 * @{ | |
169 */ | |
170 #define SPI_DEFAULT_TIMEOUT 100U | |
171 /** | |
172 * @} | |
173 */ | |
174 | |
175 /* Private macros ------------------------------------------------------------*/ | |
176 /* Private variables ---------------------------------------------------------*/ | |
177 /* Private function prototypes -----------------------------------------------*/ | |
178 /** @addtogroup SPI_Private_Functions | |
179 * @{ | |
180 */ | |
181 static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma); | |
182 static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma); | |
183 static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma); | |
184 static void SPI_DMAHalfTransmitCplt(DMA_HandleTypeDef *hdma); | |
185 static void SPI_DMAHalfReceiveCplt(DMA_HandleTypeDef *hdma); | |
186 static void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma); | |
187 static void SPI_DMAError(DMA_HandleTypeDef *hdma); | |
188 static void SPI_DMAAbortOnError(DMA_HandleTypeDef *hdma); | |
189 static void SPI_DMATxAbortCallback(DMA_HandleTypeDef *hdma); | |
190 static void SPI_DMARxAbortCallback(DMA_HandleTypeDef *hdma); | |
191 static HAL_StatusTypeDef SPI_WaitFlagStateUntilTimeout(SPI_HandleTypeDef *hspi, uint32_t Flag, uint32_t State, uint32_t Timeout, uint32_t Tickstart); | |
192 static void SPI_TxISR_8BIT(struct __SPI_HandleTypeDef *hspi); | |
193 static void SPI_TxISR_16BIT(struct __SPI_HandleTypeDef *hspi); | |
194 static void SPI_RxISR_8BIT(struct __SPI_HandleTypeDef *hspi); | |
195 static void SPI_RxISR_16BIT(struct __SPI_HandleTypeDef *hspi); | |
196 static void SPI_2linesRxISR_8BIT(struct __SPI_HandleTypeDef *hspi); | |
197 static void SPI_2linesTxISR_8BIT(struct __SPI_HandleTypeDef *hspi); | |
198 static void SPI_2linesTxISR_16BIT(struct __SPI_HandleTypeDef *hspi); | |
199 static void SPI_2linesRxISR_16BIT(struct __SPI_HandleTypeDef *hspi); | |
200 #if (USE_SPI_CRC != 0U) | |
201 static void SPI_RxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi); | |
202 static void SPI_RxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi); | |
203 static void SPI_2linesRxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi); | |
204 static void SPI_2linesRxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi); | |
205 #endif /* USE_SPI_CRC */ | |
206 static void SPI_AbortRx_ISR(SPI_HandleTypeDef *hspi); | |
207 static void SPI_AbortTx_ISR(SPI_HandleTypeDef *hspi); | |
208 static void SPI_CloseRxTx_ISR(SPI_HandleTypeDef *hspi); | |
209 static void SPI_CloseRx_ISR(SPI_HandleTypeDef *hspi); | |
210 static void SPI_CloseTx_ISR(SPI_HandleTypeDef *hspi); | |
211 static HAL_StatusTypeDef SPI_CheckFlag_BSY(SPI_HandleTypeDef *hspi, uint32_t Timeout, uint32_t Tickstart); | |
212 /** | |
213 * @} | |
214 */ | |
215 | |
216 /* Exported functions --------------------------------------------------------*/ | |
217 /** @defgroup SPI_Exported_Functions SPI Exported Functions | |
218 * @{ | |
219 */ | |
220 | |
221 /** @defgroup SPI_Exported_Functions_Group1 Initialization and de-initialization functions | |
222 * @brief Initialization and Configuration functions | |
223 * | |
224 @verbatim | |
225 =============================================================================== | |
226 ##### Initialization and de-initialization functions ##### | |
227 =============================================================================== | |
228 [..] This subsection provides a set of functions allowing to initialize and | |
229 de-initialize the SPIx peripheral: | |
230 | |
231 (+) User must implement HAL_SPI_MspInit() function in which he configures | |
232 all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ). | |
233 | |
234 (+) Call the function HAL_SPI_Init() to configure the selected device with | |
235 the selected configuration: | |
236 (++) Mode | |
237 (++) Direction | |
238 (++) Data Size | |
239 (++) Clock Polarity and Phase | |
240 (++) NSS Management | |
241 (++) BaudRate Prescaler | |
242 (++) FirstBit | |
243 (++) TIMode | |
244 (++) CRC Calculation | |
245 (++) CRC Polynomial if CRC enabled | |
246 | |
247 (+) Call the function HAL_SPI_DeInit() to restore the default configuration | |
248 of the selected SPIx peripheral. | |
249 | |
250 @endverbatim | |
251 * @{ | |
252 */ | |
253 | |
254 /** | |
255 * @brief Initialize the SPI according to the specified parameters | |
256 * in the SPI_InitTypeDef and initialize the associated handle. | |
257 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
258 * the configuration information for SPI module. | |
259 * @retval HAL status | |
260 */ | |
261 HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi) | |
262 { | |
263 /* Check the SPI handle allocation */ | |
264 if(hspi == NULL) | |
265 { | |
266 return HAL_ERROR; | |
267 } | |
268 | |
269 /* Check the parameters */ | |
270 assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance)); | |
271 assert_param(IS_SPI_MODE(hspi->Init.Mode)); | |
272 assert_param(IS_SPI_DIRECTION(hspi->Init.Direction)); | |
273 assert_param(IS_SPI_DATASIZE(hspi->Init.DataSize)); | |
274 assert_param(IS_SPI_NSS(hspi->Init.NSS)); | |
275 assert_param(IS_SPI_BAUDRATE_PRESCALER(hspi->Init.BaudRatePrescaler)); | |
276 assert_param(IS_SPI_FIRST_BIT(hspi->Init.FirstBit)); | |
277 assert_param(IS_SPI_TIMODE(hspi->Init.TIMode)); | |
278 if(hspi->Init.TIMode == SPI_TIMODE_DISABLE) | |
279 { | |
280 assert_param(IS_SPI_CPOL(hspi->Init.CLKPolarity)); | |
281 assert_param(IS_SPI_CPHA(hspi->Init.CLKPhase)); | |
282 } | |
283 #if (USE_SPI_CRC != 0U) | |
284 assert_param(IS_SPI_CRC_CALCULATION(hspi->Init.CRCCalculation)); | |
285 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) | |
286 { | |
287 assert_param(IS_SPI_CRC_POLYNOMIAL(hspi->Init.CRCPolynomial)); | |
288 } | |
289 #else | |
290 hspi->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; | |
291 #endif /* USE_SPI_CRC */ | |
292 | |
293 if(hspi->State == HAL_SPI_STATE_RESET) | |
294 { | |
295 /* Allocate lock resource and initialize it */ | |
296 hspi->Lock = HAL_UNLOCKED; | |
297 | |
298 /* Init the low level hardware : GPIO, CLOCK, NVIC... */ | |
299 HAL_SPI_MspInit(hspi); | |
300 } | |
301 | |
302 hspi->State = HAL_SPI_STATE_BUSY; | |
303 | |
304 /* Disable the selected SPI peripheral */ | |
305 __HAL_SPI_DISABLE(hspi); | |
306 | |
307 /*----------------------- SPIx CR1 & CR2 Configuration ---------------------*/ | |
308 /* Configure : SPI Mode, Communication Mode, Data size, Clock polarity and phase, NSS management, | |
309 Communication speed, First bit and CRC calculation state */ | |
310 WRITE_REG(hspi->Instance->CR1, (hspi->Init.Mode | hspi->Init.Direction | hspi->Init.DataSize | | |
311 hspi->Init.CLKPolarity | hspi->Init.CLKPhase | (hspi->Init.NSS & SPI_CR1_SSM) | | |
312 hspi->Init.BaudRatePrescaler | hspi->Init.FirstBit | hspi->Init.CRCCalculation) ); | |
313 | |
314 /* Configure : NSS management */ | |
315 WRITE_REG(hspi->Instance->CR2, (((hspi->Init.NSS >> 16U) & SPI_CR2_SSOE) | hspi->Init.TIMode)); | |
316 | |
317 #if (USE_SPI_CRC != 0U) | |
318 /*---------------------------- SPIx CRCPOLY Configuration ------------------*/ | |
319 /* Configure : CRC Polynomial */ | |
320 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) | |
321 { | |
322 WRITE_REG(hspi->Instance->CRCPR, hspi->Init.CRCPolynomial); | |
323 } | |
324 #endif /* USE_SPI_CRC */ | |
325 | |
326 #if defined(SPI_I2SCFGR_I2SMOD) | |
327 /* Activate the SPI mode (Make sure that I2SMOD bit in I2SCFGR register is reset) */ | |
328 CLEAR_BIT(hspi->Instance->I2SCFGR, SPI_I2SCFGR_I2SMOD); | |
329 #endif /* USE_SPI_CRC */ | |
330 | |
331 hspi->ErrorCode = HAL_SPI_ERROR_NONE; | |
332 hspi->State = HAL_SPI_STATE_READY; | |
333 | |
334 return HAL_OK; | |
335 } | |
336 | |
337 /** | |
338 * @brief De Initialize the SPI peripheral. | |
339 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
340 * the configuration information for SPI module. | |
341 * @retval HAL status | |
342 */ | |
343 HAL_StatusTypeDef HAL_SPI_DeInit(SPI_HandleTypeDef *hspi) | |
344 { | |
345 /* Check the SPI handle allocation */ | |
346 if(hspi == NULL) | |
347 { | |
348 return HAL_ERROR; | |
349 } | |
350 | |
351 /* Check SPI Instance parameter */ | |
352 assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance)); | |
353 | |
354 hspi->State = HAL_SPI_STATE_BUSY; | |
355 | |
356 /* Disable the SPI Peripheral Clock */ | |
357 __HAL_SPI_DISABLE(hspi); | |
358 | |
359 /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */ | |
360 HAL_SPI_MspDeInit(hspi); | |
361 | |
362 hspi->ErrorCode = HAL_SPI_ERROR_NONE; | |
363 hspi->State = HAL_SPI_STATE_RESET; | |
364 | |
365 /* Release Lock */ | |
366 __HAL_UNLOCK(hspi); | |
367 | |
368 return HAL_OK; | |
369 } | |
370 | |
371 /** | |
372 * @brief Initialize the SPI MSP. | |
373 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
374 * the configuration information for SPI module. | |
375 * @retval None | |
376 */ | |
377 __weak void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi) | |
378 { | |
379 /* Prevent unused argument(s) compilation warning */ | |
380 UNUSED(hspi); | |
381 /* NOTE : This function should not be modified, when the callback is needed, | |
382 the HAL_SPI_MspInit should be implemented in the user file | |
383 */ | |
384 } | |
385 | |
386 /** | |
387 * @brief De-Initialize the SPI MSP. | |
388 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
389 * the configuration information for SPI module. | |
390 * @retval None | |
391 */ | |
392 __weak void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi) | |
393 { | |
394 /* Prevent unused argument(s) compilation warning */ | |
395 UNUSED(hspi); | |
396 /* NOTE : This function should not be modified, when the callback is needed, | |
397 the HAL_SPI_MspDeInit should be implemented in the user file | |
398 */ | |
399 } | |
400 | |
401 /** | |
402 * @} | |
403 */ | |
404 | |
405 /** @defgroup SPI_Exported_Functions_Group2 IO operation functions | |
406 * @brief Data transfers functions | |
407 * | |
408 @verbatim | |
409 ============================================================================== | |
410 ##### IO operation functions ##### | |
411 =============================================================================== | |
412 [..] | |
413 This subsection provides a set of functions allowing to manage the SPI | |
414 data transfers. | |
415 | |
416 [..] The SPI supports master and slave mode : | |
417 | |
418 (#) There are two modes of transfer: | |
419 (++) Blocking mode: The communication is performed in polling mode. | |
420 The HAL status of all data processing is returned by the same function | |
421 after finishing transfer. | |
422 (++) No-Blocking mode: The communication is performed using Interrupts | |
423 or DMA, These APIs return the HAL status. | |
424 The end of the data processing will be indicated through the | |
425 dedicated SPI IRQ when using Interrupt mode or the DMA IRQ when | |
426 using DMA mode. | |
427 The HAL_SPI_TxCpltCallback(), HAL_SPI_RxCpltCallback() and HAL_SPI_TxRxCpltCallback() user callbacks | |
428 will be executed respectively at the end of the transmit or Receive process | |
429 The HAL_SPI_ErrorCallback()user callback will be executed when a communication error is detected | |
430 | |
431 (#) APIs provided for these 2 transfer modes (Blocking mode or Non blocking mode using either Interrupt or DMA) | |
432 exist for 1Line (simplex) and 2Lines (full duplex) modes. | |
433 | |
434 @endverbatim | |
435 * @{ | |
436 */ | |
437 | |
438 /** | |
439 * @brief Transmit an amount of data in blocking mode. | |
440 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
441 * the configuration information for SPI module. | |
442 * @param pData pointer to data buffer | |
443 * @param Size amount of data to be sent | |
444 * @param Timeout Timeout duration | |
445 * @retval HAL status | |
446 */ | |
447 HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout) | |
448 { | |
449 uint32_t tickstart = 0U; | |
450 HAL_StatusTypeDef errorcode = HAL_OK; | |
451 | |
452 /* Check Direction parameter */ | |
453 assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction)); | |
454 | |
455 /* Process Locked */ | |
456 __HAL_LOCK(hspi); | |
457 | |
458 /* Init tickstart for timeout management*/ | |
459 tickstart = HAL_GetTick(); | |
460 | |
461 if(hspi->State != HAL_SPI_STATE_READY) | |
462 { | |
463 errorcode = HAL_BUSY; | |
464 goto error; | |
465 } | |
466 | |
467 if((pData == NULL ) || (Size == 0)) | |
468 { | |
469 errorcode = HAL_ERROR; | |
470 goto error; | |
471 } | |
472 | |
473 /* Set the transaction information */ | |
474 hspi->State = HAL_SPI_STATE_BUSY_TX; | |
475 hspi->ErrorCode = HAL_SPI_ERROR_NONE; | |
476 hspi->pTxBuffPtr = (uint8_t *)pData; | |
477 hspi->TxXferSize = Size; | |
478 hspi->TxXferCount = Size; | |
479 | |
480 /*Init field not used in handle to zero */ | |
481 hspi->pRxBuffPtr = (uint8_t *)NULL; | |
482 hspi->RxXferSize = 0U; | |
483 hspi->RxXferCount = 0U; | |
484 hspi->TxISR = NULL; | |
485 hspi->RxISR = NULL; | |
486 | |
487 /* Configure communication direction : 1Line */ | |
488 if(hspi->Init.Direction == SPI_DIRECTION_1LINE) | |
489 { | |
490 SPI_1LINE_TX(hspi); | |
491 } | |
492 | |
493 #if (USE_SPI_CRC != 0U) | |
494 /* Reset CRC Calculation */ | |
495 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) | |
496 { | |
497 SPI_RESET_CRC(hspi); | |
498 } | |
499 #endif /* USE_SPI_CRC */ | |
500 | |
501 /* Check if the SPI is already enabled */ | |
502 if((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) | |
503 { | |
504 /* Enable SPI peripheral */ | |
505 __HAL_SPI_ENABLE(hspi); | |
506 } | |
507 | |
508 /* Transmit data in 16 Bit mode */ | |
509 if(hspi->Init.DataSize == SPI_DATASIZE_16BIT) | |
510 { | |
511 if((hspi->Init.Mode == SPI_MODE_SLAVE) || (hspi->TxXferCount == 0x01)) | |
512 { | |
513 hspi->Instance->DR = *((uint16_t *)pData); | |
514 pData += sizeof(uint16_t); | |
515 hspi->TxXferCount--; | |
516 } | |
517 /* Transmit data in 16 Bit mode */ | |
518 while (hspi->TxXferCount > 0U) | |
519 { | |
520 /* Wait until TXE flag is set to send data */ | |
521 if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE)) | |
522 { | |
523 hspi->Instance->DR = *((uint16_t *)pData); | |
524 pData += sizeof(uint16_t); | |
525 hspi->TxXferCount--; | |
526 } | |
527 else | |
528 { | |
529 /* Timeout management */ | |
530 if((Timeout == 0U) || ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >= Timeout))) | |
531 { | |
532 errorcode = HAL_TIMEOUT; | |
533 goto error; | |
534 } | |
535 } | |
536 } | |
537 } | |
538 /* Transmit data in 8 Bit mode */ | |
539 else | |
540 { | |
541 if((hspi->Init.Mode == SPI_MODE_SLAVE)|| (hspi->TxXferCount == 0x01)) | |
542 { | |
543 *((__IO uint8_t*)&hspi->Instance->DR) = (*pData); | |
544 pData += sizeof(uint8_t); | |
545 hspi->TxXferCount--; | |
546 } | |
547 while (hspi->TxXferCount > 0U) | |
548 { | |
549 /* Wait until TXE flag is set to send data */ | |
550 if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE)) | |
551 { | |
552 *((__IO uint8_t*)&hspi->Instance->DR) = (*pData); | |
553 pData += sizeof(uint8_t); | |
554 hspi->TxXferCount--; | |
555 } | |
556 else | |
557 { | |
558 /* Timeout management */ | |
559 if((Timeout == 0U) || ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >= Timeout))) | |
560 { | |
561 errorcode = HAL_TIMEOUT; | |
562 goto error; | |
563 } | |
564 } | |
565 } | |
566 } | |
567 | |
568 /* Wait until TXE flag */ | |
569 if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_TXE, SET, Timeout, tickstart) != HAL_OK) | |
570 { | |
571 errorcode = HAL_TIMEOUT; | |
572 goto error; | |
573 } | |
574 | |
575 /* Check Busy flag */ | |
576 if(SPI_CheckFlag_BSY(hspi, Timeout, tickstart) != HAL_OK) | |
577 { | |
578 errorcode = HAL_ERROR; | |
579 hspi->ErrorCode = HAL_SPI_ERROR_FLAG; | |
580 goto error; | |
581 } | |
582 | |
583 /* Clear overrun flag in 2 Lines communication mode because received is not read */ | |
584 if(hspi->Init.Direction == SPI_DIRECTION_2LINES) | |
585 { | |
586 __HAL_SPI_CLEAR_OVRFLAG(hspi); | |
587 } | |
588 #if (USE_SPI_CRC != 0U) | |
589 /* Enable CRC Transmission */ | |
590 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) | |
591 { | |
592 SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); | |
593 } | |
594 #endif /* USE_SPI_CRC */ | |
595 | |
596 if(hspi->ErrorCode != HAL_SPI_ERROR_NONE) | |
597 { | |
598 errorcode = HAL_ERROR; | |
599 } | |
600 | |
601 error: | |
602 hspi->State = HAL_SPI_STATE_READY; | |
603 /* Process Unlocked */ | |
604 __HAL_UNLOCK(hspi); | |
605 return errorcode; | |
606 } | |
607 | |
608 /** | |
609 * @brief Receive an amount of data in blocking mode. | |
610 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
611 * the configuration information for SPI module. | |
612 * @param pData pointer to data buffer | |
613 * @param Size amount of data to be received | |
614 * @param Timeout Timeout duration | |
615 * @retval HAL status | |
616 */ | |
617 HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout) | |
618 { | |
619 #if (USE_SPI_CRC != 0U) | |
620 __IO uint16_t tmpreg = 0U; | |
621 #endif /* USE_SPI_CRC */ | |
622 uint32_t tickstart = 0U; | |
623 HAL_StatusTypeDef errorcode = HAL_OK; | |
624 | |
625 if((hspi->Init.Mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES)) | |
626 { | |
627 hspi->State = HAL_SPI_STATE_BUSY_RX; | |
628 /* Call transmit-receive function to send Dummy data on Tx line and generate clock on CLK line */ | |
629 return HAL_SPI_TransmitReceive(hspi,pData,pData,Size,Timeout); | |
630 } | |
631 | |
632 /* Process Locked */ | |
633 __HAL_LOCK(hspi); | |
634 | |
635 /* Init tickstart for timeout management*/ | |
636 tickstart = HAL_GetTick(); | |
637 | |
638 if(hspi->State != HAL_SPI_STATE_READY) | |
639 { | |
640 errorcode = HAL_BUSY; | |
641 goto error; | |
642 } | |
643 | |
644 if((pData == NULL ) || (Size == 0)) | |
645 { | |
646 errorcode = HAL_ERROR; | |
647 goto error; | |
648 } | |
649 | |
650 /* Set the transaction information */ | |
651 hspi->State = HAL_SPI_STATE_BUSY_RX; | |
652 hspi->ErrorCode = HAL_SPI_ERROR_NONE; | |
653 hspi->pRxBuffPtr = (uint8_t *)pData; | |
654 hspi->RxXferSize = Size; | |
655 hspi->RxXferCount = Size; | |
656 | |
657 /*Init field not used in handle to zero */ | |
658 hspi->pTxBuffPtr = (uint8_t *)NULL; | |
659 hspi->TxXferSize = 0U; | |
660 hspi->TxXferCount = 0U; | |
661 hspi->RxISR = NULL; | |
662 hspi->TxISR = NULL; | |
663 | |
664 #if (USE_SPI_CRC != 0U) | |
665 /* Reset CRC Calculation */ | |
666 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) | |
667 { | |
668 SPI_RESET_CRC(hspi); | |
669 /* this is done to handle the CRCNEXT before the latest data */ | |
670 hspi->RxXferCount--; | |
671 } | |
672 #endif /* USE_SPI_CRC */ | |
673 | |
674 /* Configure communication direction: 1Line */ | |
675 if(hspi->Init.Direction == SPI_DIRECTION_1LINE) | |
676 { | |
677 SPI_1LINE_RX(hspi); | |
678 } | |
679 | |
680 /* Check if the SPI is already enabled */ | |
681 if((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) | |
682 { | |
683 /* Enable SPI peripheral */ | |
684 __HAL_SPI_ENABLE(hspi); | |
685 } | |
686 | |
687 /* Receive data in 8 Bit mode */ | |
688 if(hspi->Init.DataSize == SPI_DATASIZE_8BIT) | |
689 { | |
690 /* Transfer loop */ | |
691 while(hspi->RxXferCount > 0U) | |
692 { | |
693 /* Check the RXNE flag */ | |
694 if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE)) | |
695 { | |
696 /* read the received data */ | |
697 (* (uint8_t *)pData)= *(__IO uint8_t *)&hspi->Instance->DR; | |
698 pData += sizeof(uint8_t); | |
699 hspi->RxXferCount--; | |
700 } | |
701 else | |
702 { | |
703 /* Timeout management */ | |
704 if((Timeout == 0U) || ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >= Timeout))) | |
705 { | |
706 errorcode = HAL_TIMEOUT; | |
707 goto error; | |
708 } | |
709 } | |
710 } | |
711 } | |
712 else | |
713 { | |
714 /* Transfer loop */ | |
715 while(hspi->RxXferCount > 0U) | |
716 { | |
717 /* Check the RXNE flag */ | |
718 if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE)) | |
719 { | |
720 *((uint16_t*)pData) = hspi->Instance->DR; | |
721 pData += sizeof(uint16_t); | |
722 hspi->RxXferCount--; | |
723 } | |
724 else | |
725 { | |
726 /* Timeout management */ | |
727 if((Timeout == 0U) || ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >= Timeout))) | |
728 { | |
729 errorcode = HAL_TIMEOUT; | |
730 goto error; | |
731 } | |
732 } | |
733 } | |
734 } | |
735 | |
736 #if (USE_SPI_CRC != 0U) | |
737 /* Handle the CRC Transmission */ | |
738 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) | |
739 { | |
740 /* freeze the CRC before the latest data */ | |
741 SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); | |
742 | |
743 /* Read the latest data */ | |
744 if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, Timeout, tickstart) != HAL_OK) | |
745 { | |
746 /* the latest data has not been received */ | |
747 errorcode = HAL_TIMEOUT; | |
748 goto error; | |
749 } | |
750 | |
751 /* Receive last data in 16 Bit mode */ | |
752 if(hspi->Init.DataSize == SPI_DATASIZE_16BIT) | |
753 { | |
754 *((uint16_t*)pData) = hspi->Instance->DR; | |
755 } | |
756 /* Receive last data in 8 Bit mode */ | |
757 else | |
758 { | |
759 (*(uint8_t *)pData) = *(__IO uint8_t *)&hspi->Instance->DR; | |
760 } | |
761 | |
762 /* Wait the CRC data */ | |
763 if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, Timeout, tickstart) != HAL_OK) | |
764 { | |
765 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); | |
766 errorcode = HAL_TIMEOUT; | |
767 goto error; | |
768 } | |
769 | |
770 /* Read CRC to Flush DR and RXNE flag */ | |
771 tmpreg = hspi->Instance->DR; | |
772 /* To avoid GCC warning */ | |
773 UNUSED(tmpreg); | |
774 } | |
775 #endif /* USE_SPI_CRC */ | |
776 | |
777 /* Check the end of the transaction */ | |
778 if((hspi->Init.Mode == SPI_MODE_MASTER)&&((hspi->Init.Direction == SPI_DIRECTION_1LINE)||(hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY))) | |
779 { | |
780 /* Disable SPI peripheral */ | |
781 __HAL_SPI_DISABLE(hspi); | |
782 } | |
783 | |
784 #if (USE_SPI_CRC != 0U) | |
785 /* Check if CRC error occurred */ | |
786 if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR)) | |
787 { | |
788 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); | |
789 __HAL_SPI_CLEAR_CRCERRFLAG(hspi); | |
790 } | |
791 #endif /* USE_SPI_CRC */ | |
792 | |
793 if(hspi->ErrorCode != HAL_SPI_ERROR_NONE) | |
794 { | |
795 errorcode = HAL_ERROR; | |
796 } | |
797 | |
798 error : | |
799 hspi->State = HAL_SPI_STATE_READY; | |
800 __HAL_UNLOCK(hspi); | |
801 return errorcode; | |
802 } | |
803 | |
804 /** | |
805 * @brief Transmit and Receive an amount of data in blocking mode. | |
806 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
807 * the configuration information for SPI module. | |
808 * @param pTxData pointer to transmission data buffer | |
809 * @param pRxData pointer to reception data buffer | |
810 * @param Size amount of data to be sent and received | |
811 * @param Timeout Timeout duration | |
812 * @retval HAL status | |
813 */ | |
814 HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout) | |
815 { | |
816 uint32_t tmp = 0U, tmp1 = 0U; | |
817 #if (USE_SPI_CRC != 0U) | |
818 __IO uint16_t tmpreg1 = 0U; | |
819 #endif /* USE_SPI_CRC */ | |
820 uint32_t tickstart = 0U; | |
821 /* Variable used to alternate Rx and Tx during transfer */ | |
822 uint32_t txallowed = 1U; | |
823 HAL_StatusTypeDef errorcode = HAL_OK; | |
824 | |
825 /* Check Direction parameter */ | |
826 assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction)); | |
827 | |
828 /* Process Locked */ | |
829 __HAL_LOCK(hspi); | |
830 | |
831 /* Init tickstart for timeout management*/ | |
832 tickstart = HAL_GetTick(); | |
833 | |
834 tmp = hspi->State; | |
835 tmp1 = hspi->Init.Mode; | |
836 | |
837 if(!((tmp == HAL_SPI_STATE_READY) || \ | |
838 ((tmp1 == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (tmp == HAL_SPI_STATE_BUSY_RX)))) | |
839 { | |
840 errorcode = HAL_BUSY; | |
841 goto error; | |
842 } | |
843 | |
844 if((pTxData == NULL) || (pRxData == NULL) || (Size == 0)) | |
845 { | |
846 errorcode = HAL_ERROR; | |
847 goto error; | |
848 } | |
849 | |
850 /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */ | |
851 if(hspi->State == HAL_SPI_STATE_READY) | |
852 { | |
853 hspi->State = HAL_SPI_STATE_BUSY_TX_RX; | |
854 } | |
855 | |
856 /* Set the transaction information */ | |
857 hspi->ErrorCode = HAL_SPI_ERROR_NONE; | |
858 hspi->pRxBuffPtr = (uint8_t *)pRxData; | |
859 hspi->RxXferCount = Size; | |
860 hspi->RxXferSize = Size; | |
861 hspi->pTxBuffPtr = (uint8_t *)pTxData; | |
862 hspi->TxXferCount = Size; | |
863 hspi->TxXferSize = Size; | |
864 | |
865 /*Init field not used in handle to zero */ | |
866 hspi->RxISR = NULL; | |
867 hspi->TxISR = NULL; | |
868 | |
869 #if (USE_SPI_CRC != 0U) | |
870 /* Reset CRC Calculation */ | |
871 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) | |
872 { | |
873 SPI_RESET_CRC(hspi); | |
874 } | |
875 #endif /* USE_SPI_CRC */ | |
876 | |
877 /* Check if the SPI is already enabled */ | |
878 if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE) | |
879 { | |
880 /* Enable SPI peripheral */ | |
881 __HAL_SPI_ENABLE(hspi); | |
882 } | |
883 | |
884 /* Transmit and Receive data in 16 Bit mode */ | |
885 if(hspi->Init.DataSize == SPI_DATASIZE_16BIT) | |
886 { | |
887 if((hspi->Init.Mode == SPI_MODE_SLAVE) || (hspi->TxXferCount == 0x01U)) | |
888 { | |
889 hspi->Instance->DR = *((uint16_t *)pTxData); | |
890 pTxData += sizeof(uint16_t); | |
891 hspi->TxXferCount--; | |
892 } | |
893 while ((hspi->TxXferCount > 0U) || (hspi->RxXferCount > 0U)) | |
894 { | |
895 /* Check TXE flag */ | |
896 if(txallowed && (hspi->TxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE))) | |
897 { | |
898 hspi->Instance->DR = *((uint16_t *)pTxData); | |
899 pTxData += sizeof(uint16_t); | |
900 hspi->TxXferCount--; | |
901 /* Next Data is a reception (Rx). Tx not allowed */ | |
902 txallowed = 0U; | |
903 | |
904 #if (USE_SPI_CRC != 0U) | |
905 /* Enable CRC Transmission */ | |
906 if((hspi->TxXferCount == 0U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)) | |
907 { | |
908 SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); | |
909 } | |
910 #endif /* USE_SPI_CRC */ | |
911 } | |
912 | |
913 /* Check RXNE flag */ | |
914 if((hspi->RxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE))) | |
915 { | |
916 *((uint16_t *)pRxData) = hspi->Instance->DR; | |
917 pRxData += sizeof(uint16_t); | |
918 hspi->RxXferCount--; | |
919 /* Next Data is a Transmission (Tx). Tx is allowed */ | |
920 txallowed = 1U; | |
921 } | |
922 if((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >= Timeout)) | |
923 { | |
924 errorcode = HAL_TIMEOUT; | |
925 goto error; | |
926 } | |
927 } | |
928 } | |
929 /* Transmit and Receive data in 8 Bit mode */ | |
930 else | |
931 { | |
932 if((hspi->Init.Mode == SPI_MODE_SLAVE) || (hspi->TxXferCount == 0x01U)) | |
933 { | |
934 *((__IO uint8_t*)&hspi->Instance->DR) = (*pTxData); | |
935 pTxData += sizeof(uint8_t); | |
936 hspi->TxXferCount--; | |
937 } | |
938 while((hspi->TxXferCount > 0U) || (hspi->RxXferCount > 0U)) | |
939 { | |
940 /* check TXE flag */ | |
941 if(txallowed && (hspi->TxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE))) | |
942 { | |
943 *(__IO uint8_t *)&hspi->Instance->DR = (*pTxData++); | |
944 hspi->TxXferCount--; | |
945 /* Next Data is a reception (Rx). Tx not allowed */ | |
946 txallowed = 0U; | |
947 | |
948 #if (USE_SPI_CRC != 0U) | |
949 /* Enable CRC Transmission */ | |
950 if((hspi->TxXferCount == 0U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)) | |
951 { | |
952 SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); | |
953 } | |
954 #endif /* USE_SPI_CRC */ | |
955 } | |
956 | |
957 /* Wait until RXNE flag is reset */ | |
958 if((hspi->RxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE))) | |
959 { | |
960 (*(uint8_t *)pRxData++) = hspi->Instance->DR; | |
961 hspi->RxXferCount--; | |
962 /* Next Data is a Transmission (Tx). Tx is allowed */ | |
963 txallowed = 1U; | |
964 } | |
965 if((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >= Timeout)) | |
966 { | |
967 errorcode = HAL_TIMEOUT; | |
968 goto error; | |
969 } | |
970 } | |
971 } | |
972 | |
973 #if (USE_SPI_CRC != 0U) | |
974 /* Read CRC from DR to close CRC calculation process */ | |
975 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) | |
976 { | |
977 /* Wait until TXE flag */ | |
978 if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, Timeout, tickstart) != HAL_OK) | |
979 { | |
980 /* Error on the CRC reception */ | |
981 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); | |
982 errorcode = HAL_TIMEOUT; | |
983 goto error; | |
984 } | |
985 /* Read CRC */ | |
986 tmpreg1 = hspi->Instance->DR; | |
987 /* To avoid GCC warning */ | |
988 UNUSED(tmpreg1); | |
989 } | |
990 | |
991 /* Check if CRC error occurred */ | |
992 if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR)) | |
993 { | |
994 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); | |
995 /* Clear CRC Flag */ | |
996 __HAL_SPI_CLEAR_CRCERRFLAG(hspi); | |
997 | |
998 errorcode = HAL_ERROR; | |
999 } | |
1000 #endif /* USE_SPI_CRC */ | |
1001 | |
1002 /* Wait until TXE flag */ | |
1003 if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_TXE, SET, Timeout, tickstart) != HAL_OK) | |
1004 { | |
1005 errorcode = HAL_TIMEOUT; | |
1006 goto error; | |
1007 } | |
1008 | |
1009 /* Check Busy flag */ | |
1010 if(SPI_CheckFlag_BSY(hspi, Timeout, tickstart) != HAL_OK) | |
1011 { | |
1012 errorcode = HAL_ERROR; | |
1013 hspi->ErrorCode = HAL_SPI_ERROR_FLAG; | |
1014 goto error; | |
1015 } | |
1016 | |
1017 /* Clear overrun flag in 2 Lines communication mode because received is not read */ | |
1018 if(hspi->Init.Direction == SPI_DIRECTION_2LINES) | |
1019 { | |
1020 __HAL_SPI_CLEAR_OVRFLAG(hspi); | |
1021 } | |
1022 | |
1023 error : | |
1024 hspi->State = HAL_SPI_STATE_READY; | |
1025 __HAL_UNLOCK(hspi); | |
1026 return errorcode; | |
1027 } | |
1028 | |
1029 /** | |
1030 * @brief Transmit an amount of data in non-blocking mode with Interrupt. | |
1031 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
1032 * the configuration information for SPI module. | |
1033 * @param pData pointer to data buffer | |
1034 * @param Size amount of data to be sent | |
1035 * @retval HAL status | |
1036 */ | |
1037 HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size) | |
1038 { | |
1039 HAL_StatusTypeDef errorcode = HAL_OK; | |
1040 | |
1041 /* Check Direction parameter */ | |
1042 assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction)); | |
1043 | |
1044 /* Process Locked */ | |
1045 __HAL_LOCK(hspi); | |
1046 | |
1047 if((pData == NULL) || (Size == 0)) | |
1048 { | |
1049 errorcode = HAL_ERROR; | |
1050 goto error; | |
1051 } | |
1052 | |
1053 if(hspi->State != HAL_SPI_STATE_READY) | |
1054 { | |
1055 errorcode = HAL_BUSY; | |
1056 goto error; | |
1057 } | |
1058 | |
1059 /* Set the transaction information */ | |
1060 hspi->State = HAL_SPI_STATE_BUSY_TX; | |
1061 hspi->ErrorCode = HAL_SPI_ERROR_NONE; | |
1062 hspi->pTxBuffPtr = (uint8_t *)pData; | |
1063 hspi->TxXferSize = Size; | |
1064 hspi->TxXferCount = Size; | |
1065 | |
1066 /* Init field not used in handle to zero */ | |
1067 hspi->pRxBuffPtr = (uint8_t *)NULL; | |
1068 hspi->RxXferSize = 0U; | |
1069 hspi->RxXferCount = 0U; | |
1070 hspi->RxISR = NULL; | |
1071 | |
1072 /* Set the function for IT treatment */ | |
1073 if(hspi->Init.DataSize > SPI_DATASIZE_8BIT ) | |
1074 { | |
1075 hspi->TxISR = SPI_TxISR_16BIT; | |
1076 } | |
1077 else | |
1078 { | |
1079 hspi->TxISR = SPI_TxISR_8BIT; | |
1080 } | |
1081 | |
1082 /* Configure communication direction : 1Line */ | |
1083 if(hspi->Init.Direction == SPI_DIRECTION_1LINE) | |
1084 { | |
1085 SPI_1LINE_TX(hspi); | |
1086 } | |
1087 | |
1088 #if (USE_SPI_CRC != 0U) | |
1089 /* Reset CRC Calculation */ | |
1090 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) | |
1091 { | |
1092 SPI_RESET_CRC(hspi); | |
1093 } | |
1094 #endif /* USE_SPI_CRC */ | |
1095 | |
1096 if (hspi->Init.Direction == SPI_DIRECTION_2LINES) | |
1097 { | |
1098 /* Enable TXE interrupt */ | |
1099 __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TXE)); | |
1100 } | |
1101 else | |
1102 { | |
1103 /* Enable TXE and ERR interrupt */ | |
1104 __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_ERR)); | |
1105 } | |
1106 | |
1107 /* Check if the SPI is already enabled */ | |
1108 if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE) | |
1109 { | |
1110 /* Enable SPI peripheral */ | |
1111 __HAL_SPI_ENABLE(hspi); | |
1112 } | |
1113 | |
1114 error : | |
1115 __HAL_UNLOCK(hspi); | |
1116 return errorcode; | |
1117 } | |
1118 | |
1119 /** | |
1120 * @brief Receive an amount of data in non-blocking mode with Interrupt. | |
1121 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
1122 * the configuration information for SPI module. | |
1123 * @param pData pointer to data buffer | |
1124 * @param Size amount of data to be sent | |
1125 * @retval HAL status | |
1126 */ | |
1127 HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size) | |
1128 { | |
1129 HAL_StatusTypeDef errorcode = HAL_OK; | |
1130 | |
1131 if((hspi->Init.Direction == SPI_DIRECTION_2LINES) && (hspi->Init.Mode == SPI_MODE_MASTER)) | |
1132 { | |
1133 hspi->State = HAL_SPI_STATE_BUSY_RX; | |
1134 /* Call transmit-receive function to send Dummy data on Tx line and generate clock on CLK line */ | |
1135 return HAL_SPI_TransmitReceive_IT(hspi, pData, pData, Size); | |
1136 } | |
1137 | |
1138 /* Process Locked */ | |
1139 __HAL_LOCK(hspi); | |
1140 | |
1141 if(hspi->State != HAL_SPI_STATE_READY) | |
1142 { | |
1143 errorcode = HAL_BUSY; | |
1144 goto error; | |
1145 } | |
1146 | |
1147 if((pData == NULL) || (Size == 0)) | |
1148 { | |
1149 errorcode = HAL_ERROR; | |
1150 goto error; | |
1151 } | |
1152 | |
1153 /* Set the transaction information */ | |
1154 hspi->State = HAL_SPI_STATE_BUSY_RX; | |
1155 hspi->ErrorCode = HAL_SPI_ERROR_NONE; | |
1156 hspi->pRxBuffPtr = (uint8_t *)pData; | |
1157 hspi->RxXferSize = Size; | |
1158 hspi->RxXferCount = Size; | |
1159 | |
1160 /* Init field not used in handle to zero */ | |
1161 hspi->pTxBuffPtr = (uint8_t *)NULL; | |
1162 hspi->TxXferSize = 0U; | |
1163 hspi->TxXferCount = 0U; | |
1164 hspi->TxISR = NULL; | |
1165 | |
1166 /* Set the function for IT treatment */ | |
1167 if(hspi->Init.DataSize > SPI_DATASIZE_8BIT ) | |
1168 { | |
1169 hspi->RxISR = SPI_RxISR_16BIT; | |
1170 } | |
1171 else | |
1172 { | |
1173 hspi->RxISR = SPI_RxISR_8BIT; | |
1174 } | |
1175 | |
1176 /* Configure communication direction : 1Line */ | |
1177 if(hspi->Init.Direction == SPI_DIRECTION_1LINE) | |
1178 { | |
1179 SPI_1LINE_RX(hspi); | |
1180 } | |
1181 | |
1182 #if (USE_SPI_CRC != 0U) | |
1183 /* Reset CRC Calculation */ | |
1184 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) | |
1185 { | |
1186 SPI_RESET_CRC(hspi); | |
1187 } | |
1188 #endif /* USE_SPI_CRC */ | |
1189 | |
1190 /* Enable TXE and ERR interrupt */ | |
1191 __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR)); | |
1192 | |
1193 /* Note : The SPI must be enabled after unlocking current process | |
1194 to avoid the risk of SPI interrupt handle execution before current | |
1195 process unlock */ | |
1196 | |
1197 /* Check if the SPI is already enabled */ | |
1198 if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE) | |
1199 { | |
1200 /* Enable SPI peripheral */ | |
1201 __HAL_SPI_ENABLE(hspi); | |
1202 } | |
1203 | |
1204 error : | |
1205 /* Process Unlocked */ | |
1206 __HAL_UNLOCK(hspi); | |
1207 return errorcode; | |
1208 } | |
1209 | |
1210 /** | |
1211 * @brief Transmit and Receive an amount of data in non-blocking mode with Interrupt. | |
1212 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
1213 * the configuration information for SPI module. | |
1214 * @param pTxData pointer to transmission data buffer | |
1215 * @param pRxData pointer to reception data buffer | |
1216 * @param Size amount of data to be sent and received | |
1217 * @retval HAL status | |
1218 */ | |
1219 HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size) | |
1220 { | |
1221 uint32_t tmp = 0U, tmp1 = 0U; | |
1222 HAL_StatusTypeDef errorcode = HAL_OK; | |
1223 | |
1224 /* Check Direction parameter */ | |
1225 assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction)); | |
1226 | |
1227 /* Process locked */ | |
1228 __HAL_LOCK(hspi); | |
1229 | |
1230 tmp = hspi->State; | |
1231 tmp1 = hspi->Init.Mode; | |
1232 | |
1233 if(!((tmp == HAL_SPI_STATE_READY) || \ | |
1234 ((tmp1 == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (tmp == HAL_SPI_STATE_BUSY_RX)))) | |
1235 { | |
1236 errorcode = HAL_BUSY; | |
1237 goto error; | |
1238 } | |
1239 | |
1240 if((pTxData == NULL ) || (pRxData == NULL ) || (Size == 0)) | |
1241 { | |
1242 errorcode = HAL_ERROR; | |
1243 goto error; | |
1244 } | |
1245 | |
1246 /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */ | |
1247 if(hspi->State == HAL_SPI_STATE_READY) | |
1248 { | |
1249 hspi->State = HAL_SPI_STATE_BUSY_TX_RX; | |
1250 } | |
1251 | |
1252 /* Set the transaction information */ | |
1253 hspi->ErrorCode = HAL_SPI_ERROR_NONE; | |
1254 hspi->pTxBuffPtr = (uint8_t *)pTxData; | |
1255 hspi->TxXferSize = Size; | |
1256 hspi->TxXferCount = Size; | |
1257 hspi->pRxBuffPtr = (uint8_t *)pRxData; | |
1258 hspi->RxXferSize = Size; | |
1259 hspi->RxXferCount = Size; | |
1260 | |
1261 /* Set the function for IT treatment */ | |
1262 if(hspi->Init.DataSize > SPI_DATASIZE_8BIT ) | |
1263 { | |
1264 hspi->RxISR = SPI_2linesRxISR_16BIT; | |
1265 hspi->TxISR = SPI_2linesTxISR_16BIT; | |
1266 } | |
1267 else | |
1268 { | |
1269 hspi->RxISR = SPI_2linesRxISR_8BIT; | |
1270 hspi->TxISR = SPI_2linesTxISR_8BIT; | |
1271 } | |
1272 | |
1273 #if (USE_SPI_CRC != 0U) | |
1274 /* Reset CRC Calculation */ | |
1275 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) | |
1276 { | |
1277 SPI_RESET_CRC(hspi); | |
1278 } | |
1279 #endif /* USE_SPI_CRC */ | |
1280 | |
1281 /* Enable TXE, RXNE and ERR interrupt */ | |
1282 __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR)); | |
1283 | |
1284 /* Check if the SPI is already enabled */ | |
1285 if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE) | |
1286 { | |
1287 /* Enable SPI peripheral */ | |
1288 __HAL_SPI_ENABLE(hspi); | |
1289 } | |
1290 | |
1291 error : | |
1292 /* Process Unlocked */ | |
1293 __HAL_UNLOCK(hspi); | |
1294 return errorcode; | |
1295 } | |
1296 | |
1297 /** | |
1298 * @brief Transmit an amount of data in non-blocking mode with DMA. | |
1299 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
1300 * the configuration information for SPI module. | |
1301 * @param pData pointer to data buffer | |
1302 * @param Size amount of data to be sent | |
1303 * @retval HAL status | |
1304 */ | |
1305 HAL_StatusTypeDef HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size) | |
1306 { | |
1307 HAL_StatusTypeDef errorcode = HAL_OK; | |
1308 | |
1309 /* Check Direction parameter */ | |
1310 assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction)); | |
1311 | |
1312 /* Process Locked */ | |
1313 __HAL_LOCK(hspi); | |
1314 | |
1315 if(hspi->State != HAL_SPI_STATE_READY) | |
1316 { | |
1317 errorcode = HAL_BUSY; | |
1318 goto error; | |
1319 } | |
1320 | |
1321 if((pData == NULL) || (Size == 0)) | |
1322 { | |
1323 errorcode = HAL_ERROR; | |
1324 goto error; | |
1325 } | |
1326 | |
1327 /* Set the transaction information */ | |
1328 hspi->State = HAL_SPI_STATE_BUSY_TX; | |
1329 hspi->ErrorCode = HAL_SPI_ERROR_NONE; | |
1330 hspi->pTxBuffPtr = (uint8_t *)pData; | |
1331 hspi->TxXferSize = Size; | |
1332 hspi->TxXferCount = Size; | |
1333 | |
1334 /* Init field not used in handle to zero */ | |
1335 hspi->pRxBuffPtr = (uint8_t *)NULL; | |
1336 hspi->TxISR = NULL; | |
1337 hspi->RxISR = NULL; | |
1338 hspi->RxXferSize = 0U; | |
1339 hspi->RxXferCount = 0U; | |
1340 | |
1341 /* Configure communication direction : 1Line */ | |
1342 if(hspi->Init.Direction == SPI_DIRECTION_1LINE) | |
1343 { | |
1344 SPI_1LINE_TX(hspi); | |
1345 } | |
1346 | |
1347 #if (USE_SPI_CRC != 0U) | |
1348 /* Reset CRC Calculation */ | |
1349 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) | |
1350 { | |
1351 SPI_RESET_CRC(hspi); | |
1352 } | |
1353 #endif /* USE_SPI_CRC */ | |
1354 | |
1355 /* Set the SPI TxDMA Half transfer complete callback */ | |
1356 hspi->hdmatx->XferHalfCpltCallback = SPI_DMAHalfTransmitCplt; | |
1357 | |
1358 /* Set the SPI TxDMA transfer complete callback */ | |
1359 hspi->hdmatx->XferCpltCallback = SPI_DMATransmitCplt; | |
1360 | |
1361 /* Set the DMA error callback */ | |
1362 hspi->hdmatx->XferErrorCallback = SPI_DMAError; | |
1363 | |
1364 /* Set the DMA AbortCpltCallback */ | |
1365 hspi->hdmatx->XferAbortCallback = NULL; | |
1366 | |
1367 /* Enable the Tx DMA Stream */ | |
1368 HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->DR, hspi->TxXferCount); | |
1369 | |
1370 /* Check if the SPI is already enabled */ | |
1371 if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE) | |
1372 { | |
1373 /* Enable SPI peripheral */ | |
1374 __HAL_SPI_ENABLE(hspi); | |
1375 } | |
1376 | |
1377 /* Enable the SPI Error Interrupt Bit */ | |
1378 SET_BIT(hspi->Instance->CR2, SPI_CR2_ERRIE); | |
1379 | |
1380 /* Enable Tx DMA Request */ | |
1381 SET_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN); | |
1382 | |
1383 error : | |
1384 /* Process Unlocked */ | |
1385 __HAL_UNLOCK(hspi); | |
1386 return errorcode; | |
1387 } | |
1388 | |
1389 /** | |
1390 * @brief Receive an amount of data in non-blocking mode with DMA. | |
1391 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
1392 * the configuration information for SPI module. | |
1393 * @param pData pointer to data buffer | |
1394 * @note When the CRC feature is enabled the pData Length must be Size + 1. | |
1395 * @param Size amount of data to be sent | |
1396 * @retval HAL status | |
1397 */ | |
1398 HAL_StatusTypeDef HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size) | |
1399 { | |
1400 HAL_StatusTypeDef errorcode = HAL_OK; | |
1401 | |
1402 if((hspi->Init.Direction == SPI_DIRECTION_2LINES)&&(hspi->Init.Mode == SPI_MODE_MASTER)) | |
1403 { | |
1404 hspi->State = HAL_SPI_STATE_BUSY_RX; | |
1405 /* Call transmit-receive function to send Dummy data on Tx line and generate clock on CLK line */ | |
1406 return HAL_SPI_TransmitReceive_DMA(hspi, pData, pData, Size); | |
1407 } | |
1408 | |
1409 /* Process Locked */ | |
1410 __HAL_LOCK(hspi); | |
1411 | |
1412 if(hspi->State != HAL_SPI_STATE_READY) | |
1413 { | |
1414 errorcode = HAL_BUSY; | |
1415 goto error; | |
1416 } | |
1417 | |
1418 if((pData == NULL) || (Size == 0)) | |
1419 { | |
1420 errorcode = HAL_ERROR; | |
1421 goto error; | |
1422 } | |
1423 | |
1424 /* Set the transaction information */ | |
1425 hspi->State = HAL_SPI_STATE_BUSY_RX; | |
1426 hspi->ErrorCode = HAL_SPI_ERROR_NONE; | |
1427 hspi->pRxBuffPtr = (uint8_t *)pData; | |
1428 hspi->RxXferSize = Size; | |
1429 hspi->RxXferCount = Size; | |
1430 | |
1431 /*Init field not used in handle to zero */ | |
1432 hspi->RxISR = NULL; | |
1433 hspi->TxISR = NULL; | |
1434 hspi->TxXferSize = 0U; | |
1435 hspi->TxXferCount = 0U; | |
1436 | |
1437 /* Configure communication direction : 1Line */ | |
1438 if(hspi->Init.Direction == SPI_DIRECTION_1LINE) | |
1439 { | |
1440 SPI_1LINE_RX(hspi); | |
1441 } | |
1442 | |
1443 #if (USE_SPI_CRC != 0U) | |
1444 /* Reset CRC Calculation */ | |
1445 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) | |
1446 { | |
1447 SPI_RESET_CRC(hspi); | |
1448 } | |
1449 #endif /* USE_SPI_CRC */ | |
1450 | |
1451 /* Set the SPI RxDMA Half transfer complete callback */ | |
1452 hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfReceiveCplt; | |
1453 | |
1454 /* Set the SPI Rx DMA transfer complete callback */ | |
1455 hspi->hdmarx->XferCpltCallback = SPI_DMAReceiveCplt; | |
1456 | |
1457 /* Set the DMA error callback */ | |
1458 hspi->hdmarx->XferErrorCallback = SPI_DMAError; | |
1459 | |
1460 /* Set the DMA AbortCpltCallback */ | |
1461 hspi->hdmarx->XferAbortCallback = NULL; | |
1462 | |
1463 /* Enable the Rx DMA Stream */ | |
1464 HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->DR, (uint32_t)hspi->pRxBuffPtr, hspi->RxXferCount); | |
1465 | |
1466 /* Check if the SPI is already enabled */ | |
1467 if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE) | |
1468 { | |
1469 /* Enable SPI peripheral */ | |
1470 __HAL_SPI_ENABLE(hspi); | |
1471 } | |
1472 | |
1473 /* Enable the SPI Error Interrupt Bit */ | |
1474 SET_BIT(hspi->Instance->CR2, SPI_CR2_ERRIE); | |
1475 | |
1476 /* Enable Rx DMA Request */ | |
1477 SET_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN); | |
1478 | |
1479 error: | |
1480 /* Process Unlocked */ | |
1481 __HAL_UNLOCK(hspi); | |
1482 return errorcode; | |
1483 } | |
1484 | |
1485 /** | |
1486 * @brief Transmit and Receive an amount of data in non-blocking mode with DMA. | |
1487 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
1488 * the configuration information for SPI module. | |
1489 * @param pTxData pointer to transmission data buffer | |
1490 * @param pRxData pointer to reception data buffer | |
1491 * @note When the CRC feature is enabled the pRxData Length must be Size + 1 | |
1492 * @param Size amount of data to be sent | |
1493 * @retval HAL status | |
1494 */ | |
1495 HAL_StatusTypeDef HAL_SPI_TransmitReceive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size) | |
1496 { | |
1497 uint32_t tmp = 0U, tmp1 = 0U; | |
1498 HAL_StatusTypeDef errorcode = HAL_OK; | |
1499 | |
1500 /* Check Direction parameter */ | |
1501 assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction)); | |
1502 | |
1503 /* Process locked */ | |
1504 __HAL_LOCK(hspi); | |
1505 | |
1506 tmp = hspi->State; | |
1507 tmp1 = hspi->Init.Mode; | |
1508 if(!((tmp == HAL_SPI_STATE_READY) || | |
1509 ((tmp1 == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (tmp == HAL_SPI_STATE_BUSY_RX)))) | |
1510 { | |
1511 errorcode = HAL_BUSY; | |
1512 goto error; | |
1513 } | |
1514 | |
1515 if((pTxData == NULL ) || (pRxData == NULL ) || (Size == 0)) | |
1516 { | |
1517 errorcode = HAL_ERROR; | |
1518 goto error; | |
1519 } | |
1520 | |
1521 /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */ | |
1522 if(hspi->State == HAL_SPI_STATE_READY) | |
1523 { | |
1524 hspi->State = HAL_SPI_STATE_BUSY_TX_RX; | |
1525 } | |
1526 | |
1527 /* Set the transaction information */ | |
1528 hspi->ErrorCode = HAL_SPI_ERROR_NONE; | |
1529 hspi->pTxBuffPtr = (uint8_t*)pTxData; | |
1530 hspi->TxXferSize = Size; | |
1531 hspi->TxXferCount = Size; | |
1532 hspi->pRxBuffPtr = (uint8_t*)pRxData; | |
1533 hspi->RxXferSize = Size; | |
1534 hspi->RxXferCount = Size; | |
1535 | |
1536 /* Init field not used in handle to zero */ | |
1537 hspi->RxISR = NULL; | |
1538 hspi->TxISR = NULL; | |
1539 | |
1540 #if (USE_SPI_CRC != 0U) | |
1541 /* Reset CRC Calculation */ | |
1542 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) | |
1543 { | |
1544 SPI_RESET_CRC(hspi); | |
1545 } | |
1546 #endif /* USE_SPI_CRC */ | |
1547 | |
1548 /* Check if we are in Rx only or in Rx/Tx Mode and configure the DMA transfer complete callback */ | |
1549 if(hspi->State == HAL_SPI_STATE_BUSY_RX) | |
1550 { | |
1551 /* Set the SPI Rx DMA Half transfer complete callback */ | |
1552 hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfReceiveCplt; | |
1553 hspi->hdmarx->XferCpltCallback = SPI_DMAReceiveCplt; | |
1554 } | |
1555 else | |
1556 { | |
1557 /* Set the SPI Tx/Rx DMA Half transfer complete callback */ | |
1558 hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfTransmitReceiveCplt; | |
1559 hspi->hdmarx->XferCpltCallback = SPI_DMATransmitReceiveCplt; | |
1560 } | |
1561 | |
1562 /* Set the DMA error callback */ | |
1563 hspi->hdmarx->XferErrorCallback = SPI_DMAError; | |
1564 | |
1565 /* Set the DMA AbortCpltCallback */ | |
1566 hspi->hdmarx->XferAbortCallback = NULL; | |
1567 | |
1568 /* Enable the Rx DMA Stream */ | |
1569 HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->DR, (uint32_t)hspi->pRxBuffPtr, hspi->RxXferCount); | |
1570 | |
1571 /* Enable Rx DMA Request */ | |
1572 SET_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN); | |
1573 | |
1574 /* Set the SPI Tx DMA transfer complete callback as NULL because the communication closing | |
1575 is performed in DMA reception complete callback */ | |
1576 hspi->hdmatx->XferHalfCpltCallback = NULL; | |
1577 hspi->hdmatx->XferCpltCallback = NULL; | |
1578 hspi->hdmatx->XferErrorCallback = NULL; | |
1579 hspi->hdmatx->XferAbortCallback = NULL; | |
1580 | |
1581 /* Enable the Tx DMA Stream */ | |
1582 HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->DR, hspi->TxXferCount); | |
1583 | |
1584 /* Check if the SPI is already enabled */ | |
1585 if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE) | |
1586 { | |
1587 /* Enable SPI peripheral */ | |
1588 __HAL_SPI_ENABLE(hspi); | |
1589 } | |
1590 /* Enable the SPI Error Interrupt Bit */ | |
1591 SET_BIT(hspi->Instance->CR2, SPI_CR2_ERRIE); | |
1592 | |
1593 /* Enable Tx DMA Request */ | |
1594 SET_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN); | |
1595 | |
1596 error : | |
1597 /* Process Unlocked */ | |
1598 __HAL_UNLOCK(hspi); | |
1599 return errorcode; | |
1600 } | |
1601 | |
1602 /** | |
1603 * @brief Abort ongoing transfer (blocking mode). | |
1604 * @param hspi SPI handle. | |
1605 * @note This procedure could be used for aborting any ongoing transfer (Tx and Rx), | |
1606 * started in Interrupt or DMA mode. | |
1607 * This procedure performs following operations : | |
1608 * - Disable SPI Interrupts (depending of transfer direction) | |
1609 * - Disable the DMA transfer in the peripheral register (if enabled) | |
1610 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) | |
1611 * - Set handle State to READY | |
1612 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. | |
1613 * @note Once transfer is aborted, the __HAL_SPI_CLEAR_OVRFLAG() macro must be called in user application | |
1614 * before starting new SPI receive process. | |
1615 * @retval HAL status | |
1616 */ | |
1617 HAL_StatusTypeDef HAL_SPI_Abort(SPI_HandleTypeDef *hspi) | |
1618 { | |
1619 __IO uint32_t count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U); | |
1620 | |
1621 /* Disable TXEIE, RXNEIE and ERRIE(mode fault event, overrun error, TI frame error) interrupts */ | |
1622 if(HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXEIE)) | |
1623 { | |
1624 hspi->TxISR = SPI_AbortTx_ISR; | |
1625 } | |
1626 | |
1627 if(HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXNEIE)) | |
1628 { | |
1629 hspi->RxISR = SPI_AbortRx_ISR; | |
1630 } | |
1631 | |
1632 /* Clear ERRIE interrupts in case of DMA Mode */ | |
1633 CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_ERRIE); | |
1634 | |
1635 /* Disable the SPI DMA Tx or SPI DMA Rx request if enabled */ | |
1636 if ((HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXDMAEN)) || (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXDMAEN))) | |
1637 { | |
1638 /* Abort the SPI DMA Tx channel : use blocking DMA Abort API (no callback) */ | |
1639 if(hspi->hdmatx != NULL) | |
1640 { | |
1641 /* Set the SPI DMA Abort callback : | |
1642 will lead to call HAL_SPI_AbortCpltCallback() at end of DMA abort procedure */ | |
1643 hspi->hdmatx->XferAbortCallback = NULL; | |
1644 | |
1645 /* Abort DMA Tx Handle linked to SPI Peripheral */ | |
1646 HAL_DMA_Abort(hspi->hdmatx); | |
1647 | |
1648 /* Disable Tx DMA Request */ | |
1649 CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXDMAEN)); | |
1650 | |
1651 /* Wait until TXE flag is set */ | |
1652 do | |
1653 { | |
1654 if(count-- == 0U) | |
1655 { | |
1656 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); | |
1657 break; | |
1658 } | |
1659 } | |
1660 while((hspi->Instance->SR & SPI_FLAG_TXE) == RESET); | |
1661 } | |
1662 /* Abort the SPI DMA Rx channel : use blocking DMA Abort API (no callback) */ | |
1663 if(hspi->hdmarx != NULL) | |
1664 { | |
1665 /* Set the SPI DMA Abort callback : | |
1666 will lead to call HAL_SPI_AbortCpltCallback() at end of DMA abort procedure */ | |
1667 hspi->hdmarx->XferAbortCallback = NULL; | |
1668 | |
1669 /* Abort DMA Rx Handle linked to SPI Peripheral */ | |
1670 HAL_DMA_Abort(hspi->hdmarx); | |
1671 | |
1672 /* Disable peripheral */ | |
1673 __HAL_SPI_DISABLE(hspi); | |
1674 | |
1675 /* Disable Rx DMA Request */ | |
1676 CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_RXDMAEN)); | |
1677 | |
1678 } | |
1679 } | |
1680 /* Reset Tx and Rx transfer counters */ | |
1681 hspi->RxXferCount = 0U; | |
1682 hspi->TxXferCount = 0U; | |
1683 | |
1684 /* Reset errorCode */ | |
1685 hspi->ErrorCode = HAL_SPI_ERROR_NONE; | |
1686 | |
1687 /* Clear the Error flags in the SR register */ | |
1688 __HAL_SPI_CLEAR_OVRFLAG(hspi); | |
1689 __HAL_SPI_CLEAR_FREFLAG(hspi); | |
1690 | |
1691 /* Restore hspi->state to ready */ | |
1692 hspi->State = HAL_SPI_STATE_READY; | |
1693 | |
1694 return HAL_OK; | |
1695 } | |
1696 | |
1697 /** | |
1698 * @brief Abort ongoing transfer (Interrupt mode). | |
1699 * @param hspi SPI handle. | |
1700 * @note This procedure could be used for aborting any ongoing transfer (Tx and Rx), | |
1701 * started in Interrupt or DMA mode. | |
1702 * This procedure performs following operations : | |
1703 * - Disable SPI Interrupts (depending of transfer direction) | |
1704 * - Disable the DMA transfer in the peripheral register (if enabled) | |
1705 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) | |
1706 * - Set handle State to READY | |
1707 * - At abort completion, call user abort complete callback | |
1708 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be | |
1709 * considered as completed only when user abort complete callback is executed (not when exiting function). | |
1710 * @note Once transfer is aborted, the __HAL_SPI_CLEAR_OVRFLAG() macro must be called in user application | |
1711 * before starting new SPI receive process. | |
1712 * @retval HAL status | |
1713 */ | |
1714 HAL_StatusTypeDef HAL_SPI_Abort_IT(SPI_HandleTypeDef *hspi) | |
1715 { | |
1716 uint32_t abortcplt; | |
1717 | |
1718 /* Change Rx and Tx Irq Handler to Disable TXEIE, RXNEIE and ERRIE interrupts */ | |
1719 if(HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXEIE)) | |
1720 { | |
1721 hspi->TxISR = SPI_AbortTx_ISR; | |
1722 } | |
1723 | |
1724 if(HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXNEIE)) | |
1725 { | |
1726 hspi->RxISR = SPI_AbortRx_ISR; | |
1727 } | |
1728 | |
1729 /* Clear ERRIE interrupts in case of DMA Mode */ | |
1730 CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_ERRIE); | |
1731 | |
1732 abortcplt = 1U; | |
1733 | |
1734 /* If DMA Tx and/or DMA Rx Handles are associated to SPI Handle, DMA Abort complete callbacks should be initialised | |
1735 before any call to DMA Abort functions */ | |
1736 /* DMA Tx Handle is valid */ | |
1737 if(hspi->hdmatx != NULL) | |
1738 { | |
1739 /* Set DMA Abort Complete callback if UART DMA Tx request if enabled. | |
1740 Otherwise, set it to NULL */ | |
1741 if(HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXDMAEN)) | |
1742 { | |
1743 hspi->hdmatx->XferAbortCallback = SPI_DMATxAbortCallback; | |
1744 } | |
1745 else | |
1746 { | |
1747 hspi->hdmatx->XferAbortCallback = NULL; | |
1748 } | |
1749 } | |
1750 /* DMA Rx Handle is valid */ | |
1751 if(hspi->hdmarx != NULL) | |
1752 { | |
1753 /* Set DMA Abort Complete callback if UART DMA Rx request if enabled. | |
1754 Otherwise, set it to NULL */ | |
1755 if(HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXDMAEN)) | |
1756 { | |
1757 hspi->hdmarx->XferAbortCallback = SPI_DMARxAbortCallback; | |
1758 } | |
1759 else | |
1760 { | |
1761 hspi->hdmarx->XferAbortCallback = NULL; | |
1762 } | |
1763 } | |
1764 | |
1765 /* Disable the SPI DMA Tx or the SPI Rx request if enabled */ | |
1766 if((HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXDMAEN)) && (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXDMAEN))) | |
1767 { | |
1768 /* Abort the SPI DMA Tx channel */ | |
1769 if(hspi->hdmatx != NULL) | |
1770 { | |
1771 /* Abort DMA Tx Handle linked to SPI Peripheral */ | |
1772 if(HAL_DMA_Abort_IT(hspi->hdmatx) != HAL_OK) | |
1773 { | |
1774 hspi->hdmatx->XferAbortCallback = NULL; | |
1775 } | |
1776 else | |
1777 { | |
1778 abortcplt = 0U; | |
1779 } | |
1780 } | |
1781 /* Abort the SPI DMA Rx channel */ | |
1782 if(hspi->hdmarx != NULL) | |
1783 { | |
1784 /* Abort DMA Rx Handle linked to SPI Peripheral */ | |
1785 if(HAL_DMA_Abort_IT(hspi->hdmarx)!= HAL_OK) | |
1786 { | |
1787 hspi->hdmarx->XferAbortCallback = NULL; | |
1788 abortcplt = 1U; | |
1789 } | |
1790 else | |
1791 { | |
1792 abortcplt = 0U; | |
1793 } | |
1794 } | |
1795 } | |
1796 | |
1797 /* Disable the SPI DMA Tx or the SPI Rx request if enabled */ | |
1798 if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXDMAEN)) | |
1799 { | |
1800 /* Abort the SPI DMA Tx channel */ | |
1801 if(hspi->hdmatx != NULL) | |
1802 { | |
1803 /* Abort DMA Tx Handle linked to SPI Peripheral */ | |
1804 if(HAL_DMA_Abort_IT(hspi->hdmatx) != HAL_OK) | |
1805 { | |
1806 hspi->hdmatx->XferAbortCallback = NULL; | |
1807 } | |
1808 else | |
1809 { | |
1810 abortcplt = 0U; | |
1811 } | |
1812 } | |
1813 } | |
1814 /* Disable the SPI DMA Tx or the SPI Rx request if enabled */ | |
1815 if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXDMAEN)) | |
1816 { | |
1817 /* Abort the SPI DMA Rx channel */ | |
1818 if(hspi->hdmarx != NULL) | |
1819 { | |
1820 /* Abort DMA Rx Handle linked to SPI Peripheral */ | |
1821 if(HAL_DMA_Abort_IT(hspi->hdmarx)!= HAL_OK) | |
1822 { | |
1823 hspi->hdmarx->XferAbortCallback = NULL; | |
1824 } | |
1825 else | |
1826 { | |
1827 abortcplt = 0U; | |
1828 } | |
1829 } | |
1830 } | |
1831 | |
1832 if(abortcplt == 1U) | |
1833 { | |
1834 /* Reset Tx and Rx transfer counters */ | |
1835 hspi->RxXferCount = 0U; | |
1836 hspi->TxXferCount = 0U; | |
1837 | |
1838 /* Reset errorCode */ | |
1839 hspi->ErrorCode = HAL_SPI_ERROR_NONE; | |
1840 | |
1841 /* Clear the Error flags in the SR register */ | |
1842 __HAL_SPI_CLEAR_OVRFLAG(hspi); | |
1843 __HAL_SPI_CLEAR_FREFLAG(hspi); | |
1844 | |
1845 /* Restore hspi->State to Ready */ | |
1846 hspi->State = HAL_SPI_STATE_READY; | |
1847 | |
1848 /* As no DMA to be aborted, call directly user Abort complete callback */ | |
1849 HAL_SPI_AbortCpltCallback(hspi); | |
1850 } | |
1851 return HAL_OK; | |
1852 } | |
1853 | |
1854 /** | |
1855 * @brief Pause the DMA Transfer. | |
1856 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
1857 * the configuration information for the specified SPI module. | |
1858 * @retval HAL status | |
1859 */ | |
1860 HAL_StatusTypeDef HAL_SPI_DMAPause(SPI_HandleTypeDef *hspi) | |
1861 { | |
1862 /* Process Locked */ | |
1863 __HAL_LOCK(hspi); | |
1864 | |
1865 /* Disable the SPI DMA Tx & Rx requests */ | |
1866 CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN); | |
1867 | |
1868 /* Process Unlocked */ | |
1869 __HAL_UNLOCK(hspi); | |
1870 | |
1871 return HAL_OK; | |
1872 } | |
1873 | |
1874 /** | |
1875 * @brief Resume the DMA Transfer. | |
1876 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
1877 * the configuration information for the specified SPI module. | |
1878 * @retval HAL status | |
1879 */ | |
1880 HAL_StatusTypeDef HAL_SPI_DMAResume(SPI_HandleTypeDef *hspi) | |
1881 { | |
1882 /* Process Locked */ | |
1883 __HAL_LOCK(hspi); | |
1884 | |
1885 /* Enable the SPI DMA Tx & Rx requests */ | |
1886 SET_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN); | |
1887 | |
1888 /* Process Unlocked */ | |
1889 __HAL_UNLOCK(hspi); | |
1890 | |
1891 return HAL_OK; | |
1892 } | |
1893 | |
1894 /** | |
1895 * @brief Stop the DMA Transfer. | |
1896 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
1897 * the configuration information for the specified SPI module. | |
1898 * @retval HAL status | |
1899 */ | |
1900 HAL_StatusTypeDef HAL_SPI_DMAStop(SPI_HandleTypeDef *hspi) | |
1901 { | |
1902 /* The Lock is not implemented on this API to allow the user application | |
1903 to call the HAL SPI API under callbacks HAL_SPI_TxCpltCallback() or HAL_SPI_RxCpltCallback() or HAL_SPI_TxRxCpltCallback(): | |
1904 when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated | |
1905 and the correspond call back is executed HAL_SPI_TxCpltCallback() or HAL_SPI_RxCpltCallback() or HAL_SPI_TxRxCpltCallback() | |
1906 */ | |
1907 | |
1908 /* Abort the SPI DMA tx Stream */ | |
1909 if(hspi->hdmatx != NULL) | |
1910 { | |
1911 HAL_DMA_Abort(hspi->hdmatx); | |
1912 } | |
1913 /* Abort the SPI DMA rx Stream */ | |
1914 if(hspi->hdmarx != NULL) | |
1915 { | |
1916 HAL_DMA_Abort(hspi->hdmarx); | |
1917 } | |
1918 | |
1919 /* Disable the SPI DMA Tx & Rx requests */ | |
1920 CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN); | |
1921 hspi->State = HAL_SPI_STATE_READY; | |
1922 return HAL_OK; | |
1923 } | |
1924 | |
1925 /** | |
1926 * @brief Handle SPI interrupt request. | |
1927 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
1928 * the configuration information for the specified SPI module. | |
1929 * @retval None | |
1930 */ | |
1931 void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi) | |
1932 { | |
1933 uint32_t itsource = hspi->Instance->CR2; | |
1934 uint32_t itflag = hspi->Instance->SR; | |
1935 | |
1936 /* SPI in mode Receiver ----------------------------------------------------*/ | |
1937 if(((itflag & SPI_FLAG_OVR) == RESET) && | |
1938 ((itflag & SPI_FLAG_RXNE) != RESET) && ((itsource & SPI_IT_RXNE) != RESET)) | |
1939 { | |
1940 hspi->RxISR(hspi); | |
1941 return; | |
1942 } | |
1943 | |
1944 /* SPI in mode Transmitter -------------------------------------------------*/ | |
1945 if(((itflag & SPI_FLAG_TXE) != RESET) && ((itsource & SPI_IT_TXE) != RESET)) | |
1946 { | |
1947 hspi->TxISR(hspi); | |
1948 return; | |
1949 } | |
1950 | |
1951 /* SPI in Error Treatment --------------------------------------------------*/ | |
1952 if(((itflag & (SPI_FLAG_MODF | SPI_FLAG_OVR | SPI_FLAG_FRE)) != RESET) && ((itsource & SPI_IT_ERR) != RESET)) | |
1953 { | |
1954 /* SPI Overrun error interrupt occurred ----------------------------------*/ | |
1955 if((itflag & SPI_FLAG_OVR) != RESET) | |
1956 { | |
1957 if(hspi->State != HAL_SPI_STATE_BUSY_TX) | |
1958 { | |
1959 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_OVR); | |
1960 __HAL_SPI_CLEAR_OVRFLAG(hspi); | |
1961 } | |
1962 else | |
1963 { | |
1964 __HAL_SPI_CLEAR_OVRFLAG(hspi); | |
1965 return; | |
1966 } | |
1967 } | |
1968 | |
1969 /* SPI Mode Fault error interrupt occurred -------------------------------*/ | |
1970 if((itflag & SPI_FLAG_MODF) != RESET) | |
1971 { | |
1972 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_MODF); | |
1973 __HAL_SPI_CLEAR_MODFFLAG(hspi); | |
1974 } | |
1975 | |
1976 /* SPI Frame error interrupt occurred ------------------------------------*/ | |
1977 if((itflag & SPI_FLAG_FRE) != RESET) | |
1978 { | |
1979 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FRE); | |
1980 __HAL_SPI_CLEAR_FREFLAG(hspi); | |
1981 } | |
1982 | |
1983 if(hspi->ErrorCode != HAL_SPI_ERROR_NONE) | |
1984 { | |
1985 /* Disable all interrupts */ | |
1986 __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXNE | SPI_IT_TXE | SPI_IT_ERR); | |
1987 | |
1988 hspi->State = HAL_SPI_STATE_READY; | |
1989 /* Disable the SPI DMA requests if enabled */ | |
1990 if ((HAL_IS_BIT_SET(itsource, SPI_CR2_TXDMAEN))||(HAL_IS_BIT_SET(itsource, SPI_CR2_RXDMAEN))) | |
1991 { | |
1992 CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN)); | |
1993 | |
1994 /* Abort the SPI DMA Rx channel */ | |
1995 if(hspi->hdmarx != NULL) | |
1996 { | |
1997 /* Set the SPI DMA Abort callback : | |
1998 will lead to call HAL_SPI_ErrorCallback() at end of DMA abort procedure */ | |
1999 hspi->hdmarx->XferAbortCallback = SPI_DMAAbortOnError; | |
2000 HAL_DMA_Abort_IT(hspi->hdmarx); | |
2001 } | |
2002 /* Abort the SPI DMA Tx channel */ | |
2003 if(hspi->hdmatx != NULL) | |
2004 { | |
2005 /* Set the SPI DMA Abort callback : | |
2006 will lead to call HAL_SPI_ErrorCallback() at end of DMA abort procedure */ | |
2007 hspi->hdmatx->XferAbortCallback = SPI_DMAAbortOnError; | |
2008 HAL_DMA_Abort_IT(hspi->hdmatx); | |
2009 } | |
2010 } | |
2011 else | |
2012 { | |
2013 /* Call user error callback */ | |
2014 HAL_SPI_ErrorCallback(hspi); | |
2015 } | |
2016 } | |
2017 return; | |
2018 } | |
2019 } | |
2020 | |
2021 /** | |
2022 * @brief Tx Transfer completed callback. | |
2023 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
2024 * the configuration information for SPI module. | |
2025 * @retval None | |
2026 */ | |
2027 __weak void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi) | |
2028 { | |
2029 /* Prevent unused argument(s) compilation warning */ | |
2030 UNUSED(hspi); | |
2031 /* NOTE : This function should not be modified, when the callback is needed, | |
2032 the HAL_SPI_TxCpltCallback should be implemented in the user file | |
2033 */ | |
2034 } | |
2035 | |
2036 /** | |
2037 * @brief Rx Transfer completed callback. | |
2038 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
2039 * the configuration information for SPI module. | |
2040 * @retval None | |
2041 */ | |
2042 __weak void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) | |
2043 { | |
2044 /* Prevent unused argument(s) compilation warning */ | |
2045 UNUSED(hspi); | |
2046 /* NOTE : This function should not be modified, when the callback is needed, | |
2047 the HAL_SPI_RxCpltCallback should be implemented in the user file | |
2048 */ | |
2049 } | |
2050 | |
2051 /** | |
2052 * @brief Tx and Rx Transfer completed callback. | |
2053 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
2054 * the configuration information for SPI module. | |
2055 * @retval None | |
2056 */ | |
2057 __weak void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi) | |
2058 { | |
2059 /* Prevent unused argument(s) compilation warning */ | |
2060 UNUSED(hspi); | |
2061 /* NOTE : This function should not be modified, when the callback is needed, | |
2062 the HAL_SPI_TxRxCpltCallback should be implemented in the user file | |
2063 */ | |
2064 } | |
2065 | |
2066 /** | |
2067 * @brief Tx Half Transfer completed callback. | |
2068 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
2069 * the configuration information for SPI module. | |
2070 * @retval None | |
2071 */ | |
2072 __weak void HAL_SPI_TxHalfCpltCallback(SPI_HandleTypeDef *hspi) | |
2073 { | |
2074 /* Prevent unused argument(s) compilation warning */ | |
2075 UNUSED(hspi); | |
2076 /* NOTE : This function should not be modified, when the callback is needed, | |
2077 the HAL_SPI_TxHalfCpltCallback should be implemented in the user file | |
2078 */ | |
2079 } | |
2080 | |
2081 /** | |
2082 * @brief Rx Half Transfer completed callback. | |
2083 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
2084 * the configuration information for SPI module. | |
2085 * @retval None | |
2086 */ | |
2087 __weak void HAL_SPI_RxHalfCpltCallback(SPI_HandleTypeDef *hspi) | |
2088 { | |
2089 /* Prevent unused argument(s) compilation warning */ | |
2090 UNUSED(hspi); | |
2091 /* NOTE : This function should not be modified, when the callback is needed, | |
2092 the HAL_SPI_RxHalfCpltCallback() should be implemented in the user file | |
2093 */ | |
2094 } | |
2095 | |
2096 /** | |
2097 * @brief Tx and Rx Half Transfer callback. | |
2098 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
2099 * the configuration information for SPI module. | |
2100 * @retval None | |
2101 */ | |
2102 __weak void HAL_SPI_TxRxHalfCpltCallback(SPI_HandleTypeDef *hspi) | |
2103 { | |
2104 /* Prevent unused argument(s) compilation warning */ | |
2105 UNUSED(hspi); | |
2106 /* NOTE : This function should not be modified, when the callback is needed, | |
2107 the HAL_SPI_TxRxHalfCpltCallback() should be implemented in the user file | |
2108 */ | |
2109 } | |
2110 | |
2111 /** | |
2112 * @brief SPI error callback. | |
2113 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
2114 * the configuration information for SPI module. | |
2115 * @retval None | |
2116 */ | |
2117 __weak void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi) | |
2118 { | |
2119 /* Prevent unused argument(s) compilation warning */ | |
2120 UNUSED(hspi); | |
2121 /* NOTE : This function should not be modified, when the callback is needed, | |
2122 the HAL_SPI_ErrorCallback should be implemented in the user file | |
2123 */ | |
2124 /* NOTE : The ErrorCode parameter in the hspi handle is updated by the SPI processes | |
2125 and user can use HAL_SPI_GetError() API to check the latest error occurred | |
2126 */ | |
2127 } | |
2128 | |
2129 /** | |
2130 * @brief SPI Abort Complete callback. | |
2131 * @param hspi SPI handle. | |
2132 * @retval None | |
2133 */ | |
2134 __weak void HAL_SPI_AbortCpltCallback(SPI_HandleTypeDef *hspi) | |
2135 { | |
2136 /* Prevent unused argument(s) compilation warning */ | |
2137 UNUSED(hspi); | |
2138 | |
2139 /* NOTE : This function should not be modified, when the callback is needed, | |
2140 the HAL_SPI_AbortCpltCallback can be implemented in the user file. | |
2141 */ | |
2142 } | |
2143 | |
2144 /** | |
2145 * @} | |
2146 */ | |
2147 | |
2148 /** @defgroup SPI_Exported_Functions_Group3 Peripheral State and Errors functions | |
2149 * @brief SPI control functions | |
2150 * | |
2151 @verbatim | |
2152 =============================================================================== | |
2153 ##### Peripheral State and Errors functions ##### | |
2154 =============================================================================== | |
2155 [..] | |
2156 This subsection provides a set of functions allowing to control the SPI. | |
2157 (+) HAL_SPI_GetState() API can be helpful to check in run-time the state of the SPI peripheral | |
2158 (+) HAL_SPI_GetError() check in run-time Errors occurring during communication | |
2159 @endverbatim | |
2160 * @{ | |
2161 */ | |
2162 | |
2163 /** | |
2164 * @brief Return the SPI handle state. | |
2165 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
2166 * the configuration information for SPI module. | |
2167 * @retval SPI state | |
2168 */ | |
2169 HAL_SPI_StateTypeDef HAL_SPI_GetState(SPI_HandleTypeDef *hspi) | |
2170 { | |
2171 /* Return SPI handle state */ | |
2172 return hspi->State; | |
2173 } | |
2174 | |
2175 /** | |
2176 * @brief Return the SPI error code. | |
2177 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
2178 * the configuration information for SPI module. | |
2179 * @retval SPI error code in bitmap format | |
2180 */ | |
2181 uint32_t HAL_SPI_GetError(SPI_HandleTypeDef *hspi) | |
2182 { | |
2183 /* Return SPI ErrorCode */ | |
2184 return hspi->ErrorCode; | |
2185 } | |
2186 | |
2187 /** | |
2188 * @} | |
2189 */ | |
2190 | |
2191 /** | |
2192 * @} | |
2193 */ | |
2194 | |
2195 /** @addtogroup SPI_Private_Functions | |
2196 * @brief Private functions | |
2197 * @{ | |
2198 */ | |
2199 | |
2200 /** | |
2201 * @brief DMA SPI transmit process complete callback. | |
2202 * @param hdma pointer to a DMA_HandleTypeDef structure that contains | |
2203 * the configuration information for the specified DMA module. | |
2204 * @retval None | |
2205 */ | |
2206 static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma) | |
2207 { | |
2208 SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; | |
2209 uint32_t tickstart = 0U; | |
2210 | |
2211 /* Init tickstart for timeout managment*/ | |
2212 tickstart = HAL_GetTick(); | |
2213 | |
2214 /* DMA Normal Mode */ | |
2215 if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U) | |
2216 { | |
2217 /* Disable Tx DMA Request */ | |
2218 CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN); | |
2219 | |
2220 /* Check the end of the transaction */ | |
2221 if(SPI_CheckFlag_BSY(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK) | |
2222 { | |
2223 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); | |
2224 } | |
2225 | |
2226 /* Clear overrun flag in 2 Lines communication mode because received data is not read */ | |
2227 if(hspi->Init.Direction == SPI_DIRECTION_2LINES) | |
2228 { | |
2229 __HAL_SPI_CLEAR_OVRFLAG(hspi); | |
2230 } | |
2231 | |
2232 hspi->TxXferCount = 0U; | |
2233 hspi->State = HAL_SPI_STATE_READY; | |
2234 | |
2235 if(hspi->ErrorCode != HAL_SPI_ERROR_NONE) | |
2236 { | |
2237 HAL_SPI_ErrorCallback(hspi); | |
2238 return; | |
2239 } | |
2240 } | |
2241 HAL_SPI_TxCpltCallback(hspi); | |
2242 } | |
2243 | |
2244 /** | |
2245 * @brief DMA SPI receive process complete callback. | |
2246 * @param hdma pointer to a DMA_HandleTypeDef structure that contains | |
2247 * the configuration information for the specified DMA module. | |
2248 * @retval None | |
2249 */ | |
2250 static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma) | |
2251 { | |
2252 SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; | |
2253 #if (USE_SPI_CRC != 0U) | |
2254 uint32_t tickstart = 0U; | |
2255 __IO uint16_t tmpreg = 0U; | |
2256 | |
2257 /* Init tickstart for timeout management*/ | |
2258 tickstart = HAL_GetTick(); | |
2259 #endif /* USE_SPI_CRC */ | |
2260 | |
2261 if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U) | |
2262 { | |
2263 #if (USE_SPI_CRC != 0U) | |
2264 /* CRC handling */ | |
2265 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) | |
2266 { | |
2267 /* Wait until RXNE flag */ | |
2268 if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SPI_FLAG_RXNE, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK) | |
2269 { | |
2270 /* Error on the CRC reception */ | |
2271 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); | |
2272 } | |
2273 /* Read CRC */ | |
2274 tmpreg = hspi->Instance->DR; | |
2275 /* To avoid GCC warning */ | |
2276 UNUSED(tmpreg); | |
2277 } | |
2278 #endif /* USE_SPI_CRC */ | |
2279 | |
2280 /* Disable Rx/Tx DMA Request (done by default to handle the case master rx direction 2 lines) */ | |
2281 CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN); | |
2282 | |
2283 /* Check the end of the transaction */ | |
2284 if((hspi->Init.Mode == SPI_MODE_MASTER)&&((hspi->Init.Direction == SPI_DIRECTION_1LINE)||(hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY))) | |
2285 { | |
2286 /* Disable SPI peripheral */ | |
2287 __HAL_SPI_DISABLE(hspi); | |
2288 } | |
2289 | |
2290 hspi->RxXferCount = 0U; | |
2291 hspi->State = HAL_SPI_STATE_READY; | |
2292 | |
2293 #if (USE_SPI_CRC != 0U) | |
2294 /* Check if CRC error occurred */ | |
2295 if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR)) | |
2296 { | |
2297 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); | |
2298 __HAL_SPI_CLEAR_CRCERRFLAG(hspi); | |
2299 } | |
2300 #endif /* USE_SPI_CRC */ | |
2301 | |
2302 if(hspi->ErrorCode != HAL_SPI_ERROR_NONE) | |
2303 { | |
2304 HAL_SPI_ErrorCallback(hspi); | |
2305 return; | |
2306 } | |
2307 } | |
2308 HAL_SPI_RxCpltCallback(hspi); | |
2309 } | |
2310 | |
2311 /** | |
2312 * @brief DMA SPI transmit receive process complete callback. | |
2313 * @param hdma pointer to a DMA_HandleTypeDef structure that contains | |
2314 * the configuration information for the specified DMA module. | |
2315 * @retval None | |
2316 */ | |
2317 static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma) | |
2318 { | |
2319 SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; | |
2320 uint32_t tickstart = 0U; | |
2321 #if (USE_SPI_CRC != 0U) | |
2322 __IO int16_t tmpreg = 0U; | |
2323 #endif /* USE_SPI_CRC */ | |
2324 /* Init tickstart for timeout management*/ | |
2325 tickstart = HAL_GetTick(); | |
2326 | |
2327 if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U) | |
2328 { | |
2329 #if (USE_SPI_CRC != 0U) | |
2330 /* CRC handling */ | |
2331 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) | |
2332 { | |
2333 /* Wait the CRC data */ | |
2334 if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK) | |
2335 { | |
2336 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); | |
2337 } | |
2338 /* Read CRC to Flush DR and RXNE flag */ | |
2339 tmpreg = hspi->Instance->DR; | |
2340 /* To avoid GCC warning */ | |
2341 UNUSED(tmpreg); | |
2342 } | |
2343 #endif /* USE_SPI_CRC */ | |
2344 /* Check the end of the transaction */ | |
2345 if(SPI_CheckFlag_BSY(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK) | |
2346 { | |
2347 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); | |
2348 } | |
2349 | |
2350 /* Disable Rx/Tx DMA Request */ | |
2351 CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN); | |
2352 | |
2353 hspi->TxXferCount = 0U; | |
2354 hspi->RxXferCount = 0U; | |
2355 hspi->State = HAL_SPI_STATE_READY; | |
2356 | |
2357 #if (USE_SPI_CRC != 0U) | |
2358 /* Check if CRC error occurred */ | |
2359 if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR)) | |
2360 { | |
2361 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); | |
2362 __HAL_SPI_CLEAR_CRCERRFLAG(hspi); | |
2363 } | |
2364 #endif /* USE_SPI_CRC */ | |
2365 | |
2366 if(hspi->ErrorCode != HAL_SPI_ERROR_NONE) | |
2367 { | |
2368 HAL_SPI_ErrorCallback(hspi); | |
2369 return; | |
2370 } | |
2371 } | |
2372 HAL_SPI_TxRxCpltCallback(hspi); | |
2373 } | |
2374 | |
2375 /** | |
2376 * @brief DMA SPI half transmit process complete callback. | |
2377 * @param hdma pointer to a DMA_HandleTypeDef structure that contains | |
2378 * the configuration information for the specified DMA module. | |
2379 * @retval None | |
2380 */ | |
2381 static void SPI_DMAHalfTransmitCplt(DMA_HandleTypeDef *hdma) | |
2382 { | |
2383 SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; | |
2384 | |
2385 HAL_SPI_TxHalfCpltCallback(hspi); | |
2386 } | |
2387 | |
2388 /** | |
2389 * @brief DMA SPI half receive process complete callback | |
2390 * @param hdma pointer to a DMA_HandleTypeDef structure that contains | |
2391 * the configuration information for the specified DMA module. | |
2392 * @retval None | |
2393 */ | |
2394 static void SPI_DMAHalfReceiveCplt(DMA_HandleTypeDef *hdma) | |
2395 { | |
2396 SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; | |
2397 | |
2398 HAL_SPI_RxHalfCpltCallback(hspi); | |
2399 } | |
2400 | |
2401 /** | |
2402 * @brief DMA SPI half transmit receive process complete callback. | |
2403 * @param hdma pointer to a DMA_HandleTypeDef structure that contains | |
2404 * the configuration information for the specified DMA module. | |
2405 * @retval None | |
2406 */ | |
2407 static void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma) | |
2408 { | |
2409 SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; | |
2410 | |
2411 HAL_SPI_TxRxHalfCpltCallback(hspi); | |
2412 } | |
2413 | |
2414 /** | |
2415 * @brief DMA SPI communication error callback. | |
2416 * @param hdma pointer to a DMA_HandleTypeDef structure that contains | |
2417 * the configuration information for the specified DMA module. | |
2418 * @retval None | |
2419 */ | |
2420 static void SPI_DMAError(DMA_HandleTypeDef *hdma) | |
2421 { | |
2422 SPI_HandleTypeDef* hspi = (SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; | |
2423 | |
2424 /* Stop the disable DMA transfer on SPI side */ | |
2425 CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN); | |
2426 | |
2427 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA); | |
2428 hspi->State = HAL_SPI_STATE_READY; | |
2429 HAL_SPI_ErrorCallback(hspi); | |
2430 } | |
2431 | |
2432 /** | |
2433 * @brief DMA SPI communication abort callback, when initiated by HAL services on Error | |
2434 * (To be called at end of DMA Abort procedure following error occurrence). | |
2435 * @param hdma DMA handle. | |
2436 * @retval None | |
2437 */ | |
2438 static void SPI_DMAAbortOnError(DMA_HandleTypeDef *hdma) | |
2439 { | |
2440 SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; | |
2441 hspi->RxXferCount = 0U; | |
2442 hspi->TxXferCount = 0U; | |
2443 | |
2444 HAL_SPI_ErrorCallback(hspi); | |
2445 } | |
2446 | |
2447 /** | |
2448 * @brief DMA SPI Tx communication abort callback, when initiated by user | |
2449 * (To be called at end of DMA Tx Abort procedure following user abort request). | |
2450 * @note When this callback is executed, User Abort complete call back is called only if no | |
2451 * Abort still ongoing for Rx DMA Handle. | |
2452 * @param hdma DMA handle. | |
2453 * @retval None | |
2454 */ | |
2455 static void SPI_DMATxAbortCallback(DMA_HandleTypeDef *hdma) | |
2456 { | |
2457 __IO uint32_t count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U); | |
2458 SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; | |
2459 | |
2460 hspi->hdmatx->XferAbortCallback = NULL; | |
2461 | |
2462 /* Disable Tx DMA Request */ | |
2463 CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN ); | |
2464 | |
2465 /* Wait until TXE flag is set */ | |
2466 do | |
2467 { | |
2468 if(count-- == 0U) | |
2469 { | |
2470 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); | |
2471 break; | |
2472 } | |
2473 } | |
2474 while((hspi->Instance->SR & SPI_FLAG_TXE) == RESET); | |
2475 | |
2476 /* Check if an Abort process is still ongoing */ | |
2477 if(hspi->hdmarx != NULL) | |
2478 { | |
2479 if(hspi->hdmarx->XferAbortCallback != NULL) | |
2480 { | |
2481 return; | |
2482 } | |
2483 } | |
2484 | |
2485 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */ | |
2486 hspi->RxXferCount = 0U; | |
2487 hspi->TxXferCount = 0U; | |
2488 | |
2489 /* Reset errorCode */ | |
2490 hspi->ErrorCode = HAL_SPI_ERROR_NONE; | |
2491 | |
2492 /* Clear the Error flags in the SR register */ | |
2493 __HAL_SPI_CLEAR_FREFLAG(hspi); | |
2494 | |
2495 /* Restore hspi->State to Ready */ | |
2496 hspi->State = HAL_SPI_STATE_READY; | |
2497 | |
2498 /* Call user Abort complete callback */ | |
2499 HAL_SPI_AbortCpltCallback(hspi); | |
2500 } | |
2501 | |
2502 /** | |
2503 * @brief DMA SPI Rx communication abort callback, when initiated by user | |
2504 * (To be called at end of DMA Rx Abort procedure following user abort request). | |
2505 * @note When this callback is executed, User Abort complete call back is called only if no | |
2506 * Abort still ongoing for Tx DMA Handle. | |
2507 * @param hdma DMA handle. | |
2508 * @retval None | |
2509 */ | |
2510 static void SPI_DMARxAbortCallback(DMA_HandleTypeDef *hdma) | |
2511 { | |
2512 SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; | |
2513 | |
2514 /* Disable SPI Peripheral */ | |
2515 __HAL_SPI_DISABLE(hspi); | |
2516 | |
2517 hspi->hdmarx->XferAbortCallback = NULL; | |
2518 | |
2519 /* Disable Rx DMA Request */ | |
2520 CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN); | |
2521 | |
2522 /* Check if an Abort process is still ongoing */ | |
2523 if(hspi->hdmatx != NULL) | |
2524 { | |
2525 if(hspi->hdmatx->XferAbortCallback != NULL) | |
2526 { | |
2527 return; | |
2528 } | |
2529 } | |
2530 | |
2531 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */ | |
2532 hspi->RxXferCount = 0U; | |
2533 hspi->TxXferCount = 0U; | |
2534 | |
2535 /* Reset errorCode */ | |
2536 hspi->ErrorCode = HAL_SPI_ERROR_NONE; | |
2537 | |
2538 /* Clear the Error flags in the SR register */ | |
2539 __HAL_SPI_CLEAR_OVRFLAG(hspi); | |
2540 __HAL_SPI_CLEAR_FREFLAG(hspi); | |
2541 | |
2542 /* Restore hspi->State to Ready */ | |
2543 hspi->State = HAL_SPI_STATE_READY; | |
2544 | |
2545 /* Call user Abort complete callback */ | |
2546 HAL_SPI_AbortCpltCallback(hspi); | |
2547 } | |
2548 | |
2549 /** | |
2550 * @brief Rx 8-bit handler for Transmit and Receive in Interrupt mode. | |
2551 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
2552 * the configuration information for SPI module. | |
2553 * @retval None | |
2554 */ | |
2555 static void SPI_2linesRxISR_8BIT(struct __SPI_HandleTypeDef *hspi) | |
2556 { | |
2557 /* Receive data in 8bit mode */ | |
2558 *hspi->pRxBuffPtr++ = *((__IO uint8_t *)&hspi->Instance->DR); | |
2559 hspi->RxXferCount--; | |
2560 | |
2561 /* check end of the reception */ | |
2562 if(hspi->RxXferCount == 0U) | |
2563 { | |
2564 #if (USE_SPI_CRC != 0U) | |
2565 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) | |
2566 { | |
2567 hspi->RxISR = SPI_2linesRxISR_8BITCRC; | |
2568 return; | |
2569 } | |
2570 #endif /* USE_SPI_CRC */ | |
2571 | |
2572 /* Disable RXNE interrupt */ | |
2573 __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR)); | |
2574 | |
2575 if(hspi->TxXferCount == 0U) | |
2576 { | |
2577 SPI_CloseRxTx_ISR(hspi); | |
2578 } | |
2579 } | |
2580 } | |
2581 | |
2582 #if (USE_SPI_CRC != 0U) | |
2583 /** | |
2584 * @brief Rx 8-bit handler for Transmit and Receive in Interrupt mode. | |
2585 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
2586 * the configuration information for SPI module. | |
2587 * @retval None | |
2588 */ | |
2589 static void SPI_2linesRxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi) | |
2590 { | |
2591 __IO uint8_t tmpreg = 0U; | |
2592 | |
2593 /* Read data register to flush CRC */ | |
2594 tmpreg = *((__IO uint8_t *)&hspi->Instance->DR); | |
2595 | |
2596 /* To avoid GCC warning */ | |
2597 | |
2598 UNUSED(tmpreg); | |
2599 | |
2600 /* Disable RXNE interrupt */ | |
2601 __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR)); | |
2602 | |
2603 if(hspi->TxXferCount == 0U) | |
2604 { | |
2605 SPI_CloseRxTx_ISR(hspi); | |
2606 } | |
2607 } | |
2608 #endif /* USE_SPI_CRC */ | |
2609 | |
2610 /** | |
2611 * @brief Tx 8-bit handler for Transmit and Receive in Interrupt mode. | |
2612 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
2613 * the configuration information for SPI module. | |
2614 * @retval None | |
2615 */ | |
2616 static void SPI_2linesTxISR_8BIT(struct __SPI_HandleTypeDef *hspi) | |
2617 { | |
2618 *(__IO uint8_t *)&hspi->Instance->DR = (*hspi->pTxBuffPtr++); | |
2619 hspi->TxXferCount--; | |
2620 | |
2621 /* check the end of the transmission */ | |
2622 if(hspi->TxXferCount == 0U) | |
2623 { | |
2624 #if (USE_SPI_CRC != 0U) | |
2625 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) | |
2626 { | |
2627 SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); | |
2628 __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE); | |
2629 return; | |
2630 } | |
2631 #endif /* USE_SPI_CRC */ | |
2632 | |
2633 /* Disable TXE interrupt */ | |
2634 __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE); | |
2635 | |
2636 if(hspi->RxXferCount == 0U) | |
2637 { | |
2638 SPI_CloseRxTx_ISR(hspi); | |
2639 } | |
2640 } | |
2641 } | |
2642 | |
2643 /** | |
2644 * @brief Rx 16-bit handler for Transmit and Receive in Interrupt mode. | |
2645 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
2646 * the configuration information for SPI module. | |
2647 * @retval None | |
2648 */ | |
2649 static void SPI_2linesRxISR_16BIT(struct __SPI_HandleTypeDef *hspi) | |
2650 { | |
2651 /* Receive data in 16 Bit mode */ | |
2652 *((uint16_t*)hspi->pRxBuffPtr) = hspi->Instance->DR; | |
2653 hspi->pRxBuffPtr += sizeof(uint16_t); | |
2654 hspi->RxXferCount--; | |
2655 | |
2656 if(hspi->RxXferCount == 0U) | |
2657 { | |
2658 #if (USE_SPI_CRC != 0U) | |
2659 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) | |
2660 { | |
2661 hspi->RxISR = SPI_2linesRxISR_16BITCRC; | |
2662 return; | |
2663 } | |
2664 #endif /* USE_SPI_CRC */ | |
2665 | |
2666 /* Disable RXNE interrupt */ | |
2667 __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXNE); | |
2668 | |
2669 if(hspi->TxXferCount == 0U) | |
2670 { | |
2671 SPI_CloseRxTx_ISR(hspi); | |
2672 } | |
2673 } | |
2674 } | |
2675 | |
2676 #if (USE_SPI_CRC != 0U) | |
2677 /** | |
2678 * @brief Manage the CRC 16-bit receive for Transmit and Receive in Interrupt mode. | |
2679 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
2680 * the configuration information for SPI module. | |
2681 * @retval None | |
2682 */ | |
2683 static void SPI_2linesRxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi) | |
2684 { | |
2685 /* Receive data in 16 Bit mode */ | |
2686 __IO uint16_t tmpreg = 0U; | |
2687 | |
2688 /* Read data register to flush CRC */ | |
2689 tmpreg = hspi->Instance->DR; | |
2690 | |
2691 /* To avoid GCC warning */ | |
2692 UNUSED(tmpreg); | |
2693 | |
2694 /* Disable RXNE interrupt */ | |
2695 __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXNE); | |
2696 | |
2697 SPI_CloseRxTx_ISR(hspi); | |
2698 } | |
2699 #endif /* USE_SPI_CRC */ | |
2700 | |
2701 /** | |
2702 * @brief Tx 16-bit handler for Transmit and Receive in Interrupt mode. | |
2703 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
2704 * the configuration information for SPI module. | |
2705 * @retval None | |
2706 */ | |
2707 static void SPI_2linesTxISR_16BIT(struct __SPI_HandleTypeDef *hspi) | |
2708 { | |
2709 /* Transmit data in 16 Bit mode */ | |
2710 hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr); | |
2711 hspi->pTxBuffPtr += sizeof(uint16_t); | |
2712 hspi->TxXferCount--; | |
2713 | |
2714 /* Enable CRC Transmission */ | |
2715 if(hspi->TxXferCount == 0U) | |
2716 { | |
2717 #if (USE_SPI_CRC != 0U) | |
2718 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) | |
2719 { | |
2720 SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); | |
2721 __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE); | |
2722 return; | |
2723 } | |
2724 #endif /* USE_SPI_CRC */ | |
2725 | |
2726 /* Disable TXE interrupt */ | |
2727 __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE); | |
2728 | |
2729 if(hspi->RxXferCount == 0U) | |
2730 { | |
2731 SPI_CloseRxTx_ISR(hspi); | |
2732 } | |
2733 } | |
2734 } | |
2735 | |
2736 #if (USE_SPI_CRC != 0U) | |
2737 /** | |
2738 * @brief Manage the CRC 8-bit receive in Interrupt context. | |
2739 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
2740 * the configuration information for SPI module. | |
2741 * @retval None | |
2742 */ | |
2743 static void SPI_RxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi) | |
2744 { | |
2745 __IO uint8_t tmpreg = 0U; | |
2746 | |
2747 /* Read data register to flush CRC */ | |
2748 tmpreg = *((__IO uint8_t*)&hspi->Instance->DR); | |
2749 | |
2750 /* To avoid GCC warning */ | |
2751 UNUSED(tmpreg); | |
2752 | |
2753 SPI_CloseRx_ISR(hspi); | |
2754 } | |
2755 #endif /* USE_SPI_CRC */ | |
2756 | |
2757 /** | |
2758 * @brief Manage the receive 8-bit in Interrupt context. | |
2759 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
2760 * the configuration information for SPI module. | |
2761 * @retval None | |
2762 */ | |
2763 static void SPI_RxISR_8BIT(struct __SPI_HandleTypeDef *hspi) | |
2764 { | |
2765 *hspi->pRxBuffPtr++ = (*(__IO uint8_t *)&hspi->Instance->DR); | |
2766 hspi->RxXferCount--; | |
2767 | |
2768 #if (USE_SPI_CRC != 0U) | |
2769 /* Enable CRC Transmission */ | |
2770 if((hspi->RxXferCount == 1U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)) | |
2771 { | |
2772 SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); | |
2773 } | |
2774 #endif /* USE_SPI_CRC */ | |
2775 | |
2776 if(hspi->RxXferCount == 0U) | |
2777 { | |
2778 #if (USE_SPI_CRC != 0U) | |
2779 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) | |
2780 { | |
2781 hspi->RxISR = SPI_RxISR_8BITCRC; | |
2782 return; | |
2783 } | |
2784 #endif /* USE_SPI_CRC */ | |
2785 SPI_CloseRx_ISR(hspi); | |
2786 } | |
2787 } | |
2788 | |
2789 #if (USE_SPI_CRC != 0U) | |
2790 /** | |
2791 * @brief Manage the CRC 16-bit receive in Interrupt context. | |
2792 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
2793 * the configuration information for SPI module. | |
2794 * @retval None | |
2795 */ | |
2796 static void SPI_RxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi) | |
2797 { | |
2798 __IO uint16_t tmpreg = 0U; | |
2799 | |
2800 /* Read data register to flush CRC */ | |
2801 tmpreg = hspi->Instance->DR; | |
2802 | |
2803 /* To avoid GCC warning */ | |
2804 UNUSED(tmpreg); | |
2805 | |
2806 /* Disable RXNE and ERR interrupt */ | |
2807 __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR)); | |
2808 | |
2809 SPI_CloseRx_ISR(hspi); | |
2810 } | |
2811 #endif /* USE_SPI_CRC */ | |
2812 | |
2813 /** | |
2814 * @brief Manage the 16-bit receive in Interrupt context. | |
2815 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
2816 * the configuration information for SPI module. | |
2817 * @retval None | |
2818 */ | |
2819 static void SPI_RxISR_16BIT(struct __SPI_HandleTypeDef *hspi) | |
2820 { | |
2821 *((uint16_t *)hspi->pRxBuffPtr) = hspi->Instance->DR; | |
2822 hspi->pRxBuffPtr += sizeof(uint16_t); | |
2823 hspi->RxXferCount--; | |
2824 | |
2825 #if (USE_SPI_CRC != 0U) | |
2826 /* Enable CRC Transmission */ | |
2827 if((hspi->RxXferCount == 1U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)) | |
2828 { | |
2829 SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); | |
2830 } | |
2831 #endif /* USE_SPI_CRC */ | |
2832 | |
2833 if(hspi->RxXferCount == 0U) | |
2834 { | |
2835 #if (USE_SPI_CRC != 0U) | |
2836 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) | |
2837 { | |
2838 hspi->RxISR = SPI_RxISR_16BITCRC; | |
2839 return; | |
2840 } | |
2841 #endif /* USE_SPI_CRC */ | |
2842 SPI_CloseRx_ISR(hspi); | |
2843 } | |
2844 } | |
2845 | |
2846 /** | |
2847 * @brief Handle the data 8-bit transmit in Interrupt mode. | |
2848 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
2849 * the configuration information for SPI module. | |
2850 * @retval None | |
2851 */ | |
2852 static void SPI_TxISR_8BIT(struct __SPI_HandleTypeDef *hspi) | |
2853 { | |
2854 *(__IO uint8_t *)&hspi->Instance->DR = (*hspi->pTxBuffPtr++); | |
2855 hspi->TxXferCount--; | |
2856 | |
2857 if(hspi->TxXferCount == 0U) | |
2858 { | |
2859 #if (USE_SPI_CRC != 0U) | |
2860 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) | |
2861 { | |
2862 /* Enable CRC Transmission */ | |
2863 SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); | |
2864 } | |
2865 #endif /* USE_SPI_CRC */ | |
2866 SPI_CloseTx_ISR(hspi); | |
2867 } | |
2868 } | |
2869 | |
2870 /** | |
2871 * @brief Handle the data 16-bit transmit in Interrupt mode. | |
2872 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
2873 * the configuration information for SPI module. | |
2874 * @retval None | |
2875 */ | |
2876 static void SPI_TxISR_16BIT(struct __SPI_HandleTypeDef *hspi) | |
2877 { | |
2878 /* Transmit data in 16 Bit mode */ | |
2879 hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr); | |
2880 hspi->pTxBuffPtr += sizeof(uint16_t); | |
2881 hspi->TxXferCount--; | |
2882 | |
2883 if(hspi->TxXferCount == 0U) | |
2884 { | |
2885 #if (USE_SPI_CRC != 0U) | |
2886 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) | |
2887 { | |
2888 /* Enable CRC Transmission */ | |
2889 SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); | |
2890 } | |
2891 #endif /* USE_SPI_CRC */ | |
2892 SPI_CloseTx_ISR(hspi); | |
2893 } | |
2894 } | |
2895 | |
2896 /** | |
2897 * @brief Handle SPI Communication Timeout. | |
2898 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
2899 * the configuration information for SPI module. | |
2900 * @param Flag SPI flag to check | |
2901 * @param State flag state to check | |
2902 * @param Timeout Timeout duration | |
2903 * @param Tickstart tick start value | |
2904 * @retval HAL status | |
2905 */ | |
2906 static HAL_StatusTypeDef SPI_WaitFlagStateUntilTimeout(SPI_HandleTypeDef *hspi, uint32_t Flag, uint32_t State, uint32_t Timeout, uint32_t Tickstart) | |
2907 { | |
2908 while((((hspi->Instance->SR & Flag) == (Flag)) ? SET : RESET) != State) | |
2909 { | |
2910 if(Timeout != HAL_MAX_DELAY) | |
2911 { | |
2912 if((Timeout == 0U) || ((HAL_GetTick()-Tickstart) >= Timeout)) | |
2913 { | |
2914 /* Disable the SPI and reset the CRC: the CRC value should be cleared | |
2915 on both master and slave sides in order to resynchronize the master | |
2916 and slave for their respective CRC calculation */ | |
2917 | |
2918 /* Disable TXE, RXNE and ERR interrupts for the interrupt process */ | |
2919 __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR)); | |
2920 | |
2921 if((hspi->Init.Mode == SPI_MODE_MASTER)&&((hspi->Init.Direction == SPI_DIRECTION_1LINE)||(hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY))) | |
2922 { | |
2923 /* Disable SPI peripheral */ | |
2924 __HAL_SPI_DISABLE(hspi); | |
2925 } | |
2926 | |
2927 /* Reset CRC Calculation */ | |
2928 if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) | |
2929 { | |
2930 SPI_RESET_CRC(hspi); | |
2931 } | |
2932 | |
2933 hspi->State= HAL_SPI_STATE_READY; | |
2934 | |
2935 /* Process Unlocked */ | |
2936 __HAL_UNLOCK(hspi); | |
2937 | |
2938 return HAL_TIMEOUT; | |
2939 } | |
2940 } | |
2941 } | |
2942 | |
2943 return HAL_OK; | |
2944 } | |
2945 /** | |
2946 * @brief Handle to check BSY flag before start a new transaction. | |
2947 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
2948 * the configuration information for SPI module. | |
2949 * @param Timeout Timeout duration | |
2950 * @param Tickstart tick start value | |
2951 * @retval HAL status | |
2952 */ | |
2953 static HAL_StatusTypeDef SPI_CheckFlag_BSY(SPI_HandleTypeDef *hspi, uint32_t Timeout, uint32_t Tickstart) | |
2954 { | |
2955 /* Control the BSY flag */ | |
2956 if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_BSY, RESET, Timeout, Tickstart) != HAL_OK) | |
2957 { | |
2958 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); | |
2959 return HAL_TIMEOUT; | |
2960 } | |
2961 return HAL_OK; | |
2962 } | |
2963 | |
2964 /** | |
2965 * @brief Handle the end of the RXTX transaction. | |
2966 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
2967 * the configuration information for SPI module. | |
2968 * @retval None | |
2969 */ | |
2970 static void SPI_CloseRxTx_ISR(SPI_HandleTypeDef *hspi) | |
2971 { | |
2972 uint32_t tickstart = 0U; | |
2973 __IO uint32_t count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U); | |
2974 /* Init tickstart for timeout managment*/ | |
2975 tickstart = HAL_GetTick(); | |
2976 | |
2977 /* Disable ERR interrupt */ | |
2978 __HAL_SPI_DISABLE_IT(hspi, SPI_IT_ERR); | |
2979 | |
2980 /* Wait until TXE flag is set */ | |
2981 do | |
2982 { | |
2983 if(count-- == 0U) | |
2984 { | |
2985 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); | |
2986 break; | |
2987 } | |
2988 } | |
2989 while((hspi->Instance->SR & SPI_FLAG_TXE) == RESET); | |
2990 | |
2991 /* Check the end of the transaction */ | |
2992 if(SPI_CheckFlag_BSY(hspi, SPI_DEFAULT_TIMEOUT, tickstart)!=HAL_OK) | |
2993 { | |
2994 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); | |
2995 } | |
2996 | |
2997 /* Clear overrun flag in 2 Lines communication mode because received is not read */ | |
2998 if(hspi->Init.Direction == SPI_DIRECTION_2LINES) | |
2999 { | |
3000 __HAL_SPI_CLEAR_OVRFLAG(hspi); | |
3001 } | |
3002 | |
3003 #if (USE_SPI_CRC != 0U) | |
3004 /* Check if CRC error occurred */ | |
3005 if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET) | |
3006 { | |
3007 hspi->State = HAL_SPI_STATE_READY; | |
3008 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); | |
3009 __HAL_SPI_CLEAR_CRCERRFLAG(hspi); | |
3010 HAL_SPI_ErrorCallback(hspi); | |
3011 } | |
3012 else | |
3013 { | |
3014 #endif /* USE_SPI_CRC */ | |
3015 if(hspi->ErrorCode == HAL_SPI_ERROR_NONE) | |
3016 { | |
3017 if(hspi->State == HAL_SPI_STATE_BUSY_RX) | |
3018 { | |
3019 hspi->State = HAL_SPI_STATE_READY; | |
3020 HAL_SPI_RxCpltCallback(hspi); | |
3021 } | |
3022 else | |
3023 { | |
3024 hspi->State = HAL_SPI_STATE_READY; | |
3025 HAL_SPI_TxRxCpltCallback(hspi); | |
3026 } | |
3027 } | |
3028 else | |
3029 { | |
3030 hspi->State = HAL_SPI_STATE_READY; | |
3031 HAL_SPI_ErrorCallback(hspi); | |
3032 } | |
3033 #if (USE_SPI_CRC != 0U) | |
3034 } | |
3035 #endif /* USE_SPI_CRC */ | |
3036 } | |
3037 | |
3038 /** | |
3039 * @brief Handle the end of the RX transaction. | |
3040 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
3041 * the configuration information for SPI module. | |
3042 * @retval None | |
3043 */ | |
3044 static void SPI_CloseRx_ISR(SPI_HandleTypeDef *hspi) | |
3045 { | |
3046 /* Disable RXNE and ERR interrupt */ | |
3047 __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR)); | |
3048 | |
3049 /* Check the end of the transaction */ | |
3050 if((hspi->Init.Mode == SPI_MODE_MASTER)&&((hspi->Init.Direction == SPI_DIRECTION_1LINE)||(hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY))) | |
3051 { | |
3052 /* Disable SPI peripheral */ | |
3053 __HAL_SPI_DISABLE(hspi); | |
3054 } | |
3055 | |
3056 /* Clear overrun flag in 2 Lines communication mode because received is not read */ | |
3057 if(hspi->Init.Direction == SPI_DIRECTION_2LINES) | |
3058 { | |
3059 __HAL_SPI_CLEAR_OVRFLAG(hspi); | |
3060 } | |
3061 hspi->State = HAL_SPI_STATE_READY; | |
3062 | |
3063 #if (USE_SPI_CRC != 0U) | |
3064 /* Check if CRC error occurred */ | |
3065 if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET) | |
3066 { | |
3067 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); | |
3068 __HAL_SPI_CLEAR_CRCERRFLAG(hspi); | |
3069 HAL_SPI_ErrorCallback(hspi); | |
3070 } | |
3071 else | |
3072 { | |
3073 #endif /* USE_SPI_CRC */ | |
3074 if(hspi->ErrorCode == HAL_SPI_ERROR_NONE) | |
3075 { | |
3076 HAL_SPI_RxCpltCallback(hspi); | |
3077 } | |
3078 else | |
3079 { | |
3080 HAL_SPI_ErrorCallback(hspi); | |
3081 } | |
3082 #if (USE_SPI_CRC != 0U) | |
3083 } | |
3084 #endif /* USE_SPI_CRC */ | |
3085 } | |
3086 | |
3087 /** | |
3088 * @brief Handle the end of the TX transaction. | |
3089 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
3090 * the configuration information for SPI module. | |
3091 * @retval None | |
3092 */ | |
3093 static void SPI_CloseTx_ISR(SPI_HandleTypeDef *hspi) | |
3094 { | |
3095 uint32_t tickstart = 0U; | |
3096 __IO uint32_t count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U); | |
3097 | |
3098 /* Init tickstart for timeout management*/ | |
3099 tickstart = HAL_GetTick(); | |
3100 | |
3101 /* Wait until TXE flag is set */ | |
3102 do | |
3103 { | |
3104 if(count-- == 0U) | |
3105 { | |
3106 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); | |
3107 break; | |
3108 } | |
3109 } | |
3110 while((hspi->Instance->SR & SPI_FLAG_TXE) == RESET); | |
3111 | |
3112 /* Disable TXE and ERR interrupt */ | |
3113 __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_ERR)); | |
3114 | |
3115 /* Check Busy flag */ | |
3116 if(SPI_CheckFlag_BSY(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK) | |
3117 { | |
3118 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); | |
3119 } | |
3120 | |
3121 /* Clear overrun flag in 2 Lines communication mode because received is not read */ | |
3122 if(hspi->Init.Direction == SPI_DIRECTION_2LINES) | |
3123 { | |
3124 __HAL_SPI_CLEAR_OVRFLAG(hspi); | |
3125 } | |
3126 | |
3127 hspi->State = HAL_SPI_STATE_READY; | |
3128 if(hspi->ErrorCode != HAL_SPI_ERROR_NONE) | |
3129 { | |
3130 HAL_SPI_ErrorCallback(hspi); | |
3131 } | |
3132 else | |
3133 { | |
3134 HAL_SPI_TxCpltCallback(hspi); | |
3135 } | |
3136 } | |
3137 | |
3138 /** | |
3139 * @} | |
3140 */ | |
3141 | |
3142 /** | |
3143 * @brief Handle abort a Tx or Rx transaction. | |
3144 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
3145 * the configuration information for SPI module. | |
3146 * @retval None | |
3147 */ | |
3148 static void SPI_AbortRx_ISR(SPI_HandleTypeDef *hspi) | |
3149 { | |
3150 __IO uint32_t tmpreg = 0U; | |
3151 __IO uint32_t count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U); | |
3152 | |
3153 /* Wait until TXE flag is set */ | |
3154 do | |
3155 { | |
3156 if(count-- == 0U) | |
3157 { | |
3158 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); | |
3159 break; | |
3160 } | |
3161 } | |
3162 while((hspi->Instance->SR & SPI_FLAG_TXE) == RESET); | |
3163 | |
3164 /* Disable SPI Peripheral */ | |
3165 __HAL_SPI_DISABLE(hspi); | |
3166 | |
3167 /* Disable TXEIE, RXNEIE and ERRIE(mode fault event, overrun error, TI frame error) interrupts */ | |
3168 CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXEIE | SPI_CR2_RXNEIE | SPI_CR2_ERRIE)); | |
3169 | |
3170 /* Flush DR Register */ | |
3171 tmpreg = (*(__IO uint32_t *)&hspi->Instance->DR); | |
3172 | |
3173 /* To avoid GCC warning */ | |
3174 UNUSED(tmpreg); | |
3175 } | |
3176 | |
3177 /** | |
3178 * @brief Handle abort a Tx or Rx transaction. | |
3179 * @param hspi pointer to a SPI_HandleTypeDef structure that contains | |
3180 * the configuration information for SPI module. | |
3181 * @retval None | |
3182 */ | |
3183 static void SPI_AbortTx_ISR(SPI_HandleTypeDef *hspi) | |
3184 { | |
3185 /* Disable TXEIE, RXNEIE and ERRIE(mode fault event, overrun error, TI frame error) interrupts */ | |
3186 CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXEIE | SPI_CR2_RXNEIE | SPI_CR2_ERRIE)); | |
3187 | |
3188 /* Disable SPI Peripheral */ | |
3189 __HAL_SPI_DISABLE(hspi); | |
3190 } | |
3191 /** | |
3192 * @} | |
3193 */ | |
3194 #endif /* HAL_SPI_MODULE_ENABLED */ | |
3195 | |
3196 /** | |
3197 * @} | |
3198 */ | |
3199 | |
3200 /** | |
3201 * @} | |
3202 */ | |
3203 | |
3204 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |