⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dma.c

📁 os arm os arm os arm os arm os arm os arm os arm os arm os arm os arm os arm os arm os arm os arm
💻 C
字号:
/* *	ApOS (Another Project software for s3c2410) *	 *	This program is free software; you can redistribute it and/or modify *	it under the terms of the GNU General Public License version 2 as *	published by the Free Software Foundation. *			 *						Copyright caiyuqing * *	this file define the functions of the DMA block *  	本文件实现了对DMA模块进行操作的函数 */#include "../include/s3c2410/s3c2410.h"#include "../include/s3c2410/dma.h"#include "../include/kernel/irq.h"extern irq_ptr irq_rotunie[32];/* *	DMA global object,any functions of the dma control is base it.  *	DMA全局对象,整个系统的DMA操作(初始化,设置等等)都是基于这个对象的 */struct dma_ctrl_object dma_ctrl_object;/* *	system can get the status of a dma opteration througth *	thease four global variable *	四个全局变量,通过他们系统可以知道dma操作是否已经完成 */char sys_dma0_done;char sys_dma1_done;char sys_dma2_done;char sys_dma3_done;/* *	irq for chanel0	 *	0号通道dma中断服务例程 */void dma0_irq(struct cpu_registers *regs);/* *	initialize the DMA object *	初始化 dma_ctrl_object 对象 */void dma_ctrl_obj_init(struct dma_ctrl_object *dco){	//0通道对象初始化	dco->chanel0.disrc	=&rDISRC0;	dco->chanel0.disrcc	=&rDISRCC0;	dco->chanel0.didst	=&rDIDST0;	dco->chanel0.didstc	=&rDIDSTC0;	dco->chanel0.dcon	=&rDCON0;	dco->chanel0.dstat	=&rDSTAT0;	dco->chanel0.dcsrc	=&rDCSRC0;	dco->chanel0.dcdst	=&rDCDST0;	dco->chanel0.dmasktrig	=&rDMASKTRIG0;	dco->chanel0.tc_opt	=1;	//1通道对象初始化	dco->chanel1.disrc	=&rDISRC1;	dco->chanel1.disrcc	=&rDISRCC1;	dco->chanel1.didst	=&rDIDST1;	dco->chanel1.didstc	=&rDIDSTC1;	dco->chanel1.dcon	=&rDCON1;	dco->chanel1.dstat	=&rDSTAT1;	dco->chanel1.dcsrc	=&rDCSRC1;	dco->chanel1.dcdst	=&rDCDST1;	dco->chanel1.dmasktrig	=&rDMASKTRIG1;	dco->chanel1.tc_opt	=1;		//2通道对象初始化	dco->chanel2.disrc	=&rDISRC2;	dco->chanel2.disrcc	=&rDISRCC2;	dco->chanel2.didst	=&rDIDST2;	dco->chanel2.didstc	=&rDIDSTC2;	dco->chanel2.dcon	=&rDCON2;	dco->chanel2.dstat	=&rDSTAT2;	dco->chanel2.dcsrc	=&rDCSRC2;	dco->chanel2.dcdst	=&rDCDST2;	dco->chanel2.dmasktrig	=&rDMASKTRIG2;	dco->chanel2.tc_opt	=1;		//3通道对象初始化	dco->chanel3.disrc	=&rDISRC3;	dco->chanel3.disrcc	=&rDISRCC3;	dco->chanel3.didst	=&rDIDST3;	dco->chanel3.didstc	=&rDIDSTC3;	dco->chanel3.dcon	=&rDCON3;	dco->chanel3.dstat	=&rDSTAT3;	dco->chanel3.dcsrc	=&rDCSRC3;	dco->chanel3.dcdst	=&rDCDST3;	dco->chanel3.dmasktrig	=&rDMASKTRIG3;	dco->chanel3.tc_opt	=1;	irq_rotunie[INT_DMA0]	=&dma0_irq;}/* *	we use chanel0 to perform the data transfer between memory and memory *	本函数使用DMA的0号通道对内存间的数据传送 *	src_addr:	source address 		源地址 *	dest_addr:	destination address	目标地址 *	len:		data length(byts)	数据长度(字节) */int dma_mem_copy(unsigned int* src_addr,unsigned int* dest_addr,int len){	struct dma_ctrl_object *dma_obj	=&dma_ctrl_object;	struct dma_chanel *dma_chanel	=((struct dma_chanel *)dma_obj)+0;		unsigned int tc=(len);		irq_mask(INT_DMA0,IRQ_UNMASK);	sys_dma0_done=0;		//必须清除DCache,否则数据会出错	invalidate_DCache();	/*	 *	LOC: 0	address increment	 *	INC: 0	AHB	 */	*dma_chanel->disrc=src_addr;	*dma_chanel->disrcc=(0<<LOC_OFFSET)|(0<<INC_OFFSET);	*dma_chanel->didst=dest_addr;	*dma_chanel->didstc=(0<<LOC_OFFSET)|(0<<INC_OFFSET);		/*	 *	DMD_HS:	 1	Handshake mode.	 *	 *	SYNC:	 1	DREQ and DACK are synchronized to HCLK.	 *			由于是内存间的数据传递,数据源设备是内存,应该同步于HCLK	 *			所以将SYNC位设置为1	 *			若数据源设备是属于外部总线的,则必须同步于PCLK,必须将该	 *			位设置为0	 *				 *	INT:	 1	interrupt request is generated when all the transfer is done.	 *			当该位为1时,则DMA完成(既CURR_TC变为0)之后相应的DMA中断将被触发	 *		 *	TSZ:	 0	an union transfer is performed.	 *			DMA设备每次占用总线时传递数据的次数,0是传递1次后释放总线,	 *			1是传递4次后再释放总线	 *				 *	SERVMODE:1	Whole service mode.	 *	 *	SWHW_SEL:0	S/W request mode.	 *			DMA触发方式的选择,0软件触发,1为硬件触发。	 *			当设置为硬件触发之后我们必须设置HWSRCSEL位	 *			为4个通道配置触发源	 *				 *	RELOAD:	 1	DMA channel (DMA REQ) is turned off when a current value of 	 *			transfer count becomes 0.	 *			当设置为1时,则一旦某通道完成了DMA操作(既CURR_TC变为0),该通道	 *			将被马上关闭。(既DMASKTRIG寄存器的ON_OFF位被置0)	 *			若设置为0时,则完成DMA操作之后的通道并不关闭(既DMASKTRIG寄存器	 *			的ON_OFF位还是1),它会紧接着处理新的请求(如果有的话)	 *	 *	DSZ:	 00	BYTE.	 *			DMA每次传送数据的字节数	 *				 *	TC:	 tc 当前DMA请求总共需要传递多少次数据(必须占用多少次总线)	 *		 一个DMA操作传递的数据字节数实际上是 DSZ*TSZ*TC	 *				 */	*dma_chanel->dcon=(1<<DMD_HS_OFFSET)|(1<<SYNC_OFFSET)|			(1<<INT_OFFSET)|(0<<TSZ_OFFSET)|(1<<SERVMODE_OFFSET)|			(0<<SWHW_SEL_OFFSET)|(1<<RELOAD_OFFSET)|(BYTE<<DSZ_OFFSET)|			(tc);	//ready?	//while((*dma_chanel->dstat)&0xfffff!=0);	while(((*dma_chanel->dstat)>>20)&0x3!=0);//DMA is busy	/*	 *	DMA on, SW_TRIG 	 *	开启DMA通道,触发一个DMA信号	 */	*dma_chanel->dmasktrig=(1<<ON_OFF_OFFSET)|(1<<SW_TRIG_OFFSET);		return tc;}void dma_stop(int chanel){	struct dma_ctrl_object *dma_obj	=&dma_ctrl_object;	struct dma_chanel *dma_chanel	=((struct dma_chanel *)dma_obj)+chanel;		*dma_chanel->dmasktrig=(1<<STOP_OFFSET);}/* *	irq for dam chanel0 *	dma chanel0 中断服务例程 */void dma0_irq(struct cpu_registers *regs){	/*	 *	clean the interrupt pin and mask the interrupt,set	 *	the sys_dmaX_done to 1,indecate that the DMA opteration 	 *	is complete.	 *		 *	清除中断信号并屏蔽该中断,将sys_dmaX_done	 *	设置为0表示一个DMA操作已经完成	 */	clean_src_pnd(INT_DMA0);	clean_int_pnd(INT_DMA0);	irq_mask(INT_DMA0,IRQ_MASK);	sys_dma0_done=1;}int dma_copy_done(){	return sys_dma0_done;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -