#include "cpu_dma.h"

#define DMA_CHANNEL_0_BIT								    ((uint32_t)0x0001)
#define DMA_CHANNEL_1_BIT								    ((uint32_t)0x0002)
#define DMA_CHANNEL_2_BIT								    ((uint32_t)0x0004)
#define DMA_CHANNEL_3_BIT								    ((uint32_t)0x0008)

/************ operation definition for DMA  DMA_CTL_H REGISTER ************/
#define DMA_CTL_BLOCK_TS_Pos								(0)
#define DMA_CTL_BLOCK_TS_Mask								(0x0fffU<<DMA_CTL_BLOCK_TS_Pos)

/************ operation definition for DMA  DMA_CTL_L REGISTER ************/
#define DMA_CTL_TT_FC_Pos									(20)
#define DMA_CTL_TT_FC_Mask									(0x07U<<DMA_CTL_TT_FC_Pos)

#define DMA_CTL_TT_FC_Memory_to_Memory_Set					(0x00U<<DMA_CTL_TT_FC_Pos)
#define DMA_CTL_TT_FC_Memory_to_Peripheral_Set				(0x01U<<DMA_CTL_TT_FC_Pos)
#define DMA_CTL_TT_FC_Peripheral_to_Memory_Set				(0x02U<<DMA_CTL_TT_FC_Pos)
#define DMA_CTL_TT_FC_Peripheral_to_Memory_P_Set			(0x04U<<DMA_CTL_TT_FC_Pos)
#define DMA_CTL_TT_FC_Memory_to_Peripheral_P_Set			(0x06U<<DMA_CTL_TT_FC_Pos)

#define DMA_CTL_SRC_MSIZE_Pos								(14)
#define DMA_CTL_SRC_MSIZE_Mask								(0x07U<<DMA_CTL_SRC_MSIZE_Pos)

#define DMA_CTL_DEST_MSIZE_Pos								(11)
#define DMA_CTL_DEST_MSIZE_Mask								(0x07U<<DMA_CTL_DEST_MSIZE_Pos)

#define DMA_CTL_SINC_Pos									(9)
#define DMA_CTL_SINC_Mask									(0x03U<<DMA_CTL_SINC_Pos)

#define DMA_CTL_DINC_Pos									(7)
#define DMA_CTL_DINC_Mask									(0x03U<<DMA_CTL_DINC_Pos)

#define DMA_CTL_SRC_TR_WIDTH_Pos							(4)
#define DMA_CTL_SRC_TR_WIDTH_Mask							(0x07U<<DMA_CTL_SRC_TR_WIDTH_Pos)

#define DMA_CTL_DST_TR_WIDTH_Pos							(1)
#define DMA_CTL_DST_TR_WIDTH_Mask							(0x07U<<DMA_CTL_DST_TR_WIDTH_Pos)

#define DMA_CTL_INT_EN_Set									((uint32_t)0x01)

/************ operation definition for DMA  DMA_CFG_L REGISTER ************/
#define DMA_CFG_HS_SEL_SRC_Pos								(11)
#define DMA_CFG_HS_SEL_SRC_Mask								(0x01U<<DMA_CFG_HS_SEL_SRC_Pos)//0 HARD 1 SOFT

#define DMA_CFG_HS_SEL_DST_Pos								(10)
#define DMA_CFG_HS_SEL_DST_Mask								(0x01U<<DMA_CFG_HS_SEL_DST_Pos)

/************ operation definition for DMA  DMA_CFG_H REGISTER ************/
#define DMA_CFG_DEST_PER_Pos								(12)
#define DMA_CFG_DEST_PER_Mask								(0x03U<<DMA_CFG_DEST_PER_Pos)//need write current channel num

#define DMA_CFG_SRC_PER_Pos									(7)
#define DMA_CFG_SRC_PER_Mask								(0x03U<<DMA_CFG_SRC_PER_Pos)//need write current channel num

extern void sysctrl_dma_channel_config(dma_type_def* dma_channelx, uint32_t dma_peripheral, uint32_t dma_dir);

void dma_channe_config(dma_type_def* dma_channelx, uint32_t dma_peripheral, uint32_t dma_dir);

