  /**
  ******************************************************************************
  * @file    kpm32xx_ddl_dma.c
  * @author  Kiwi Software Team
  * @brief   DMA DDL module driver.
  *          This file provides firmware functions to manage the following
  *          functionalities of the DMA peripheral:
  *          1.peripheral initializes
  *          2.data transfer without CPU
  * @note
  *          V1.0.0, 2024/12/20.
  *
  * Copyright (c) 2024, Kiwi Instruments Co,. Ltd.
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *
  *   3. Neither the name of the copyright holder nor the names of its contributors
  *      may be used to endorse or promote products derived from this software without
  *      specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
  * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  * THE POSSIBILITY OF SUCH DAMAGE.
  ******************************************************************************
  */


#include <string.h>
#include "kpm32xx_ddl.h"



#ifdef DDL_DMA_MODULE_ENABLED

typedef struct
{
	__IO uint32_t CH_SRC;                        /* DMA channel source register, address offset: 0x100      */
	__IO uint32_t CH_DST;                        /* DMA channel destination register, address offset: 0x104 */
	__IO uint32_t CH_CTRL;                       /* DMA channel control register, address offset: 0x108     */
} DMA_Channel_T;

typedef struct
{
	DMA_ChannelIndex_T      channelIndex;        /* DMA channel index                    */
	DMA_DeviceIndex_T       deviceIndex;         /* Device index request for DMA channel */
	DMA_DeviceRequest_T     requestType;         /* Device type request for DMA channel  */
} DMA_ChannelMap_T;

typedef struct
{
	DMA_ChannelIndex_T      channelIndex;         /* DMA channel index          */
	uint8_t                 used;                 /* The channel is used or not */
} DMA_ChannelStatus_T;

#define DDL_TIMEOUT_DMA_ABORT    5U                   /* 5 ms */


