/**
  ******************************************************************************
  * @file    ys32md211_dma.c
  * @author  YSPRING Application Team
  * @version V1.0.1
  * @date    2025.02.15
  * @brief   This file provides firmware functions to manage the following 
  *          functionalities of the Direct Memory Access controller (DMA):
  *           + Initialization and Configuration
  *           + Data Counter
  *           + Interrupts and flags management
  *
  *  @verbatim
  ==============================================================================
                      ##### How to use this driver #####
  ==============================================================================
    [..]
    (#) Enable The DMA controller clock using 
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA, ENABLE) function for DMA.
    (#) Enable and configure the peripheral to be connected to the DMA channel
       (except for internal SRAM / FLASH memories: no initialization is necessary).
    (#) For a given Channel, program the Source and Destination addresses, 
        the transfer Direction, the Buffer Size, the Peripheral and Memory 
        Incrementation mode and Data Size, the Circular or Normal mode, 
        the channel transfer Priority, the Memory-to-Memory transfer,
        the channel TransMode.
        mode (if needed) using the DMA_Init() function.
    (#) Enable the NVIC and the corresponding interrupt(s) using the function 
        DMA_ITConfig() if you need to use DMA interrupts.
    (#) Enable the DMA channel using the DMA_Cmd() function.
    (#) Activate the needed channel Request using PPP_DMACmd() function for 
        any PPP peripheral except internal SRAM and FLASH (ie. SPI, USART ...) 
        The function allowing this operation is provided in each PPP peripheral 
        driver (ie. SPI_DMACmd for SPI peripheral).
    (#) Optionally, you can configure the number of data to be transferred
        when the channel is disabled (ie. after each Transfer Complete event
        or when a Transfer Error occurs) using the function DMA_SetCurrDataCounter().
        And you can get the number of remaining data to be transferred using 
        the function DMA_GetCurrDataCounter() at run time (when the DMA channel is
        enabled and running).
    (#) Above all, you must use DMA_RemapConfig() to Configure the DMAx channels remapping,
        and before using this function you must enable the SYSCFG Clock by 
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE), 
        and Add driver file(ys32md211_syscfg.c).
    (#) To control DMA events you can use one of the following two methods:
        (##) Check on DMA channel flags using the function DMA_GetFlagStatus().
        (##) Use DMA interrupts through the function DMA_ITConfig() at initialization
             phase and DMA_GetITStatus() function into interrupt routines in
             communication phase.
             After checking on a flag you should clear it using DMA_ClearFlag()
             function. And after checking on an interrupt event you should 
             clear it using DMA_ClearITPendingBit() function.
    @endverbatim
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "ys32md211_dma.h"

/** @addtogroup YS32MD211_StdPeriph_Driver
  * @{
  */

/** @defgroup DMA 
  * @brief DMA driver modules
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/

/* DMA Channelx interrupt pending bit masks */
#define DMA_CHANNEL1_IT_MASK    ((uint32_t)(DMA_ISR_GIF1 | DMA_ISR_TCIF1 | DMA_ISR_HTIF1 | DMA_ISR_TEIF1))
#define DMA_CHANNEL2_IT_MASK    ((uint32_t)(DMA_ISR_GIF2 | DMA_ISR_TCIF2 | DMA_ISR_HTIF2 | DMA_ISR_TEIF2))
#define DMA_CHANNEL3_IT_MASK    ((uint32_t)(DMA_ISR_GIF3 | DMA_ISR_TCIF3 | DMA_ISR_HTIF3 | DMA_ISR_TEIF3))
#define DMA_CCRx_CONFIG_MASK    ((uint32_t)0x7FF0)


/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/** @defgroup DMA_Private_Functions 
  * @{
  */

/** @defgroup DMA_Group1 Initialization and Configuration functions
 *  @brief   Initialization and Configuration functions
 *
@verbatim   
 ===============================================================================
            ##### Initialization and Configuration functions #####
 ===============================================================================
    [..] This subsection provides functions allowing to initialize the DMA channel 
         source and destination addresses, incrementation and data sizes, transfer 
         direction, buffer size, circular/normal mode selection, memory-to-memory 
         mode selection and channel priority value, TransMode selection.
    [..] The DMA_Init() function follows the DMA configuration procedures as described 
         in reference manual.
@endverbatim
  * @{
  */
    