typedef struct
{
	uint32_t dma_addr; 
	uint32_t dma_tr_width;
	uint32_t dma_inc;
	uint32_t dma_handshake;
	uint32_t dma_msize;
}dma_peripheral_info_def;

typedef enum
{
	dma_peripheral_type_peripheral = ((uint32_t)0x0001),
	dma_peripheral_type_memory
}dma_peripheral_type_def;

/*******************************************************************************
* 函数名   : dma_get_peripheral_config.
* 说明     : 获取DMA外部配置
* 参数     : -dma_peripheral_info_struct,    DMA参数，参考 dma_peripheral_info_def 定义
             -dma_init_struct,  			 DMA初始化参数,参考 dma_init_type_def 定义
             -dma_peripheral_type, 			 DMA传输类型,参考 dma_peripheral_type_def 定义
* 返回值   : None.
* 示例     : dma_get_peripheral_config(&DMA_SRC, dma_peripheral, dma_peripheral_type_memory);
*******************************************************************************/
static void dma_get_peripheral_config(dma_peripheral_info_def *dma_peripheral_info_struct,
									dma_init_type_def *dma_init_struct, 
									dma_peripheral_type_def dma_peripheral_type)
{
	if (dma_peripheral_type_peripheral == dma_peripheral_type)
	{
		dma_peripheral_info_struct->dma_addr = dma_init_struct->dma_perpheral_base_addr;
		dma_peripheral_info_struct->dma_inc = dma_init_struct->dma_periphearl_inc; 
		dma_peripheral_info_struct->dma_tr_width =  dma_init_struct->dma_peripheral_data_size;
		dma_peripheral_info_struct->dma_msize =  dma_init_struct->dma_peripheral_burst_size;
		dma_peripheral_info_struct->dma_handshake =  dma_init_struct->dma_peripheral_handshake_size;
	} 
	else if (dma_peripheral_type_memory == dma_peripheral_type)
	{
		dma_peripheral_info_struct->dma_addr = dma_init_struct->dma_memory_base_addr;
		dma_peripheral_info_struct->dma_inc = dma_init_struct->dma_memory_inc; 
		dma_peripheral_info_struct->dma_tr_width =  dma_init_struct->dma_memory_data_size;
		dma_peripheral_info_struct->dma_msize =  dma_init_struct->dma_memory_burst_size;
		dma_peripheral_info_struct->dma_handshake = 0;
	}
}

/*******************************************************************************
* 函数名   : dma_get_channelx_bit.
* 说明     : 获取DMA通道位
* 参数     : -dma_channelx,    DMA通道选择，参考 cpu.h 定义
* 返回值   : DMA通道位.
* 示例     : dma_get_channelx_bit(DMA_Channel_0);
*******************************************************************************/
static uint32_t dma_get_channelx_bit(dma_type_def *dma_channelx)
{
	uint32_t ret_channelx_bit = 0;
	
	if (dma_channelx == DMA_Channel_0)
	{
		ret_channelx_bit = DMA_CHANNEL_0_BIT;
	}
	else if (dma_channelx == DMA_Channel_1)
	{
		ret_channelx_bit = DMA_CHANNEL_1_BIT;
	}
	else if (dma_channelx == DMA_Channel_2)
	{
		ret_channelx_bit = DMA_CHANNEL_2_BIT;
	}
	else if (dma_channelx == DMA_Channel_3)
	{
		ret_channelx_bit = DMA_CHANNEL_3_BIT;
	}

	return ret_channelx_bit;
}

/*******************************************************************************
* 函数名   : dma_is_channel_enabled.
* 说明     : DMA通道使能
* 参数     : -dma_channelx,    DMA通道选择，参考 cpu.h 定义
* 返回值   : 使能
* 示例     : dma_is_channel_enabled(DMA_Channel_0);
*******************************************************************************/
functional_state_t dma_is_channel_enabled(dma_type_def *dma_channelx)
{
	uint32_t tmp_channelx_bit = 0;
	
	tmp_channelx_bit = dma_get_channelx_bit(dma_channelx);

	if (DMA->ChEnReg_L & tmp_channelx_bit)
	{
		return ENABLE;
	}

	return DISABLE;
}

