This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
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;
}
Hi Gang,
I'm not sure I fully understand your problem.
The blue code will wait until your McBSP DR pin goes high. So this depends really on your external HW if cod stops at this location or move on ...
Kind regards,
one and zero
GANG ZHANG said:Uint32 * ptr_Base;
Since this corresponds to memory mapped registers (or similar) in your FPGA this should be declared volatile.
GANG ZHANG said:I sampled EMIFA timing with FPGA chipscope, found that the following writing EMIFA program timing is wrong(DSP didn't write CE4 to FPGA).
Do you literally see nothing at all or is it just that the timing is wrong or you're only seeing a partial transfer? More details please!
If you see nothing at all, which is my current interpretation, my best guess would be that perhaps you have enabled the MAR bits corresponding to this address range and made it cacheable.
GANG ZHANG said://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;
What does gen_wr_cmd() do? Does it interact with the FPGA at all?
one and zero said:The blue code will wait until your McBSP DR pin goes high. So this depends really on your external HW if cod stops at this location or move on ...
Hi, one and zero. Thank you for your reply. The reason why my program stop at the blue code is that FPGA needs to parse the 'command' of red code sended via EMIFA and read data from DDR2 interfaced with FPGA, then send data back to DSP via EMIFA. If FPGA doesn't receiver the right EMIFA timing signals, It will not drive McBSP DR pin high.
Brad Griffis said:Do you literally see nothing at all or is it just that the timing is wrong or you're only seeing a partial transfer? More details please!
If you see nothing at all, which is my current interpretation, my best guess would be that perhaps you have enabled the MAR bits corresponding to this address range and made it cacheable.
Hi, Brad. Thanks for your reply. I see nothing at all in chipscope if I don't set breakpoint at the red code(even if my program has been executed to the blue code).
what does the MAR bits ? Are they the registers in Table 5-8( Megamodule Cache Configuration Registers) of SPRS276J?
Brad Griffis said:
What does gen_wr_cmd() do? Does it interact with the FPGA at all?
gen_wr_cmd() is a simple sub function which used to set the vaule of some vairables. It is not interfaced with FPGA at all. It's only related with DSP.
Hi Gang,
when you set a breakpoint in the red code area you see the data in the FPGA?
Kind regards,
one and zero
one and zero said:Hi Gang,
when you set a breakpoint in the red code area you see the data in the FPGA?
Kind regards,
one and zero
yes, I can see the right data in the FPGA if I set a breakpoint in the red code. and if i add code after each *ptr_Base++ = fpga_cmd; and move the breakpoint, I can also see the right data(EMIFA timing signals) in the FPGA.
Hi, Brad. I have added volaitle with Uint32 * ptr_Base and set MAR192 = 0. The problem is still there.
Hi Gang,
could you do the following experiment.
Set a breakpoint in the red area. Check if the data is in the FPGA. Run to the blue area and stop. Look in the FPGA if the data is still there ...
Kind regards,
one and zero
GANG ZHANG said:The reason why my program stop at the blue code is that FPGA needs to parse the 'command' of red code sended via EMIFA and read data from DDR2 interfaced with FPGA, then send data back to DSP via EMIFA. If FPGA doesn't receiver the right EMIFA timing signals, It will not drive McBSP DR pin high.
So the FPGA interfaces with both the EMIFA and the DDR2 interface? Are their data locations that get accessed by both the FPGA and the DSP? If so, you will need to make sure you handle cache coherence.
GANG ZHANG said://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;
Try adding one more line after that:
*ptr_Base; // read back last value to force writes to complete
I'm not sure whether this will do anything or not, but based on the fact that putting a breakpoint in these areas seems to help I wonder if putting this extra read will also help. Let us know if it makes any difference. If so, then we can try to understand why!
Also, I see ptr_Base is defined as type Uint32*. You are trying to send 32-bits of data to your FPGA for each write, correct?
Brad Griffis said:So the FPGA interfaces with both the EMIFA and the DDR2 interface? Are their data locations that get accessed by both the FPGA and the DSP? If so, you will need to make sure you handle cache coherence.
Hi,Brad. FPGA interfaces with both the EMIFA and the DDR2 interface. The data in DDR2 are only accessed by FPGA. When DSP writes data to DDR2, It first send the start address( the first *ptr_Base++ = fpga_cmd;) and the number of data writen to DDR2 ( the second *ptr_Base++ = fpga_cmd;) to FPGA. After FPGA receives these two commands from DSP, DSP starts EMDA3 to send data(32-bit wide) to FPGA via EMIFA, then FPGA write these data to DDR2. DSP read data from DDR2 is similar.
The problem is that now FPGA can't receive the two commands(*ptr_Base++ = fpga_cmd;) from DSP correctly, but it can receive data sent by EMDA3 correctly. The two commands are the premise,. Without these two commands, FPGA doesn't know where and how many data should be writen to DDR2.
Brad Griffis said:Also, I see ptr_Base is defined as type Uint32*. You are trying to send 32-bits of data to your FPGA for each write, correct?
yes. DSP writes 32-bit data to FPGA.
Hi Gang,
one more thing to check:
DDR2 Memory Controller and EMIFA: PRIO_RAISE Bits Should Be Changed From Default Following Reset. The PRIO_RAISE bits should be set to FEh.
Have you done that?
Kind regards,
one and zero
Brad Griffis said:Try adding one more line after that:
*ptr_Base; // read back last value to force writes to complete
Hi, Brad. As your suggestion, I added *ptr_Base; after the last line of red code. It works.
I also do another experiment: I added for(j=0;j<1;j++); after the last line, It also works.
What I want to ask is that does write emifa directly conflicts with edma3 without the added *ptr_Base; or for(j=0;j<1;j++); ?
one and zero said:Hi Gang,
one more thing to check:
DDR2 Memory Controller and EMIFA: PRIO_RAISE Bits Should Be Changed From Default Following Reset. The PRIO_RAISE bits should be set to FEh.
Have you done that?
Kind regards,
one and zero
Hi, one and zero. I am not use DDR2 Memory Controller of C6455. I simply use EMDA3 to write data to RAM in FPGA via EMIFA.
GANG ZHANG said:Hi, Brad. As your suggestion, I added *ptr_Base; after the last line of red code. It works.
I also do another experiment: I added for(j=0;j<1;j++); after the last line, It also works.
What I want to ask is that does write emifa directly conflicts with edma3 without the added *ptr_Base; or for(j=0;j<1;j++); ?
Great! I'm glad you have a solution that works, but I'd still like to make sure we have truly solved the issue and not just covered it.
Without the read at the end (or the delay), are you sure that you never see the data? What I suspect could be happening here is that your EDMA writes might be getting ahead of your CPU writes. Can you check if that's the case? That is, without the read at the end do you see all the EDMA traffic and then see the CPU writes? If so, then I believe the read is the correct solution because that will force the CPU writes to complete before you even start the EDMA.
Hi Gang,
please also make sure that the PRIO_RAISE bits are set to FEh. See usage notes in the errata sheet for details ... it's also documented in the EMIFA User's guide I believe.
Kind regards,
one and zero
Brad Griffis said:Without the read at the end (or the delay), are you sure that you never see the data? What I suspect could be happening here is that your EDMA writes might be getting ahead of your CPU writes. Can you check if that's the case? That is, without the read at the end do you see all the EDMA traffic and then see the CPU writes? If so, then I believe the read is the correct solution because that will force the CPU writes to complete before you even start the EDMA.
Hi, Brad. The problem is solved. I have sampled the data with chipscope in FPGA : Without the read at the end (or the delay), EDMA is surely getting ahead of CPU writes. What you have suspected are right.
Thanks very much for your suggestions.
GANG ZHANG said:I have sampled the data with chipscope in FPGA : Without the read at the end (or the delay), EDMA is surely getting ahead of CPU writes.
Great! I'm glad we were able to fully understand the issue. Although the time delay makes it work, the read is the more robust solution because it will guarantee that you don't kick off the EDMA until the write has completed.
Thanks for reporting back on the issue and for verifying the answer.
Best regards,
Brad