/* DMA channel map table */
static const DMA_ChannelMap_T channelMap[DDL_DMA_CHANNEL_NUM][DDL_DMA_DEVICE_NUM] =
{
	/* channel 0 */
	{
	{DMA_CHANNEL_0, DMA_DEVICE_0, SCI0_DMA_TX},
	{DMA_CHANNEL_0, DMA_DEVICE_1, SCI1_DMA_TX},
	{DMA_CHANNEL_0, DMA_DEVICE_2, SCI2_DMA_TX},
	{DMA_CHANNEL_0, DMA_DEVICE_3, MEM_TO_MEM},
	{DMA_CHANNEL_0, DMA_DEVICE_4, IIC0_DMA_TX},
	{DMA_CHANNEL_0, DMA_DEVICE_5, IIC1_DMA_TX},
	{DMA_CHANNEL_0, DMA_DEVICE_6, SPI0_DMA_TX},
	{DMA_CHANNEL_0, DMA_DEVICE_7, DNU_CH0},
	{DMA_CHANNEL_0, DMA_DEVICE_8, ADC0_DMA_RX},
	{DMA_CHANNEL_0, DMA_DEVICE_9, TIMA0_UD},
	{DMA_CHANNEL_0, DMA_DEVICE_10, MEM_TO_MEM},
	{DMA_CHANNEL_0, DMA_DEVICE_11, TIMA2_TD},
	{DMA_CHANNEL_0, DMA_DEVICE_12, TIMG0_TD},
	{DMA_CHANNEL_0, DMA_DEVICE_13, TIMG1_CC3D},
	{DMA_CHANNEL_0, DMA_DEVICE_14, TIMG2_CC2D},
	{DMA_CHANNEL_0, DMA_DEVICE_15, MEM_TO_MEM}
	},
	/* channel 1 */
	{
	{DMA_CHANNEL_1, DMA_DEVICE_0, SCI0_DMA_RX},
	{DMA_CHANNEL_1, DMA_DEVICE_1, SCI1_DMA_RX},
	{DMA_CHANNEL_1, DMA_DEVICE_2, SCI2_DMA_RX},
	{DMA_CHANNEL_1, DMA_DEVICE_3, MEM_TO_MEM},
	{DMA_CHANNEL_1, DMA_DEVICE_4, IIC0_DMA_RX},
	{DMA_CHANNEL_1, DMA_DEVICE_5, IIC1_DMA_RX},
	{DMA_CHANNEL_1, DMA_DEVICE_6, SPI0_DMA_RX},
	{DMA_CHANNEL_1, DMA_DEVICE_7, DNU_CH1},
	{DMA_CHANNEL_1, DMA_DEVICE_8, ADC1_DMA_RX},
	{DMA_CHANNEL_1, DMA_DEVICE_9, TIMA0_CC0D},
	{DMA_CHANNEL_1, DMA_DEVICE_10, TIMA1_UD},
	{DMA_CHANNEL_1, DMA_DEVICE_11, MEM_TO_MEM},
	{DMA_CHANNEL_1, DMA_DEVICE_12, MEM_TO_MEM},
	{DMA_CHANNEL_1, DMA_DEVICE_13, TIMG1_TD},
	{DMA_CHANNEL_1, DMA_DEVICE_14, TIMG2_CC3D},
	{DMA_CHANNEL_1, DMA_DEVICE_15, MEM_TO_MEM}
	},
	/* channel 2 */
	{
	{DMA_CHANNEL_2, DMA_DEVICE_0, SCI0_DMA_TX},
	{DMA_CHANNEL_2, DMA_DEVICE_1, SCI1_DMA_TX},
	{DMA_CHANNEL_2, DMA_DEVICE_2, SCI2_DMA_TX},
	{DMA_CHANNEL_2, DMA_DEVICE_3, MEM_TO_MEM},
	{DMA_CHANNEL_2, DMA_DEVICE_4, IIC0_DMA_TX},
	{DMA_CHANNEL_2, DMA_DEVICE_5, IIC1_DMA_TX},
	{DMA_CHANNEL_2, DMA_DEVICE_6, SPI0_DMA_TX},
	{DMA_CHANNEL_2, DMA_DEVICE_7, DNU_CH2},
	{DMA_CHANNEL_2, DMA_DEVICE_8, ADC0_DMA_RX},
	{DMA_CHANNEL_2, DMA_DEVICE_9, TIMA0_CC1D},
	{DMA_CHANNEL_2, DMA_DEVICE_10, TIMA1_CC0D},
	{DMA_CHANNEL_2, DMA_DEVICE_11, TIMA2_UD},
	{DMA_CHANNEL_2, DMA_DEVICE_12, MEM_TO_MEM},
	{DMA_CHANNEL_2, DMA_DEVICE_13, MEM_TO_MEM},
	{DMA_CHANNEL_2, DMA_DEVICE_14, TIMG2_TD},
	{DMA_CHANNEL_2, DMA_DEVICE_15, MEM_TO_MEM}
	},
	/* channel 3 */
	{
	{DMA_CHANNEL_3, DMA_DEVICE_0, SCI0_DMA_RX},
	{DMA_CHANNEL_3, DMA_DEVICE_1, SCI1_DMA_RX},
	{DMA_CHANNEL_3, DMA_DEVICE_2, SCI2_DMA_RX},
	{DMA_CHANNEL_3, DMA_DEVICE_3, MEM_TO_MEM},
	{DMA_CHANNEL_3, DMA_DEVICE_4, IIC0_DMA_RX},
	{DMA_CHANNEL_3, DMA_DEVICE_5, IIC1_DMA_RX},
	{DMA_CHANNEL_3, DMA_DEVICE_6, SPI0_DMA_RX},
	{DMA_CHANNEL_3, DMA_DEVICE_7, MEM_TO_MEM},
	{DMA_CHANNEL_3, DMA_DEVICE_8, ADC1_DMA_RX},
	{DMA_CHANNEL_3, DMA_DEVICE_9, TIMA0_CC2D},
	{DMA_CHANNEL_3, DMA_DEVICE_10, TIMA1_CC1D},
	{DMA_CHANNEL_3, DMA_DEVICE_11, TIMA2_CC0D},
	{DMA_CHANNEL_3, DMA_DEVICE_12, TIMG0_UD},
	{DMA_CHANNEL_3, DMA_DEVICE_13, MEM_TO_MEM},
	{DMA_CHANNEL_3, DMA_DEVICE_14, MEM_TO_MEM},
	{DMA_CHANNEL_3, DMA_DEVICE_15, MEM_TO_MEM}
	},
	/* channel 4 */
	{
	{DMA_CHANNEL_4, DMA_DEVICE_0, SCI0_DMA_TX},
	{DMA_CHANNEL_4, DMA_DEVICE_1, SCI1_DMA_TX},
	{DMA_CHANNEL_4, DMA_DEVICE_2, SCI2_DMA_TX},
	{DMA_CHANNEL_4, DMA_DEVICE_3, MEM_TO_MEM},
	{DMA_CHANNEL_4, DMA_DEVICE_4, IIC0_DMA_TX},
	{DMA_CHANNEL_4, DMA_DEVICE_5, IIC1_DMA_TX},
	{DMA_CHANNEL_4, DMA_DEVICE_6, SPI0_DMA_TX},
	{DMA_CHANNEL_4, DMA_DEVICE_7, MEM_TO_MEM},
	{DMA_CHANNEL_4, DMA_DEVICE_8, ADC0_DMA_RX},
	{DMA_CHANNEL_4, DMA_DEVICE_9, TIMA0_CC3D},
	{DMA_CHANNEL_4, DMA_DEVICE_10, TIMA1_CC2D},
	{DMA_CHANNEL_4, DMA_DEVICE_11, TIMA2_CC1D},
	{DMA_CHANNEL_4, DMA_DEVICE_12, TIMG0_CC0D},
	{DMA_CHANNEL_4, DMA_DEVICE_13, TIMG1_UD},
	{DMA_CHANNEL_4, DMA_DEVICE_14, MEM_TO_MEM},
	{DMA_CHANNEL_4, DMA_DEVICE_15, MEM_TO_MEM}
	},
	/* channel 5 */
	{
	{DMA_CHANNEL_5, DMA_DEVICE_0, SCI0_DMA_RX},
	{DMA_CHANNEL_5, DMA_DEVICE_1, SCI1_DMA_RX},
	{DMA_CHANNEL_5, DMA_DEVICE_2, SCI2_DMA_RX},
	{DMA_CHANNEL_5, DMA_DEVICE_3, MEM_TO_MEM},
	{DMA_CHANNEL_5, DMA_DEVICE_4, IIC0_DMA_RX},
	{DMA_CHANNEL_5, DMA_DEVICE_5, IIC1_DMA_RX},
	{DMA_CHANNEL_5, DMA_DEVICE_6, SPI0_DMA_RX},
	{DMA_CHANNEL_5, DMA_DEVICE_7, MEM_TO_MEM},
	{DMA_CHANNEL_5, DMA_DEVICE_8, ADC1_DMA_RX},
	{DMA_CHANNEL_5, DMA_DEVICE_9, TIMA0_COMD},
	{DMA_CHANNEL_5, DMA_DEVICE_10, TIMA1_CC3D},
	{DMA_CHANNEL_5, DMA_DEVICE_11, TIMA2_CC2D},
	{DMA_CHANNEL_5, DMA_DEVICE_12, TIMG0_CC1D},
	{DMA_CHANNEL_5, DMA_DEVICE_13, TIMG1_CC0D},
	{DMA_CHANNEL_5, DMA_DEVICE_14, TIMG2_UD},
	{DMA_CHANNEL_5, DMA_DEVICE_15, MEM_TO_MEM}
	},
	/* channel 6 */
	{
	{DMA_CHANNEL_6, DMA_DEVICE_0, SCI0_DMA_TX},
	{DMA_CHANNEL_6, DMA_DEVICE_1, SCI1_DMA_TX},
	{DMA_CHANNEL_6, DMA_DEVICE_2, SCI2_DMA_TX},
	{DMA_CHANNEL_6, DMA_DEVICE_3, MEM_TO_MEM},
	{DMA_CHANNEL_6, DMA_DEVICE_4, IIC0_DMA_TX},
	{DMA_CHANNEL_6, DMA_DEVICE_5, IIC1_DMA_TX},
	{DMA_CHANNEL_6, DMA_DEVICE_6, SPI0_DMA_TX},
	{DMA_CHANNEL_6, DMA_DEVICE_7, MEM_TO_MEM},
	{DMA_CHANNEL_6, DMA_DEVICE_8, ADC0_DMA_RX},
	{DMA_CHANNEL_6, DMA_DEVICE_9, TIMA0_TD},
	{DMA_CHANNEL_6, DMA_DEVICE_10, TIMA1_COMD},
	{DMA_CHANNEL_6, DMA_DEVICE_11, TIMA2_CC3D},
	{DMA_CHANNEL_6, DMA_DEVICE_12, TIMG0_CC2D},
	{DMA_CHANNEL_6, DMA_DEVICE_13, TIMG1_CC1D},
	{DMA_CHANNEL_6, DMA_DEVICE_14, TIMG2_CC0D},
	{DMA_CHANNEL_6, DMA_DEVICE_15, MEM_TO_MEM}
	},
	/* channel 7 */
	{
	{DMA_CHANNEL_7, DMA_DEVICE_0, SCI0_DMA_RX},
	{DMA_CHANNEL_7, DMA_DEVICE_1, SCI1_DMA_RX},
	{DMA_CHANNEL_7, DMA_DEVICE_2, SCI2_DMA_RX},
	{DMA_CHANNEL_7, DMA_DEVICE_3, MEM_TO_MEM},
	{DMA_CHANNEL_7, DMA_DEVICE_4, IIC0_DMA_RX},
	{DMA_CHANNEL_7, DMA_DEVICE_5, IIC1_DMA_RX},
	{DMA_CHANNEL_7, DMA_DEVICE_6, SPI0_DMA_RX},
	{DMA_CHANNEL_7, DMA_DEVICE_7, MEM_TO_MEM},
	{DMA_CHANNEL_7, DMA_DEVICE_8, ADC1_DMA_RX},
	{DMA_CHANNEL_7, DMA_DEVICE_9, MEM_TO_MEM},
	{DMA_CHANNEL_7, DMA_DEVICE_10, TIMA1_TD},
	{DMA_CHANNEL_7, DMA_DEVICE_11, TIMA2_COMD},
	{DMA_CHANNEL_7, DMA_DEVICE_12, TIMG0_CC3D},
	{DMA_CHANNEL_7, DMA_DEVICE_13, TIMG1_CC2D},
	{DMA_CHANNEL_7, DMA_DEVICE_14, TIMG2_CC1D},
	{DMA_CHANNEL_7, DMA_DEVICE_15, MEM_TO_MEM}
	},
};


