/**
 *******************************************************************************
 * @file    dpm32m0xx_dma.h
 *
 * @brief   Header file for DMA firmware driver.
 *
 * @author  DPM
 *
 * @version V1.0.0
 *
 * @date    2023-11-01
 *
 *******************************************************************************/

#ifndef __DPM32M0XX_DMA_H__
#define __DPM32M0XX_DMA_H__



#ifdef __cplusplus
extern "C" {
#endif

#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpadded"
#endif

#include "dpm32m0xx.h"

#if defined (DPM32M08x) || defined (DPM32M05x)



#define DMA_SR()                      REG32(DMA_BASE)                                /*!< the address of DMA channel status register           */
#define DMA_CH_CFG0(channel)          REG32((DMA_BASE + 0x04UL) + 0x10UL*(channel))  /*!< the address of DMA channel configuration 0 register  */
#define DMA_CH_CFG1(channel)          REG32((DMA_BASE + 0x08UL) + 0x10UL*(channel))  /*!< the address of DMA channel configuration 1 register  */
#define DMA_CH_SRC_ADDR(channel)      REG32((DMA_BASE + 0x0CUL) + 0x10UL*(channel))  /*!< the address of DMA channel source addr register      */
#define DMA_CH_DST_ADDR(channel)      REG32((DMA_BASE + 0x10UL) + 0x10UL*(channel))  /*!< the address of DMA channel destination addr register */

/**
 ******************************************************************************
 * @brief DMA channel enumeration.
 *****************************************************************************/
typedef enum
{
  DMA_CH0                             = 0x00UL,   /*!< DMA channel 0. */
  DMA_CH1                             = 0x01UL,   /*!< DMA channel 1. */
#if defined (DPM32M08x)
  DMA_CH2                             = 0x02UL,   /*!< DMA channel 2. */
  DMA_CH3                             = 0x03UL,   /*!< DMA channel 3. */
  DMA_CH4                             = 0x04UL    /*!< DMA channel 4. */
#endif
} DMA_ChannelEnum;

/**
 ******************************************************************************
 * @brief DMA request source enumeration.
 *****************************************************************************/
#if defined (DPM32M08x)
typedef enum
{
  DMA_SW_TRIG_REQ                     =  0UL,            /*!< software trigger DMA request.           */
  DMA_UART0_TX_REQ                    =  1UL,            /*!< UART0 transmission trigger DMA request. */
  DMA_UART0_RX_REQ                    =  2UL,            /*!< UART0 receive trigger DMA request.      */
  DMA_UART1_TX_REQ                    =  3UL,            /*!< UART1 transmission trigger DMA request. */
  DMA_UART1_RX_REQ                    =  4UL,            /*!< UART1 receive trigger DMA request.      */
  DMA_UART2_TX_REQ                    =  5UL,            /*!< UART2 transmission trigger DMA request. */
  DMA_UART2_RX_REQ                    =  6UL,            /*!< UART2 receive trigger DMA request.      */
  DMA_SPI0_TX_REQ                     =  7UL,            /*!< SPI0 transmission trigger DMA request.  */
  DMA_SPI0_RX_REQ                     =  8UL,            /*!< SPI0 receive trigger DMA request.       */
  DMA_SPI1_TX_REQ                     =  9UL,            /*!< SPI1 transmission trigger DMA request.  */
  DMA_SPI1_RX_REQ                     = 10UL,            /*!< SPI1 receive trigger DMA request.       */
  DMA_I2C_TX_REQ                      = 11UL,            /*!< I2C transmission trigger DMA request.   */
  DMA_I2C_RX_REQ                      = 12UL,            /*!< I2C receive trigger DMA request.        */
  DMA_DSP_REQ                         = 13UL,            /*!< DSP trigger DMA request.                */
  DMA_ADC0_EOC_REQ                    = 14UL,            /*!< ADC0 EOC trigger DMA request.           */
  DMA_ADC0_EOS_REQ                    = 15UL,            /*!< ADC0 EOS trigger DMA request.           */
  DMA_ADC0_EOT0_REQ                   = 16UL,            /*!< ADC0 EOT0 trigger DMA request.          */
  DMA_ADC0_EOT1_REQ                   = 17UL,            /*!< ADC0 EOT1 trigger DMA request.          */
  DMA_ADC1_EOC_REQ                    = 18UL,            /*!< ADC1 EOC trigger DMA request.           */
  DMA_ADC1_EOS_REQ                    = 19UL,            /*!< ADC1 EOS trigger DMA request.           */
  DMA_ADC1_EOT0_REQ                   = 20UL,            /*!< ADC1 EOT0 trigger DMA request.          */
  DMA_ADC1_EOT1_REQ                   = 21UL,            /*!< ADC1 EOT1 trigger DMA request.          */
  DMA_TIM0_REQ                        = 22UL,            /*!< TIM0 trigger DMA request.               */
  DMA_TIM1_REQ                        = 23UL,            /*!< TIM1 trigger DMA request.               */
  DMA_TIM2_REQ                        = 24UL,            /*!< TIM2 trigger DMA request.               */
  DMA_TIM3_REQ                        = 25UL,            /*!< TIM3 trigger DMA request.               */
  DMA_TIM4_REQ                        = 26UL,            /*!< TIM4 trigger DMA request.               */
  DMA_TIM5_REQ                        = 27UL,            /*!< TIM5 trigger DMA request.               */
  DMA_CCT0_REQ                        = 28UL,            /*!< CCT0 trigger DMA request.               */
  DMA_CCT1_REQ                        = 29UL,            /*!< CCT1 trigger DMA request.               */
  DMA_EPWM_REQ                        = 30UL             /*!< EPWM trigger DMA request.               */
} DMA_ReqSourceEnum;
#elif defined (DPM32M05x)
typedef enum
{
  DMA_SW_TRIG_REQ                     =  0UL,            /*!< software trigger DMA request.           */
  DMA_UART0_TX_REQ                    =  1UL,            /*!< UART0 transmission trigger DMA request. */
  DMA_UART0_RX_REQ                    =  2UL,            /*!< UART0 receive trigger DMA request.      */
  DMA_UART1_TX_REQ                    =  3UL,            /*!< UART1 transmission trigger DMA request. */
  DMA_UART1_RX_REQ                    =  4UL,            /*!< UART1 receive trigger DMA request.      */
  DMA_SPI0_TX_REQ                     =  7UL,            /*!< SPI0 transmission trigger DMA request.  */
  DMA_SPI0_RX_REQ                     =  8UL,            /*!< SPI0 receive trigger DMA request.       */
  DMA_I2C_TX_REQ                      = 11UL,            /*!< I2C transmission trigger DMA request.   */
  DMA_I2C_RX_REQ                      = 12UL,            /*!< I2C receive trigger DMA request.        */
  DMA_ADC0_EOC_REQ                    = 14UL,            /*!< ADC0 EOC trigger DMA request.           */
  DMA_ADC0_EOS_REQ                    = 15UL,            /*!< ADC0 EOS trigger DMA request.           */
  DMA_ADC0_EOT0_REQ                   = 16UL,            /*!< ADC0 EOT0 trigger DMA request.          */
  DMA_ADC0_EOT1_REQ                   = 17UL,            /*!< ADC0 EOT1 trigger DMA request.          */
  DMA_TIM0_REQ                        = 22UL,            /*!< TIM0 trigger DMA request.               */
  DMA_TIM1_REQ                        = 23UL,            /*!< TIM1 trigger DMA request.               */
  DMA_TIM2_REQ                        = 24UL,            /*!< TIM2 trigger DMA request.               */
  DMA_TIM3_REQ                        = 25UL,            /*!< TIM3 trigger DMA request.               */
  DMA_TIM4_REQ                        = 26UL,            /*!< TIM4 trigger DMA request.               */
  DMA_TIM5_REQ                        = 27UL,            /*!< TIM5 trigger DMA request.               */
  DMA_CCT0_REQ                        = 28UL,            /*!< CCT0 trigger DMA request.               */
  DMA_CCT1_REQ                        = 29UL,            /*!< CCT1 trigger DMA request.               */
  DMA_EPWM_REQ                        = 30UL             /*!< EPWM trigger DMA request.               */
} DMA_ReqSourceEnum;
#endif

/**
 ******************************************************************************
 * @brief  DMA transmission data bit width enumeration.
 *****************************************************************************/
typedef enum
{
  DMA_DATA_SIZE_8                     = 0x00UL,   /*!< DMA transmission data bit width with 8 bit.  */
  DMA_DATA_SIZE_16                    = 0x01UL,   /*!< DMA transmission data bit width with 16 bit. */
  DMA_DATA_SIZE_32                    = 0x02UL    /*!< DMA transmission data bit width with 32 bit. */
} DMA_DataSizeEnum;

/**
 ******************************************************************************
 * @brief  DMA address incremented mode enumeration.
 *****************************************************************************/
typedef enum
{
  DMA_ADDR_MODE_RESET                 = 0x00UL,   /*!< Reset to the initial source address every time a DMA request is triggered.      */
  DMA_ADDR_MODE_INCREASE              = 0x01UL    /*!< Every time a DMA request is triggered,
                                                  The source address is automatically incremented based on the last transmission. */
} DMA_AddrModeEnum;

/**
 ******************************************************************************
 * @brief  DMA interrupt type enumeration.
 *****************************************************************************/
typedef enum
{
  DMA_INT_TYPE_FINISH                 = 0x08UL,   /*!< DMA transmit finish interrupt. */
  DMA_INT_TYPE_ERROR                  = 0x10UL    /*!< DMA transmit error interrupt.  */
} DMA_IntTypeEnum;

/**
 ******************************************************************************
 * @brief  DMA interrupt flag enumeration.
 *****************************************************************************/
typedef enum
{
  DMA_INT_FLAG_FINISH                 = 0x00UL,   /*!< DMA transmit finish. */
  DMA_INT_FLAG_ERROR                  = 0x01UL    /*!< DMA transmit error.  */
} DMA_IntFlagEnum;


/**
 ******************************************************************************
 * @brief  DMA transmit status enumeration.
 *****************************************************************************/
typedef enum
{
  DMA_TRANSMIT_STATUS_IDLE            = 0x00UL,   /*!< DMA transmit idle.                                        */
  DMA_TRANSMIT_STATUS_SRCADDR_ERR     = 0x01UL,   /*!< DMA transmit accessing the source address module error.   */
  DMA_TRANSMIT_STATUS_DSTADDR_ERR     = 0x02UL,   /*!< DMA transmit accessing the distance address module error. */
  DMA_TRANSMIT_STATUS_BUSY            = 0x03UL    /*!< DMA transmit busy.                                        */
} DMA_TransmitStatusEnum;


/**
 ******************************************************************************
 * @brief DMA initialization structure definition.
 *****************************************************************************/
typedef struct
{
  DMA_ReqSourceEnum         DMA_ReqSource;        /*!< Specifies the DMA request source.
                                                       This parameter can be a value of @ref DMA_ReqSourceEnum. */
  uint32_t                  DMA_SrcAddr;          /*!< Specifies the source address.                            */
  uint32_t                  DMA_DstAddr;          /*!< Specifies the destination address.                       */
  DMA_AddrModeEnum          DMA_SrcIncMode;       /*!< Specifies the source address mode.
                                                       This parameter can be a value of @ref DMA_AddrModeEnum.  */
  DMA_AddrModeEnum          DMA_DstIncMode;       /*!< Specifies the destination address mode.
                                                       This parameter can be a value of @ref DMA_AddrModeEnum.  */
  uint16_t                  DMA_RoundNum;         /*!< Specifies the DMA round transmission data number.
                                                       This parameter can be a value of 0~4095.                 */
  uint16_t                  DMA_DataNum;          /*!< Specifies the DMA transmission data number.
                                                       This parameter can be a value of 0~65535.                */
  DMA_DataSizeEnum          DMA_DataSize;         /*!< Specifies the DMA transmission data size.
                                                       This parameter can be a value of @ref DMA_DataSizeEnum.  */
  FunctionalState           DMA_ErrIntState;      /*!< Specifies the error interrupt state.
                                                       This parameter can be a value of @ref FunctionalState.   */
  FunctionalState           DMA_FISIntState;      /*!< Specifies the finish interrupt state.
                                                       This parameter can be a value of @ref FunctionalState.   */
  FunctionalState           DMA_CICRState;        /*!< Specifies the CICR state.
                                                       This parameter can be a value of @ref FunctionalState.   */
} DMA_InitTypeStruct;


/* DMA param check. */
#if defined (DPM32M08x)
#define IS_DMA_CHANNEL(x)        (((x) == DMA_CH0) || \
                                  ((x) == DMA_CH1) || \
                                  ((x) == DMA_CH2) || \
                                  ((x) == DMA_CH3) || \
                                  ((x) == DMA_CH4))

