2
|
1 /**
|
|
2 ******************************************************************************
|
|
3 * @file stm32f1xx_hal_dma.c
|
|
4 * @author MCD Application Team
|
|
5 * @version V1.0.4
|
|
6 * @date 29-April-2016
|
|
7 * @brief DMA HAL module driver.
|
|
8 *
|
|
9 * This file provides firmware functions to manage the following
|
|
10 * functionalities of the Direct Memory Access (DMA) peripheral:
|
|
11 * + Initialization and de-initialization functions
|
|
12 * + IO operation functions
|
|
13 * + Peripheral State and errors functions
|
|
14 @verbatim
|
|
15 ==============================================================================
|
|
16 ##### How to use this driver #####
|
|
17 ==============================================================================
|
|
18 [..]
|
|
19 (#) Enable and configure the peripheral to be connected to the DMA Channel
|
|
20 (except for internal SRAM / FLASH memories: no initialization is
|
|
21 necessary) please refer to Reference manual for connection between peripherals
|
|
22 and DMA requests.
|
|
23
|
|
24 (#) For a given Channel, program the required configuration through the following parameters:
|
|
25 Transfer Direction, Source and Destination data formats,
|
|
26 Circular or Normal mode, Channel Priority level, Source and Destination Increment mode,
|
|
27 using HAL_DMA_Init() function.
|
|
28
|
|
29 (#) Use HAL_DMA_GetState() function to return the DMA state and HAL_DMA_GetError() in case of error
|
|
30 detection.
|
|
31
|
|
32 (#) Use HAL_DMA_Abort() function to abort the current transfer
|
|
33
|
|
34 -@- In Memory-to-Memory transfer mode, Circular mode is not allowed.
|
|
35 *** Polling mode IO operation ***
|
|
36 =================================
|
|
37 [..]
|
|
38 (+) Use HAL_DMA_Start() to start DMA transfer after the configuration of Source
|
|
39 address and destination address and the Length of data to be transferred
|
|
40 (+) Use HAL_DMA_PollForTransfer() to poll for the end of current transfer, in this
|
|
41 case a fixed Timeout can be configured by User depending from his application.
|
|
42
|
|
43 *** Interrupt mode IO operation ***
|
|
44 ===================================
|
|
45 [..]
|
|
46 (+) Configure the DMA interrupt priority using HAL_NVIC_SetPriority()
|
|
47 (+) Enable the DMA IRQ handler using HAL_NVIC_EnableIRQ()
|
|
48 (+) Use HAL_DMA_Start_IT() to start DMA transfer after the configuration of
|
|
49 Source address and destination address and the Length of data to be transferred.
|
|
50 In this case the DMA interrupt is configured
|
|
51 (+) Use HAL_DMAy_Channelx_IRQHandler() called under DMA_IRQHandler() Interrupt subroutine
|
|
52 (+) At the end of data transfer HAL_DMA_IRQHandler() function is executed and user can
|
|
53 add his own function by customization of function pointer XferCpltCallback and
|
|
54 XferErrorCallback (i.e a member of DMA handle structure).
|
|
55
|
|
56 *** DMA HAL driver macros list ***
|
|
57 =============================================
|
|
58 [..]
|
|
59 Below the list of most used macros in DMA HAL driver.
|
|
60
|
|
61 (+) __HAL_DMA_ENABLE: Enable the specified DMA Channel.
|
|
62 (+) __HAL_DMA_DISABLE: Disable the specified DMA Channel.
|
|
63 (+) __HAL_DMA_GET_FLAG: Get the DMA Channel pending flags.
|
|
64 (+) __HAL_DMA_CLEAR_FLAG: Clear the DMA Channel pending flags.
|
|
65 (+) __HAL_DMA_ENABLE_IT: Enable the specified DMA Channel interrupts.
|
|
66 (+) __HAL_DMA_DISABLE_IT: Disable the specified DMA Channel interrupts.
|
|
67 (+) __HAL_DMA_GET_IT_SOURCE: Check whether the specified DMA Channel interrupt has occurred or not.
|
|
68
|
|
69 [..]
|
|
70 (@) You can refer to the DMA HAL driver header file for more useful macros
|
|
71
|
|
72 @endverbatim
|
|
73 ******************************************************************************
|
|
74 * @attention
|
|
75 *
|
|
76 * <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
|
|
77 *
|
|
78 * Redistribution and use in source and binary forms, with or without modification,
|
|
79 * are permitted provided that the following conditions are met:
|
|
80 * 1. Redistributions of source code must retain the above copyright notice,
|
|
81 * this list of conditions and the following disclaimer.
|
|
82 * 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
83 * this list of conditions and the following disclaimer in the documentation
|
|
84 * and/or other materials provided with the distribution.
|
|
85 * 3. Neither the name of STMicroelectronics nor the names of its contributors
|
|
86 * may be used to endorse or promote products derived from this software
|
|
87 * without specific prior written permission.
|
|
88 *
|
|
89 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
90 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
91 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
92 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
93 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
94 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
95 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
96 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
97 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
98 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
99 *
|
|
100 ******************************************************************************
|
|
101 */
|
|
102
|
|
103 /* Includes ------------------------------------------------------------------*/
|
|
104 #include "stm32f1xx_hal.h"
|
|
105
|
|
106 /** @addtogroup STM32F1xx_HAL_Driver
|
|
107 * @{
|
|
108 */
|
|
109
|
|
110 /** @defgroup DMA DMA
|
|
111 * @brief DMA HAL module driver
|
|
112 * @{
|
|
113 */
|
|
114
|
|
115 #ifdef HAL_DMA_MODULE_ENABLED
|
|
116
|
|
117 /* Private typedef -----------------------------------------------------------*/
|
|
118 /* Private define ------------------------------------------------------------*/
|
|
119 /** @defgroup DMA_Private_Constants DMA Private Constants
|
|
120 * @{
|
|
121 */
|
|
122 #define HAL_TIMEOUT_DMA_ABORT ((uint32_t)1000) /* 1s */
|
|
123 /**
|
|
124 * @}
|
|
125 */
|
|
126
|
|
127 /* Private macro -------------------------------------------------------------*/
|
|
128 /* Private variables ---------------------------------------------------------*/
|
|
129 /* Private function prototypes -----------------------------------------------*/
|
|
130 /** @defgroup DMA_Private_Functions DMA Private Functions
|
|
131 * @{
|
|
132 */
|
|
133 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
|
|
134 /**
|
|
135 * @}
|
|
136 */
|
|
137
|
|
138 /* Exported functions ---------------------------------------------------------*/
|
|
139
|
|
140 /** @defgroup DMA_Exported_Functions DMA Exported Functions
|
|
141 * @{
|
|
142 */
|
|
143
|
|
144 /** @defgroup DMA_Exported_Functions_Group1 Initialization and de-initialization functions
|
|
145 * @brief Initialization and de-initialization functions
|
|
146 *
|
|
147 @verbatim
|
|
148 ===============================================================================
|
|
149 ##### Initialization and de-initialization functions #####
|
|
150 ===============================================================================
|
|
151 [..]
|
|
152 This section provides functions allowing to initialize the DMA Channel source
|
|
153 and destination addresses, incrementation and data sizes, transfer direction,
|
|
154 circular/normal mode selection, memory-to-memory mode selection and Channel priority value.
|
|
155 [..]
|
|
156 The HAL_DMA_Init() function follows the DMA configuration procedures as described in
|
|
157 reference manual.
|
|
158
|
|
159 @endverbatim
|
|
160 * @{
|
|
161 */
|
|
162
|
|
163 /**
|
|
164 * @brief Initializes the DMA according to the specified
|
|
165 * parameters in the DMA_InitTypeDef and create the associated handle.
|
|
166 * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
|
|
167 * the configuration information for the specified DMA Channel.
|
|
168 * @retval HAL status
|
|
169 */
|
|
170 HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
|
|
171 {
|
|
172 uint32_t tmp = 0;
|
|
173
|
|
174 /* Check the DMA handle allocation */
|
|
175 if(hdma == NULL)
|
|
176 {
|
|
177 return HAL_ERROR;
|
|
178 }
|
|
179
|
|
180 /* Check the parameters */
|
|
181 assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
|
|
182 assert_param(IS_DMA_DIRECTION(hdma->Init.Direction));
|
|
183 assert_param(IS_DMA_PERIPHERAL_INC_STATE(hdma->Init.PeriphInc));
|
|
184 assert_param(IS_DMA_MEMORY_INC_STATE(hdma->Init.MemInc));
|
|
185 assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(hdma->Init.PeriphDataAlignment));
|
|
186 assert_param(IS_DMA_MEMORY_DATA_SIZE(hdma->Init.MemDataAlignment));
|
|
187 assert_param(IS_DMA_MODE(hdma->Init.Mode));
|
|
188 assert_param(IS_DMA_PRIORITY(hdma->Init.Priority));
|
|
189
|
|
190 if(hdma->State == HAL_DMA_STATE_RESET)
|
|
191 {
|
|
192 /* Allocate lock resource and initialize it */
|
|
193 hdma->Lock = HAL_UNLOCKED;
|
|
194 }
|
|
195
|
|
196 /* Change DMA peripheral state */
|
|
197 hdma->State = HAL_DMA_STATE_BUSY;
|
|
198
|
|
199 /* Get the CR register value */
|
|
200 tmp = hdma->Instance->CCR;
|
|
201
|
|
202 /* Clear PL, MSIZE, PSIZE, MINC, PINC, CIRC, DIR bits */
|
|
203 tmp &= ((uint32_t)~(DMA_CCR_PL | DMA_CCR_MSIZE | DMA_CCR_PSIZE | \
|
|
204 DMA_CCR_MINC | DMA_CCR_PINC | DMA_CCR_CIRC | \
|
|
205 DMA_CCR_DIR));
|
|
206
|
|
207 /* Prepare the DMA Channel configuration */
|
|
208 tmp |= hdma->Init.Direction |
|
|
209 hdma->Init.PeriphInc | hdma->Init.MemInc |
|
|
210 hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment |
|
|
211 hdma->Init.Mode | hdma->Init.Priority;
|
|
212
|
|
213 /* Write to DMA Channel CR register */
|
|
214 hdma->Instance->CCR = tmp;
|
|
215
|
|
216 /* Initialise the error code */
|
|
217 hdma->ErrorCode = HAL_DMA_ERROR_NONE;
|
|
218
|
|
219 /* Initialize the DMA state*/
|
|
220 hdma->State = HAL_DMA_STATE_READY;
|
|
221
|
|
222 return HAL_OK;
|
|
223 }
|
|
224
|
|
225 /**
|
|
226 * @brief DeInitializes the DMA peripheral
|
|
227 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
|
228 * the configuration information for the specified DMA Channel.
|
|
229 * @retval HAL status
|
|
230 */
|
|
231 HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
|
|
232 {
|
|
233 /* Check the DMA handle allocation */
|
|
234 if(hdma == NULL)
|
|
235 {
|
|
236 return HAL_ERROR;
|
|
237 }
|
|
238
|
|
239 /* Check the parameters */
|
|
240 assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
|
|
241
|
|
242 /* Check the DMA peripheral state */
|
|
243 if(hdma->State == HAL_DMA_STATE_BUSY)
|
|
244 {
|
|
245 return HAL_ERROR;
|
|
246 }
|
|
247
|
|
248 /* Disable the selected DMA Channelx */
|
|
249 __HAL_DMA_DISABLE(hdma);
|
|
250
|
|
251 /* Reset DMA Channel control register */
|
|
252 hdma->Instance->CCR = 0;
|
|
253
|
|
254 /* Reset DMA Channel Number of Data to Transfer register */
|
|
255 hdma->Instance->CNDTR = 0;
|
|
256
|
|
257 /* Reset DMA Channel peripheral address register */
|
|
258 hdma->Instance->CPAR = 0;
|
|
259
|
|
260 /* Reset DMA Channel memory address register */
|
|
261 hdma->Instance->CMAR = 0;
|
|
262
|
|
263 /* Clear all flags */
|
|
264 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
|
|
265 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
|
|
266 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
|
|
267
|
|
268 /* Initialize the error code */
|
|
269 hdma->ErrorCode = HAL_DMA_ERROR_NONE;
|
|
270
|
|
271 /* Initialize the DMA state */
|
|
272 hdma->State = HAL_DMA_STATE_RESET;
|
|
273
|
|
274 /* Release Lock */
|
|
275 __HAL_UNLOCK(hdma);
|
|
276
|
|
277 return HAL_OK;
|
|
278 }
|
|
279
|
|
280 /**
|
|
281 * @}
|
|
282 */
|
|
283
|
|
284 /** @defgroup DMA_Exported_Functions_Group2 Input and Output operation functions
|
|
285 * @brief I/O operation functions
|
|
286 *
|
|
287 @verbatim
|
|
288 ===============================================================================
|
|
289 ##### IO operation functions #####
|
|
290 ===============================================================================
|
|
291 [..] This section provides functions allowing to:
|
|
292 (+) Configure the source, destination address and data length and Start DMA transfer
|
|
293 (+) Configure the source, destination address and data length and
|
|
294 Start DMA transfer with interrupt
|
|
295 (+) Abort DMA transfer
|
|
296 (+) Poll for transfer complete
|
|
297 (+) Handle DMA interrupt request
|
|
298
|
|
299 @endverbatim
|
|
300 * @{
|
|
301 */
|
|
302
|
|
303 /**
|
|
304 * @brief Starts the DMA Transfer.
|
|
305 * @param hdma : pointer to a DMA_HandleTypeDef structure that contains
|
|
306 * the configuration information for the specified DMA Channel.
|
|
307 * @param SrcAddress: The source memory Buffer address
|
|
308 * @param DstAddress: The destination memory Buffer address
|
|
309 * @param DataLength: The length of data to be transferred from source to destination
|
|
310 * @retval HAL status
|
|
311 */
|
|
312 HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
|
|
313 {
|
|
314 /* Process locked */
|
|
315 __HAL_LOCK(hdma);
|
|
316
|
|
317 /* Change DMA peripheral state */
|
|
318 hdma->State = HAL_DMA_STATE_BUSY;
|
|
319
|
|
320 /* Check the parameters */
|
|
321 assert_param(IS_DMA_BUFFER_SIZE(DataLength));
|
|
322
|
|
323 /* Disable the peripheral */
|
|
324 __HAL_DMA_DISABLE(hdma);
|
|
325
|
|
326 /* Configure the source, destination address and the data length */
|
|
327 DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
|
|
328
|
|
329 /* Enable the Peripheral */
|
|
330 __HAL_DMA_ENABLE(hdma);
|
|
331
|
|
332 return HAL_OK;
|
|
333 }
|
|
334
|
|
335 /**
|
|
336 * @brief Start the DMA Transfer with interrupt enabled.
|
|
337 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
|
338 * the configuration information for the specified DMA Channel.
|
|
339 * @param SrcAddress: The source memory Buffer address
|
|
340 * @param DstAddress: The destination memory Buffer address
|
|
341 * @param DataLength: The length of data to be transferred from source to destination
|
|
342 * @retval HAL status
|
|
343 */
|
|
344 HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
|
|
345 {
|
|
346 /* Process locked */
|
|
347 __HAL_LOCK(hdma);
|
|
348
|
|
349 /* Change DMA peripheral state */
|
|
350 hdma->State = HAL_DMA_STATE_BUSY;
|
|
351
|
|
352 /* Check the parameters */
|
|
353 assert_param(IS_DMA_BUFFER_SIZE(DataLength));
|
|
354
|
|
355 /* Disable the peripheral */
|
|
356 __HAL_DMA_DISABLE(hdma);
|
|
357
|
|
358 /* Configure the source, destination address and the data length */
|
|
359 DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
|
|
360
|
|
361 /* Enable the transfer complete interrupt */
|
|
362 __HAL_DMA_ENABLE_IT(hdma, DMA_IT_TC);
|
|
363
|
|
364 /* Enable the Half transfer complete interrupt */
|
|
365 __HAL_DMA_ENABLE_IT(hdma, DMA_IT_HT);
|
|
366
|
|
367 /* Enable the transfer Error interrupt */
|
|
368 __HAL_DMA_ENABLE_IT(hdma, DMA_IT_TE);
|
|
369
|
|
370 /* Enable the Peripheral */
|
|
371 __HAL_DMA_ENABLE(hdma);
|
|
372
|
|
373 return HAL_OK;
|
|
374 }
|
|
375
|
|
376 /**
|
|
377 * @brief Aborts the DMA Transfer.
|
|
378 * @param hdma : pointer to a DMA_HandleTypeDef structure that contains
|
|
379 * the configuration information for the specified DMA Channel.
|
|
380 *
|
|
381 * @note After disabling a DMA Channel, a check for wait until the DMA Channel is
|
|
382 * effectively disabled is added. If a Channel is disabled
|
|
383 * while a data transfer is ongoing, the current data will be transferred
|
|
384 * and the Channel will be effectively disabled only after the transfer of
|
|
385 * this single data is finished.
|
|
386 * @retval HAL status
|
|
387 */
|
|
388 HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
|
|
389 {
|
|
390 uint32_t tickstart = 0x00;
|
|
391
|
|
392 /* Disable the channel */
|
|
393 __HAL_DMA_DISABLE(hdma);
|
|
394
|
|
395 /* Get tick */
|
|
396 tickstart = HAL_GetTick();
|
|
397
|
|
398 /* Check if the DMA Channel is effectively disabled */
|
|
399 while((hdma->Instance->CCR & DMA_CCR_EN) != 0)
|
|
400 {
|
|
401 /* Check for the Timeout */
|
|
402 if((HAL_GetTick() - tickstart) > HAL_TIMEOUT_DMA_ABORT)
|
|
403 {
|
|
404 /* Update error code */
|
|
405 SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TIMEOUT);
|
|
406
|
|
407 /* Change the DMA state */
|
|
408 hdma->State = HAL_DMA_STATE_TIMEOUT;
|
|
409
|
|
410 /* Process Unlocked */
|
|
411 __HAL_UNLOCK(hdma);
|
|
412
|
|
413 return HAL_TIMEOUT;
|
|
414 }
|
|
415 }
|
|
416 /* Change the DMA state */
|
|
417 hdma->State = HAL_DMA_STATE_READY;
|
|
418
|
|
419 /* Process Unlocked */
|
|
420 __HAL_UNLOCK(hdma);
|
|
421
|
|
422 return HAL_OK;
|
|
423 }
|
|
424
|
|
425 /**
|
|
426 * @brief Polling for transfer complete.
|
|
427 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
|
428 * the configuration information for the specified DMA Channel.
|
|
429 * @param CompleteLevel: Specifies the DMA level complete.
|
|
430 * @param Timeout: Timeout duration.
|
|
431 * @retval HAL status
|
|
432 */
|
|
433 HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout)
|
|
434 {
|
|
435 uint32_t temp;
|
|
436 uint32_t tickstart = 0x00;
|
|
437
|
|
438 /* Get the level transfer complete flag */
|
|
439 if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
|
|
440 {
|
|
441 /* Transfer Complete flag */
|
|
442 temp = __HAL_DMA_GET_TC_FLAG_INDEX(hdma);
|
|
443 }
|
|
444 else
|
|
445 {
|
|
446 /* Half Transfer Complete flag */
|
|
447 temp = __HAL_DMA_GET_HT_FLAG_INDEX(hdma);
|
|
448 }
|
|
449
|
|
450 /* Get tick */
|
|
451 tickstart = HAL_GetTick();
|
|
452
|
|
453 while(__HAL_DMA_GET_FLAG(hdma, temp) == RESET)
|
|
454 {
|
|
455 if((__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET))
|
|
456 {
|
|
457 /* Clear the transfer error flags */
|
|
458 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
|
|
459
|
|
460 /* Update error code */
|
|
461 SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TE);
|
|
462
|
|
463 /* Change the DMA state */
|
|
464 hdma->State= HAL_DMA_STATE_ERROR;
|
|
465
|
|
466 /* Process Unlocked */
|
|
467 __HAL_UNLOCK(hdma);
|
|
468
|
|
469 return HAL_ERROR;
|
|
470 }
|
|
471 /* Check for the Timeout */
|
|
472 if(Timeout != HAL_MAX_DELAY)
|
|
473 {
|
|
474 if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout))
|
|
475 {
|
|
476 /* Update error code */
|
|
477 SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TIMEOUT);
|
|
478
|
|
479 /* Change the DMA state */
|
|
480 hdma->State = HAL_DMA_STATE_TIMEOUT;
|
|
481
|
|
482 /* Process Unlocked */
|
|
483 __HAL_UNLOCK(hdma);
|
|
484
|
|
485 return HAL_TIMEOUT;
|
|
486 }
|
|
487 }
|
|
488 }
|
|
489
|
|
490 if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
|
|
491 {
|
|
492 /* Clear the transfer complete flag */
|
|
493 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
|
|
494
|
|
495 /* The selected Channelx EN bit is cleared (DMA is disabled and
|
|
496 all transfers are complete) */
|
|
497 hdma->State = HAL_DMA_STATE_READY;
|
|
498
|
|
499 }
|
|
500 else
|
|
501 {
|
|
502 /* Clear the half transfer complete flag */
|
|
503 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
|
|
504
|
|
505 /* The selected Channelx EN bit is cleared (DMA is disabled and
|
|
506 all transfers of half buffer are complete) */
|
|
507 hdma->State = HAL_DMA_STATE_READY_HALF;
|
|
508 }
|
|
509
|
|
510 /* Process unlocked */
|
|
511 __HAL_UNLOCK(hdma);
|
|
512
|
|
513 return HAL_OK;
|
|
514 }
|
|
515
|
|
516 /**
|
|
517 * @brief Handles DMA interrupt request.
|
|
518 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
|
519 * the configuration information for the specified DMA Channel.
|
|
520 * @retval None
|
|
521 */
|
|
522 void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
|
|
523 {
|
|
524 /* Transfer Error Interrupt management ***************************************/
|
|
525 if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET)
|
|
526 {
|
|
527 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TE) != RESET)
|
|
528 {
|
|
529 /* Disable the transfer error interrupt */
|
|
530 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE);
|
|
531
|
|
532 /* Clear the transfer error flag */
|
|
533 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
|
|
534
|
|
535 /* Update error code */
|
|
536 SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TE);
|
|
537
|
|
538 /* Change the DMA state */
|
|
539 hdma->State = HAL_DMA_STATE_ERROR;
|
|
540
|
|
541 /* Process Unlocked */
|
|
542 __HAL_UNLOCK(hdma);
|
|
543
|
|
544 if (hdma->XferErrorCallback != NULL)
|
|
545 {
|
|
546 /* Transfer error callback */
|
|
547 hdma->XferErrorCallback(hdma);
|
|
548 }
|
|
549 }
|
|
550 }
|
|
551
|
|
552 /* Half Transfer Complete Interrupt management ******************************/
|
|
553 if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)) != RESET)
|
|
554 {
|
|
555 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != RESET)
|
|
556 {
|
|
557 /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
|
|
558 if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0)
|
|
559 {
|
|
560 /* Disable the half transfer interrupt */
|
|
561 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
|
|
562 }
|
|
563 /* Clear the half transfer complete flag */
|
|
564 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
|
|
565
|
|
566 /* Change DMA peripheral state */
|
|
567 hdma->State = HAL_DMA_STATE_READY_HALF;
|
|
568
|
|
569 if(hdma->XferHalfCpltCallback != NULL)
|
|
570 {
|
|
571 /* Half transfer callback */
|
|
572 hdma->XferHalfCpltCallback(hdma);
|
|
573 }
|
|
574 }
|
|
575 }
|
|
576
|
|
577 /* Transfer Complete Interrupt management ***********************************/
|
|
578 if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)) != RESET)
|
|
579 {
|
|
580 if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != RESET)
|
|
581 {
|
|
582 if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0)
|
|
583 {
|
|
584 /* Disable the transfer complete interrupt */
|
|
585 __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TC);
|
|
586 }
|
|
587 /* Clear the transfer complete flag */
|
|
588 __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
|
|
589
|
|
590 /* Update error code */
|
|
591 SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_NONE);
|
|
592
|
|
593 /* Change the DMA state */
|
|
594 hdma->State = HAL_DMA_STATE_READY;
|
|
595
|
|
596 /* Process Unlocked */
|
|
597 __HAL_UNLOCK(hdma);
|
|
598
|
|
599 if(hdma->XferCpltCallback != NULL)
|
|
600 {
|
|
601 /* Transfer complete callback */
|
|
602 hdma->XferCpltCallback(hdma);
|
|
603 }
|
|
604 }
|
|
605 }
|
|
606 }
|
|
607
|
|
608 /**
|
|
609 * @}
|
|
610 */
|
|
611
|
|
612 /** @defgroup DMA_Exported_Functions_Group3 Peripheral State functions
|
|
613 * @brief Peripheral State functions
|
|
614 *
|
|
615 @verbatim
|
|
616 ===============================================================================
|
|
617 ##### State and Errors functions #####
|
|
618 ===============================================================================
|
|
619 [..]
|
|
620 This subsection provides functions allowing to
|
|
621 (+) Check the DMA state
|
|
622 (+) Get error code
|
|
623
|
|
624 @endverbatim
|
|
625 * @{
|
|
626 */
|
|
627
|
|
628 /**
|
|
629 * @brief Returns the DMA state.
|
|
630 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
|
631 * the configuration information for the specified DMA Channel.
|
|
632 * @retval HAL state
|
|
633 */
|
|
634 HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma)
|
|
635 {
|
|
636 return hdma->State;
|
|
637 }
|
|
638
|
|
639 /**
|
|
640 * @brief Return the DMA error code
|
|
641 * @param hdma : pointer to a DMA_HandleTypeDef structure that contains
|
|
642 * the configuration information for the specified DMA Channel.
|
|
643 * @retval DMA Error Code
|
|
644 */
|
|
645 uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma)
|
|
646 {
|
|
647 return hdma->ErrorCode;
|
|
648 }
|
|
649
|
|
650 /**
|
|
651 * @}
|
|
652 */
|
|
653
|
|
654 /**
|
|
655 * @}
|
|
656 */
|
|
657
|
|
658 /** @addtogroup DMA_Private_Functions DMA Private Functions
|
|
659 * @{
|
|
660 */
|
|
661
|
|
662 /**
|
|
663 * @brief Sets the DMA Transfer parameter.
|
|
664 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
|
665 * the configuration information for the specified DMA Channel.
|
|
666 * @param SrcAddress: The source memory Buffer address
|
|
667 * @param DstAddress: The destination memory Buffer address
|
|
668 * @param DataLength: The length of data to be transferred from source to destination
|
|
669 * @retval HAL status
|
|
670 */
|
|
671 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
|
|
672 {
|
|
673 /* Configure DMA Channel data length */
|
|
674 hdma->Instance->CNDTR = DataLength;
|
|
675
|
|
676 /* Peripheral to Memory */
|
|
677 if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
|
|
678 {
|
|
679 /* Configure DMA Channel destination address */
|
|
680 hdma->Instance->CPAR = DstAddress;
|
|
681
|
|
682 /* Configure DMA Channel source address */
|
|
683 hdma->Instance->CMAR = SrcAddress;
|
|
684 }
|
|
685 /* Memory to Peripheral */
|
|
686 else
|
|
687 {
|
|
688 /* Configure DMA Channel source address */
|
|
689 hdma->Instance->CPAR = SrcAddress;
|
|
690
|
|
691 /* Configure DMA Channel destination address */
|
|
692 hdma->Instance->CMAR = DstAddress;
|
|
693 }
|
|
694 }
|
|
695
|
|
696 /**
|
|
697 * @}
|
|
698 */
|
|
699
|
|
700 #endif /* HAL_DMA_MODULE_ENABLED */
|
|
701 /**
|
|
702 * @}
|
|
703 */
|
|
704
|
|
705 /**
|
|
706 * @}
|
|
707 */
|
|
708
|
|
709 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|