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

📄 dma.c

📁 2440 开发板的测试程序。包括uart,iic,lcd
💻 C
字号:
#include "def.h"
#include "option.h"
#include "2440addr.h"
#include "2440lib.h"
#include "2440slib.h" 
#include "dma.h"

#define	DMA_CHECK_ATTR	1

typedef struct
{
	//can't use __packed???
	volatile U32 DISRC;		//0x0
	volatile U32 DISRCC;	//0x4
	volatile U32 DIDST;		//0x8
	volatile U32 DIDSTC;	//0xc
	volatile U32 DCON;		//0x10
	volatile U32 DSTAT;		//0x14
	volatile U32 DCSRC;		//0x18
	volatile U32 DCDST;		//0x1c
	volatile U32 DMASKTRIG; //0x20
}DMAReg;

static struct
{
	U16 used;
	U16 DevID;
	DMAReg* pDMA;
}
DMAChannel[MAX_DMA_CHANNEL];

/********************************************************/
//attr高16位为设备ID,低16位的高8位为DMA传送源,目的属性(AHP/APB,INCREASE/FIX)
//低8位为请求源,返回值失败为REQUEST_DMA_FAIL,成功高16位为设备ID,低8位为申请到的通道
U32 RequestDMASW( U32 attr , U32 mode )
{
	U16 channel;
	U32 ret;

	attr &= ~0xff;
	mode &= ~HW_TRIG;

	for ( channel = 0; channel < ( MAX_DMA_CHANNEL*0x10 ); channel += 0x10 )
	{
		ret = RequestDMA( attr | channel , mode );
		if ( ret != REQUEST_DMA_FAIL )
			break;
	}
	return ret;
}

U32 RequestDMA( U32 attr , U32 mode )
{
	U16 DevID, ReqSrc, ch;
	U32 ret = REQUEST_DMA_FAIL, r;

	DevID = attr >> 16;	
	ReqSrc = attr & 0xff;	

	if ( ( ( ReqSrc >> 4 ) >= MAX_DMA_CHANNEL ) || ( ( ReqSrc & 0xf ) > 4 ) )
		return ret;

	EnterCritical( &r );

	if ( DMAChannel[ReqSrc >> 4].used != DMA_IS_FREE )
	{
		U8 src = ReqSrc;			

		if ( src == REQ_IISDI )
		{
			if ( DMAChannel[2].used != DMA_IS_FREE )
				goto RequestDmaExit;
			else
				ReqSrc = 0x21;
		}
		else if ( src == REQ_SDI )
		{
			if ( DMAChannel[2].used != DMA_IS_FREE )
			{
				if ( DMAChannel[3].used != DMA_IS_FREE )
					goto RequestDmaExit;
				else
					ReqSrc = 0x31;
			}
			else
				ReqSrc = 0x22;
		}
		else if ( src == REQ_SPI )
		{
			if ( DMAChannel[3].used != DMA_IS_FREE )
				goto RequestDmaExit;
			else
				ReqSrc = 0x32;
		}
		else if ( src == REQ_TIMER )
		{
			if ( DMAChannel[2].used != DMA_IS_FREE )
			{
				if ( DMAChannel[3].used != DMA_IS_FREE )
					goto RequestDmaExit;
				else
					ReqSrc = 0x33;
			}
			else
				ReqSrc = 0x23;
		}
		else
			goto RequestDmaExit;
	}	

	ch = ReqSrc >> 4;
	if ( mode & HW_TRIG )
		DMAChannel[ch].used = DMA_IS_HWTRIG;
	else
		DMAChannel[ch].used = DMA_IS_SWTRIG;	
	DMAChannel[ch].DevID = DevID;
	DMAChannel[ch].pDMA = ( DMAReg * ) ( 0x4b000000 + ( ch ) * 0x40 );	
	DMAChannel[ch].pDMA->DMASKTRIG = 1 << 2;	//stop dma
	DMAChannel[ch].pDMA->DISRCC = ( attr >> 8 ) & 3;	
	DMAChannel[ch].pDMA->DIDSTC = ( attr >> 12 ) & 3;	
	mode &= ~0x07000000;
	mode |= ( ReqSrc & 0x7 ) << 24;
	DMAChannel[ch].pDMA->DCON = mode;	

	//	DbgOut("Request DMA %x success\n", ReqSrc);
	ret = ( DevID << 16 ) | ReqSrc;

	RequestDmaExit:
	ExitCritical( &r );	
	return ret;
}

U16 ReleaseDMA( U32 attr )
{
	U16 DevID, ReqSrc, ch;	

	DevID = attr >> 16;
	ReqSrc = attr & 0xf;
	ch = ( attr & 0xf0 ) >> 4;

#if	DMA_CHECK_ATTR					
	if ( ( ch >= MAX_DMA_CHANNEL ) || ( ReqSrc > 4 ) )
		return 1;
	if ( ( DMAChannel[ch].used == DMA_IS_FREE ) || ( DMAChannel[ch].DevID != DevID ) )
		return 1;
#endif	

	DMAChannel[ch].pDMA->DMASKTRIG = 0;//4;	//stop dma and channel off 
	DMAChannel[ch].used = DMA_IS_FREE;

	return 0;
}