/*******************************************************************************
* 函数名   : dma_init.
* 说明     : DMA初始化
* 参数     : -dma_channelx,    DMA通道选择，参考 cpu.h 定义
			 -dma_init_struct  DMA初始化参数配置
* 返回值   : 空
* 示例     : dma_init(DMA_Channel_0, &dma_init_struct);
*******************************************************************************/
void dma_init(dma_type_def *dma_channelx, dma_init_type_def *dma_init_struct)
{
	uint32_t tmpCtlxReg = 0;
	uint32_t tmpCfgxReg = 0;
	uint32_t tmp_channelx_bit = 0;
	dma_peripheral_info_def DMA_SRC, DMA_DST;

	switch(dma_init_struct->dma_dir)
	{
	case DMA_DIR_Memory_To_Memory:
	case DMA_DIR_Peripheral_To_Memory:
		{
			dma_get_peripheral_config(&DMA_SRC, dma_init_struct, dma_peripheral_type_peripheral);
			dma_get_peripheral_config(&DMA_DST, dma_init_struct, dma_peripheral_type_memory);
			break;
		}
	case DMA_DIR_Memory_To_Peripheral:
		{
			dma_get_peripheral_config(&DMA_SRC, dma_init_struct, dma_peripheral_type_memory);
			dma_get_peripheral_config(&DMA_DST, dma_init_struct, dma_peripheral_type_peripheral);
			break;
		}
	}

	dma_channel_cmd(dma_channelx, DISABLE);

	tmp_channelx_bit = dma_get_channelx_bit(dma_channelx);
	if (DMA->ChEnReg_L & tmp_channelx_bit)
	{
		return;
	}
	
	// Clear any pending interrupts on the channel from the previous DMA transfer by writing to the
	// Interrupt Clear registers: ClearTfr, ClearBlock, ClearSrcTran, ClearDstTran, and ClearErr.
	// Reading the Interrupt Raw Status and Interrupt Status registers confirms that all interrupts have been
	// cleared.
	DMA->ClearTfr_L = tmp_channelx_bit;
	DMA->ClearBlock_L = tmp_channelx_bit;
	DMA->ClearSrcTran_L = tmp_channelx_bit;
	DMA->ClearDstTran_L = tmp_channelx_bit;
	DMA->ClearErr_L = tmp_channelx_bit;
	if ((DMA->RawBlock_L & tmp_channelx_bit) | (DMA->RawDstTran_L & tmp_channelx_bit) | (DMA->RawErr_L & tmp_channelx_bit) \
		| (DMA->RawSrcTran_L & tmp_channelx_bit) | (DMA->RawTfr_L & tmp_channelx_bit)  | (DMA->StatusBlock_L & tmp_channelx_bit) \
		| (DMA->StatusDstTran_L & tmp_channelx_bit) | (DMA->StatusErr_L & tmp_channelx_bit) | (DMA->StatusSrcTran_L & tmp_channelx_bit) \
		| (DMA->StatusTfr_L & tmp_channelx_bit))
	{
		return;
	}

	// Program the following channel registers:
	// a. Write the starting source address in the SARx register for channel x
	dma_channelx->SAR_L = DMA_SRC.dma_addr;
	// b. Write the starting destination address in the DARx register for channel x
	dma_channelx->DAR_L = DMA_DST.dma_addr;

	// c. Program CTLx and CFGx according to Row 1, as shown in Table 7-1 on page 233. Program the LLPx register with 0 (see page 153).

	// d. Write the control information for the DMA transfer in the CTLx register for channel x (see
	// page 155). For example, in the register, you can program the following:
	// 	i. Set up the transfer type (memory or non-memory peripheral for source and destination) and
	// flow control device by programming the TT_FC of the CTLx register. Table 6-4 on page 161
	// lists the decoding for this field.

	// SET block size
	dma_channelx->CTL_H &= ~DMA_CTL_BLOCK_TS_Mask;
	dma_channelx->CTL_H |= dma_init_struct->dma_block_size;

	tmpCtlxReg &= ~DMA_CTL_SRC_MSIZE_Mask;
	tmpCtlxReg |= DMA_SRC.dma_msize << DMA_CTL_SRC_MSIZE_Pos;

	tmpCtlxReg &= ~DMA_CTL_DEST_MSIZE_Mask;
	tmpCtlxReg |= DMA_DST.dma_msize << DMA_CTL_DEST_MSIZE_Pos;
	
	//only use DMAC as Flow Control
	tmpCtlxReg &= ~DMA_CTL_TT_FC_Mask;
	switch(dma_init_struct->dma_dir)
	{
	case DMA_DIR_Memory_To_Memory:
		tmpCtlxReg |= DMA_CTL_TT_FC_Memory_to_Memory_Set;
		break;

	case DMA_DIR_Memory_To_Peripheral:
		tmpCtlxReg |= DMA_CTL_TT_FC_Memory_to_Peripheral_Set;
		break;

	case DMA_DIR_Peripheral_To_Memory:
		tmpCtlxReg |= DMA_CTL_TT_FC_Peripheral_to_Memory_Set;
		break;

	default:
		tmpCtlxReg |= DMA_CTL_TT_FC_Memory_to_Memory_Set;
		break;
	}

	// ii. Set up the transfer characteristics, such as:
	// Transfer width for the source in the SRC_TR_WIDTH field. Table 6-3 on page 161 lists the
	// decoding for this field.
	tmpCtlxReg &= ~DMA_CTL_SRC_TR_WIDTH_Mask;
	tmpCtlxReg |= (DMA_SRC.dma_tr_width << DMA_CTL_SRC_TR_WIDTH_Pos);

	// Transfer width for the destination in the DST_TR_WIDTH field. Table 6-3 on page 161
	// lists the decoding for this field.
	tmpCtlxReg &= ~DMA_CTL_DST_TR_WIDTH_Mask;
	tmpCtlxReg |= (DMA_DST.dma_tr_width << DMA_CTL_DST_TR_WIDTH_Pos);

	// Source master layer in the SMS field where the source resides.
	// default is 0;scpu just one ahb master
	// Destination master layer in the DMS field where the destination resides
	// default is 0;scpu just one ahb master

	// Incrementing/decrementing or fixed address for the source in the SINC field.
	tmpCtlxReg &= ~DMA_CTL_SINC_Mask;
	tmpCtlxReg |= (DMA_SRC.dma_inc << DMA_CTL_SINC_Pos);
	//  Incrementing/decrementing or fixed address for the destination in the DINC field.
	tmpCtlxReg &= ~DMA_CTL_DINC_Mask;
	tmpCtlxReg |= (DMA_DST.dma_inc << DMA_CTL_DINC_Pos);

	dma_channelx->CTL_L = tmpCtlxReg;

	// e. Write the channel configuration information into the CFGx register for channel x (see page 166).
	// i. Designate the handshaking interface type (hardware or software) for the source and
	// destination peripherals; this is not required for memory.
	tmpCfgxReg &= ~(DMA_CFG_HS_SEL_SRC_Mask | DMA_CFG_HS_SEL_DST_Mask); //硬件握手
	//Configure for Default(SoftWare) HankShake
	tmpCfgxReg |= (1 << DMA_CFG_HS_SEL_SRC_Pos) | (1 << DMA_CFG_HS_SEL_DST_Pos);	
	
	if(DMA_DIR_Memory_To_Memory == dma_init_struct->dma_dir)
	{
		// memory to memory do not need SET the SYSCTRL HardShake bits
	}
	else
	{
		if (DMA_DIR_Peripheral_To_Memory == dma_init_struct->dma_dir)
		{
			tmpCfgxReg &= ~DMA_CFG_HS_SEL_SRC_Mask;
			tmpCfgxReg |= DMA_SRC.dma_handshake << DMA_CFG_HS_SEL_SRC_Pos; //SRC HandShake Config
		}
		if (DMA_DIR_Memory_To_Peripheral == dma_init_struct->dma_dir)
		{
			tmpCfgxReg &= ~DMA_CFG_HS_SEL_DST_Mask;
			tmpCfgxReg |= DMA_DST.dma_handshake << DMA_CFG_HS_SEL_DST_Pos; //DTS HandShake Config
		}
	}
	dma_channelx->CFG_L = tmpCfgxReg;


	// 	ii. If the hardware handshaking interface is activated for the source or destination peripheral,
	// assign a handshaking interface to the source and destination peripheral; this requires
	// programming the SRC_PER and DEST_PER bits, respectively
	DMA_Channel_0->CFG_H |= (0 << DMA_CFG_DEST_PER_Pos) | (0 << DMA_CFG_SRC_PER_Pos);
	DMA_Channel_1->CFG_H |= (1 << DMA_CFG_DEST_PER_Pos) | (1 << DMA_CFG_SRC_PER_Pos);
	DMA_Channel_2->CFG_H |= (2 << DMA_CFG_DEST_PER_Pos) | (2 << DMA_CFG_SRC_PER_Pos);
	DMA_Channel_3->CFG_H |= (3 << DMA_CFG_DEST_PER_Pos) | (3 << DMA_CFG_SRC_PER_Pos);

	if(DMA_DIR_Memory_To_Memory != dma_init_struct->dma_dir)
		dma_channe_config(dma_channelx, dma_init_struct->dma_peripheral, dma_init_struct->dma_dir);

	// 	4. Ensure that bit 0 of the DmaCfgReg register is enabled before writing to ChEnReg.
	dma_cmd(ENABLE);
}