/**
  * @brief  Deinitializes the DMAy Channelx registers to their default reset
  *         values.
  * @param  DMAy_Channelx: x can be 1 to 3 
  *            @arg DMA_CHANNEL1: DMA Channel1 select
  *            @arg DMA_CHANNEL2: DMA Channel2 select
  *            @arg DMA_CHANNEL3: DMA Channel3 select

  * @retval None
  */
void DMA_DeInit(DMA_CHANNEL_TypeDef* DMAy_Channelx)
{
  /* Check the parameters */
  assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx));

  /* Disable the selected DMAy Channelx */
  DMAy_Channelx->CCR &= (uint16_t)(~DMA_CHANNEL_CCR_EN);

  /* Reset DMAy Channelx control register */
  DMAy_Channelx->CCR  = 0;

  /* Reset DMAy Channelx remaining bytes register */
  DMAy_Channelx->CNDTR = 0;

  /* Reset DMAy Channelx peripheral address register */
  DMAy_Channelx->CPAR  = 0;

  /* Reset DMAy Channelx memory address register */
  DMAy_Channelx->CMAR = 0;

  if (DMAy_Channelx == DMA_CHANNEL1)
  {
    /* Reset interrupt pending bits for DMA Channel1 */
    DMA->IFCR |= DMA_CHANNEL1_IT_MASK;
  }
  else if (DMAy_Channelx == DMA_CHANNEL2)
  {
    /* Reset interrupt pending bits for DMA Channel2 */
    DMA->IFCR |= DMA_CHANNEL2_IT_MASK;
  }
  else if (DMAy_Channelx == DMA_CHANNEL3)
  {
    /* Reset interrupt pending bits for DMA Channel3 */
    DMA->IFCR |= DMA_CHANNEL3_IT_MASK;
  }
}

/**
  * @brief  Initializes the DMAy Channelx according to the specified parameters 
  *         in the DMA_InitStruct.
  * @param  DMAy_Channelx: x can be 1 to 3
  *            @arg DMA_CHANNEL1: DMA Channel1 select
  *            @arg DMA_CHANNEL2: DMA Channel2 select
  *            @arg DMA_CHANNEL3: DMA Channel3 select
  * @param  DMA_InitStruct: pointer to a DMA_InitTypeDef structure that contains
  *         the configuration information for the specified DMA Channel.
  * @retval None
  */
