InOut Simultaneous Streaming Issue with EZ USB FX2

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Jobin
Level 1
Level 1
First reply posted First question asked Welcome!

For our new application, we are trying to stream data in & out over EP02 and EP86 eps of CY7C68013A128AXC. We are using VC++ host app to source/sink the data using a que of buffer requests as in the reference streaming application. Other side we have a ProAsic3 FPGA to echo the data.

We have another design for In streaming over two EPs and it is working at high bit rates without any issue.

In the present In/Out design, we are looping the data from an FPGA but seeing missing of a byte somewhere around in a burst of 32bytes(no specific pattern).

Our code from firmware, FPGA & host app are pasted below. Can we know the why we are missing the data inbtw?

 

TDInit

-----------------------------------------------------------------------------------------------------------

void TD_Init(void) // Called once at startup
{
int i;
// set the CPU clock to 48MHz
//CPUCS = ((CPUCS & ~bmCLKSPD) | bmCLKSPD1) ;
//CPUCS=CPUCS&0xe7;
// set the slave FIFO interface to 48MHz
//IFCONFIG |= 0x40;
CPUCS = ((CPUCS & ~bmCLKSPD) | bmCLKSPD1) ; //48MHz
// Registers which require a synchronization delay, see section 15.14
// FIFORESET FIFOPINPOLAR
// INPKTEND OUTPKTEND
// EPxBCH:L REVCTL
// GPIFTCB3 GPIFTCB2
// GPIFTCB1 GPIFTCB0
// EPxFIFOPFH:L EPxAUTOINLENH:L
// EPxFIFOCFG EPxGPIFFLGSEL
// PINFLAGSxx EPxFIFOIRQ
// EPxFIFOIE GPIFIRQ
// GPIFIE GPIFADRH:L
// UDMACRCH:L EPxGPIFTRIG
// GPIFTRIG

// Note: The pre-REVE EPxGPIFTCH/L register are affected, as well...
// ...these have been replaced by GPIFTC[B3:B0] registers

// default: all endpoints have their VALID bit set
// default: TYPE1 = 1 and TYPE0 = 0 --> BULK
// default: EP2 and EP4 DIR bits are 0 (OUT direction)
// default: EP6 and EP8 DIR bits are 1 (IN direction)
// default: EP2, EP4, EP6, and EP8 are double buffered

// we are just using the default values, yes this is not necessary...
//EP1OUTCFG = 0xA0;
//EP1INCFG = 0xA0;
// SYNCDELAY; // see TRM section 15.14
//EP4CFG = 0xA0;
//SYNCDELAY;
//EP6CFG = 0xE2; //Dual
// EP6CFG = 0xe0; //Quad
// EP6CFG = 0xf0;
//SYNCDELAY;
// EP8CFG = 0xE0;

// out endpoints do not come up armed. Arm EP1, EP2 and EP4 OUT endpoints
//EP1OUTBC = 0x40; // arm the EP1 OUT endpoint by writing to the byte count
// since the defaults are double buffered we must write dummy byte counts twice
//SYNCDELAY;
//EP2BCL = 0x80; // arm EP2OUT by writing byte count w/skip.
//SYNCDELAY;
//EP2BCL = 0x80;
//SYNCDELAY;
//EP4BCL = 0x80; // arm EP4OUT by writing byte count w/skip.
//SYNCDELAY;
//EP4BCL = 0x80;


//INT0# and INT1#
//PORTACFG = 0x03; // PA0 and PA1 are INT0 and INT1

//TCON |= 0x05; // Detect INT0 and INT1 on fallinfg edge
//IE |= 0x05; // Enable External Interrupts 0 and 1

EA = 1; // Enable Global Interrupt

EP1OUTBC=64;
EP1INBC=64;

//EP2CFG = 0xa2;
//EP4CFG = 0xA0;
SYNCDELAY;

//EP2BCH=0x02;
//EP2BCL=1;
EP4BCL=1;


//EP0BCL=64;
EP1INBC=1;

 

/**********************Timer0 Init***************************/

// CKCON=0xf7;
//CKCON|=0x8;
//TL0=TH0=255;
//TH0=0x0f;
//TL0=0xa0;
//TH0=0x7d;//0x0f;
//TL0=0x0;//0xa0;
//TR0=1;/*Start Timer0*/
//TMOD=0x00;/*Timer0 Mode0*/
//TMOD=0x10;
//IE|=2;//ET0=1; /*Enable Timer0 Interrupt*/
//PT0=1; /*Timer Int Priority Low*/
//goto skip;
EP6AUTOINLENH=0x02;
EP6AUTOINLENL=0x00;


//EP6ISOINPKTS=0x02;

EP6CFG =0xe0;//0xd0;//0xe0;//0xd0;//0xe0;//0xd0;// 0xe0;//0xd0;//0xE0; // EP2 is DIR=IN, TYPE=BULK, SIZE=512, BUF=4x
EP6FIFOCFG=0x0c;

//EP4FIFOCFG =0x15;
//EP4CFG=0xa0;
EP2CFG = 0xa0;
EP2FIFOCFG=0x10;//0x11;
EP2AUTOINLENH=0x02;
EP2AUTOINLENL=0x00;


PINFLAGSAB=0;
SYNCDELAY;
PINFLAGSCD=0;
FIFOPINPOLAR=0;



// EPIE |= bmBIT3 |bmBIT4 | bmBIT5; // Enable EP2, EP4 and EP1 OUT Endpoint interrupts
// EPIE |= bmBIT6 |bmBIT7 | bmBIT2; // Enable EP6, EP8 and EP1 IN Endpoint interrupts

// Prepare data

FIFORESET=0x80;
SYNCDELAY;
FIFORESET=0x04;
SYNCDELAY;
FIFORESET=0x00;

EP6BCH = 0x02;
EP6BCL = 0x00;
EP2BCL=1;



IOE=(0<<4)|0xE;/*Assert HRE*/ SYNCDELAY;SYNCDELAY;
IFCONFIG =0xcb;//|= 0x40;
SYNCDELAY;



OED=0xff;
OEE=0xff; /*Port E As Output for FPGA CMD*/
OEB=0xff; /*Port B As Output for FPGA Data*/
SYNCDELAY;SYNCDELAY;SYNCDELAY;SYNCDELAY;
IOE=0x0d;
SYNCDELAY;SYNCDELAY;SYNCDELAY;SYNCDELAY;

IOE=0x0f;

//CPUCS&=0xe7;//12MHz

//CPUCS=0xef;//24MHZ

EP0BCL=0x00; //ARM EP0 Control EP
EP0CS |= bmHSNAK;
// We want to get SOF interrupts
USBIE |= bmSOF;

EPIE |= bmBIT3 |bmBIT4 | bmBIT5; // Enable EP2, EP4 and EP1 OUT Endpoint interrupts
EPIE |= bmBIT6 |bmBIT7 | bmBIT2; // Enable EP6, EP8 and EP1 IN Endpoint interrupts

// enable dual autopointer feature
AUTOPTRSETUP |= 0x01;

Rwuen = TRUE; // Enable remote-wakeup
EA=1;
}