/*******************************************************************************
* 函数名   : dma_channel_cmd.
* 说明     : DMA通道使能
* 参数     : -dma_channelx,    DMA通道选择，参考 cpu.h 定义
			 -new_state,       使能或不使能,参考 functional_state_t 定义
* 返回值   : None.
* 示例     : dma_channel_cmd(DMA_Channel_0, ENABLE);
*******************************************************************************/
void dma_channel_cmd(dma_type_def* dma_channelx, functional_state_t new_state)
{
	uint32_t tmp_channelx_bit = 0;
	tmp_channelx_bit = dma_get_channelx_bit(dma_channelx);

	if(new_state != DISABLE)
	{		
		DMA->ChEnReg_L =  (tmp_channelx_bit<<8) | tmp_channelx_bit;
	}
	else
	{
		DMA->ChEnReg_L = tmp_channelx_bit<<8 | 0;
	}	
}

/*******************************************************************************
* 函数名   : dma_cmd.
* 说明     : DMA使能
* 参数     : -new_state        使能或不使能,参考 functional_state_t 定义
* 返回值   : None.
* 示例     : dma_cmd(ENABLE);
*******************************************************************************/
void dma_cmd(functional_state_t new_state)
{
	if (new_state != DISABLE)
	{
		DMA->DmaCfgReg_L = 1;
	}
	else
	{
		DMA->DmaCfgReg_L = 0;
	}
}