void DMA_Init(DMA_CHANNEL_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct)
{
  uint32_t tmpreg = 0;

  /* Check the parameters */
  assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx));
  assert_param(IS_DMA_DIR(DMA_InitStruct->DMA_DIR));
  assert_param(IS_DMA_BUFFER_SIZE(DMA_InitStruct->DMA_BufferSize));
  assert_param(IS_DMA_PERIPHERAL_INC_STATE(DMA_InitStruct->DMA_PeripheralInc));
  assert_param(IS_DMA_MEMORY_INC_STATE(DMA_InitStruct->DMA_MemoryInc));
  assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(DMA_InitStruct->DMA_PeripheralDataSize));
  assert_param(IS_DMA_MEMORY_DATA_SIZE(DMA_InitStruct->DMA_MemoryDataSize));
  assert_param(IS_DMA_MODE(DMA_InitStruct->DMA_Mode));
  assert_param(IS_DMA_PRIORITY(DMA_InitStruct->DMA_Priority));
  assert_param(IS_DMA_M2M_STATE(DMA_InitStruct->DMA_M2M));

  /*--------------------------- DMAy Channelx CCR Configuration ----------------*/
  /* Get the DMAy_Channelx CCR value */
  tmpreg = DMAy_Channelx->CCR;

  /* Clear MEM2MEM, PL, MSIZE, PSIZE, MINC, PINC, CIRC and DIR bits */
  tmpreg &= (~DMA_CCRx_CONFIG_MASK);

  /* Configure DMAy Channelx: data transfer, data size, priority level and mode */
  /* Set DIR bit according to DMA_DIR value */
  /* Set CIRC bit according to DMA_Mode value */
  /* Set PINC bit according to DMA_PeripheralInc value */
  /* Set MINC bit according to DMA_MemoryInc value */
  /* Set PSIZE bits according to DMA_PeripheralDataSize value */
  /* Set MSIZE bits according to DMA_MemoryDataSize value */
  /* Set PL bits according to DMA_Priority value */
  /* Set the MEM2MEM bit according to DMA_M2M value */
  tmpreg |= DMA_InitStruct->DMA_DIR | DMA_InitStruct->DMA_Mode |
      DMA_InitStruct->DMA_PeripheralInc | DMA_InitStruct->DMA_MemoryInc |
      DMA_InitStruct->DMA_PeripheralDataSize | DMA_InitStruct->DMA_MemoryDataSize |
      DMA_InitStruct->DMA_Priority | DMA_InitStruct->DMA_M2M;

  /* Write to DMAy Channelx CCR */
  DMAy_Channelx->CCR = tmpreg;

  /*--------------------------- DMAy Channelx CNDTR Configuration --------------*/
  /* Write to DMAy Channelx CNDTR */
  DMAy_Channelx->CNDTR = DMA_InitStruct->DMA_BufferSize;

  /*--------------------------- DMAy Channelx CPAR Configuration ---------------*/
  /* Write to DMAy Channelx CPAR */
  DMAy_Channelx->CPAR = DMA_InitStruct->DMA_PeripheralBaseAddr;

  /*--------------------------- DMAy Channelx CMAR Configuration ---------------*/
  /* Write to DMAy Channelx CMAR */
  DMAy_Channelx->CMAR = DMA_InitStruct->DMA_MemoryBaseAddr;
}

/**
  * @brief  Fills each DMA_InitStruct member with its default value.
  * @param  DMA_InitStruct: pointer to a DMA_InitTypeDef structure which will
  *         be initialized.
  * @retval None
  */
void DMA_StructInit(DMA_InitTypeDef* DMA_InitStruct)
{
  /*-------------- Reset DMA init structure parameters values ------------------*/
  /* Initialize the DMA_PeripheralBaseAddr member */
  DMA_InitStruct->DMA_PeripheralBaseAddr = 0;
  /* Initialize the DMA_MemoryBaseAddr member */
  DMA_InitStruct->DMA_MemoryBaseAddr = 0;
  /* Initialize the DMA_DIR member */
  DMA_InitStruct->DMA_DIR = DMA_DIR_PeripheralSRC;
  /* Initialize the DMA_BufferSize member */
  DMA_InitStruct->DMA_BufferSize = 0;
  /* Initialize the DMA_PeripheralInc member */
  DMA_InitStruct->DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  /* Initialize the DMA_MemoryInc member */
  DMA_InitStruct->DMA_MemoryInc = DMA_MemoryInc_Disable;
  /* Initialize the DMA_PeripheralDataSize member */
  DMA_InitStruct->DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  /* Initialize the DMA_MemoryDataSize member */
  DMA_InitStruct->DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  /* Initialize the DMA_Mode member */
  DMA_InitStruct->DMA_Mode = DMA_Mode_Normal;
  /* Initialize the DMA_Priority member */
  DMA_InitStruct->DMA_Priority = DMA_Priority_Low;
  /* Initialize the DMA_M2M member */
  DMA_InitStruct->DMA_M2M = DMA_M2M_Disable;
}

/**
  * @brief  Enables or disables the specified DMAy Channelx.
  * @param  DMAy_Channelx: x can be 1 to 3
  *            @arg DMA_CHANNEL1: DMA Channel1 select
  *            @arg DMA_CHANNEL2: DMA Channel2 select
  *            @arg DMA_CHANNEL3: DMA Channel3 select
  * @param  NewState: new state of the DMA Channelx. 
  *         This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void DMA_Cmd(DMA_CHANNEL_TypeDef* DMAy_Channelx, FunctionalState NewState)
{
  /* Check the parameters */
  assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx));
  assert_param(IS_FUNCTIONAL_STATE(NewState));

  if (NewState != DISABLE)
  {
    /* Enable the selected DMAy Channelx */
    DMAy_Channelx->CCR |= DMA_CHANNEL_CCR_EN;
  }
  else
  {
    /* Disable the selected DMAy Channelx */
    DMAy_Channelx->CCR &= (uint16_t)(~DMA_CHANNEL_CCR_EN);
  }
}