#define IS_DMA_REQ_SOURCE(x)     (((x) == DMA_SW_TRIG_REQ) || \
                                  ((x) == DMA_UART0_TX_REQ) || \
                                  ((x) == DMA_UART0_RX_REQ) || \
                                  ((x) == DMA_UART1_TX_REQ) || \
                                  ((x) == DMA_UART1_RX_REQ) || \
                                  ((x) == DMA_UART2_TX_REQ) || \
                                  ((x) == DMA_UART2_RX_REQ) || \
                                  ((x) == DMA_SPI0_TX_REQ) || \
                                  ((x) == DMA_SPI0_RX_REQ) || \
                                  ((x) == DMA_I2C_TX_REQ) || \
                                  ((x) == DMA_I2C_RX_REQ) || \
                                  ((x) == DMA_DSP_REQ) || \
                                  ((x) == DMA_ADC0_EOC_REQ) || \
                                  ((x) == DMA_ADC0_EOS_REQ) || \
                                  ((x) == DMA_ADC0_EOT0_REQ) || \
                                  ((x) == DMA_ADC0_EOT1_REQ) || \
                                  ((x) == DMA_ADC1_EOC_REQ) || \
                                  ((x) == DMA_ADC1_EOS_REQ) || \
                                  ((x) == DMA_ADC1_EOT0_REQ) || \
                                  ((x) == DMA_ADC1_EOT1_REQ) || \
                                  ((x) == DMA_TIM0_REQ) || \
                                  ((x) == DMA_TIM1_REQ) || \
                                  ((x) == DMA_TIM2_REQ) || \
                                  ((x) == DMA_TIM3_REQ) || \
                                  ((x) == DMA_TIM4_REQ) || \
                                  ((x) == DMA_TIM5_REQ) || \
                                  ((x) == DMA_CCT0_REQ) || \
                                  ((x) == DMA_CCT1_REQ) || \
                                  ((x) == DMA_EPWM_REQ))