/*******************************************************************************
* 函数名   : dma_set_src_single_req.
* 说明     : 设置single source 传输请求
* 参数     : -dma_channelx,    DMA通道选择，参考 cpu.h 定义
* 返回值   : None.
* 示例     : dma_set_src_single_req(DMA_Channel_0);
*******************************************************************************/
void dma_set_src_single_req(dma_type_def* dma_channelx)
{
	uint32_t tmp_channelx_bit = 0;
	tmp_channelx_bit = dma_get_channelx_bit(dma_channelx);
	DMA->SglReqSrcReg_L = tmp_channelx_bit;
	DMA->ReqSrcReg_L = tmp_channelx_bit;
}

/*******************************************************************************
* 函数名   : dma_set_src_block_req.
* 说明     : 设置block source 传输请求
* 参数     : -dma_channelx,    DMA通道选择，参考 cpu.h 定义
* 返回值   : None.
* 示例     : dma_set_src_block_req(DMA_Channel_0);
*******************************************************************************/
void dma_set_src_block_req(dma_type_def* dma_channelx)
{
	uint32_t tmp_channelx_bit = 0;
	tmp_channelx_bit = dma_get_channelx_bit(dma_channelx);
	DMA->ReqSrcReg_L = tmp_channelx_bit;
	DMA->SglReqSrcReg_L = tmp_channelx_bit;
}

