S3C6410 裸机DMA

/*************************************************************************************************************
 * 文件名:	dma.c
 * 功能:		S3C6410 DMA底层驱动函数
 * 作者:		[email protected]
 * 创建时间:	2013年01月23日21:06
 * 最后修改时间:2013年01月23日
 * 详细:		DMA控制器底层驱动
*************************************************************************************************************/
#include "system.h"
#include "DMA.h"



/*************************************************************************************************************************
*函数    		:	void DMA_Init(void)
*功能    		:	DMA初始化
*参数    		:	无
*返回    		:	无
*依赖		: 	底层
*作者     		:	[email protected]
*时间     	:	20130131
*最后修改时间	:	20130131
*说明     	:	无
*************************************************************************************************************************/
void DMA_Init(void)
{
	Set_GateClk(HCLK_DMA0, ENABLE);
	Set_GateClk(HCLK_DMA1, ENABLE);
	
}



/*************************************************************************************************************************
*函数    		:	void DMA_SetConfig(DMA_TypeDef *DMA, DMA_CHX ch, DMA_Config *config)
*功能    		:	DMA配置
*参数    		:	DMA:DMA模块选择,见DMA_TypeDef;ch:通道选择,见DMA_CHX;config:配置,见DMA_Config
*返回    		:	无
*依赖		: 	底层
*作者     		:	[email protected]
*时间     	:	20130131
*最后修改时间	:	20130131
*说明     	:	用于设置DMA
*************************************************************************************************************************/
void DMA_SetConfig(DMA_TypeDef *DMA, DMA_CHX ch, DMA_Config *config)
{
	DMA_Enable(DMA);			//使能DMA模块
	(DMA->CH[ch]).SrcAddr	= 	config->SrcAddr;													//设置源地址
	(DMA->CH[ch]).DestAddr	= 	config->DestAddr;													//设置目标地址
	(DMA->CH[ch]).Control0	= 	   0x80000000		//1<<31												//是否在当前的传输完成后产生中断
								| ((config->DestIncrement == ENABLE) ? (1 << 27) : 0)				//目标地址自增
								| ((config->SrcIncrement == ENABLE) ? (1 << 26) : 0)				//源地址自增
								| ((config->DestPeripheral == DMA_MEM) ? AHB_M1 : AHB_M2) << 25		//目标AHB主机选择
								| ((config->SrcPeripheral == DMA_MEM) ? AHB_M1 : AHB_M2) << 24		//源AHB主机选择
								| (config->FlowWidth & 0x7) << 21									//目标传输宽度
								| (config->FlowWidth & 0x7) << 18									//源传输宽度
								| (config->BurstSize & 0x7) << 15									//目标传输脉冲大小,单次传输的数量
								| (config->BurstSize & 0x7) << 12;									//源传输脉冲大小,单次传输的数量
	(DMA->CH[ch]).Control1	= 	config->DataSize & 0x1ffffff;										//传输数据数量
	(DMA->CH[ch]).Config 	= 	  (0<<18)// enable DMA requests
								| (0<<16)	// disables locked transfers
								| (1<<15)	// Teminal count interrupt enable
								| (0<<14)	// Interrupt error mask														//允许DMA请求
								| (((config->SrcPeripheral == DMA_MEM) ? 0 : 1) << 12)
								| (((config->DestPeripheral == DMA_MEM) ? 0 : 1) << 11)									//传输模式,如内存到内存等
								| (config->DestPeripheral & 0x0f) << 6		//目标外设
								| (config->SrcPeripheral & 0x0f) << 1;		//源外设
	(DMA->CH[ch]).LLI 		= 	config->LLIArrd;													//下一个传输LLI配置位置
	//(DMA->CH[ch]).ConfigExp = 	7;
}



/*************************************************************************************************************************
*函数    		:	void DMA_Enable(DMA_TypeDef *DMA)
*功能    		:	DMA使能
*参数    		:	DMA:DMA模块选择,见DMA_TypeDef;
*返回    		:	无
*依赖		: 	底层
*作者     		:	[email protected]
*时间     	:	20130131
*最后修改时间	:	20130131
*说明     	:	无
*************************************************************************************************************************/
void DMA_Enable(DMA_TypeDef *DMA)
{
	DMA->Config = 0x01;	//AHB小端模式,启动DMA控制器	
}



/*************************************************************************************************************************
*函数    		:	void DMA_Disable(DMA_TypeDef *DMA)
*功能    		:	DMA关闭
*参数    		:	DMA:DMA模块选择,见DMA_TypeDef;
*返回    		:	无
*依赖		: 	底层
*作者     		:	[email protected]
*时间     	:	20130131
*最后修改时间	:	20130131
*说明     	:	无
*************************************************************************************************************************/
void DMA_Disable(DMA_TypeDef *DMA)
{
	DMA->Config = 0x00;	//AHB小端模式,关闭DMA控制器	
}