/**
  * @brief  Makes DMA active.
  * @param  none
  * 
  * @retval none
  */
void DDL_DMA_Instance_Active(void)
{
	/* Clock and Reset */
	__DDL_RCC_DMA_ACTIVE();
    __DDL_RCC_DMA_CLK_RELEASE();
}


/**
  * @brief  Return the DMA channel base address depending on channel number.
  * @param  DMAx  DMAx Pointer to DMA instance.
  * @param  channel DMA channel select.
  * @retval channelAddr  base address
  */
static uint32_t DMA_CalcChannelBaseAddr(DMA_Type *DMAx, DMA_ChannelIndex_T channel)
{
	uint32_t channelAddr = 0;

	channelAddr = (uint32_t)(DMA_CHANNEL_BASE + (channel * 0x10));

	return channelAddr;
}


/**
  * @brief  enable channel config hold feature .
  * @param  DMAx  DMAx Pointer to DMA instance.
  * @param  channel DMA channel select.
  * @retval DDL status
  */
DDL_Status_T DDL_DMA_EnableChannelCfgHold(DMA_Type *DMAx, DMA_ChannelIndex_T channel)
{
	DMA_Channel_T * channelAddr;

	channelAddr = (DMA_Channel_T *)(DMA_CHANNEL_BASE + (channel * 0x10));
    SET_BIT(channelAddr->CH_CTRL, DMA_CHCTRL_CFGHOLDEN);

	return DDL_OK;
}


