xref: /btstack/port/stm32-l476rg-nucleo-sx1280/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.c (revision 6b8177c56d8d42c688f52897394f8b5eac7ee972)
1 /**
2   ******************************************************************************
3   * @file    stm32l4xx_hal_dma.c
4   * @author  MCD Application Team
5   * @brief   DMA HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the Direct Memory Access (DMA) peripheral:
8   *           + Initialization and de-initialization functions
9   *           + IO operation functions
10   *           + Peripheral State and errors functions
11   @verbatim
12   ==============================================================================
13                         ##### How to use this driver #####
14   ==============================================================================
15   [..]
16    (#) Enable and configure the peripheral to be connected to the DMA Channel
17        (except for internal SRAM / FLASH memories: no initialization is
18        necessary). Please refer to the Reference manual for connection between peripherals
19        and DMA requests.
20 
21    (#) For a given Channel, program the required configuration through the following parameters:
22        Channel request, Transfer Direction, Source and Destination data formats,
23        Circular or Normal mode, Channel Priority level, Source and Destination Increment mode
24        using HAL_DMA_Init() function.
25 
26        Prior to HAL_DMA_Init the peripheral clock shall be enabled for both DMA & DMAMUX
27        thanks to:
28       (##) DMA1 or DMA2: __HAL_RCC_DMA1_CLK_ENABLE() or  __HAL_RCC_DMA2_CLK_ENABLE() ;
29       (##) DMAMUX1:      __HAL_RCC_DMAMUX1_CLK_ENABLE();
30 
31    (#) Use HAL_DMA_GetState() function to return the DMA state and HAL_DMA_GetError() in case of error
32        detection.
33 
34    (#) Use HAL_DMA_Abort() function to abort the current transfer
35 
36      -@-   In Memory-to-Memory transfer mode, Circular mode is not allowed.
37 
38      *** Polling mode IO operation ***
39      =================================
40      [..]
41        (+) Use HAL_DMA_Start() to start DMA transfer after the configuration of Source
42            address and destination address and the Length of data to be transferred
43        (+) Use HAL_DMA_PollForTransfer() to poll for the end of current transfer, in this
44            case a fixed Timeout can be configured by User depending from his application.
45 
46      *** Interrupt mode IO operation ***
47      ===================================
48      [..]
49        (+) Configure the DMA interrupt priority using HAL_NVIC_SetPriority()
50        (+) Enable the DMA IRQ handler using HAL_NVIC_EnableIRQ()
51        (+) Use HAL_DMA_Start_IT() to start DMA transfer after the configuration of
52            Source address and destination address and the Length of data to be transferred.
53            In this case the DMA interrupt is configured
54        (+) Use HAL_DMA_IRQHandler() called under DMA_IRQHandler() Interrupt subroutine
55        (+) At the end of data transfer HAL_DMA_IRQHandler() function is executed and user can
56               add his own function to register callbacks with HAL_DMA_RegisterCallback().
57 
58      *** DMA HAL driver macros list ***
59      =============================================
60      [..]
61        Below the list of macros in DMA HAL driver.
62 
63        (+) __HAL_DMA_ENABLE: Enable the specified DMA Channel.
64        (+) __HAL_DMA_DISABLE: Disable the specified DMA Channel.
65        (+) __HAL_DMA_GET_FLAG: Get the DMA Channel pending flags.
66        (+) __HAL_DMA_CLEAR_FLAG: Clear the DMA Channel pending flags.
67        (+) __HAL_DMA_ENABLE_IT: Enable the specified DMA Channel interrupts.
68        (+) __HAL_DMA_DISABLE_IT: Disable the specified DMA Channel interrupts.
69        (+) __HAL_DMA_GET_IT_SOURCE: Check whether the specified DMA Channel interrupt is enabled or not.
70 
71      [..]
72       (@) You can refer to the DMA HAL driver header file for more useful macros
73 
74   @endverbatim
75   ******************************************************************************
76   * @attention
77   *
78   * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
79   * All rights reserved.</center></h2>
80   *
81   * This software component is licensed by ST under BSD 3-Clause license,
82   * the "License"; You may not use this file except in compliance with the
83   * License. You may obtain a copy of the License at:
84   *                        opensource.org/licenses/BSD-3-Clause
85   *
86   ******************************************************************************
87   */
88 
89 /* Includes ------------------------------------------------------------------*/
90 #include "stm32l4xx_hal.h"
91 
92 /** @addtogroup STM32L4xx_HAL_Driver
93   * @{
94   */
95 
96 /** @defgroup DMA DMA
97   * @brief DMA HAL module driver
98   * @{
99   */
100 
101 #ifdef HAL_DMA_MODULE_ENABLED
102 
103 /* Private typedef -----------------------------------------------------------*/
104 /* Private define ------------------------------------------------------------*/
105 /* Private macro -------------------------------------------------------------*/
106 /* Private variables ---------------------------------------------------------*/
107 /* Private function prototypes -----------------------------------------------*/
108 /** @defgroup DMA_Private_Functions DMA Private Functions
109   * @{
110   */
111 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
112 #if defined(DMAMUX1)
113 static void DMA_CalcDMAMUXChannelBaseAndMask(DMA_HandleTypeDef *hdma);
114 static void DMA_CalcDMAMUXRequestGenBaseAndMask(DMA_HandleTypeDef *hdma);
115 #endif /* DMAMUX1 */
116 
117 /**
118   * @}
119   */
120 
121 /* Exported functions ---------------------------------------------------------*/
122 
123 /** @defgroup DMA_Exported_Functions DMA Exported Functions
124   * @{
125   */
126 
127 /** @defgroup DMA_Exported_Functions_Group1 Initialization and de-initialization functions
128  *  @brief   Initialization and de-initialization functions
129  *
130 @verbatim
131  ===============================================================================
132              ##### Initialization and de-initialization functions  #####
133  ===============================================================================
134     [..]
135     This section provides functions allowing to initialize the DMA Channel source
136     and destination addresses, incrementation and data sizes, transfer direction,
137     circular/normal mode selection, memory-to-memory mode selection and Channel priority value.
138     [..]
139     The HAL_DMA_Init() function follows the DMA configuration procedures as described in
140     reference manual.
141 
142 @endverbatim
143   * @{
144   */
145 
146 /**
147   * @brief  Initialize the DMA according to the specified
148   *         parameters in the DMA_InitTypeDef and initialize the associated handle.
149   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
150   *              the configuration information for the specified DMA Channel.
151   * @retval HAL status
152   */
HAL_DMA_Init(DMA_HandleTypeDef * hdma)153 HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
154 {
155   uint32_t tmp;
156 
157   /* Check the DMA handle allocation */
158   if(hdma == NULL)
159   {
160     return HAL_ERROR;
161   }
162 
163   /* Check the parameters */
164   assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
165   assert_param(IS_DMA_DIRECTION(hdma->Init.Direction));
166   assert_param(IS_DMA_PERIPHERAL_INC_STATE(hdma->Init.PeriphInc));
167   assert_param(IS_DMA_MEMORY_INC_STATE(hdma->Init.MemInc));
168   assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(hdma->Init.PeriphDataAlignment));
169   assert_param(IS_DMA_MEMORY_DATA_SIZE(hdma->Init.MemDataAlignment));
170   assert_param(IS_DMA_MODE(hdma->Init.Mode));
171   assert_param(IS_DMA_PRIORITY(hdma->Init.Priority));
172 
173   assert_param(IS_DMA_ALL_REQUEST(hdma->Init.Request));
174 
175   /* Compute the channel index */
176   if ((uint32_t)(hdma->Instance) < (uint32_t)(DMA2_Channel1))
177   {
178     /* DMA1 */
179     hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2U;
180     hdma->DmaBaseAddress = DMA1;
181   }
182   else
183   {
184     /* DMA2 */
185     hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA2_Channel1) / ((uint32_t)DMA2_Channel2 - (uint32_t)DMA2_Channel1)) << 2U;
186     hdma->DmaBaseAddress = DMA2;
187   }
188 
189   /* Change DMA peripheral state */
190   hdma->State = HAL_DMA_STATE_BUSY;
191 
192   /* Get the CR register value */
193   tmp = hdma->Instance->CCR;
194 
195   /* Clear PL, MSIZE, PSIZE, MINC, PINC, CIRC, DIR and MEM2MEM bits */
196   tmp &= ((uint32_t)~(DMA_CCR_PL    | DMA_CCR_MSIZE  | DMA_CCR_PSIZE  |
197                       DMA_CCR_MINC  | DMA_CCR_PINC   | DMA_CCR_CIRC   |
198                       DMA_CCR_DIR   | DMA_CCR_MEM2MEM));
199 
200   /* Prepare the DMA Channel configuration */
201   tmp |=  hdma->Init.Direction        |
202           hdma->Init.PeriphInc           | hdma->Init.MemInc           |
203           hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment |
204           hdma->Init.Mode                | hdma->Init.Priority;
205 
206   /* Write to DMA Channel CR register */
207   hdma->Instance->CCR = tmp;
208 
209 #if defined(DMAMUX1)
210   /* Initialize parameters for DMAMUX channel :
211      DMAmuxChannel, DMAmuxChannelStatus and DMAmuxChannelStatusMask
212   */
213   DMA_CalcDMAMUXChannelBaseAndMask(hdma);
214 
215   if(hdma->Init.Direction == DMA_MEMORY_TO_MEMORY)
216   {
217     /* if memory to memory force the request to 0*/
218     hdma->Init.Request = DMA_REQUEST_MEM2MEM;
219   }
220 
221   /* Set peripheral request  to DMAMUX channel */
222   hdma->DMAmuxChannel->CCR = (hdma->Init.Request & DMAMUX_CxCR_DMAREQ_ID);
223 
224   /* Clear the DMAMUX synchro overrun flag */
225   hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
226 
227   if(((hdma->Init.Request > 0U) && (hdma->Init.Request <= DMA_REQUEST_GENERATOR3)))
228   {
229     /* Initialize parameters for DMAMUX request generator :
230        DMAmuxRequestGen, DMAmuxRequestGenStatus and DMAmuxRequestGenStatusMask
231     */
232     DMA_CalcDMAMUXRequestGenBaseAndMask(hdma);
233 
234     /* Reset the DMAMUX request generator register*/
235     hdma->DMAmuxRequestGen->RGCR = 0U;
236 
237     /* Clear the DMAMUX request generator overrun flag */
238     hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
239   }
240   else
241   {
242     hdma->DMAmuxRequestGen = 0U;
243     hdma->DMAmuxRequestGenStatus = 0U;
244     hdma->DMAmuxRequestGenStatusMask = 0U;
245   }
246 #endif /* DMAMUX1 */
247 
248 #if !defined (DMAMUX1)
249 
250   /* Set request selection */
251   if(hdma->Init.Direction != DMA_MEMORY_TO_MEMORY)
252   {
253     /* Write to DMA channel selection register */
254     if (DMA1 == hdma->DmaBaseAddress)
255     {
256       /* Reset request selection for DMA1 Channelx */
257       DMA1_CSELR->CSELR &= ~(DMA_CSELR_C1S << (hdma->ChannelIndex & 0x1cU));
258 
259       /* Configure request selection for DMA1 Channelx */
260       DMA1_CSELR->CSELR |= (uint32_t) (hdma->Init.Request << (hdma->ChannelIndex & 0x1cU));
261     }
262     else /* DMA2 */
263     {
264       /* Reset request selection for DMA2 Channelx */
265       DMA2_CSELR->CSELR &= ~(DMA_CSELR_C1S << (hdma->ChannelIndex & 0x1cU));
266 
267       /* Configure request selection for DMA2 Channelx */
268       DMA2_CSELR->CSELR |= (uint32_t) (hdma->Init.Request << (hdma->ChannelIndex & 0x1cU));
269     }
270   }
271 
272 #endif /* STM32L431xx || STM32L432xx || STM32L433xx || STM32L442xx || STM32L443xx */
273        /* STM32L471xx || STM32L475xx || STM32L476xx || STM32L442xx || STM32L486xx */
274        /* STM32L496xx || STM32L4A6xx                                              */
275 
276   /* Initialise the error code */
277   hdma->ErrorCode = HAL_DMA_ERROR_NONE;
278 
279   /* Initialize the DMA state*/
280   hdma->State = HAL_DMA_STATE_READY;
281 
282   /* Allocate lock resource and initialize it */
283   hdma->Lock = HAL_UNLOCKED;
284 
285   return HAL_OK;
286 }
287 
288 /**
289   * @brief  DeInitialize the DMA peripheral.
290   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
291   *               the configuration information for the specified DMA Channel.
292   * @retval HAL status
293   */
HAL_DMA_DeInit(DMA_HandleTypeDef * hdma)294 HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
295 {
296 
297   /* Check the DMA handle allocation */
298   if (NULL == hdma )
299   {
300     return HAL_ERROR;
301   }
302 
303   /* Check the parameters */
304   assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
305 
306   /* Disable the selected DMA Channelx */
307   __HAL_DMA_DISABLE(hdma);
308 
309   /* Compute the channel index */
310   if ((uint32_t)(hdma->Instance) < (uint32_t)(DMA2_Channel1))
311   {
312     /* DMA1 */
313     hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2U;
314     hdma->DmaBaseAddress = DMA1;
315   }
316   else
317   {
318     /* DMA2 */
319     hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA2_Channel1) / ((uint32_t)DMA2_Channel2 - (uint32_t)DMA2_Channel1)) << 2U;
320     hdma->DmaBaseAddress = DMA2;
321   }
322 
323   /* Reset DMA Channel control register */
324   hdma->Instance->CCR = 0U;
325 
326   /* Clear all flags */
327   hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex & 0x1CU));
328 
329 #if !defined (DMAMUX1)
330 
331   /* Reset DMA channel selection register */
332   if (DMA1 == hdma->DmaBaseAddress)
333   {
334     /* DMA1 */
335     DMA1_CSELR->CSELR &= ~(DMA_CSELR_C1S << (hdma->ChannelIndex & 0x1cU));
336   }
337   else
338   {
339     /* DMA2 */
340     DMA2_CSELR->CSELR &= ~(DMA_CSELR_C1S << (hdma->ChannelIndex & 0x1cU));
341   }
342 #endif /* STM32L431xx || STM32L432xx || STM32L433xx || STM32L442xx || STM32L443xx */
343        /* STM32L471xx || STM32L475xx || STM32L476xx || STM32L442xx || STM32L486xx */
344        /* STM32L496xx || STM32L4A6xx                                              */
345 
346 #if defined(DMAMUX1)
347 
348   /* Initialize parameters for DMAMUX channel :
349      DMAmuxChannel, DMAmuxChannelStatus and DMAmuxChannelStatusMask */
350 
351   DMA_CalcDMAMUXChannelBaseAndMask(hdma);
352 
353   /* Reset the DMAMUX channel that corresponds to the DMA channel */
354   hdma->DMAmuxChannel->CCR = 0U;
355 
356   /* Clear the DMAMUX synchro overrun flag */
357   hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
358 
359   /* Reset Request generator parameters if any */
360   if(((hdma->Init.Request >  0U) && (hdma->Init.Request <= DMA_REQUEST_GENERATOR3)))
361   {
362     /* Initialize parameters for DMAMUX request generator :
363        DMAmuxRequestGen, DMAmuxRequestGenStatus and DMAmuxRequestGenStatusMask
364     */
365     DMA_CalcDMAMUXRequestGenBaseAndMask(hdma);
366 
367     /* Reset the DMAMUX request generator register*/
368     hdma->DMAmuxRequestGen->RGCR = 0U;
369 
370     /* Clear the DMAMUX request generator overrun flag */
371     hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
372   }
373 
374   hdma->DMAmuxRequestGen = 0U;
375   hdma->DMAmuxRequestGenStatus = 0U;
376   hdma->DMAmuxRequestGenStatusMask = 0U;
377 
378 #endif /* DMAMUX1 */
379 
380   /* Clean callbacks */
381   hdma->XferCpltCallback = NULL;
382   hdma->XferHalfCpltCallback = NULL;
383   hdma->XferErrorCallback = NULL;
384   hdma->XferAbortCallback = NULL;
385 
386   /* Initialise the error code */
387   hdma->ErrorCode = HAL_DMA_ERROR_NONE;
388 
389   /* Initialize the DMA state */
390   hdma->State = HAL_DMA_STATE_RESET;
391 
392   /* Release Lock */
393   __HAL_UNLOCK(hdma);
394 
395   return HAL_OK;
396 }
397 
398 /**
399   * @}
400   */
401 
402 /** @defgroup DMA_Exported_Functions_Group2 Input and Output operation functions
403  *  @brief   Input and Output operation functions
404  *
405 @verbatim
406  ===============================================================================
407                       #####  IO operation functions  #####
408  ===============================================================================
409     [..]  This section provides functions allowing to:
410       (+) Configure the source, destination address and data length and Start DMA transfer
411       (+) Configure the source, destination address and data length and
412           Start DMA transfer with interrupt
413       (+) Abort DMA transfer
414       (+) Poll for transfer complete
415       (+) Handle DMA interrupt request
416 
417 @endverbatim
418   * @{
419   */
420 
421 /**
422   * @brief  Start the DMA Transfer.
423   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
424   *               the configuration information for the specified DMA Channel.
425   * @param  SrcAddress The source memory Buffer address
426   * @param  DstAddress The destination memory Buffer address
427   * @param  DataLength The length of data to be transferred from source to destination
428   * @retval HAL status
429   */
HAL_DMA_Start(DMA_HandleTypeDef * hdma,uint32_t SrcAddress,uint32_t DstAddress,uint32_t DataLength)430 HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
431 {
432   HAL_StatusTypeDef status = HAL_OK;
433 
434   /* Check the parameters */
435   assert_param(IS_DMA_BUFFER_SIZE(DataLength));
436 
437   /* Process locked */
438   __HAL_LOCK(hdma);
439 
440   if(HAL_DMA_STATE_READY == hdma->State)
441   {
442     /* Change DMA peripheral state */
443     hdma->State = HAL_DMA_STATE_BUSY;
444     hdma->ErrorCode = HAL_DMA_ERROR_NONE;
445 
446     /* Disable the peripheral */
447     __HAL_DMA_DISABLE(hdma);
448 
449     /* Configure the source, destination address and the data length & clear flags*/
450     DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
451 
452     /* Enable the Peripheral */
453     __HAL_DMA_ENABLE(hdma);
454   }
455   else
456   {
457     /* Process Unlocked */
458     __HAL_UNLOCK(hdma);
459     status = HAL_BUSY;
460   }
461   return status;
462 }
463 
464 /**
465   * @brief  Start the DMA Transfer with interrupt enabled.
466   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
467   *               the configuration information for the specified DMA Channel.
468   * @param  SrcAddress The source memory Buffer address
469   * @param  DstAddress The destination memory Buffer address
470   * @param  DataLength The length of data to be transferred from source to destination
471   * @retval HAL status
472   */
HAL_DMA_Start_IT(DMA_HandleTypeDef * hdma,uint32_t SrcAddress,uint32_t DstAddress,uint32_t DataLength)473 HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
474 {
475   HAL_StatusTypeDef status = HAL_OK;
476 
477   /* Check the parameters */
478   assert_param(IS_DMA_BUFFER_SIZE(DataLength));
479 
480   /* Process locked */
481   __HAL_LOCK(hdma);
482 
483   if(HAL_DMA_STATE_READY == hdma->State)
484   {
485     /* Change DMA peripheral state */
486     hdma->State = HAL_DMA_STATE_BUSY;
487     hdma->ErrorCode = HAL_DMA_ERROR_NONE;
488 
489     /* Disable the peripheral */
490     __HAL_DMA_DISABLE(hdma);
491 
492     /* Configure the source, destination address and the data length & clear flags*/
493     DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
494 
495     /* Enable the transfer complete interrupt */
496     /* Enable the transfer Error interrupt */
497     if(NULL != hdma->XferHalfCpltCallback )
498     {
499       /* Enable the Half transfer complete interrupt as well */
500       __HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
501     }
502     else
503     {
504       __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
505       __HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_TE));
506     }
507 
508 #ifdef DMAMUX1
509 
510     /* Check if DMAMUX Synchronization is enabled*/
511     if((hdma->DMAmuxChannel->CCR & DMAMUX_CxCR_SE) != 0U)
512     {
513       /* Enable DMAMUX sync overrun IT*/
514       hdma->DMAmuxChannel->CCR |= DMAMUX_CxCR_SOIE;
515     }
516 
517     if(hdma->DMAmuxRequestGen != 0U)
518     {
519       /* if using DMAMUX request generator, enable the DMAMUX request generator overrun IT*/
520       /* enable the request gen overrun IT*/
521       hdma->DMAmuxRequestGen->RGCR |= DMAMUX_RGxCR_OIE;
522     }
523 
524 #endif /* DMAMUX1 */
525 
526     /* Enable the Peripheral */
527     __HAL_DMA_ENABLE(hdma);
528   }
529   else
530   {
531     /* Process Unlocked */
532     __HAL_UNLOCK(hdma);
533 
534     /* Remain BUSY */
535     status = HAL_BUSY;
536   }
537   return status;
538 }
539 
540 /**
541   * @brief  Abort the DMA Transfer.
542   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
543   *               the configuration information for the specified DMA Channel.
544     * @retval HAL status
545   */
HAL_DMA_Abort(DMA_HandleTypeDef * hdma)546 HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
547 {
548   HAL_StatusTypeDef status = HAL_OK;
549 
550   /* Check the DMA peripheral state */
551   if(hdma->State != HAL_DMA_STATE_BUSY)
552   {
553     hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
554 
555     /* Process Unlocked */
556     __HAL_UNLOCK(hdma);
557 
558     return HAL_ERROR;
559   }
560   else
561   {
562     /* Disable DMA IT */
563     __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
564 
565 #if defined(DMAMUX1)
566     /* disable the DMAMUX sync overrun IT*/
567     hdma->DMAmuxChannel->CCR &= ~DMAMUX_CxCR_SOIE;
568 #endif /* DMAMUX1 */
569 
570     /* Disable the channel */
571     __HAL_DMA_DISABLE(hdma);
572 
573     /* Clear all flags */
574     hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex & 0x1CU));
575 
576 #if defined(DMAMUX1)
577     /* Clear the DMAMUX synchro overrun flag */
578     hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
579 
580     if(hdma->DMAmuxRequestGen != 0U)
581     {
582       /* if using DMAMUX request generator, disable the DMAMUX request generator overrun IT*/
583       /* disable the request gen overrun IT*/
584       hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_OIE;
585 
586       /* Clear the DMAMUX request generator overrun flag */
587       hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
588     }
589 
590 #endif /* DMAMUX1 */
591 
592     /* Change the DMA state */
593     hdma->State = HAL_DMA_STATE_READY;
594 
595     /* Process Unlocked */
596     __HAL_UNLOCK(hdma);
597 
598     return status;
599   }
600 }
601 
602 /**
603   * @brief  Aborts the DMA Transfer in Interrupt mode.
604   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
605   *                 the configuration information for the specified DMA Channel.
606   * @retval HAL status
607   */
HAL_DMA_Abort_IT(DMA_HandleTypeDef * hdma)608 HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma)
609 {
610   HAL_StatusTypeDef status = HAL_OK;
611 
612   if(HAL_DMA_STATE_BUSY != hdma->State)
613   {
614     /* no transfer ongoing */
615     hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
616 
617     status = HAL_ERROR;
618   }
619   else
620   {
621     /* Disable DMA IT */
622     __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
623 
624     /* Disable the channel */
625     __HAL_DMA_DISABLE(hdma);
626 
627 #if defined(DMAMUX1)
628     /* disable the DMAMUX sync overrun IT*/
629     hdma->DMAmuxChannel->CCR &= ~DMAMUX_CxCR_SOIE;
630 
631     /* Clear all flags */
632     hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex & 0x1CU));
633 
634     /* Clear the DMAMUX synchro overrun flag */
635     hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
636 
637     if(hdma->DMAmuxRequestGen != 0U)
638     {
639       /* if using DMAMUX request generator, disable the DMAMUX request generator overrun IT*/
640       /* disable the request gen overrun IT*/
641       hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_OIE;
642 
643       /* Clear the DMAMUX request generator overrun flag */
644       hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
645     }
646 
647 #else
648     /* Clear all flags */
649     hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex & 0x1CU));
650 #endif /* DMAMUX1 */
651 
652     /* Change the DMA state */
653     hdma->State = HAL_DMA_STATE_READY;
654 
655     /* Process Unlocked */
656     __HAL_UNLOCK(hdma);
657 
658     /* Call User Abort callback */
659     if(hdma->XferAbortCallback != NULL)
660     {
661       hdma->XferAbortCallback(hdma);
662     }
663   }
664   return status;
665 }
666 
667 /**
668   * @brief  Polling for transfer complete.
669   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
670   *                  the configuration information for the specified DMA Channel.
671   * @param  CompleteLevel Specifies the DMA level complete.
672   * @param  Timeout       Timeout duration.
673   * @retval HAL status
674   */
HAL_DMA_PollForTransfer(DMA_HandleTypeDef * hdma,HAL_DMA_LevelCompleteTypeDef CompleteLevel,uint32_t Timeout)675 HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, HAL_DMA_LevelCompleteTypeDef CompleteLevel, uint32_t Timeout)
676 {
677   uint32_t temp;
678   uint32_t tickstart;
679 
680   if(HAL_DMA_STATE_BUSY != hdma->State)
681   {
682     /* no transfer ongoing */
683     hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
684     __HAL_UNLOCK(hdma);
685     return HAL_ERROR;
686   }
687 
688   /* Polling mode not supported in circular mode */
689   if ((hdma->Instance->CCR & DMA_CCR_CIRC) != 0U)
690   {
691     hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
692     return HAL_ERROR;
693   }
694 
695   /* Get the level transfer complete flag */
696   if (HAL_DMA_FULL_TRANSFER == CompleteLevel)
697   {
698     /* Transfer Complete flag */
699     temp = DMA_FLAG_TC1 << (hdma->ChannelIndex & 0x1CU);
700   }
701   else
702   {
703     /* Half Transfer Complete flag */
704     temp = DMA_FLAG_HT1 << (hdma->ChannelIndex & 0x1CU);
705   }
706 
707   /* Get tick */
708   tickstart = HAL_GetTick();
709 
710   while((hdma->DmaBaseAddress->ISR & temp) == 0U)
711   {
712     if((hdma->DmaBaseAddress->ISR & (DMA_FLAG_TE1 << (hdma->ChannelIndex& 0x1CU))) != 0U)
713     {
714       /* When a DMA transfer error occurs */
715       /* A hardware clear of its EN bits is performed */
716       /* Clear all flags */
717       hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex & 0x1CU));
718 
719       /* Update error code */
720       hdma->ErrorCode = HAL_DMA_ERROR_TE;
721 
722       /* Change the DMA state */
723       hdma->State= HAL_DMA_STATE_READY;
724 
725       /* Process Unlocked */
726       __HAL_UNLOCK(hdma);
727 
728       return HAL_ERROR;
729     }
730     /* Check for the Timeout */
731     if(Timeout != HAL_MAX_DELAY)
732     {
733       if(((HAL_GetTick() - tickstart) > Timeout) ||  (Timeout == 0U))
734       {
735         /* Update error code */
736         hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
737 
738         /* Change the DMA state */
739         hdma->State = HAL_DMA_STATE_READY;
740 
741         /* Process Unlocked */
742         __HAL_UNLOCK(hdma);
743 
744         return HAL_ERROR;
745       }
746     }
747   }
748 
749 #if defined(DMAMUX1)
750   /*Check for DMAMUX Request generator (if used) overrun status */
751   if(hdma->DMAmuxRequestGen != 0U)
752   {
753     /* if using DMAMUX request generator Check for DMAMUX request generator overrun */
754     if((hdma->DMAmuxRequestGenStatus->RGSR & hdma->DMAmuxRequestGenStatusMask) != 0U)
755     {
756       /* Disable the request gen overrun interrupt */
757       hdma->DMAmuxRequestGen->RGCR |= DMAMUX_RGxCR_OIE;
758 
759       /* Clear the DMAMUX request generator overrun flag */
760       hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
761 
762       /* Update error code */
763       hdma->ErrorCode |= HAL_DMA_ERROR_REQGEN;
764     }
765   }
766 
767   /* Check for DMAMUX Synchronization overrun */
768   if((hdma->DMAmuxChannelStatus->CSR & hdma->DMAmuxChannelStatusMask) != 0U)
769   {
770     /* Clear the DMAMUX synchro overrun flag */
771     hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
772 
773     /* Update error code */
774     hdma->ErrorCode |= HAL_DMA_ERROR_SYNC;
775   }
776 #endif /* DMAMUX1 */
777 
778   if(HAL_DMA_FULL_TRANSFER == CompleteLevel)
779   {
780     /* Clear the transfer complete flag */
781     hdma->DmaBaseAddress->IFCR = (DMA_FLAG_TC1 << (hdma->ChannelIndex& 0x1CU));
782 
783     /* Process unlocked */
784     __HAL_UNLOCK(hdma);
785 
786     /* The selected Channelx EN bit is cleared (DMA is disabled and
787     all transfers are complete) */
788     hdma->State = HAL_DMA_STATE_READY;
789   }
790   else
791   {
792     /* Clear the half transfer complete flag */
793     hdma->DmaBaseAddress->IFCR = (DMA_FLAG_HT1 << (hdma->ChannelIndex & 0x1CU));
794   }
795 
796   return HAL_OK;
797 }
798 
799 /**
800   * @brief  Handle DMA interrupt request.
801   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
802   *               the configuration information for the specified DMA Channel.
803   * @retval None
804   */
HAL_DMA_IRQHandler(DMA_HandleTypeDef * hdma)805 void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
806 {
807   uint32_t flag_it = hdma->DmaBaseAddress->ISR;
808   uint32_t source_it = hdma->Instance->CCR;
809 
810   /* Half Transfer Complete Interrupt management ******************************/
811   if (((flag_it & (DMA_FLAG_HT1 << (hdma->ChannelIndex & 0x1CU))) != 0U) && ((source_it & DMA_IT_HT) != 0U))
812   {
813       /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
814       if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
815       {
816         /* Disable the half transfer interrupt */
817         __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
818       }
819       /* Clear the half transfer complete flag */
820       hdma->DmaBaseAddress->IFCR = DMA_ISR_HTIF1 << (hdma->ChannelIndex & 0x1CU);
821 
822       /* DMA peripheral state is not updated in Half Transfer */
823       /* but in Transfer Complete case */
824 
825       if(hdma->XferHalfCpltCallback != NULL)
826       {
827         /* Half transfer callback */
828         hdma->XferHalfCpltCallback(hdma);
829       }
830   }
831 
832   /* Transfer Complete Interrupt management ***********************************/
833   else if (((flag_it & (DMA_FLAG_TC1 << (hdma->ChannelIndex & 0x1CU))) != 0U) && ((source_it & DMA_IT_TC) != 0U))
834   {
835     if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
836     {
837       /* Disable the transfer complete interrupt if the DMA mode is not CIRCULAR */
838       /* Disable the transfer complete and error interrupt */
839       /* if the DMA mode is not CIRCULAR  */
840       __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE | DMA_IT_TC);
841 
842       /* Change the DMA state */
843       hdma->State = HAL_DMA_STATE_READY;
844     }
845     /* Clear the transfer complete flag */
846     hdma->DmaBaseAddress->IFCR = (DMA_ISR_TCIF1 << (hdma->ChannelIndex & 0x1CU));
847 
848     /* Process Unlocked */
849     __HAL_UNLOCK(hdma);
850 
851     if(hdma->XferCpltCallback != NULL)
852     {
853       /* Transfer complete callback */
854       hdma->XferCpltCallback(hdma);
855     }
856   }
857 
858   /* Transfer Error Interrupt management **************************************/
859   else if (((flag_it & (DMA_FLAG_TE1 << (hdma->ChannelIndex & 0x1CU))) != 0U) && ((source_it & DMA_IT_TE) !=  0U))
860   {
861     /* When a DMA transfer error occurs */
862     /* A hardware clear of its EN bits is performed */
863     /* Disable ALL DMA IT */
864     __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
865 
866     /* Clear all flags */
867     hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex & 0x1CU));
868 
869     /* Update error code */
870     hdma->ErrorCode = HAL_DMA_ERROR_TE;
871 
872     /* Change the DMA state */
873     hdma->State = HAL_DMA_STATE_READY;
874 
875     /* Process Unlocked */
876     __HAL_UNLOCK(hdma);
877 
878     if (hdma->XferErrorCallback != NULL)
879     {
880       /* Transfer error callback */
881       hdma->XferErrorCallback(hdma);
882     }
883   }
884   else
885   {
886     /* Nothing To Do */
887   }
888   return;
889 }
890 
891 /**
892   * @brief  Register callbacks
893   * @param  hdma                 pointer to a DMA_HandleTypeDef structure that contains
894   *                               the configuration information for the specified DMA Channel.
895   * @param  CallbackID           User Callback identifer
896   *                               a HAL_DMA_CallbackIDTypeDef ENUM as parameter.
897   * @param  pCallback            pointer to private callbacsk function which has pointer to
898   *                               a DMA_HandleTypeDef structure as parameter.
899   * @retval HAL status
900   */
HAL_DMA_RegisterCallback(DMA_HandleTypeDef * hdma,HAL_DMA_CallbackIDTypeDef CallbackID,void (* pCallback)(DMA_HandleTypeDef * _hdma))901 HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID, void (* pCallback)( DMA_HandleTypeDef * _hdma))
902 {
903   HAL_StatusTypeDef status = HAL_OK;
904 
905   /* Process locked */
906   __HAL_LOCK(hdma);
907 
908   if(HAL_DMA_STATE_READY == hdma->State)
909   {
910     switch (CallbackID)
911     {
912      case  HAL_DMA_XFER_CPLT_CB_ID:
913            hdma->XferCpltCallback = pCallback;
914            break;
915 
916      case  HAL_DMA_XFER_HALFCPLT_CB_ID:
917            hdma->XferHalfCpltCallback = pCallback;
918            break;
919 
920      case  HAL_DMA_XFER_ERROR_CB_ID:
921            hdma->XferErrorCallback = pCallback;
922            break;
923 
924      case  HAL_DMA_XFER_ABORT_CB_ID:
925            hdma->XferAbortCallback = pCallback;
926            break;
927 
928      default:
929            status = HAL_ERROR;
930            break;
931     }
932   }
933   else
934   {
935     status = HAL_ERROR;
936   }
937 
938   /* Release Lock */
939   __HAL_UNLOCK(hdma);
940 
941   return status;
942 }
943 
944 /**
945   * @brief  UnRegister callbacks
946   * @param  hdma                 pointer to a DMA_HandleTypeDef structure that contains
947   *                               the configuration information for the specified DMA Channel.
948   * @param  CallbackID           User Callback identifer
949   *                               a HAL_DMA_CallbackIDTypeDef ENUM as parameter.
950   * @retval HAL status
951   */
HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef * hdma,HAL_DMA_CallbackIDTypeDef CallbackID)952 HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID)
953 {
954   HAL_StatusTypeDef status = HAL_OK;
955 
956     /* Process locked */
957   __HAL_LOCK(hdma);
958 
959   if(HAL_DMA_STATE_READY == hdma->State)
960   {
961     switch (CallbackID)
962     {
963      case  HAL_DMA_XFER_CPLT_CB_ID:
964            hdma->XferCpltCallback = NULL;
965            break;
966 
967      case  HAL_DMA_XFER_HALFCPLT_CB_ID:
968            hdma->XferHalfCpltCallback = NULL;
969            break;
970 
971      case  HAL_DMA_XFER_ERROR_CB_ID:
972            hdma->XferErrorCallback = NULL;
973            break;
974 
975      case  HAL_DMA_XFER_ABORT_CB_ID:
976            hdma->XferAbortCallback = NULL;
977            break;
978 
979     case   HAL_DMA_XFER_ALL_CB_ID:
980            hdma->XferCpltCallback = NULL;
981            hdma->XferHalfCpltCallback = NULL;
982            hdma->XferErrorCallback = NULL;
983            hdma->XferAbortCallback = NULL;
984            break;
985 
986     default:
987            status = HAL_ERROR;
988            break;
989     }
990   }
991   else
992   {
993     status = HAL_ERROR;
994   }
995 
996   /* Release Lock */
997   __HAL_UNLOCK(hdma);
998 
999   return status;
1000 }
1001 
1002 /**
1003   * @}
1004   */
1005 
1006 
1007 
1008 /** @defgroup DMA_Exported_Functions_Group3 Peripheral State and Errors functions
1009  *  @brief    Peripheral State and Errors functions
1010  *
1011 @verbatim
1012  ===============================================================================
1013             ##### Peripheral State and Errors functions #####
1014  ===============================================================================
1015     [..]
1016     This subsection provides functions allowing to
1017       (+) Check the DMA state
1018       (+) Get error code
1019 
1020 @endverbatim
1021   * @{
1022   */
1023 
1024 /**
1025   * @brief  Return the DMA handle state.
1026   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
1027   *               the configuration information for the specified DMA Channel.
1028   * @retval HAL state
1029   */
HAL_DMA_GetState(DMA_HandleTypeDef * hdma)1030 HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma)
1031 {
1032   /* Return DMA handle state */
1033   return hdma->State;
1034 }
1035 
1036 /**
1037   * @brief  Return the DMA error code.
1038   * @param  hdma : pointer to a DMA_HandleTypeDef structure that contains
1039   *              the configuration information for the specified DMA Channel.
1040   * @retval DMA Error Code
1041   */
HAL_DMA_GetError(DMA_HandleTypeDef * hdma)1042 uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma)
1043 {
1044   return hdma->ErrorCode;
1045 }
1046 
1047 /**
1048   * @}
1049   */
1050 
1051 /**
1052   * @}
1053   */
1054 
1055 /** @addtogroup DMA_Private_Functions
1056   * @{
1057   */
1058 
1059 /**
1060   * @brief  Sets the DMA Transfer parameter.
1061   * @param  hdma       pointer to a DMA_HandleTypeDef structure that contains
1062   *                     the configuration information for the specified DMA Channel.
1063   * @param  SrcAddress The source memory Buffer address
1064   * @param  DstAddress The destination memory Buffer address
1065   * @param  DataLength The length of data to be transferred from source to destination
1066   * @retval HAL status
1067   */
DMA_SetConfig(DMA_HandleTypeDef * hdma,uint32_t SrcAddress,uint32_t DstAddress,uint32_t DataLength)1068 static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
1069 {
1070 #if defined(DMAMUX1)
1071   /* Clear the DMAMUX synchro overrun flag */
1072   hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
1073 
1074   if(hdma->DMAmuxRequestGen != 0U)
1075   {
1076     /* Clear the DMAMUX request generator overrun flag */
1077     hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
1078   }
1079 #endif
1080 
1081   /* Clear all flags */
1082   hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex & 0x1CU));
1083 
1084   /* Configure DMA Channel data length */
1085   hdma->Instance->CNDTR = DataLength;
1086 
1087   /* Memory to Peripheral */
1088   if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
1089   {
1090     /* Configure DMA Channel destination address */
1091     hdma->Instance->CPAR = DstAddress;
1092 
1093     /* Configure DMA Channel source address */
1094     hdma->Instance->CMAR = SrcAddress;
1095   }
1096   /* Peripheral to Memory */
1097   else
1098   {
1099     /* Configure DMA Channel source address */
1100     hdma->Instance->CPAR = SrcAddress;
1101 
1102     /* Configure DMA Channel destination address */
1103     hdma->Instance->CMAR = DstAddress;
1104   }
1105 }
1106 
1107 #if defined(DMAMUX1)
1108 
1109 /**
1110   * @brief  Updates the DMA handle with the DMAMUX  channel and status mask depending on channel number
1111   * @param  hdma        pointer to a DMA_HandleTypeDef structure that contains
1112   *                     the configuration information for the specified DMA Channel.
1113   * @retval None
1114   */
DMA_CalcDMAMUXChannelBaseAndMask(DMA_HandleTypeDef * hdma)1115 static void DMA_CalcDMAMUXChannelBaseAndMask(DMA_HandleTypeDef *hdma)
1116 {
1117   uint32_t channel_number;
1118 
1119   /* check if instance is not outside the DMA channel range */
1120   if ((uint32_t)hdma->Instance < (uint32_t)DMA2_Channel1)
1121   {
1122     /* DMA1 */
1123     hdma->DMAmuxChannel = (DMAMUX1_Channel0 + (hdma->ChannelIndex >> 2U));
1124   }
1125   else
1126   {
1127     /* DMA2 */
1128     hdma->DMAmuxChannel = (DMAMUX1_Channel7 + (hdma->ChannelIndex >> 2U));
1129   }
1130 
1131   channel_number = (((uint32_t)hdma->Instance & 0xFFU) - 8U) / 20U;
1132   hdma->DMAmuxChannelStatus = DMAMUX1_ChannelStatus;
1133   hdma->DMAmuxChannelStatusMask = 1UL << (channel_number & 0x1FU);
1134 }
1135 
1136 /**
1137   * @brief  Updates the DMA handle with the DMAMUX  request generator params
1138   * @param  hdma        pointer to a DMA_HandleTypeDef structure that contains
1139   *                     the configuration information for the specified DMA Channel.
1140   * @retval None
1141   */
1142 
DMA_CalcDMAMUXRequestGenBaseAndMask(DMA_HandleTypeDef * hdma)1143 static void DMA_CalcDMAMUXRequestGenBaseAndMask(DMA_HandleTypeDef *hdma)
1144 {
1145   uint32_t request =  hdma->Init.Request & DMAMUX_CxCR_DMAREQ_ID;
1146 
1147   /* DMA Channels are connected to DMAMUX1 request generator blocks*/
1148   hdma->DMAmuxRequestGen = (DMAMUX_RequestGen_TypeDef *)((uint32_t)(((uint32_t)DMAMUX1_RequestGenerator0) + ((request - 1U) * 4U)));
1149 
1150   hdma->DMAmuxRequestGenStatus = DMAMUX1_RequestGenStatus;
1151 
1152   /* here "Request" is either DMA_REQUEST_GENERATOR0 to DMA_REQUEST_GENERATOR3, i.e. <= 4*/
1153   hdma->DMAmuxRequestGenStatusMask = 1UL << ((request - 1U) & 0x3U);
1154 }
1155 
1156 #endif /* DMAMUX1 */
1157 
1158 /**
1159   * @}
1160   */
1161 
1162 /**
1163   * @}
1164   */
1165 
1166 #endif /* HAL_DMA_MODULE_ENABLED */
1167 /**
1168   * @}
1169   */
1170 
1171 /**
1172   * @}
1173   */
1174 
1175 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1176