U16 StartDMA( U32 attr )
{
	U16 DevID, ReqSrc, ch;	

	DevID = attr >> 16;
	ReqSrc = attr & 0xf;
	ch = ( attr & 0xf0 ) >> 4;		
#if	DMA_CHECK_ATTR		
	if ( ( ch >= MAX_DMA_CHANNEL ) || ( ReqSrc > 4 ) )
		return 1;
	if ( ( DMAChannel[ch].used == DMA_IS_FREE ) || ( DMAChannel[ch].DevID != DevID ) )
		return 1;
#endif

	if ( DMAChannel[ch].used == DMA_IS_HWTRIG )
		DMAChannel[ch].pDMA->DMASKTRIG = 2;		//channel on
	if ( DMAChannel[ch].used == DMA_IS_SWTRIG )
		DMAChannel[ch].pDMA->DMASKTRIG = 3;		//sw_trig

	return 0;
}

U16 StopDMA( U32 attr )
{
	U16 DevID, ReqSrc, ch;

	DevID = attr >> 16;
	ReqSrc = attr & 0xf;
	ch = ( attr & 0xf0 ) >> 4;		
#if	DMA_CHECK_ATTR		
	if ( ( ch >= MAX_DMA_CHANNEL ) || ( ReqSrc > 4 ) )
		return 1;
	if ( ( DMAChannel[ch].used == DMA_IS_FREE ) || ( DMAChannel[ch].DevID != DevID ) )
		return 1;
#endif	

	DMAChannel[ch].pDMA->DMASKTRIG = 1 << 2;	//channel off	

	return 0;
}

U16 SetDMARun( U32 attr , U32 src_addr , U32 dst_addr , U32 len )
{
	U16 DevID, ReqSrc, ch;	

	DevID = attr >> 16;
	ReqSrc = attr & 0xf;
	ch = ( attr & 0xf0 ) >> 4;		
#if	DMA_CHECK_ATTR		
	if ( ( ch >= MAX_DMA_CHANNEL ) || ( ReqSrc > 4 ) )
		return 1;
	if ( ( DMAChannel[ch].used == DMA_IS_FREE ) || ( DMAChannel[ch].DevID != DevID ) )
		return 1;
#endif
	DMAChannel[ch].pDMA->DISRC = src_addr;
	DMAChannel[ch].pDMA->DIDST = dst_addr;
	DMAChannel[ch].pDMA->DCON &= ~0xfffff;
	DMAChannel[ch].pDMA->DCON |= len & 0xfffff;

	if ( attr & DMA_START )
	{
		if ( DMAChannel[ch].used == DMA_IS_HWTRIG )
			DMAChannel[ch].pDMA->DMASKTRIG = 2;		//channel on
		if ( DMAChannel[ch].used == DMA_IS_SWTRIG )
			DMAChannel[ch].pDMA->DMASKTRIG = 3;		//sw_trig
	}

	return 0;
}

U32 QueryDMAStat( U32 attr )
{
	U16 DevID, ReqSrc, ch;

	DevID = attr >> 16;
	ReqSrc = attr & 0xf;
	ch = ( attr & 0xf0 ) >> 4;		
#if	DMA_CHECK_ATTR		
	if ( ( ch >= MAX_DMA_CHANNEL ) || ( ReqSrc > 4 ) )
		return -1;
	if ( ( DMAChannel[ch].used == DMA_IS_FREE ) || ( DMAChannel[ch].DevID != DevID ) )
		return -1;
#endif	

	return DMAChannel[ch].pDMA->DSTAT;	//STAT[21:20], CURR_TC[19:0] 
}

U32 QueryDMASrc( U32 attr )
{
	U16 DevID, ReqSrc, ch;

	DevID = attr >> 16;
	ReqSrc = attr & 0xf;
	ch = ( attr & 0xf0 ) >> 4;		
#if	DMA_CHECK_ATTR		
	if ( ( ch >= MAX_DMA_CHANNEL ) || ( ReqSrc > 4 ) )
		return -1;
	if ( ( DMAChannel[ch].used == DMA_IS_FREE ) || ( DMAChannel[ch].DevID != DevID ) )
		return -1;
#endif	

	return DMAChannel[ch].pDMA->DCSRC;
}

U32 QueryDMADst( U32 attr )
{
	U16 DevID, ReqSrc, ch;

	DevID = attr >> 16;
	ReqSrc = attr & 0xf;
	ch = ( attr & 0xf0 ) >> 4;		
#if	DMA_CHECK_ATTR		
	if ( ( ch >= MAX_DMA_CHANNEL ) || ( ReqSrc > 4 ) )
		return -1;
	if ( ( DMAChannel[ch].used == DMA_IS_FREE ) || ( DMAChannel[ch].DevID != DevID ) )
		return -1;
#endif	

	return DMAChannel[ch].pDMA->DCDST;
}

⌨️ 快捷键说明

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