-------------------------------------------------------------------------------------------------------------------------

HDL

---------------------------------------------------------


SLOE<=TRE;
PKT_END<='1';

LOOP_BACK :PROCESS(RST, LINK_CLK)
begin

if(RST='0')then
FIFO_ADR<="00"; --- out FIFO
TRE<= '1';
TWE <= '1';
db_cont1<='1'; --by default write

db_out<=X"0000";

lbFsm<=IDLE;

elsif rising_edge(LINK_CLK) then

case lbFsm is

when IDLE=>
TWE<='1';
TRE<='1';
db_cont1<='1';
-- lbFsm<=TRE_HIGH;
if(MCU_FIFO_EMPTY = '1' ) then --if MCU OUT fifo not empty
lbFsm<=TRE_HIGH;
TRE<='0';

end if;

when TRE_HIGH=>

--db_out<=db_in;

TRE<='1';
lbFsm<=SET_IN_FIFO_ADR;

when SET_IN_FIFO_ADR=>
FIFO_ADR<="10";
lbFsm<=WRITE_EP;

when WRITE_EP=>

--lbFsm<=SET_OUT_FIFO_ADR;

if(MCU_FIFO_FULL = '1' ) then --if MCU IN fifo not full
db_cont1<='0';
db_out<=db_out+1;
lbFsm<=TWE_LOW;
end if;

