|
RT,自己DIY的DM642板和FPGA板(两块板子,引脚接出),前段时间利用外部中断、EMIF+FPGA逻辑实现了16宽异步读写。
但是当利用EDMA方式读写时发现读出的数据很诡异,每个数字出现四次,实际我在逻辑那段检测到#CE2的低电平后都会更改数据并保持若干个EMIFCLK(该逻辑在CPU读写时没有问题)。
已经尝试过各种EDMA传输模式,好像都不管用。
附上程序段:
#define SampleCol 200 #define SampleRow 6
#define FPGA_Read_CS 0x0a0080000
#pragma DATA_SECTION(ImgRec, ".buffers");
//#pragma DATA_ALIGN(ping,128);
#pragma DATA_ALIGN(ImgRec,8);
Uint16 ImgRec[SampleRow][SampleCol];
extern far void vectors();
static GPIO_Handle hGpio;
void GPIOconfig()
{
hGpio = GPIO_open(GPIO_DEV0,GPIO_OPEN_RESET);
GPIO_reset(hGpio);
GPIO_pinEnable(hGpio,GPIO_PIN4); //使能外部中断口
GPIO_pinDirection(hGpio,GPIO_PIN4,GPIO_INPUT);
GPIO_intPolarity(hGpio,GPIO_PIN4,GPIO_FALLING); //上升沿触发外部中断
}
void EmifConfig()
{
EMIFA_Config myEmifConfig;
myEmifConfig.gblctl=0x00052038;
myEmifConfig.cectl0=0xffffffd3;
myEmifConfig.cectl1=0xfff1d10b;
// CE2空间: RDSETUP=2
myEmifConfig.cectl2=0x20228310;
myEmifConfig.cesec2=0x0000000f;
myEmifConfig.cectl3=0x20228300;
myEmifConfig.cesec3=0x0000000f;
myEmifConfig.cesec0=0x0000000f;
myEmifConfig.cesec1=0x0000000f;
myEmifConfig.sdctl=0x57119000;
myEmifConfig.sdtim=0x00000446;
myEmifConfig.sdext=0x0005452b;
EMIFA_config(&myEmifConfig);
CACHE_setL2Mode(CACHE_32KCACHE);
CACHE_enableCaching(CACHE_EMIFA_CE00);
CACHE_enableCaching(CACHE_EMIFA_CE01);
}
EDMA_Handle hEdma; //Handle for the EDMA channel
EDMA_Handle hEdmaTrans; //Handle for the ping EDMA reload parameters
EDMA_Config cfgEdma; //EDMA configuration structure
EDMA_Config cfgEdmaTrans =
{
//Making Options parameter register - EDMA_OPT
EDMA_OPT_RMK
(
EDMA_OPT_PRI_URGENT,
EDMA_OPT_ESIZE_16BIT, //此处一次传32bit,所以IDX=4
EDMA_OPT_2DS_NO,
EDMA_OPT_SUM_NONE,
EDMA_OPT_2DD_YES,
EDMA_OPT_DUM_INC,
EDMA_OPT_TCINT_YES, //允许传输完成中断
EDMA_OPT_TCC_OF(TCCINTNUM), //通道号
EDMA_OPT_TCCM_OF(TCCINTNUM >> 4),
EDMA_OPT_ATCINT_NO,
EDMA_OPT_ATCC_OF(0),
EDMA_OPT_PDTS_DISABLE,
EDMA_OPT_PDTD_DISABLE,
EDMA_OPT_LINK_YES, //链接
EDMA_OPT_FS_NO
),
EDMA_SRC_OF(FPGA_Read_CS),//Source address register
EDMA_CNT_RMK(EDMA_CNT_FRMCNT_OF(SampleRow-1),EDMA_CNT_ELECNT_OF(SampleCol)), //Transfer count parameter
EDMA_DST_OF(ImgRec), //Destination address parameter
EDMA_IDX_RMK(EDMA_IDX_FRMIDX_OF(SampleCol*2), EDMA_IDX_ELEIDX_OF(0)),//Index parameter
EDMA_RLD_OF(0x00000000) //Count reload/link parameter
};
void setupInterrupts(void)
{
IRQ_globalDisable();
IRQ_setVecs(vectors); /* point to the IRQ vector table */
IRQ_nmiEnable();
IRQ_globalEnable();
IRQ_map(IRQ_EVT_EDMAINT, 8);
IRQ_reset(IRQ_EVT_EDMAINT);
}
//---------Function prototypes---------
extern far void vectors();
void setupInterrupts(void);
//Function used to stop EDMA
void stopEdma(void);
//---------main routine---------
void main()
{
CSL_init();
GPIOconfig();
EmifConfig();
setupInterrupts();
EDMA_clearPram(0x00000000);
hEdma = EDMA_open(EDMA_CHA_EXTINT4, EDMA_OPEN_RESET);
hEdmaTrans = EDMA_allocTable(-1);
cfgEdma = cfgEdmaTrans;
cfgEdmaTrans.rld = EDMA_RLD_RMK(0,hEdmaTrans);
EDMA_config(hEdma, &cfgEdma);
EDMA_config(hEdmaTrans, &cfgEdmaTrans);
EDMA_intDisable(TCCINTNUM);
EDMA_intClear(TCCINTNUM);
EDMA_intEnable(TCCINTNUM); //置CIER第8位为1
IRQ_enable(IRQ_EVT_EDMAINT);
EDMA_enableChannel(hEdma);
while(1);
}
interrupt void
c_int08(void)
{
EDMA_intClear(TCCINTNUM); //传输完成标志清除
stopEdma();
printf ("\nDone.....");
exit(0);
}
因为是驱动验证所以写的不规范,望有过调试经验的高手给予解惑。
|
|