/**
  * @brief  disable channel config hold feature.
  * @param  DMAx  DMAx Pointer to DMA instance.
  * @param  channel DMA channel select.
  * @retval DDL status
  */
DDL_Status_T DDL_DMA_DisableChannelCfgHold(DMA_Type *DMAx, DMA_ChannelIndex_T channel)
{
	DMA_Channel_T * channelAddr;

	channelAddr = (DMA_Channel_T *)(DMA_CHANNEL_BASE + (channel * 0x10));
    CLEAR_BIT(channelAddr->CH_CTRL, DMA_CHCTRL_CFGHOLDEN);

	return DDL_OK;
}


/**
  * @brief  Set the DMA channel Transfer parameter.
  * @param  DMAx  DMAx Pointer to DMA instance.
  * @param  channel DMA channel select.
  * @param  pDMAStruct Pointer to a DMA_Init_T structure that contains
  *         the configuration information for the given DMA module.
  * @retval DDL status
  */
void DDL_DMA_SetChannelConfig(DMA_Type *DMAx, DMA_ChannelIndex_T channel, DMA_ChannelConfig_T *pDMAStruct)
{
	uint32_t byteSize = 0;
	DMA_Channel_T *base = NULL;
	uint32_t srcEndAddr = 0, dstEndAddr = 0;

	if (pDMAStruct->dataAlignment == DMA_DATAALIGN_WORD)
	{
		byteSize = (pDMAStruct->dataLength - 1) << 2;
	}
	else if (pDMAStruct->dataAlignment == DMA_DATAALIGN_HALFWORD)
	{
		byteSize = (pDMAStruct->dataLength - 1) << 1;
	}
	else
	{
		byteSize = pDMAStruct->dataLength - 1;
	}

	/* Calculate end address */
	if (pDMAStruct->increment == DMA_SRC_INC_DST_INC)
	{
		srcEndAddr = pDMAStruct->srcAddress + byteSize;
		dstEndAddr = pDMAStruct->dstAddress + byteSize;
	}
	else if (pDMAStruct->increment == DMA_SRC_KEEP_DST_INC)
	{
		srcEndAddr = pDMAStruct->srcAddress;
		dstEndAddr = pDMAStruct->dstAddress + byteSize;
	}
	else if (pDMAStruct->increment == DMA_SRC_INC_DST_KEEP)
	{
		srcEndAddr = pDMAStruct->srcAddress + byteSize;
		dstEndAddr = pDMAStruct->dstAddress;
	}

	/* Calculate channel base address */
	base = (DMA_Channel_T *)DMA_CalcChannelBaseAddr(DMAx,channel);

	/* Set DMA transmit type */
	__DDL_DMA_SET_CHANNEL_TRANSMIT_TYPE(base, pDMAStruct->transmitType);

	/* Set arbit interval */
	__DDL_DMA_SET_CHANNEL_ARBIT_INTERVAL(base, pDMAStruct->arbitInterval);

	/* Set data alignment */
	__DDL_DMA_SET_CHANNEL_DATA_SIZE(base ,pDMAStruct->dataAlignment);

	/* Configure DMA Stream data length */
	MODIFY_REG(base->CH_CTRL, DMA_CHCTRL_DATALENGTH_Mask, (pDMAStruct->dataLength - 1) << DMA_CHCTRL_DATALENGTH_Pos);

	/* Configure source end address and destination end address */
	__DDL_DMA_SET_CHANNEL_SRC_END_ADDR(base, srcEndAddr);
	__DDL_DMA_SET_CHANNEL_DST_END_ADDR(base, dstEndAddr);
}