when TWE_LOW=>
TWE<='0';
lbFsm<=TWE_HIGH;

when TWE_HIGH=>

TWE<='1';
lbFsm<=SET_OUT_FIFO_ADR;

when SET_OUT_FIFO_ADR=>
FIFO_ADR<="00";
lbFsm<=IDLE;

when others=>

end case;



end if;

end PROCESS LOOP_BACK;

--------------------------------------------------------------------------------------------------------------------------

VC++ code

--------------------------------------------------------------------------------------------------------------------------

/**********************Reading the Data from EP86*********************************/
UINT Xfer_StreamerIn(LPVOID params)
{

CATS_CHECKOUTDlg *dlg = (CATS_CHECKOUTDlg *) params;


static Err=0;

int QueueSize =dlg->m_que_size;//256;//m_Words;//1;// 4;
int Timeout = dlg->m_time_out;//300;//23;//2097;

int n =2;//1;//4;//1;// dlg->m_PacketsCombo.GetCurSel();

//int PPX =dlg->m_usbTransferSize/512;//pow(2,n + 3);//204m_Frames;//12m_Frames;// (int) pow(2,n + 3);

int PPX =pow(2,n + 3);

static unsigned int tmr_word=0;
FILE *fp1,*fp2,*fp3,*fp4,*fp5;

log_enb=true;

if(log_enb)
{
fp1=fopen("EZ_USB_LOG.txt","wt");
}

if (!dlg->USBDevice->IsOpen()) {
AfxMessageBox("SORRY, U DON'T HAVE BSED LABS CHECKOUT CARD.", MB_OK | MB_ICONEXCLAMATION);
return false;
}


if (!dlg->InEndPt) {
AfxMessageBox("SORRY, U DON'T HAVE BSED LABS PCM DECODER CARD", MB_OK | MB_ICONEXCLAMATION);
return false;
}

//unsigned int StrMinFrame[256];
// Allocate the arrays needed for queueing
PUCHAR *buffers = new PUCHAR[QueueSize];
CCyIsoPktInfo **isoPktInfos = new CCyIsoPktInfo*[QueueSize];
PUCHAR *contexts = new PUCHAR[QueueSize];
OVERLAPPED *inOvLap = new OVERLAPPED[QueueSize];

LONG i;
//LONG len =dlg->m_usbTransferSize;// dlg->InEndPt->MaxPktSize * PPX; // Each xfer request will get PPX isoc packets
LONG len =dlg->InEndPt->MaxPktSize * PPX;

dlg->InEndPt->SetXferSize(len);

for (i=0; i< QueueSize; i++) {
buffers[i] = new UCHAR[len];
isoPktInfos[i] = new CCyIsoPktInfo[PPX];
memset(&(inOvLap[i]),0,sizeof(OVERLAPPED));
inOvLap[i].hEvent = CreateEvent(NULL, false, false, NULL);
}

// Queue-up the first batch of transfer requests
for (i=0; i< QueueSize; i++)
contexts[i] = dlg->InEndPt->BeginDataXfer(buffers[i], len, &inOvLap[i]);


i=0;
//dlg->t1 = GetTickCount();

while(dlg->bStreaming) {
LONG rLen = len; // Reset this each time through because
// FinishDataXfer may modify it

// Wait for the xfer to complete.
if (!dlg->InEndPt->WaitForXfer(&inOvLap[i], INFINITE)) {
dlg->InEndPt->Abort();
//Wait for the stalled command to complete
WaitForSingleObject(inOvLap[i].hEvent,INFINITE);
}


bool success=dlg->InEndPt->FinishDataXfer(buffers[i], rLen, &inOvLap[i], contexts[i], isoPktInfos[i]);

if(success)
{
//dlg->t2 = GetTickCount();

CCyIsoPktInfo *pkts = isoPktInfos[i];
for (int j=0; j< PPX; j++)
{
pkts[j].Length = 0; // Reset to zero for re-use.

}
}


 

 

dlg->bRefresh=false;

if(!success)
{
//AfxMessageBox("NO SIGNAL!");
AfxMessageBox("USB TIME OUT OCCURED.TRY WITH A HIGHER TIME OUT VALUE");
dlg->bStreaming=false;
GetLocalTime(&T);

if(log_enb)
{

fclose(fp1);

}

CloseHandle(inOvLap[i].hEvent);
delete [] buffers[i];
delete [] isoPktInfos;
delete [] contexts;
delete [] inOvLap;
dlg->XferThread = NULL;
return(true);
}
static unsigned int frame_cntr=0;

unsigned int data;
int k=0;
CString tmr;
static unsigned int d=0;

if(success)
for(int m=0;m<rLen;m++)

{


data=buffers[i][m];

if(log_enb) fprintf(fp1,"%02X ",data);

d++;
d&=0x1f;

if(m&0xf==0)
if(log_enb) fprintf(fp1,"\n ");


}



// Re-submit this request to keep the queue full
contexts[i] = dlg->InEndPt->BeginDataXfer(buffers[i], len, &inOvLap[i]);

i++;
if (i == QueueSize) i=0;

}

 

if(log_enb)
{


GetLocalTime(&T);


fclose(fp1);


}


// Clean-up
dlg->InEndPt->Abort();
WaitForSingleObject(inOvLap[i].hEvent,INFINITE);

for (i=0; i< QueueSize; i++) { // Wait for all the queued requests to be cancelled
LONG rLen = len;

 

if (!dlg->InEndPt->WaitForXfer(&inOvLap[i], 1)) {

dlg->InEndPt->Abort();
//AfxMessageBox("USB CONNECTION ERROR");
dlg->bStreaming=false;
// Wait for the stalled command to complete
WaitForSingleObject(inOvLap[i].hEvent,1);//INFINITE);
break;

}


//Release contexts[i]


CloseHandle(inOvLap[i].hEvent);

delete [] buffers[i];

delete [] isoPktInfos[i];
}


Sleep(100);
delete [] buffers;
delete [] contexts;
delete [] isoPktInfos;
delete [] inOvLap;
Thread1Completed=true;

dlg->XferThread = NULL;
//dlg->m_lst.ResetContent();


return true;

}