/*************************************************************************************************************************
*函数    		:	void DMA_StartChannels(DMA_TypeDef *DMA, DMA_CHX ch)
*功能    		:	DMA通道传输开始
*参数    		:	DMA:DMA模块选择,见DMA_TypeDef;ch:通道选择,见DMA_CHX;
*返回    		:	无
*依赖		: 	底层
*作者     		:	[email protected]
*时间     	:	20130131
*最后修改时间	:	20130131
*说明     	:	无
*************************************************************************************************************************/
void DMA_StartChannels(DMA_TypeDef *DMA, DMA_CHX ch)
{
	DMA_ClearIntTCStatus(DMA0, ch);
	DMA_ClearIntErrorStatus(DMA0, ch);
	
	(DMA->CH[ch]).Config |= 1 << 0;		//通道使能
}



/*************************************************************************************************************************
*函数    		:	void DMA_WaitComplete(DMA_TypeDef *DMA, DMA_CHX ch)
*功能    		:	等待传输完成
*参数    		:	DMA:DMA模块选择,见DMA_TypeDef;ch:通道选择,见DMA_CHX;
*返回    		:	无
*依赖		: 	底层
*作者     		:	[email protected]
*时间     	:	20130131
*最后修改时间	:	20130131
*说明     	:	无
*************************************************************************************************************************/
void DMA_WaitComplete(DMA_TypeDef *DMA, DMA_CHX ch)
{
	while(!(DMA->RawIntTCStatus & (1 << ch)));
}


/*************************************************************************************************************************
*函数    		:	void DMA_ClearIntTCStatus(DMA_TypeDef *DMA, DMA_CHX ch)
*功能    		:	DMA清除DMA传输完成中断状态
*参数    		:	DMA:DMA模块选择,见DMA_TypeDef;ch:通道选择,见DMA_CHX;
*返回    		:	无
*依赖		: 	底层
*作者     		:	[email protected]
*时间     	:	20130131
*最后修改时间	:	20130131
*说明     	:	无
*************************************************************************************************************************/
void DMA_ClearIntTCStatus(DMA_TypeDef *DMA, DMA_CHX ch)
{
	DMA->IntTcClear |= 1 << ch;
}


/*************************************************************************************************************************
*函数    		:	void DMA_ClearIntErrorStatus(DMA_TypeDef *DMA, DMA_CHX ch)
*功能    		:	清除DMA传输错误中断状态
*参数    		:	DMA:DMA模块选择,见DMA_TypeDef;ch:通道选择,见DMA_CHX;
*返回    		:	无
*依赖		: 	底层
*作者     		:	[email protected]
*时间     	:	20130131
*最后修改时间	:	20130131
*说明     	:	无
*************************************************************************************************************************/
void DMA_ClearIntErrorStatus(DMA_TypeDef *DMA, DMA_CHX ch)
{
	DMA->IntErrClear |= 1 << ch;
}
 
 
 
 
 
 
#ifndef DMA_H_
#define DMA_H_


//DMA通道定义
typedef enum 
{
	DMA_CH0		=	0,
	DMA_CH1		=	1,
	DMA_CH2		=	2,
	DMA_CH3		=	3,
	DMA_CH4		=	4,
	DMA_CH5		=	5,
	DMA_CH6		=	6,
	DMA_CH7		=	7,
}DMA_CHX;

//DMA单独通道结构
typedef volatile struct
{
	vu32	SrcAddr;
	vu32	DestAddr;
	vu32	LLI;
	vu32	Control0;
	vu32	Control1;
	vu32	Config;
	vu32	ConfigExp;
	vu32	Reserved;
}DMA_CH_Config;

//DMA寄存器结构
typedef volatile struct
{
	vu32	IntStatus;		//中断状态
	vu32	IntTcStatus;	//处理过程中中断状态
	vu32	IntTcClear;		//中断清除
	vu32 	IntErrorStatus;
	vu32	IntErrClear;
	vu32	RawIntTCStatus;
	vu32	RawIntErrorStatus;
	vu32	EnbldChns;
	vu32	SoftBReq;
	vu32	SoftSReq;
	vu32	SoftLBReq;
	vu32	SoftLSReq;
	vu32	Config;
	vu32	Sync;
	vu32	Reserved[50];//保留
	DMA_CH_Config CH[8];		//8个独立通道
} DMA_TypeDef;

//4个DMA控制器的基址
#define DMA0_BASE		0x75000000
#define DMA1_BASE		0x75100000
#define SDMA0_BASE		0x7DB00000
#define SDMA1_BASE		0x7DC00000

//DMA寄存器指针
#define DMA0	((DMA_TypeDef *)DMA0_BASE)
#define DMA1	((DMA_TypeDef *)DMA1_BASE)
#define SDMA0	((DMA_TypeDef *)SDMA0_BASE)
#define SDMA1	((DMA_TypeDef *)SDMA1_BASE)