/**
  * @brief  Configure the DMAx channels remapping.
  * @param  DMAy_Channelx: x can be 1 to 3
  *         @arg DMA_MAP_CH1: DMA Channel1 MAP
  *         @arg DMA_MAP_CH2: DMA Channel2 MAP
  *         @arg DMA_MAP_CH3: DMA Channel3 MAP
  * @param  DMARemap: 
  *         @arg DMA_MAP_ADC       : DMA map to ADC       
  *         @arg DMA_MAP_SPI1_TX    : DMA map to SPI_TX   
  *         @arg DMA_MAP_SPI1_RX    : DMA map to SPI_RX   
  *         @arg DMA_MAP_UART1_TX  : DMA map to UART1_TX  
  *         @arg DMA_MAP_UART1_RX  : DMA map to UART1_RX  
  *         @arg DMA_MAP_UART2_TX  : DMA map to UART2_TX  
  *         @arg DMA_MAP_UART2_RX  : DMA map to UART2_RX  
  *         @arg DMA_MAP_I2C1_TX    : DMA map to I2C_TX   
  *         @arg DMA_MAP_I2C1_RX    : DMA map to I2C_RX   
  *         @arg DMA_MAP_TIM1_CH1  : DMA map to TIM1_CH1  
  *         @arg DMA_MAP_TIM1_CH2  : DMA map to TIM1_CH2  
  *         @arg DMA_MAP_TIM1_CH3  : DMA map to TIM1_CH3  
  *         @arg DMA_MAP_TIM1_CH4  : DMA map to TIM1_CH4  
  *         @arg DMA_MAP_TIM1_COM  : DMA map to TIM1_COM  
  *         @arg DMA_MAP_TIM1_UP   : DMA map to TIM1_UP   
  *         @arg DMA_MAP_TIM1_TRIG : DMA map to TIM1_TRIG 
  *         @arg DMA_MAP_TIM3_CH1  : DMA map to TIM3_CH1  
  *         @arg DMA_MAP_TIM3_CH3  : DMA map to TIM3_CH3  
  *         @arg DMA_MAP_TIM3_CH4  : DMA map to TIM3_CH4  
  *         @arg DMA_MAP_TIM3_TRG  : DMA map to TIM3_TRG  
  *         @arg DMA_MAP_TIM3_UP   : DMA map to TIM3_UP   
  *         @arg DMA_MAP_TIM16_CH1 : DMA map to TIM16_CH1 
  *         @arg DMA_MAP_TIM16_UP  : DMA map to TIM16_UP  
  *         @arg DMA_MAP_TIM17_CH1 : DMA map to TIM17_CH1 
  *         @arg DMA_MAP_TIM17_UP  : DMA map to TIM17_UP  
  * @param  NewState: new state of the DMA Channelx. 
  *         This parameter can be: ENABLE or DISABLE.
  * @note   Before using this function, ys32md211xx_syscfg.c need be put in Driver
  *         and SYSCFG clock should be enable.  
  * @retval None
  */
void DMA_RemapConfig(uint32_t DMAy_Channelx, uint32_t DMARemap, FunctionalState NewState)
{
  SYSCFG_DMAChannelRemapConfig(DMAy_Channelx, DMARemap, NewState);
}

/**
  * @brief  Set the DMAy Channelx transfer mode.
  * @param  DMAy_Channelx: x can be 1 to 3
  *            @arg DMA_CHANNEL1: DMA Channel1 select
  *            @arg DMA_CHANNEL2: DMA Channel2 select
  *            @arg DMA_CHANNEL3: DMA Channel3 select
  * @param  TransferMode: DMA TransferMode Selection
  *         This parameter can be one of the following values:
  *         @arg @ref DMA_TransMode_All : Complete all transfer number values per DMA request
  *         @arg @ref DMA_TransMode_One : Complete one transfer number values per DMA request
  * @note   This function can only be used when the DMAy_Channelx is disabled.
  * @retval None.
  */