/*******************************************************************************
* 函数名   : dma_set_src_address.
* 说明     : 设置DMA传输的源地址
* 参数     : -dma_channelx,    DMA通道选择，参考 cpu.h 定义
			 -Address		   地址
* 返回值   : None.
* 示例     :dma_set_src_address(DMA_Channel_0,(uint32_t)&src_buf[0]);
*******************************************************************************/
void dma_set_src_address(dma_type_def* dma_channelx, uint32_t Address)
{
	// 	a. Write the starting source address in the SARx register for channel x
	dma_channelx->SAR_L = Address;
}

/*******************************************************************************
* 函数名   : dma_set_dsr_address.
* 说明     : 设置DMA传输的目的地址
* 参数     : -dma_channelx,    DMA通道选择，参考 cpu.h 定义
			 -Address		   地址
* 返回值   : None.
* 示例     :dma_set_dsr_address(DMA_Channel_0,(uint32_t)&dst_buf[0]);
*******************************************************************************/
void dma_set_dsr_address(dma_type_def* dma_channelx, uint32_t Address)
{
	// 	b. Write the starting destination address in the DARx register for channel x
	dma_channelx->DAR_L = Address;
}

/*******************************************************************************
* 函数名   : dma_it_config.
* 说明     : DMA中断配置 
* 参数     : -dma_channelx,    DMA通道选择，参考 cpu.h 定义
			 -dma_it		   中断类型
			 -new_state		   使能或不使能,参考 functional_state_t 定义
* 返回值   : None.
* 示例     :dma_it_config(DMA_Channel_0, DMA_IT_DMATransferComplete, ENABLE);
*******************************************************************************/
void dma_it_config(dma_type_def* dma_channelx, uint32_t dma_it, functional_state_t new_state)
{
	uint32_t  i = 0;
	uint32_t tmp_channelx_bit = 0;
	tmp_channelx_bit = dma_get_channelx_bit(dma_channelx);

	if(new_state != DISABLE)
	{
		dma_channelx->CTL_L |= DMA_CTL_INT_EN_Set;
	}
	else
	{
		dma_channelx->CTL_L &= ~DMA_CTL_INT_EN_Set;
		tmp_channelx_bit &= ~((uint32_t)0x0f);
	}
	
	for (i = 0;i < 5;i++)
	{
		uint32_t tmp_DMA_IT = dma_it&(((uint32_t)0x01)<<i);

		switch(tmp_DMA_IT)
		{
		case DMA_IT_BlockTransferComplete:
			DMA->MaskBlock_L = (tmp_channelx_bit << 8 | tmp_channelx_bit);
			break;
		case DMA_IT_DestinationTransactionComplete:
			DMA->MaskDstTran_L = (tmp_channelx_bit << 8 | tmp_channelx_bit);
			break;
		case DMA_IT_Error:
			DMA->MaskErr_L = (tmp_channelx_bit << 8 | tmp_channelx_bit);
			break;
		case DMA_IT_SourceTransactionComplete:
			DMA->MaskSrcTran_L = (tmp_channelx_bit << 8 | tmp_channelx_bit);
			break;
		case DMA_IT_DMATransferComplete:
			DMA->MaskTfr_L = (tmp_channelx_bit << 8 | tmp_channelx_bit);//中断屏蔽寄存器配置，打开DMA中断
			break;
		}
	}
}

/*******************************************************************************
* 函数名   : dma_clear_it_pending_bit.
* 说明     : 清除DMA中断位 
* 参数     : -dma_channelx,    DMA通道选择，参考 cpu.h 定义
			 -dma_it		   中断类型
* 返回值   : None.
* 示例     :dma_clear_it_pending_bit(DMA_Channel_0, DMA_IT_DMATransferComplete);
*******************************************************************************/
void dma_clear_it_pending_bit(dma_type_def* dma_channelx,uint32_t dma_it)
{
	uint32_t tmp_channelx_bit = 0;
	tmp_channelx_bit = dma_get_channelx_bit(dma_channelx);

	switch(dma_it)
	{
	case DMA_IT_BlockTransferComplete:
		DMA->ClearBlock_L = tmp_channelx_bit;
		break;
	case DMA_IT_DestinationTransactionComplete:
		DMA->ClearDstTran_L = tmp_channelx_bit;
		break;
	case DMA_IT_Error:
		DMA->ClearErr_L = tmp_channelx_bit;
		break;
	case DMA_IT_SourceTransactionComplete:
		DMA->ClearSrcTran_L = tmp_channelx_bit;
		break;
	case DMA_IT_DMATransferComplete:
		DMA->ClearTfr_L = tmp_channelx_bit;//清中断
		break;
	}
}

