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

📄 dmademodlg.cpp

📁 在windows ce下开发的,应用于三星arm9平台
💻 CPP
字号:
// DMAdemoDlg.cpp : implementation file
//

#include "stdafx.h"
#include "DMAdemo.h"
#include "DMAdemoDlg.h"
#include "def.h"
#include "option.h"
#include "2440addr.h"
#include "2440lib.h"
#include "2440slib.h" 
#include "dma.h"
#include "ceddk.h"						//ddk头文件
#pragma comment(lib,"ceddk.lib")		//加载lib文件



#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

    PHYSICAL_ADDRESS dmaPhysicalBase;	//定义物理地址对象
	unsigned long *memio;			//内存映射首地址
	int 	p;
	#define DMAPhysicalAddress_Base (volatile unsigned long)	0x4B000000	//DMA硬件首地址

	 struct DMAReg
	{						//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
	}dmaregg;

static struct{
	U16 used;
	U16 DevID;
	DMAReg *pDMA;
}
DMAChannel[MAX_DMA_CHANNEL];
//--------------------------地址映射-----------------------------//
void DMAInit()
{
	dmaPhysicalBase.LowPart = DMAPhysicalAddress_Base;
	dmaPhysicalBase.HighPart = 0;
	p=TransBusAddrToVirtual(Internal,0,dmaPhysicalBase,3000000,0,(void**)memio);
	if(p==false) 
	{
		AfxMessageBox(_T("I/O ports distributed fail,program will exit,plase restart."),MB_YESNO);    
		ExitProcess(0);
	}

	dmaregg.DISRC=READ_REGISTER_ULONG(memio);
	dmaregg.DISRCC=READ_REGISTER_ULONG(memio+4);
	dmaregg.DIDST=READ_REGISTER_ULONG(memio+8);
	dmaregg.DIDSTC=READ_REGISTER_ULONG(memio+12);
	dmaregg.DCON=READ_REGISTER_ULONG(memio+16);
	dmaregg.DSTAT=READ_REGISTER_ULONG(memio+20);
	dmaregg.DCSRC=READ_REGISTER_ULONG(memio+24);
	dmaregg.DCDST=READ_REGISTER_ULONG(memio+28);
	dmaregg.DMASKTRIG=READ_REGISTER_ULONG(memio+32);

}

/********************************************************/
//attr高16位为设备ID,低16位的高8位为DMA传送源,目的属性(AHP/APB,INCREASE/FIX)
//低8位为请求源,返回值失败为REQUEST_DMA_FAIL,成功高16位为设备ID,低8位为申请到的通道
U32 RequestDMASW()
{
	U16 channel;
	U32 attr;
	U32 mode;
	U32 ret;
	
	attr &= ~0xff;
	mode &= ~HW_TRIG;// DCON paramaters
	
	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()
{
	U16 DevID, ReqSrc, ch;
	U32 attr;
	U32 mode;
	U32 ret=REQUEST_DMA_FAIL, r;
	
	attr &= ~0xff;
	mode &= ~HW_TRIG;    //添加初始化  15:58 16.5.2008

	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 =(U8) 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()
{
	U16 DevID, ReqSrc, ch;	
	U32 attr ;
	attr&= ~0xff;

	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()
{
	U16 DevID, ReqSrc, ch;	
	U32 attr ;
	attr&= ~0xff;
	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()
{
	U16 DevID, ReqSrc, ch;
	U32 attr;
	attr&= ~0xff;

	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()
{
	U16 DevID, ReqSrc, ch;
	U32 attr;
	attr&= ~0xff;

	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()
{
	U16 DevID, ReqSrc, ch;
	U32 attr ;
	attr&= ~0xff;

	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;
}





CDMAdemoDlg::CDMAdemoDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CDMAdemoDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CDMAdemoDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CDMAdemoDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDMAdemoDlg)
	DDX_Control(pDX, IDC_LIST1, m_list);
	DDX_Control(pDX, IDC_BUTTON3, m_bt3);
	DDX_Control(pDX, IDC_BUTTON2, m_bt2);
	DDX_Control(pDX, IDC_BUTTON1, m_bt1);
	// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
	
}

BEGIN_MESSAGE_MAP(CDMAdemoDlg, CDialog)
	//{{AFX_MSG_MAP(CDMAdemoDlg)
	ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
	ON_BN_CLICKED(IDC_BUTTON2, OnButton2)
	ON_BN_CLICKED(IDC_BUTTON3, OnButton3)
	ON_LBN_SELCHANGE(IDC_LIST1, OnSelchangeList1)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDMAdemoDlg message handlers

BOOL CDMAdemoDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	CenterWindow(GetDesktopWindow());	// center to the hpc screen
	//--------初始化DMA通道-----------------
	RequestDMASW();
	RequestDMA();
	m_bt1.SetWindowText(_T("Request DMA %x success"));

	//未完待续-------------------------
	return TRUE;  // return TRUE  unless you set the focus to a control
}



void CDMAdemoDlg::OnButton1() 
{
	// TODO: Add your control notification handler code here
	
}

void CDMAdemoDlg::OnButton2() 
{
	// TODO: Add your control notification handler code here
	
}


void CDMAdemoDlg::OnButton3()
{
	StartDMA();
	QueryDMASrc();
	QueryDMADst();
	QueryDMAStat();

}

void CDMAdemoDlg::OnSelchangeList1() 
{
	OnButton3();
	
}

⌨️ 快捷键说明

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