//DMA源定义
typedef enum
{
	//DMA0,SDMA0
	DMA_MEM			=	0,
	DMA_UART0_0		=	0,		
	DMA_UART0_1		=	1,		
	DMA_UART1_0		=	2,		
	DMA_UART1_1		=	3,	
	DMA_UART2_0		=	4,	
	DMA_UART2_1		=	5,	
	DMA_UART3_0		=	6,	
	DMA_UART3_1		=	7,		
	DMA_PCM0_TX		=	8,		
	DMA_PCM0_RX		=	9,		
	DMA_I2S0_TX		=	10,		
	DMA_I2S0_RX		=	11,		
	DMA_SPI0_TX		=	12,		
	DMA_SPI0_RX		=	13,		
	DMA_HSI_TX		=	14,		
	DMA_HSI_RX		=	15,
	//DMA1,SDMA1
	DMA_PCM1_TX		= 	16,
	DMA_PCM1_RX		= 	17,
	DMA_I2S1_TX		= 	18,
	DMA_I2S1_RX		= 	19,
	DMA_SPI1_TX		= 	20,
	DMA_SPI1_RX		= 	21,
	DMA_AC_PCMout	= 	22,
	DMA_AC_PCMin	= 	23,
	DMA_AC_MICin	= 	24,
	DMA_PWM			= 	25,
	DMA_IrDA		= 	26,
	DMA_SECU_RX		= 	30,
	DMA_SECU_TX		= 	31
}DMA_Sources_Type;


//DMA传输类型定义
/*
typedef enum
{
	MemToMem		=	0,	//内存到内存
	MemToPer		=	1,	//内存到外设
	PerToMem		=	2,	//外设到内存
	PerToPer		=	3	//外设到外设	
}DMA_Transfer_Type;
*/

typedef enum
{
    NO_INT_PEND = 0x0,
    TC_INT_PEND = 0x1,
    ERR_INT_PEND = 0x2,
    TC_AND_ERR_INT_PEND = 0x3
} DMA_INT_STATUS;


//DMA AHB主机选择定义
typedef enum
{
	AHB_M1		=	0,	//AHB主机1
	AHB_M2		=	1,	//AHB主机2
}DMA_AHB_Type;

//DAM传输宽度
typedef enum
{
	WIDTH_8BIT			=	0,	//8bit
	WIDTH_16BIT			=	1,	//16bit
	WIDTH_32BIT			=	2	//32bit
}DAM_Width_Type;


//源或目标突发传输大小
typedef enum
{
	BURST1				=	0,
	BURST4				=	1,
	BURST8				=	2,
	BURST16				=	4,
	BURST32				=	5,
	BURST64				=	6,
	BURST128			=	7,
	BURST256			=	8
}DMA_BurstSize_Type;
/*
 *DMAC内部每个通道的4字FIFO。因此,脉冲串的大小和传输宽度是有限的由FIFO
大小。例如,如果数据宽度为字,可用的突发脉冲尺寸是4下。如果数据宽度为字节,可突发尺寸
在16岁以下。
*/

//DMA传输配置
typedef struct
{
	u32					SrcAddr;		//DMA源地址
	u32					DestAddr;		//DAM目标地址
	DMA_Sources_Type	SrcPeripheral;	//源外设
	DMA_Sources_Type	DestPeripheral;	//目标外设
	FunctionalState		SrcIncrement;	//源地址增量模式
	FunctionalState		DestIncrement;	//目标地址增量模式
	DAM_Width_Type		FlowWidth;		//传输宽度
	DMA_BurstSize_Type	BurstSize;		//突发传输大小
	u32					DataSize;		//传输数据个数,32bit
	u32					LLIArrd;		//下一个传输配置地址
}DMA_Config;


//LLI地址设置
typedef struct 
{
	u32					SrcAddr;	//下一个传输的源地址
	u32					DestAddr;	//下一个传输的目标地址
	u32					LLIAddr;	//下一个传输的LLI地址
	u32					DMAControl0;//下一个传输的DMAControl0数据
	u32					DMAControl1;//下一个传输的DMAControl1数据
}DMA_LLI_Addr;



//函数声明
void DMA_Init(void);
void DMA_SetConfig(DMA_TypeDef *DMA, DMA_CHX ch, DMA_Config *config);
void DMA_Enable(DMA_TypeDef *DMA);
void DMA_Disable(DMA_TypeDef *DMA);
void DMA_WaitComplete(DMA_TypeDef *DMA, DMA_CHX ch);
void DMA_ClearIntTCStatus(DMA_TypeDef *DMA, DMA_CHX ch);
void DMA_ClearIntErrorStatus(DMA_TypeDef *DMA, DMA_CHX ch);
void DMA_StartChannels(DMA_TypeDef *DMA, DMA_CHX ch);



#endif /*DMA_H_*/





   

你可能感兴趣的:(三星,dma,OK6410,s3c6410,OK6410,s3c6410,裸机)