📄 dmademodlg.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 + -