void DMA_SetTransferMode(DMA_CHANNEL_TypeDef* DMAy_Channelx, uint16_t TransferMode)
{
  /* Check the parameters */
  assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx));
  assert_param(IS_DMA_TRANS_MODE(TransferMode));
  
  DMAy_Channelx ->CCR &= (~DMA_CHANNEL_CCR_TRANS_MODE);

  /*--------------------------- DMAy Channelx CCR Configuration --------------*/
  /* Write to DMAy Channelx CCR TRANS_MODE bit */
  DMAy_Channelx->CCR |= TransferMode;
}

/**
  * @}
  */

/** @defgroup DMA_Group2 Data Counter functions
 *  @brief   Data Counter functions 
 *
@verbatim
 ===============================================================================
                      ##### Data Counter functions #####
 ===============================================================================
    [..] This subsection provides function allowing to configure and read the buffer 
         size (number of data to be transferred).The DMA data counter can be written 
         only when the DMA channel is disabled (ie. after transfer complete event).
    [..] The following function can be used to write the Channel data counter value:
         (+) void DMA_SetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx, uint16_t 
             DataNumber).
    -@- It is advised to use this function rather than DMA_Init() in situations 
        where only the Data buffer needs to be reloaded.
    [..] The DMA data counter can be read to indicate the number of remaining transfers 
         for the relative DMA channel. This counter is decremented at the end of each 
         data transfer and when the transfer is complete: 
         (+) If Normal mode is selected: the counter is set to 0.
         (+) If Circular mode is selected: the counter is reloaded with the initial 
         value(configured before enabling the DMA channel).
    [..] The following function can be used to read the Channel data counter value:
         (+) uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx).

@endverbatim
  * @{
  */

/**
  * @brief  Sets the number of data units in the current DMAy Channelx transfer.
  * @param  DMAy_Channelx: x can be 1 to 3
  *            @arg DMA_CHANNEL1: DMA Channel1 select
  *            @arg DMA_CHANNEL2: DMA Channel2 select
  *            @arg DMA_CHANNEL3: DMA Channel3 select
  * @param  DataNumber: The number of data units in the current DMAy Channelx
  *         transfer.
  * @note   This function can only be used when the DMAy_Channelx is disabled.
  * @retval None.
  */
void DMA_SetCurrDataCounter(DMA_CHANNEL_TypeDef* DMAy_Channelx, uint16_t DataNumber)
{
  /* Check the parameters */
  assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx));

  /*--------------------------- DMAy Channelx CNDTR Configuration --------------*/
  /* Write to DMAy Channelx CNDTR */
  DMAy_Channelx->CNDTR = DataNumber;
}

/**
  * @brief  Returns the number of remaining data units in the current
  *         DMAy Channelx transfer.
  * @param  DMAy_Channelx: x can be 1 to 3
  *            @arg DMA_CHANNEL1: DMA Channel1 select
  *            @arg DMA_CHANNEL2: DMA Channel2 select
  *            @arg DMA_CHANNEL3: DMA Channel3 select
  * @retval The number of remaining data units in the current DMAy Channelx
  *         transfer.
  */
uint16_t DMA_GetCurrDataCounter(DMA_CHANNEL_TypeDef* DMAy_Channelx)
{
  /* Check the parameters */
  assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx));
  /* Return the number of remaining data units for DMAy Channelx */
  return ((uint16_t)(DMAy_Channelx->CNDTR));
}

/**
  * @}
  */