/**
  * @brief  Configure the elements of structure DMA_Init_T to default values.
  * @param  pDMAStruct Pointer to a DMA_Init_T structure that contains
  *                  the configuration information for the given DMA module.
  *
  * @retval None
  */
void DDL_DMA_StructInit(void)
{    
	
}

/**
  * @brief  Configure the elements of channel structure DMA_Init_T to default values.
  * @param  pDMAStruct Pointer to a DMA_Init_T structure that contains
  *                  the configuration information for the given DMA module.
  *
  * @retval None
  */
void DDL_DMA_ChannelStructInit(DMA_ChannelConfig_T *pDMAStruct)
{
    pDMAStruct->arbitInterval = DMA_ARBIT_INTERVAL_1;
    pDMAStruct->ebusEnable = RESET;
    pDMAStruct->priority = DMA_PRIORITY_NORMAL;
    pDMAStruct->transmitType = DMA_TRANSMIT_AUTO;
	pDMAStruct->increment = DMA_SRC_INC_DST_INC;
	pDMAStruct->dataAlignment = DMA_DATAALIGN_WORD;
    pDMAStruct->srcAddress = 0;
    pDMAStruct->dstAddress = 0;
    pDMAStruct->dataLength = 0;
}




/**
  * @brief  Initialize the DMA according to the specified
  *         parameters in the DMA_Init_T and create the associated handle.
  * @param  DMAx  DMAx Pointer to DMA instance.
  * @retval None
  */