/////////////////////////////////////////////////////////////////////////////////////////////
/**********************Reading the Data from EP86*********************************/
UINT Xfer_StreamerOut(LPVOID params)
{

CATS_CHECKOUTDlg *dlg = (CATS_CHECKOUTDlg *) params;


static Err=0;

int QueueSize =dlg->m_que_size;//256;//m_Words;//1;// 4;
int Timeout = dlg->m_time_out;//300;//23;//2097;

int n =2;//1;//4;//1;// dlg->m_PacketsCombo.GetCurSel();

//int PPX =dlg->m_usbTransferSize/512;//pow(2,n + 3);//204m_Frames;//12m_Frames;// (int) pow(2,n + 3);

int PPX =pow(2,n + 3);//204m_Frames;//12m_Frames;// (int) pow(2,n + 3);

static unsigned int tmr_word=0;
FILE *fp1,*fp2,*fp3,*fp4,*fp5;

log_enb=true;

if(log_enb)
{
fp1=fopen("EZ_USB_LOG.txt","wt");
}

if (!dlg->USBDevice->IsOpen()) {
AfxMessageBox("SORRY, U DON'T HAVE BSED LABS CHECKOUT CARD.", MB_OK | MB_ICONEXCLAMATION);
return false;
}


if (!dlg->OutEndPt) {
AfxMessageBox("SORRY, U DON'T HAVE BSED LABS PCM DECODER CARD", MB_OK | MB_ICONEXCLAMATION);
return false;
}

//unsigned int StrMinFrame[256];
// Allocate the arrays needed for queueing
PUCHAR *buffers = new PUCHAR[QueueSize];
CCyIsoPktInfo **isoPktInfos = new CCyIsoPktInfo*[QueueSize];
PUCHAR *contexts = new PUCHAR[QueueSize];
OVERLAPPED *outOvLap = new OVERLAPPED[QueueSize];

LONG i;
//LONG len =dlg->m_usbTransferSize;// dlg->InEndPt->MaxPktSize * PPX; // Each xfer request will get PPX isoc packets

LONG len =dlg->InEndPt->MaxPktSize * PPX;

dlg->OutEndPt->SetXferSize(len);

for (i=0; i< QueueSize; i++) {
buffers[i] = new UCHAR[len];
isoPktInfos[i] = new CCyIsoPktInfo[PPX];
memset(&(outOvLap[i]),0,sizeof(OVERLAPPED));
outOvLap[i].hEvent = CreateEvent(NULL, false, false, NULL);
}

// Queue-up the first batch of transfer requests
for (i=0; i< QueueSize; i++)
contexts[i] = dlg->OutEndPt->BeginDataXfer(buffers[i], len, &outOvLap[i]);



//dlg->t1 = GetTickCount();

for(i=0;i<QueueSize;i++)
for(int m=0;m<len;m++)
{
buffers[i][m]=m&0xf;

}


i=0;

while(dlg->bStreaming) {
LONG rLen = len; // Reset this each time through because
// FinishDataXfer may modify it

// Wait for the xfer to complete.
if (!dlg->OutEndPt->WaitForXfer(&outOvLap[i], INFINITE)) {
dlg->OutEndPt->Abort();
//Wait for the stalled command to complete
WaitForSingleObject(outOvLap[i].hEvent,INFINITE);
}

//for(int m=0;m<rLen;m++)
{
// buffers[i][m]=m&0xf;

}

bool success=dlg->OutEndPt->FinishDataXfer(buffers[i], rLen, &outOvLap[i], contexts[i], isoPktInfos[i]);

if(success)
{
//dlg->t2 = GetTickCount();

CCyIsoPktInfo *pkts = isoPktInfos[i];
for (int j=0; j< PPX; j++)
{
pkts[j].Length = 0; // Reset to zero for re-use.

}
}


 

 

dlg->bRefresh=false;

if(!success)
{
//AfxMessageBox("NO SIGNAL!");
AfxMessageBox("USB TIME OUT OCCURED.TRY WITH A HIGHER TIME OUT VALUE");
dlg->bStreaming=false;
GetLocalTime(&T);

if(log_enb)
{

fclose(fp1);

}

CloseHandle(outOvLap[i].hEvent);
delete [] buffers[i];
delete [] isoPktInfos;
delete [] contexts;
delete [] outOvLap;
dlg->XferThread = NULL;
return(true);
}
static unsigned int frame_cntr=0;

unsigned int data;
int k=0;
CString tmr;
static unsigned int d=0;

//if(success)
// for(int m=0;m<rLen;m++)

// {


//data=buffers[i][m];

// if(log_enb) fprintf(fp1,"%02X ",data);

//}



// Re-submit this request to keep the queue full
contexts[i] = dlg->OutEndPt->BeginDataXfer(buffers[i], len, &outOvLap[i]);

i++;
if (i == QueueSize) i=0;

Sleep(10);


}

 

if(log_enb)
{


GetLocalTime(&T);


fclose(fp1);


}


// Clean-up
dlg->OutEndPt->Abort();
WaitForSingleObject(outOvLap[i].hEvent,INFINITE);

for (i=0; i< QueueSize; i++) { // Wait for all the queued requests to be cancelled
LONG rLen = len;

 

if (!dlg->OutEndPt->WaitForXfer(&outOvLap[i], 1)) {

dlg->OutEndPt->Abort();
//AfxMessageBox("USB CONNECTION ERROR");
dlg->bStreaming=false;
// Wait for the stalled command to complete
WaitForSingleObject(outOvLap[i].hEvent,1);//INFINITE);
break;

}


//Release contexts[i]


CloseHandle(outOvLap[i].hEvent);

delete [] buffers[i];

delete [] isoPktInfos[i];
}


Sleep(100);
delete [] buffers;
delete [] contexts;
delete [] isoPktInfos;
delete [] outOvLap;
Thread1Completed=true;

dlg->XferThread = NULL;
//dlg->m_lst.ResetContent();


return true;

 

}

0 Likes
2 Replies
MallikaK_22
Moderator
Moderator
Moderator
50 likes received 750 replies posted 250 solutions authored

Hi,

Kindly go through the following App Note: https://www.cypress.com/documentation/application-notes/an61345-designing-ez-usb-fx2lp-slave-fifo-in... 

It consists of a detailed explanation along with the firmware source for a similar loopback application as you are implementing.

Regards,

Mallika

0 Likes

I have followed the same. Its all working except occasional byte miss. Pls have a look on the code shared above and suggest possible corrections if any required.

0 Likes