/** @defgroup DMA_Group3 Interrupts and flags management functions
 *  @brief   Interrupts and flags management functions 
 *
@verbatim
 ===============================================================================
          ##### Interrupts and flags management functions #####
 ===============================================================================
    [..] This subsection provides functions allowing to configure the DMA Interrupts 
         sources and check or clear the flags or pending bits status.
         The user should identify which mode will be used in his application to manage 
         the DMA controller events: Polling mode or Interrupt mode. 
  *** Polling Mode ***
  ====================
    [..] Each DMA channel can be managed through 4 event Flags:(y : DMA Controller 
         number  x : DMA channel number ).
         (#) DMAy_FLAG_TCx : to indicate that a Transfer Complete event occurred.
         (#) DMAy_FLAG_HTx : to indicate that a Half-Transfer Complete event occurred.
         (#) DMAy_FLAG_TEx : to indicate that a Transfer Error occurred.
         (#) DMAy_FLAG_GLx : to indicate that at least one of the events described 
             above occurred.
    -@- Clearing DMAy_FLAG_GLx results in clearing all other pending flags of the 
        same channel (DMAy_FLAG_TCx, DMAy_FLAG_HTx and DMAy_FLAG_TEx).
    [..]In this Mode it is advised to use the following functions:
        (+) FlagStatus DMA_GetFlagStatus(uint32_t DMA_FLAG);
        (+) void DMA_ClearFlag(uint32_t DMA_FLAG);

  *** Interrupt Mode ***
  ======================
    [..] Each DMA channel can be managed through 4 Interrupts:
    (+) Interrupt Source
       (##) DMA_IT_TC: specifies the interrupt source for the Transfer Complete 
            event.
       (##) DMA_IT_HT : specifies the interrupt source for the Half-transfer Complete 
            event.
       (##) DMA_IT_TE : specifies the interrupt source for the transfer errors event.
       (##) DMA_IT_GL : to indicate that at least one of the interrupts described 
            above occurred.
    -@@- Clearing DMA_IT_GL interrupt results in clearing all other interrupts of 
        the same channel (DMA_IT_TCx, DMA_IT_HT and DMA_IT_TE).
    [..]In this Mode it is advised to use the following functions:
        (+) void DMA_ITConfig(DMA_Channel_TypeDef* DMAy_Channelx, uint32_t DMA_IT, 
            FunctionalState NewState);
        (+) ITStatus DMA_GetITStatus(uint32_t DMA_IT);
        (+) void DMA_ClearITPendingBit(uint32_t DMA_IT);

@endverbatim
  * @{
  */

/**
  * @brief  Enables or disables the specified DMAy Channelx interrupts.
  * @param  DMAy_Channelx: x can be 1 to 3
  *            @arg DMA_CHANNEL1: DMA Channel1 select
  *            @arg DMA_CHANNEL2: DMA Channel2 select
  *            @arg DMA_CHANNEL3: DMA Channel3 select
  * @param  DMA_IT: specifies the DMA interrupts sources to be enabled
  *         or disabled. 
  *          This parameter can be any combination of the following values:
  *            @arg DMA_IT_TC: Transfer complete interrupt mask
  *            @arg DMA_IT_HT: Half transfer interrupt mask
  *            @arg DMA_IT_TE: Transfer error interrupt mask
  * @param  NewState: new state of the specified DMA interrupts.
  *         This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void DMA_ITConfig(DMA_CHANNEL_TypeDef* DMAy_Channelx, uint32_t DMA_IT, FunctionalState NewState)
{
  /* Check the parameters */
  assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx));
  assert_param(IS_DMA_CONFIG_IT(DMA_IT));
  assert_param(IS_FUNCTIONAL_STATE(NewState));

  if (NewState != DISABLE)
  {
    /* Enable the selected DMA interrupts */
    DMAy_Channelx->CCR |= DMA_IT;
  }
  else
  {
    /* Disable the selected DMA interrupts */
    DMAy_Channelx->CCR &= ~DMA_IT;
  }
}