#elif defined (DPM32M05x)
#define IS_DMA_CHANNEL(x)        (((x) == DMA_CH0) || \
                                  ((x) == DMA_CH1))

#define IS_DMA_REQ_SOURCE(x)     (((x) == DMA_SW_TRIG_REQ) || \
                                  ((x) == DMA_UART0_TX_REQ) || \
                                  ((x) == DMA_UART0_RX_REQ) || \
                                  ((x) == DMA_UART1_TX_REQ) || \
                                  ((x) == DMA_UART1_RX_REQ) || \
                                  ((x) == DMA_SPI0_TX_REQ) || \
                                  ((x) == DMA_SPI0_RX_REQ) || \
                                  ((x) == DMA_I2C_TX_REQ) || \
                                  ((x) == DMA_I2C_RX_REQ) || \
                                  ((x) == DMA_ADC0_EOC_REQ) || \
                                  ((x) == DMA_ADC0_EOS_REQ) || \
                                  ((x) == DMA_ADC0_EOT0_REQ) || \
                                  ((x) == DMA_ADC0_EOT1_REQ) || \
                                  ((x) == DMA_TIM0_REQ) || \
                                  ((x) == DMA_TIM1_REQ) || \
                                  ((x) == DMA_TIM2_REQ) || \
                                  ((x) == DMA_TIM3_REQ) || \
                                  ((x) == DMA_TIM4_REQ) || \
                                  ((x) == DMA_TIM5_REQ) || \
                                  ((x) == DMA_CCT0_REQ) || \
                                  ((x) == DMA_CCT1_REQ) || \
                                  ((x) == DMA_EPWM_REQ))
