Hi, everyone. In my program, I write data from DSP(c6455) via EMIFA to BLOCKRAM in FPGA. When I debugged my program, I found that my program run differently by setting breakpoint or not. If I set breakpoint at any line with red font, it can run exactly(I can sample the right EMIFA timing signals). But if I set breakpoint at other place or move it, my program will stop at the line with blue font: I sampled EMIFA timing with FPGA chipscope, found that the following writing EMIFA program timing is wrong(DSP didn't write CE4 to FPGA).
//send write command via CE4
ptr_Base = (Uint32 *)0xC0000000;
//the first write command,mainly write the num of 32bit data
fpga_cmd = gen_wr_cmd(num_wr_data,wr_ddr2_start_addr,0);
*ptr_Base++ = fpga_cmd;
// the second write command,mainly write the ddr2 start address
fpga_cmd = gen_wr_cmd(num_wr_data,wr_ddr2_start_addr,1);
*ptr_Base++ = fpga_cmd;
*ptr_Base++ = 0x0;
Can anyone give me some suggestions? Thanks very much for you help.
The following is my program:
#include <stdio.h>
#include <csl_gpio.h>
#include <csl_edma3.h>
#include <soc.h>
#include <stdlib.h>
#include <csl_mcbsp.h>
#include "rd_wr_cmd.h"
/*********************** the declaration of macro ******************************************/
#define BUFF_SZ0 65536
/*********************** the inner register definitioin ************************************/
#define PERLOCK (*(int*)0x02AC0004) // Peripheral Lock Register
#define PERCFG0 (*(int*)0x02AC0008) // Peripheral Configuration register
#define PERCFG1 (*(int*)0x02AC002C) // Peripheral configuration 1
#define EMIFA_CE2CFG (*(int*)0x70000080) // EMIFA CE2 Configuration register
#define EMIFA_CE3CFG (*(int*)0x70000084) // EMIFA CE3 Configuration register
#define EMIFA_CE4CFG (*(int*)0x70000088) // EMIFA CE4 Configuration register
//Mcbsp registers
#define MCBSP0_SPCR (*(volatile int*)0x028C0008) // MCBSP0 Serial port control register
#define MCBSP0_PCR (*(volatile int*)0x028C0024) // MCBSP0 Pin control register
#define MCBSP1_SPCR (*(volatile int*)0x02900008) // MCBSP1 Serial port control register
#define MCBSP1_PCR (*(volatile int*)0x02900024) // MCBSP1 Pin control register
//GPIO registers
#define GPIO_DIR (*(volatile int*)0x02B00010) // GPIO direction register
#define GPIO_INDATA (*(volatile int*)0x02B00020) // GPIO Input Data Register
#define GPIO_CLRDATA (*(volatile int*)0x02B0001C) // GPIO Clear Data Register
#define GPIO_SET_RIS_TRIG (*(volatile int*)0x02B00024) // GPIO Set Rising Edge Interrupt Register
//EDMA3 register
#define EDMA3_IPR (*(volatile int*)0x02A01068) // Interrupt Pending Register
#define EDMA3_IPRH (*(volatile int*)0x02A0106C) // Interrupt Pending High Register
#define EDMA3_ICR (*(volatile int*)0x02A01070) // Interrupt Clear Register
#define EDMA3_ICRH (*(volatile int*)0x02A01074) // Interrupt Clear High Register
#define EDMA3_EESRH (*(volatile int*)0x02A01034) // Event Enable Set Register High
#define EDMA3_ER (*(volatile int*)0x02A01000) // Event Register
#define EDMA3_ERH (*(volatile int*)0x02A01004) // Event Register
#define EDMA3_ESRH (*(volatile int*)0x02A01014) // Event Set Register High
//EDMA3 PARAM MAP
#define EDMA3_CHA47_OPT (*(volatile int*)0x02A045E0)
#define EDMA3_CHA47_SRC (*(volatile int*)0x02A045E4)
/********************** the CSL structure declaration ***********************************/
CSL_Status intStat,status;
/* MCBSP handle*/
CSL_McbspContext pContext;
CSL_McbspObj mcbspObj0;
CSL_McbspHandle hMcbsp0;
CSL_McbspObj mcbspObj1;
CSL_McbspHandle hMcbsp1;
/* EDMA3 handle */
CSL_Edma3Handle hModule;
CSL_Edma3ChannelHandle hChannel0,hChannel1;
CSL_Edma3ChannelErr chErrClear;
CSL_Edma3Context edmaContext;
CSL_Edma3QueryInfo info;
CSL_Edma3CmdDrae regionAccess;
CSL_Edma3ChannelAttr chAttr;
CSL_Edma3ParamSetup myParamSetup;
CSL_Edma3ParamSetup linkParamSetup;
CSL_Edma3Obj edmaObj;
CSL_Edma3ChannelObj chObj;
CSL_Edma3ParamHandle hParamRd;
CSL_Edma3ParamHandle hParamWr;
/*********************** the alignment memory declaration ******************************/
#pragma DATA_SECTION(rd_buffer,".bss");
#pragma DATA_ALIGN(rd_buffer,256);
int rd_buffer[BUFF_SZ0];
#pragma DATA_SECTION(wr_buffer_not,".bss");
#pragma DATA_ALIGN(wr_buffer_not,256);
int wr_buffer[BUFF_SZ0];
#pragma DATA_SECTION(wr_buffer,".bss");
#pragma DATA_ALIGN(wr_buffer,256);
int wr_buffer_not[BUFF_SZ0];
void main()
{
/*************** the declaration of 2-dimension axis of x,y--(x0,y0),(x1,y1) ***************/
Uint32 x0,x1;
Uint32 y0,y1;
Uint32 num_pixels,num_rd_pixels;
Uint32 num_wr_pixels; //number of bytes write to ddr2 sdram(32bit)
Uint32 fpga_cmd;
Uint16 Mcbsp_outData;
Uint32 img_width,img_height;
Uint32 num_wr_data;
Uint32 wr_ddr2_start_addr;
Uint32 * ptr_Base;
Uint32 i,j,tmp;
Uint32 aCnt,bCnt;
Uint32 error_flag;
Uint32 go_on;
/**************** set the value of the above variables******************************************/
img_width = 1024;
img_height = 1024;
num_wr_data = 0x3800;
wr_ddr2_start_addr = 0x0;
num_wr_pixels = 4*num_wr_data;
x0 = 0x00000000;
x1 = 0x0000001B;
y0 = 0x00000000;
y1 = 0x000003FF;
if (x0 >= 8192 | y0 >= 8192 | x1 >= 8192 | y1 >= 8192)
{
printf("ERROR : the value of (x0,y0),(x1,y1) can't greater than (8191,8191),(8191,8191)");
return;
}
num_pixels = (y1 - y0 + 1) * (x1 - x0 + 1);
if (num_pixels && 0x00000001)
{
num_rd_pixels = (num_pixels + 1)/2;
}
else
{
num_rd_pixels = num_pixels/2;
}
//initialize wr_buffer memory
for(i=0; i<BUFF_SZ0*2; i++)
{
if((i%2) == 0)
tmp = i & 0x0000FFFF;
else
{
tmp = ((i & 0x0000FFFF)<<16)|tmp;
wr_buffer[i/2]=tmp;
}
}
for(i=0;i<BUFF_SZ0;i++)
{
wr_buffer_not[i] = wr_buffer[i+1];
}
wr_buffer_not[BUFF_SZ0-1] = wr_buffer[0];
memset(rd_buffer,0,sizeof(rd_buffer));
/*********configure EDMA3,EMIFA_CE3,GPIO,Mcbsp for reading data from RAM in FPGA**********/
PERLOCK = 0x0F0A0B00; //Unlock the register
PERCFG0 = 0x00004540; //Unlock MCBSP, GPIO, TIMER
PERCFG1 = 0x00000001; //Unlock EMIFA
EMIFA_CE3CFG = 0x8000040E; //Configre EMIFA CE3 as synchronous RAM interface
EMIFA_CE4CFG = 0x8000040A; //Configre EMIFA CE4 as synchronous RAM interface
// EMIFA_CE3CFG = 0x8000010A; //Configre EMIFA CE3 as synchronous RAM interface
// EMIFA_CE4CFG = 0x8000010A; //Configre EMIFA CE4 as synchronous RAM interface
/*************************** Setup Module for Mcbsp ***************************************/
/* Initialize the MCBSP CSL module */
status = CSL_mcbspInit(&pContext);
/* Open the CSL module */
hMcbsp0 = CSL_mcbspOpen (&mcbspObj0, CSL_MCBSP_0, NULL, &status);
hMcbsp1 = CSL_mcbspOpen (&mcbspObj1, CSL_MCBSP_1, NULL, &status);
MCBSP0_SPCR &= ~0x00010001;//Mcbsp0:set XRST,RRST of SPCR =0
MCBSP0_SPCR &= ~0x00008000;//Mcbsp0:set DLB = 0
MCBSP0_PCR |= 0x00003000;//Mcbsp0:set XIOEN,RIOEN of PCR = 1
MCBSP0_PCR |= 0x00000100;//Mcbsp0:set CLKRM =1
MCBSP1_SPCR &= ~0x00010001;//Mcbsp1:set XRST,RRST of SPCR =0
MCBSP1_SPCR &= ~0x00008000;//Mcbsp1:set DLB = 0
MCBSP1_PCR |= 0x00003000;//Mcbsp1:set XIOEN,RIOEN of PCR = 1
// clear mcbps clkr0 = 0;
Mcbsp_outData = 0;
CSL_mcbspIoWrite(hMcbsp0, CSL_MCBSP_IO_CLKR, Mcbsp_outData);
/************************** Edma Module Initialization ***********************************/
CSL_edma3Init(&edmaContext);
/* Edma Module Level Open */
hModule = CSL_edma3Open(&edmaObj,CSL_EDMA3,NULL,&status);
EDMA3_EESRH = 0x0000C000;
EDMA3_ICR = 0xFFFFFFFF;
EDMA3_ICRH = 0xFFFFFFFF;//clear all of the IPRH.
chAttr.chaNum = CSL_EDMA3_CHA_47;
hChannel0 = CSL_edma3ChannelOpen(&chObj,CSL_EDMA3,&chAttr,&status);
/* Setup the EDMA3 channel0 to EVENT-47 and EDMA3TC queue 1 */
CSL_edma3HwChannelSetupParam (hChannel0, CSL_EDMA3_CHA_47);
CSL_edma3HwChannelSetupQue(hChannel0, CSL_EDMA3_QUE_1);
/* Channel setup */
hParamWr = CSL_edma3GetParamHandle(hChannel0,CSL_EDMA3_CHA_47,&status);
chAttr.chaNum = CSL_EDMA3_CHA_46;
hChannel1 = CSL_edma3ChannelOpen(&chObj,CSL_EDMA3,&chAttr,&status);
/* Setup the EDMA3 channel0 to EVENT-46 and EDMA3TC queue 2 */
CSL_edma3HwChannelSetupParam (hChannel0, CSL_EDMA3_CHA_46);
CSL_edma3HwChannelSetupQue(hChannel0, CSL_EDMA3_QUE_2);
/* Channel setup */
hParamRd = CSL_edma3GetParamHandle(hChannel0,CSL_EDMA3_CHA_46,&status);
/*********************Reset GP0*********************************************/
ptr_Base = (Uint32 *)0xC0000000;
//first cmd
fpga_cmd = Dsp_Rw_End(0);
*ptr_Base++ = fpga_cmd;
//second cmd
fpga_cmd = Dsp_Rw_End(1);
*ptr_Base++ = fpga_cmd;
*ptr_Base++ = 0x0;
/********************Change the image width X height to 1024x1024**********************************************/
ptr_Base = (Uint32 *)0xC0000000;
//send the first change target command to FPGA
fpga_cmd = gen_img_resolution(img_width,img_height,0);
*ptr_Base++ = fpga_cmd;
//send the second change target command to FPGA
fpga_cmd = gen_img_resolution(img_width,img_height,1);
*ptr_Base++ = fpga_cmd;
*ptr_Base++ = 0x0;
/* execute the write&read command cycle */
for(i=0;i<10000;i++)
{
error_flag = 0;
go_on = 1;
/********************WRITE data to DDR2 SDRAM via FPGA interface module******************************/
myParamSetup.option = CSL_EDMA3_OPT_MAKE( CSL_EDMA3_ITCCH_DIS,\
CSL_EDMA3_TCCH_DIS,\
CSL_EDMA3_ITCINT_DIS,\
CSL_EDMA3_TCINT_DIS,\
CSL_EDMA3_CHA_47,\
CSL_EDMA3_TCC_NORMAL,\
CSL_EDMA3_FIFOWIDTH_NONE,\
CSL_EDMA3_STATIC_DIS,\
CSL_EDMA3_SYNC_A,\
CSL_EDMA3_ADDRMODE_INCR,\
CSL_EDMA3_ADDRMODE_INCR);
if(i%2 == 0)
{
myParamSetup.srcAddr = (Uint32)wr_buffer;
}
else
{
myParamSetup.srcAddr = (Uint32)wr_buffer_not;
}
myParamSetup.dstAddr = 0xB0000000;
myParamSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(num_wr_pixels,1);
myParamSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE(0,0);//for wr pixels <=64K bytes
myParamSetup.linkBcntrld = CSL_EDMA3_LINKBCNTRLD_MAKE(0xFFFF,0);
myParamSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0,0);
myParamSetup.cCnt = 1;
CSL_edma3ParamSetup(hParamWr,&myParamSetup);
CSL_edma3HwChannelControl(hChannel0, CSL_EDMA3_CMD_CHANNEL_ENABLE, NULL);
if(EDMA3_CHA47_OPT == 0x0 || EDMA3_CHA47_SRC == 0x0)
{
break;
}
//send write command via CE4
ptr_Base = (Uint32 *)0xC0000000;
//the first write command,mainly write the num of 32bit data
fpga_cmd = gen_wr_cmd(num_wr_data,wr_ddr2_start_addr,0);
*ptr_Base++ = fpga_cmd;
// the second write command,mainly write the ddr2 start address
fpga_cmd = gen_wr_cmd(num_wr_data,wr_ddr2_start_addr,1);
*ptr_Base++ = fpga_cmd;
*ptr_Base++ = 0x0;
//manully trigger edma3 47th event
EDMA3_ESRH = 0x00008000;
while(1)
{
if((MCBSP0_PCR & 0x00000010) == 0x0)
{
}
else
{
break;
}
}
EDMA3_ICRH = 0x00008000;//clear the IPRH bit of EVENT-47 to 0
/*********************Reset GP0*********************************************/
ptr_Base = (Uint32 *)0xC0000000;
//first cmd
fpga_cmd = Dsp_Rw_End(0);
*ptr_Base++ = fpga_cmd;
//second cmd
fpga_cmd = Dsp_Rw_End(1);
*ptr_Base++ = fpga_cmd;
*ptr_Base++ = 0x0;
/********************READ data from DDR2 SDRAM via FPGA interface module *************************************/
memset(rd_buffer,0,sizeof(rd_buffer));
/* param setup */
myParamSetup.option = CSL_EDMA3_OPT_MAKE( CSL_EDMA3_ITCCH_DIS,\
CSL_EDMA3_TCCH_DIS,\
CSL_EDMA3_ITCINT_DIS,\
CSL_EDMA3_TCINT_EN,\
CSL_EDMA3_CHA_46,\
CSL_EDMA3_TCC_NORMAL,\
CSL_EDMA3_FIFOWIDTH_NONE,\
CSL_EDMA3_STATIC_DIS,\
CSL_EDMA3_SYNC_A,\
CSL_EDMA3_ADDRMODE_INCR,\
CSL_EDMA3_ADDRMODE_INCR);
myParamSetup.srcAddr = 0xB0000000;
myParamSetup.dstAddr = (Uint32)rd_buffer;
myParamSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(4*num_rd_pixels,1);
myParamSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE(0,0);
myParamSetup.linkBcntrld = CSL_EDMA3_LINKBCNTRLD_MAKE(0xFFFF,0);
myParamSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0,0);
myParamSetup.cCnt = 1;
CSL_edma3ParamSetup(hParamRd,&myParamSetup);
CSL_edma3HwChannelControl(hChannel1, CSL_EDMA3_CMD_CHANNEL_ENABLE, NULL);
//send READ command
ptr_Base = (Uint32 *)0xC0000000;
//send the first READ command to FPGA
fpga_cmd = gen_rd_cmd(x0,y0,0);
*ptr_Base++ = fpga_cmd;
//send the second READ command to FPGA
fpga_cmd = gen_rd_cmd(x1,y1,1);
*ptr_Base++ = fpga_cmd;
*ptr_Base++ = 0x0;
while(1)
{
if((MCBSP0_PCR & 0x00000010) == 0x0)
{
}
else
{
break;
}
}
EDMA3_ESRH = 0x00004000;
do{
}
while (!(EDMA3_IPRH & 0x00004000));
EDMA3_ICRH = 0x00004000;//clear the IPRH bit of EVENT-46 to 0.
Mcbsp_outData = CSL_MCBSP_IO_CLKR;
CSL_mcbspIoWrite(hMcbsp0, CSL_MCBSP_IO_CLKR, Mcbsp_outData);
/*********************Reset GP0*********************************************/
ptr_Base = (Uint32 *)0xC0000000;
//first cmd
fpga_cmd = Dsp_Rw_End(0);
*ptr_Base++ = fpga_cmd;
//second cmd
fpga_cmd = Dsp_Rw_End(1);
*ptr_Base++ = fpga_cmd;
*ptr_Base++ = 0x0;
//set mcbsp clkr0 = 0;
Mcbsp_outData = 0;
CSL_mcbspIoWrite(hMcbsp0, CSL_MCBSP_IO_CLKR, Mcbsp_outData);
/* Compare whether the tranfer data are equal to each other */
printf("The %4d Transfer:\n",i);
for(j=0;j<num_rd_pixels;)
{
if(i%2 == 0)
{
if(rd_buffer[j] != wr_buffer[j])
{
printf("Error:rd_buffer[%x]= 0x%08x; wr_buffer[%x]= 0x%08x\n",j,rd_buffer[j],j,wr_buffer[j]);
error_flag++;
}
}
else
{
if(rd_buffer[j] != wr_buffer_not[j])
{
printf("Error:rd_buffer[%x]= 0x%08x; wr_buffer_not[%x]= 0x%08x\n",j,rd_buffer[j],j,wr_buffer_not[j]);
error_flag++;
}
}
j +=8;
}
if(error_flag != 0)
{
printf("GO ON OR NOT: =0--RETURN; =1--GO ON!");
scanf("%d",&go_on);
printf("\n");
}
if(go_on == 0)
break;
}
/*************************** Close EDMA3,MCBSP module ********************************/
/* Disable channel and clear the EDMA event registers */
CSL_edma3HwChannelControl(hChannel0,CSL_EDMA3_CMD_CHANNEL_DISABLE,NULL);
CSL_edma3HwChannelControl(hChannel0,CSL_EDMA3_CMD_CHANNEL_CLEAR,NULL);
CSL_edma3HwChannelControl(hChannel1,CSL_EDMA3_CMD_CHANNEL_DISABLE,NULL);
CSL_edma3HwChannelControl(hChannel1,CSL_EDMA3_CMD_CHANNEL_CLEAR,NULL);
/* clear the error registers */
chErrClear.missed = TRUE;
chErrClear.secEvt = TRUE;
CSL_edma3HwChannelControl (hChannel0, CSL_EDMA3_CMD_CHANNEL_CLEARERR, &chErrClear);
CSL_edma3HwChannelControl (hChannel1, CSL_EDMA3_CMD_CHANNEL_CLEARERR, &chErrClear);
CSL_edma3ChannelClose(hChannel0);
CSL_edma3ChannelClose(hChannel1);
CSL_edma3Close(hModule);
/* close Mcbsp0*/
CSL_mcbspClose(hMcbsp0);
CSL_mcbspClose(hMcbsp1);
return;
}