/**
  * @brief  Checks whether the specified DMAy Channelx flag is set or not.
  * @param  DMAy_FLAG: specifies the flag to check.
  *          This parameter can be one of the following values:
  *            @arg DMA_FLAG_GI1: DMA Channel1 global flag.
  *            @arg DMA_FLAG_TC1: DMA Channel1 transfer complete flag.
  *            @arg DMA_FLAG_HT1: DMA Channel1 half transfer flag.
  *            @arg DMA_FLAG_TE1: DMA Channel1 transfer error flag.
  *            @arg DMA_FLAG_GI2: DMA Channel2 global flag.
  *            @arg DMA_FLAG_TC2: DMA Channel2 transfer complete flag.
  *            @arg DMA_FLAG_HT2: DMA Channel2 half transfer flag.
  *            @arg DMA_FLAG_TE2: DMA Channel2 transfer error flag.
  *            @arg DMA_FLAG_GI3: DMA Channel3 global flag.
  *            @arg DMA_FLAG_TC3: DMA Channel3 transfer complete flag.
  *            @arg DMA_FLAG_HT3: DMA Channel3 half transfer flag.
  *            @arg DMA_FLAG_TE3: DMA Channel3 transfer error flag.
  * @note   The Global flag (DMAy_FLAG_GLx) is set whenever any of the other flags 
  *         relative to the same channel is set (Transfer Complete, Half-transfer 
  *         Complete or Transfer Error flags: DMAy_FLAG_TCx, DMAy_FLAG_HTx or 
  *         DMAy_FLAG_TEx). 
  *      
  * @retval The new state of DMA_FLAG (SET or RESET).
  */
FlagStatus DMA_GetFlagStatus(uint32_t DMAy_FLAG)
{
  FlagStatus bitstatus = RESET;
  uint32_t tmpreg = 0;

  /* Get DMA ISR register value */
  tmpreg = DMA->ISR ;

  /* Check the status of the specified DMAy flag */
  if ((tmpreg & DMAy_FLAG) != (uint32_t)RESET)
  {
    /* DMAy_FLAG is set */
    bitstatus = SET;
  }
  else
  {
    /* DMAy_FLAG is reset */
    bitstatus = RESET;
  }

  /* Return the DMAy_FLAG status */
  return  bitstatus;
}

/**
  * @brief  Clears the DMAy Channelx's pending flags.
  * @param  DMAy_FLAG: specifies the flag to clear.
  *          This parameter can be any combination (for the same DMA) of the following values:
  *            @arg DMA_FLAG_GI1: DMA Channel1 global flag.
  *            @arg DMA_FLAG_TC1: DMA Channel1 transfer complete flag.
  *            @arg DMA_FLAG_HT1: DMA Channel1 half transfer flag.
  *            @arg DMA_FLAG_TE1: DMA Channel1 transfer error flag.
  *            @arg DMA_FLAG_GI2: DMA Channel2 global flag.
  *            @arg DMA_FLAG_TC2: DMA Channel2 transfer complete flag.
  *            @arg DMA_FLAG_HT2: DMA Channel2 half transfer flag.
  *            @arg DMA_FLAG_TE2: DMA Channel2 transfer error flag.
  *            @arg DMA_FLAG_GI3: DMA Channel3 global flag.
  *            @arg DMA_FLAG_TC3: DMA Channel3 transfer complete flag.
  *            @arg DMA_FLAG_HT3: DMA Channel3 half transfer flag.
  *            @arg DMA_FLAG_TE3: DMA Channel3 transfer error flag.
  *              
  * @note   Clearing the Global flag (DMAy_FLAG_GLx) results in clearing all other flags
  *         relative to the same channel (Transfer Complete, Half-transfer Complete and
  *         Transfer Error flags: DMAy_FLAG_TCx, DMAy_FLAG_HTx and DMAy_FLAG_TEx).
  *
  * @retval None
  */
void DMA_ClearFlag(uint32_t DMAy_FLAG)
{
  /* Check the parameters */
  assert_param(IS_DMA_CLEAR_FLAG(DMAy_FLAG));

  /* Clear the selected DMAy flags */
  DMA->IFCR = DMAy_FLAG;
}