#endif

#define IS_DMA_DATA_SIZE(x)      (((x) == DMA_DATA_SIZE_8) || \
                                  ((x) == DMA_DATA_SIZE_16) || \
                                  ((x) == DMA_DATA_SIZE_32))


#define IS_DMA_ADDR_MODE(x)      (((x) == DMA_ADDR_MODE_RESET) || \
                                  ((x) == DMA_ADDR_MODE_INCREASE))



/* Deinitializes,initialization and cmd functions. */
void                    DMA_DeInit(DMA_ChannelEnum DMA_Channel);
void                    DMA_Init(DMA_ChannelEnum DMA_Channel, DMA_InitTypeStruct* DMA_InitType);
void                    DMA_StructInit(DMA_InitTypeStruct* DMA_InitType);
void                    DMA_Cmd(DMA_ChannelEnum DMA_Channel, FunctionalState NewState);

/* Software trigger transmit functions. */
void                    DMA_SoftTriggerTransmit(DMA_ChannelEnum DMA_Channel);

/* Data counter functions. */
void                    DMA_SetDataNum(DMA_ChannelEnum DMA_Channel, uint16_t DataNum);
uint16_t                DMA_GetDataNum(DMA_ChannelEnum DMA_Channel);

/* Data round functions. */
void                    DMA_SetRoundNum(DMA_ChannelEnum DMA_Channel, uint16_t RoundNum);
uint16_t                DMA_GetRoundNum(DMA_ChannelEnum DMA_Channel);

/* DMA interrupt related functions. */
void                    DMA_IntCmd(DMA_ChannelEnum DMA_Channel, DMA_IntTypeEnum DMA_IntType, FunctionalState NewState);
FunctionalState         DMA_GetIntCmdStatus(DMA_ChannelEnum DMA_Channel, DMA_IntTypeEnum DMA_IntType);
FlagState               DMA_GetIntFlagStatus(DMA_ChannelEnum DMA_Channel, DMA_IntFlagEnum DMA_IntFlag);
void                    DMA_ClearIntFlag(DMA_ChannelEnum DMA_Channel, DMA_IntFlagEnum DMA_IntFlag);
DMA_TransmitStatusEnum  DMA_GetTransmitStatus(DMA_ChannelEnum DMA_Channel);



#endif /* DPM32M08x || DPM32M05x */

#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang diagnostic pop
#endif

#ifdef __cplusplus
}
#endif

#endif /* __DPM32M0XX_DMA_H__ */