void DDL_DMA_Init(DMA_Type *DMAx)
{
	if (!(DMAx->STATUS & 0x01))
	{
		__DDL_DMA_ENABLE(DMAx);
	}
}

/**
  * @brief  Stop the DMA channel
  * @param  DMAx  DMAx Pointer to DMA instance.
  * @retval None
  */
void DDL_DMA_ChannelStop(DMA_Type *DMAx, DMA_ChannelIndex_T channel)
{
    /* Disable the specified channel. */
    __DDL_DMA_CHANNEL_DISABLE(DMAx, channel);
}


/**
  * @brief  Enable DMA interrupt with specified type.
  * @param  DMAx      DMA instance.
  * @param  channel   DMA channel select.
  *
  * @retval None.
  */
void DDL_DMA_IntEnable(DMA_Type* DMAx, DMA_ChannelIndex_T channel)
{
    /* Enable the interrupt */
    __DDL_DMA_CLEAR_IT_FLAG(DMAx, (0x1UL << channel));
    __DDL_DMA_ENABLE_IT(DMAx, (0x1UL << channel));
}


/**
  * @brief  Enable DMA interrupt with specified type.
  * @param  DMAx      DMA instance.
  * @param  channel   DMA channel select.
  *
  * @retval None.
  */
void DDL_DMA_IntDisable(DMA_Type* DMAx, DMA_ChannelIndex_T channel)
{
    /* Disable the selected DMA channel */
	__DDL_DMA_DISABLE_IT(DMAx, (0x1UL << channel));
	__DDL_DMA_CLEAR_IT_FLAG(DMAx, (0x1UL << channel));
	NVIC_DisableIRQ(DMA_IRQn);
}


/**
  * @brief  Start the DMA Transfer without interrupt.
  * @param  DMAx  DMAx Pointer to DMA instance.
  * @param  channel DMA channel select.
  * @param  device DMA device select.
  * @param  pDMAStruct Pointer to a DMA_Init_T structure that contains
  *         the configuration information for the given DMA module.
  * @retval None
  * @note   This API will not generate DMA interrupt when DMA transfer complete, it only
  *         uses in the case : the other IP will generate interrupt when operate finish.
  */
void DDL_DMA_ChannelStart(DMA_Type* DMAx, DMA_ChannelIndex_T channel, DMA_DeviceIndex_T device, DMA_ChannelConfig_T *pDMAStruct)
{
    /* Set channel address control policy */
	SET_BITMASK(DMAx->ADDR_KEEP, (0x3UL << (channel * 2)), ((pDMAStruct->increment) << (channel * 2)));

	/* Set channel priority */
	if (pDMAStruct->priority == DMA_PRIORITY_HIGH)
	{
		__DDL_DMA_SET_HIGH_PRIORITY(DMAx, (0x1UL << channel));
	}
	else
	{
		__DDL_DMA_CLEAR_HIGH_PRIORITY(DMAx, (0x1UL << channel));
	}

	/* channel select device */
	if (pDMAStruct->ebusEnable == RESET)
	{
		SET_BITMASK(DMAx->CH_SEL, (0xFUL << (channel * 4)), (device << (channel * 4)));
	}

	/* EBUS configuration for DMA */
	if (pDMAStruct->ebusEnable != RESET)
	{
		SET_BITMASK(DMAx->EBUS_CTRL, 0x7U << (channel * 4), pDMAStruct->ebusEvent << (channel * 4));
		/* Enable EBUS */
		CLEAR_BIT(DMAx->EBUS_CTRL, 0x1U << (channel * 4 + 3));
	}

	/* Enable the specified channel */
	__DDL_DMA_CHANNEL_ENABLE(DMAx, (0x1UL << channel));
	if ((channelMap[channel][device].requestType == MEM_TO_MEM) && (pDMAStruct->ebusEnable == RESET))
	{
		__DDL_DMA_SOFT_REQUEST_SET(DMAx, (0x1UL << channel));
	}
	else
	{
		__DDL_DMA_MASK_REQUEST_CLEAR(DMAx, (0x1UL << channel));
	}
}

#endif /** DDL_DMA_MODULE_ENABLED */