/**
  * @brief  Checks whether the specified DMAy Channelx interrupt has occurred or not.
  * @param  DMAy_IT: specifies the DMA interrupt source to check. 
  *          This parameter can be one of the following values:
  *            @arg DMA_IT_GI1: DMA Channel1 global interrupt.
  *            @arg DMA_IT_TC1: DMA Channel1 transfer complete interrupt.
  *            @arg DMA_IT_HT1: DMA Channel1 half transfer interrupt.
  *            @arg DMA_IT_TE1: DMA Channel1 transfer error interrupt.
  *            @arg DMA_IT_GI2: DMA Channel2 global interrupt.
  *            @arg DMA_IT_TC2: DMA Channel2 transfer complete interrupt.
  *            @arg DMA_IT_HT2: DMA Channel2 half transfer interrupt.
  *            @arg DMA_IT_TE2: DMA Channel2 transfer error interrupt.
  *            @arg DMA_IT_GI3: DMA Channel3 global interrupt.
  *            @arg DMA_IT_TC3: DMA Channel3 transfer complete interrupt.
  *            @arg DMA_IT_HT3: DMA Channel3 half transfer interrupt.
  *            @arg DMA_IT_TE3: DMA Channel3 transfer error interrupt.
  * @note   The Global interrupt (DMAy_FLAG_GLx) is set whenever any of the other 
  *         interrupts relative to the same channel is set (Transfer Complete, 
  *         Half-transfer Complete or Transfer Error interrupts: DMAy_IT_TCx, 
  *         DMAy_IT_HTx or DMAy_IT_TEx). 
  *      
  * @retval The new state of DMA_IT (SET or RESET).
  */
ITStatus DMA_GetITStatus(uint32_t DMAy_IT)
{
  ITStatus bitstatus = RESET;
  uint32_t tmpreg = 0;

  /* Check the parameters */
  assert_param(IS_DMA_GET_IT(DMAy_IT));

  /* Get DMA1 ISR register value */
  tmpreg = DMA->ISR;

  /* Check the status of the specified DMAy interrupt */
  if ((tmpreg & DMAy_IT) != (uint32_t)RESET)
  {
    /* DMAy_IT is set */
    bitstatus = SET;
  }
  else
  {
    /* DMAy_IT is reset */
    bitstatus = RESET;
  }
  /* Return the DMAy_IT status */
  return  bitstatus;
}

/**
  * @brief  Clears the DMAy Channelx's interrupt pending bits.
  * @param  DMAy_IT: specifies the DMA interrupt pending bit to clear.
  *          This parameter can be any combination (for the same DMA) of the following values:
  *            @arg DMA_IT_GI1: DMA Channel1 global interrupt.
  *            @arg DMA_IT_TC1: DMA Channel1 transfer complete interrupt.
  *            @arg DMA_IT_HT1: DMA Channel1 half transfer interrupt.
  *            @arg DMA_IT_TE1: DMA Channel1 transfer error interrupt.
  *            @arg DMA_IT_GI2: DMA Channel2 global interrupt.
  *            @arg DMA_IT_TC2: DMA Channel2 transfer complete interrupt.
  *            @arg DMA_IT_HT2: DMA Channel2 half transfer interrupt.
  *            @arg DMA_IT_TE2: DMA Channel2 transfer error interrupt.
  *            @arg DMA_IT_GI3: DMA Channel3 global interrupt.
  *            @arg DMA_IT_TC3: DMA Channel3 transfer complete interrupt.
  *            @arg DMA_IT_HT3: DMA Channel3 half transfer interrupt.
  *            @arg DMA_IT_TE3: DMA Channel3 transfer error interrupt.
  *     
  * @note   Clearing the Global interrupt (DMAy_IT_GLx) results in clearing all other 
  *         interrupts relative to the same channel (Transfer Complete, Half-transfer 
  *         Complete and Transfer Error interrupts: DMAy_IT_TCx, DMAy_IT_HTx and 
  *         DMAy_IT_TEx).  
  *        
  * @retval None
  */
void DMA_ClearITPendingBit(uint32_t DMAy_IT)
{
  /* Check the parameters */
  assert_param(IS_DMA_CLEAR_IT(DMAy_IT));

  /* Clear the selected DMAy interrupt pending bits */
  DMA->IFCR = DMAy_IT;
}

/**
  * @}
  */

/**
  * @}
  */

/**
  * @}
  */

/**
  * @}
  */