/*******************************************************************************
* 函数名   : dma_get_it_status.
* 说明     : 获取DMA中断状态 
* 参数     : -dma_channelx,       DMA通道选择，参考 cpu.h 定义
			 -dma_it		      中断类型
* 返回值   : -bitStatus = SET     产生相应中断
			 -bitStatus = RESET   未产生相应中断
* 示例     :dma_get_it_status(DMA_Channel_0, DMA_IT_DMATransferComplete);
*******************************************************************************/
itstatus dma_get_it_status(dma_type_def* dma_channelx,uint32_t dma_it)
{
	uint32_t dma_it_status = 0;
	itstatus bitStatus = RESET;

	uint32_t tmp_channelx_bit = 0;
	tmp_channelx_bit = dma_get_channelx_bit(dma_channelx);

	switch(dma_it)
	{
	case DMA_IT_BlockTransferComplete:
		dma_it_status = DMA->StatusBlock_L;
		break;
	case DMA_IT_DestinationTransactionComplete:
		dma_it_status = DMA->StatusDstTran_L;
		break;
	case DMA_IT_Error:
		dma_it_status = DMA->StatusErr_L;
		break;
	case DMA_IT_SourceTransactionComplete:
		dma_it_status = DMA->StatusSrcTran_L;
		break;
	case DMA_IT_DMATransferComplete:
		dma_it_status = DMA->StatusTfr_L;
		break;
	}

	if((dma_it_status & tmp_channelx_bit) != RESET)
	{
		bitStatus = SET;
	}
	else
	{
		bitStatus = RESET;
	}
	
	return bitStatus;
}

/*******************************************************************************
* 函数名   : dma_get_raw_status.
* 说明     : 获取DMA原状态 
* 参数     : -dma_channelx,        DMA通道选择，参考 cpu.h 定义
			 -dma_it		       中断类型
* 返回值   : -bitStatus = SET      产生相应状态
			 -bitStatus = RESET    未产生相应状态
* 示例     :dma_get_raw_status(DMA_Channel_0, DMA_IT_DMATransferComplete);
*******************************************************************************/
flag_status dma_get_raw_status(dma_type_def* dma_channelx,uint32_t dma_it)
{
	uint32_t dma_raw_status = 0;
	itstatus bitStatus = RESET;

	uint32_t tmp_channelx_bit = 0;
	tmp_channelx_bit = dma_get_channelx_bit(dma_channelx);

	switch(dma_it)
	{
	case DMA_IT_BlockTransferComplete:
		dma_raw_status = DMA->RawBlock_L;
		break;
	case DMA_IT_DestinationTransactionComplete:
		dma_raw_status = DMA->RawDstTran_L;
		break;
	case DMA_IT_Error:
		dma_raw_status = DMA->RawErr_L;
		break;
	case DMA_IT_SourceTransactionComplete:
		dma_raw_status = DMA->RawSrcTran_L;
		break;
	case DMA_IT_DMATransferComplete:
		dma_raw_status = DMA->RawTfr_L;
		break;
	}

	if(dma_raw_status & tmp_channelx_bit)
	{
		bitStatus = SET;
	}
	else
	{
		bitStatus = RESET;
	}
	
	return bitStatus;
}

/*******************************************************************************
* 函数名   : dma_channe_config.
* 说明     : DMA通道配置
* 参数     : -dma_channelx,        DMA通道选择，参考 cpu.h 定义
			 -dma_peripheral       DMA外设选择
			 -dma_dir			   传输方向
* 返回值   : None.
* 示例     : dma_channe_config(DMA_Channel_0，DMA_Peripheral_UART0，DMA_RX);
*******************************************************************************/
void dma_channe_config(dma_type_def* dma_channelx, uint32_t dma_peripheral, uint32_t dma_dir)
{
	sysctrl_dma_channel_config(dma_channelx, dma_peripheral, dma_dir);
}
