You are here

How to indicate the EPxFIFO BUF overflow and stop the transfer forever | Cypress Semiconductor

How to indicate the EPxFIFO BUF overflow and stop the transfer forever

Summary: 7 Replies, Latest post by andrewsobotka on 22 Mar 2010 04:35 PM PDT
Verified Answers: 0
Last post
Log in to post new comments.
yanzhisheng's picture
User
4 posts

Hello everyone,

Thank you for your attentation.

What I used is CY7C68013A chip, the data streams continuously into the CY7C68013A from the extern master logic and the extern master logic can NOT stopped.

So whenever the host is too busy to receive the data from UBS, the overflow will occur in the CY7C68013A. I shall configure the EP2FIFO FULL flag interrupt to indicate the overflow occurs and stop the transfer.

firstly, I try to do it: if the EP2FIFO FULL flag interrupt is actived, assert the STALL bit of EP2. But it failed to stop transfer because the host maybe to recover the STALL.

What Should I do if I would to stop the transfer and prevent the host from recover the transfer again?

Thank you again!

yanzhisheng's picture
User
4 posts

:beer;The following is the source code:

#pragma NOIV // Do not generate interrupt vectors

//-----------------------------------------------------------------------------

// File: FX2_to_extsyncFIFO.c

// Contents: Hooks required to implement FX2 GPIF to external sync. FIFO

// interface using CY4265-15AC

//

// Copyright (c) 2003 Cypress Semiconductor, Inc. All rights reserved

//-----------------------------------------------------------------------------

#include "fx2.h"

#include "fx2regs.h"

#include "fx2sdly.h" // SYNCDELAY macro, see Section 15.14 of FX2 Tech.

// Ref. Manual for usage details.

#define EXTFIFONOTFULL GPIFREADYSTAT & bmBIT1

#define EXTFIFONOTEMPTY GPIFREADYSTAT & bmBIT0

extern BOOL GotSUD; //Received setup data flag

extern BOOL Sleep;

extern BOOL Rwuen;

extern BOOL Selfpwr;

BYTE Configuration; //Current configuration

BYTE AlternateSetting; //Alternate settings

extern BOOL in_enable; //Flag enable IN transfers

BOOL enum_high_speed = FALSE; //Flag to let firmware know FX2 enumerated at high speed

extern const char xdata FlowStates[36];

//-----------------------------------------------------------------------------

// Task Dispatcher hooks

// The following hooks are called by the task dispatcher.

//-----------------------------------------------------------------------------

void Setup_FLOWSTATE_Read ( void );

//void GpifInit ();

void TD_Init(void) //Called once at startup

{

//Set the CPU clock to 48MHz

CPUCS = ((CPUCS & ~bmCLKSPD) | bmCLKSPD1);

//FIFO interface

//**********************************************//

SYNCDELAY;

IFCONFIG=0x13;//IFCONFIG.7 selects between internal and external sources: 0 = external, 1 = internal.

//IFCONFIG.6 selects between the 30- and 48-MHz internal clock: 0 = 30 MHz, 1 = 48 MHz.

//IFCONFIG.5 is the output enable for the internal clock source: 0 = disable, 1 = enable.

//IFCONFIG.4 inverts the polarity of the interface clock (whether it's internal or external): 0 = normal,1 = inverted.

//IFCONFIG.3 = 1 asynchronous mode; IFCONFIG.3 = 0 synchronous mode

//IFCFG1 IFCFG0

// 0 0 Ports

// 0 1 Reserved

// 1 0 GPIF Interface (internal master)

// 1 1 Slave FIFO Interface (external master)

//REVCTL

//**********************************************//

SYNCDELAY;

REVCTL=0x01; //SET REVCTL.0=0 & REVCTL.1=1

//USB Domain of the FIFO

//***********************************************************//

SYNCDELAY; //EP1OUTCFG, EP1INCFG

EP1OUTCFG=0xA0; // Bit7 bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0

SYNCDELAY; // VALID 0 TYPE1 TYPE0 0 0 0 0

EP1INCFG=0xA0; //TYPE[1:0], 00,01=VALID; 10=BULK; 11=INTERRUPT;

SYNCDELAY; //EPxCFG where x=2,4,6,8

EP2CFG = 0xE8; // Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0

SYNCDELAY; // VALID DIR TYPE1 TYPE0 SIZE 0 BUF1 BUF0

EP4CFG = 0x00; //DIR:0=OUT; 1=IN.

SYNCDELAY; //TYPE[1:0], 00=Invalid, 01=ISOCHRONOUS, 10=BULK, 11=INTERRUPT

EP6CFG = 0x00; //SIZE: 0=512 bytes, 1=1024 bytes.

SYNCDELAY; //BUF[1:0], 00=Quad, 01=Invalid, 10=Double, 11=Triple.

EP8CFG = 0x00;

//Reset FIFOs

//***********************************************************//

SYNCDELAY;

FIFORESET = 0x80; //Write 0x80 to this register to NAK all transfers from the host, then write 0x02, 0x04, 0x06, or 0x08

SYNCDELAY; //to reset an individual FIFO (i.e., to restore endpoint FIFO flags and byte counts to their default

FIFORESET = 0x02; //states), then write 0x00 to restore normal operation.

SYNCDELAY;

FIFORESET = 0x00;

//Peripheral Domain side of FIFO

//**********************************************************//

SYNCDELAY;

EP2FIFOCFG = 0x09; // Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0

// 0 INFM1 OEP1 AUTOOUT AUTOIN ZEROLENIN 0 WORDWIDE

//INFM1==1, The FIFO falgs for that endpoint become valid one sample earlier than when the FULL condition occurs. only to IN endpoints and operating synchronously.

//OEP1==1, The FIFO for that endpoint become valid one sample earlier than when the EMPTY condition occurs. applies only to OUT endpoints and operating aschrously.

//WORDWIDE applies when IFCFG=11 or 10.

//*******************************************************//

//FLAGA,FLAGB,FLAGC,FLAGD

SYNCDELAY;

PINFLAGSAB=0x00; //FLAGx3 FLAGx2 FLAGx1 FLAGx0 Pin Function

SYNCDELAY; // 0 0 0 0 FLAGA=PF, FLAGB=FF, FLAGC=EF, FLAGD=EP2PF.

PINFLAGSCD=0x40; // 0 0 0 1 Reserved

// 0 0 1 0 Reserved

// 0 0 1 1 Reserved

// 0 1 0 0 EP2 PF

// 0 1 0 1 EP4 PF

// 0 1 1 0 EP6 PF

// 0 1 1 1 EP8 PF

// 1 0 0 0 EP2 EF

// 1 0 0 1 EP4 EF

// 1 0 1 0 EP6 EF

// 1 0 1 1 EP8 EF

// 1 1 0 0 EP2 FF

// 1 1 0 1 EP4 FF

// 1 1 1 0 EP6 FF

// 1 1 1 1 EP8 FF

//*******************************************************//

SYNCDELAY;

FIFOPINPOLAR=0x3F; // Bit5 (PKTEND) 0:active low; 1:active high

// Bit4 (SLOE) 0:active low; 1:active high

// Bit3 (SLRD) 0:active low; 1:active high

// Bit2 (SLWR) 0:active low; 1:active high

// Bit1 (Empty Flag) 0:active low; 1:active high

// Bit0 (Full Flag) 0:active low; 1:active high

//*******************************************************//

SYNCDELAY; // Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0

EP2FIFOPFH=0x81; // DECIS PKTSTAT IN:PKTS[2] IN:PKTS[1] IN:PKTS[0] 0 PFC9 PFC8

SYNCDELAY; // OUT:PFC12 OUT:PFC11 OUT:PFC10 0

EP2FIFOPFL=0x00; // For OUT packets, DECIS=0 (or 1):PF is asserted when the number is less/equal (or greater/equal) the threshold.

// For IN packets, PKTSTAT=1, The threshold is stored in PFC9:0, PKTSTAT=0, the threshold is stored in PKTS2:0 and PFC9:0

//*******************************************************//

SYNCDELAY;

PORTACFG=0x00; // Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0

//FLAGD SLCS 0 0 0 0 INT1 INT0

//FLAGD=1 when IFCFG[1:0]=11 configures PA7 as FLAGD.

//SLCS=1 when IFCFG[1:0]=11 configures PA7 as S\L\C\S\.

//INT[1:0] configures PA[1:0] as INT1 and INT0 pins.

//*******************************************************//

SYNCDELAY;

OEA|=0x88; //Output Enable (Port A) PORTA.7: Enable PORTA.3:Enable

SYNCDELAY;

IOA=0x88; //PORTA.3=1 reset and suspend the FPGA.

//******************************************************//

SYNCDELAY;

IE|=0x80; // IE.7 IE.6 IE.5 IE.4 IE.3 IE.2 IE.1 IE.0

// EA Serial_1 Timer_2 Serial_0 Timer_1 External_1 Timer_0 External_0

//*************************EIE******************************//

SYNCDELAY; // Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0

EIE|=0x05; // EX6 EX5 EX4 EI2C EUSB

//*****************Enable selected interrupts****************

USBIE |= bmSUDAV | bmSUTOK | bmSUSP | bmURES | bmHSGRANT; //Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0

// 0 EP0ACK HSGRANT URES SUSP SUTOK SOF SUDAV

//**************************IP******************************//

IP=0x05; //Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0

// 1 Serial_1 Timer_2 Serial_0 Timer_1 INT1 Timer_0 INT0

//=1:high priority, =0:low priority

//*************************EIP******************************//

EIP=0x01; //Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0

// 1 1 1 INT6 INT5 INT4/GPIF/FIFO I2CINT PUSB

//=1: high priority, =0: low priority

//*************************Endpoint Interrupt Enable********//

SYNCDELAY; // Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0

EPIE|=0x08; // EP8 EP6 EP4 EP2 EP1OUT EP1IN EP0OUT EPOIN

//****************EP2 Slave FIFO Flag Interrupt Enable******//

EP2FIFOIE=0x01; // Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0

// 0 0 0 0 EDGEPF PF EF FF

//EDGE=0 (or 1), the interrupt fires on the rising (falling) edge of the programmable flag

//*************************TCON*****************************//

SYNCDELAY; // Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0

TCON=0x05; // TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0

//TCON.2(IT1) - INT1 is detected on falling edge when IT1 = 1; INT1 is detected as a low level when IT1 = 0.

//TCON.0(IT0) - INT0 is detected on falling edge when IT0 = 1; INT0 is detected as a low level when IT0 = 0.

//ARM EP1OUT

SYNCDELAY;

EP1OUTBC=0; //Set the BUSY bit in EP1OUTCS by writing any value to EP1OUTBC, arm the endpoint for EP1OUT transfer.

//The BUSY bit in EP1OUTCS, BUSY=1 means the SIE owns the buffer,

//BUSY=0 means that the firmware may read from or write the buffer.

//At power-on (or whenever a 0-to-1 transition occurs on the RESET pin), the BUSY

//bit is set to 0,

//Firware arms the endpoint for OUT transfers by writing any value to the

//byte count register EP1OUTBC, which automatically sets BUSY=1.

//BUSY is automatically cleared to 0 after the FX2 verifies the OUT data for

//accuracy and ACKs the transfer.

//A 1-to-0 BUSY transition asserts the EP1OUT interrupt request, signaling

//new EP1OUT data is availabe.

SYNCDELAY;

in_enable=FALSE;

}

void TD_Poll(void)

{

}

BOOL TD_Suspend(void) // Called before the device goes into suspend mode

{

return(TRUE);

}

BOOL TD_Resume(void) // Called after the device resumes

{

return(TRUE);

}

//-----------------------------------------------------------------------------

// Device Request hooks

// The following hooks are called by the end point 0 device request parser.

//-----------------------------------------------------------------------------

BOOL DR_GetDescriptor(void)

{

return(TRUE);

}

BOOL DR_SetConfiguration(void) // Called when a Set Configuration command is received

{

if( EZUSB_HIGHSPEED( ) )

{ // FX2 enumerated at high speed

SYNCDELAY; //

EP2AUTOINLENH = 0x02; // 0x02,set AUTOIN commit length to 512 bytes

SYNCDELAY; //

EP2AUTOINLENL = 0x00;

SYNCDELAY;

enum_high_speed = TRUE;

}

else

{ // FX2 enumerated at full speed

SYNCDELAY;

EP2AUTOINLENH = 0x00; // set AUTOIN commit length to 64 bytes

SYNCDELAY;

EP2AUTOINLENL = 0x40;

SYNCDELAY;

enum_high_speed = FALSE;

}

Configuration = SETUPDAT[2];

return(TRUE); // Handled by user code

}

BOOL DR_GetConfiguration(void) // Called when a Get Configuration command is received

{

EP0BUF[0] = Configuration;

EP0BCH = 0;

EP0BCL = 1;

return(TRUE); // Handled by user code

}

BOOL DR_SetInterface(void) // Called when a Set Interface command is received

{

AlternateSetting = SETUPDAT[2];

return(TRUE); // Handled by user code

}

BOOL DR_GetInterface(void) // Called when a Set Interface command is received

{

EP0BUF[0] = AlternateSetting;

EP0BCH = 0;

EP0BCL = 1;

return(TRUE); // Handled by user code

}

BOOL DR_GetStatus(void)

{

return(TRUE);

}

BOOL DR_ClearFeature(void)

{

return(TRUE);

}

BOOL DR_SetFeature(void)

{

return(TRUE);

}

#define VX_B1 0xB1 // reset the external FIFO

BOOL DR_VendorCmnd(void)

{

switch (SETUPDAT[1])

{

case VX_B1:

{

//start FPGA

OEA=0xfc; //1111 1100 // 1:turn on output buffer ; 0: turn off

SYNCDELAY;

IOA&=0xf7;

*EP0BUF=VX_B1;

EP0BCH=0;

EP0BCL=1;

EP0CS |= bmHSNAK;

break;

}

default:

return(TRUE);

}

return(FALSE);

}

//-----------------------------------------------------------------------------

// USB Interrupt Handlers

// The following functions are called by the USB interrupt jump table.

//-----------------------------------------------------------------------------

// Setup Data Available Interrupt Handler

void ISR_Sudav(void) interrupt 0

{

GotSUD = TRUE; // Set flag

EZUSB_IRQ_CLEAR();

USBIRQ = bmSUDAV; // Clear SUDAV IRQ

}

// Setup Token Interrupt Handler

void ISR_Sutok(void) interrupt 0

{

EZUSB_IRQ_CLEAR();

USBIRQ = bmSUTOK; // Clear SUTOK IRQ

}

void ISR_Sof(void) interrupt 0

{

EZUSB_IRQ_CLEAR();

USBIRQ = bmSOF; // Clear SOF IRQ

}

void ISR_Ures(void) interrupt 0

{

// whenever we get a USB reset, we should revert to full speed mode

pConfigDscr = pFullSpeedConfigDscr;

((CONFIGDSCR xdata *) pConfigDscr)->type = CONFIG_DSCR;

pOtherConfigDscr = pHighSpeedConfigDscr;

((CONFIGDSCR xdata *) pOtherConfigDscr)->type = OTHERSPEED_DSCR;

EZUSB_IRQ_CLEAR();

USBIRQ = bmURES; // Clear URES IRQ

}

void ISR_Susp(void) interrupt 0

{

Sleep = TRUE;

EZUSB_IRQ_CLEAR();

USBIRQ = bmSUSP;

}

void ISR_Highspeed(void) interrupt 0

{

if (EZUSB_HIGHSPEED())

{

pConfigDscr = pHighSpeedConfigDscr;

((CONFIGDSCR xdata *) pConfigDscr)->type = CONFIG_DSCR;

pOtherConfigDscr = pFullSpeedConfigDscr;

((CONFIGDSCR xdata *) pOtherConfigDscr)->type = OTHERSPEED_DSCR;

}

EZUSB_IRQ_CLEAR();

USBIRQ = bmHSGRANT;

}

void ISR_Ep0ack(void) interrupt 0

{

}

void ISR_Stub(void) interrupt 0

{

}

void ISR_Ep0in(void) interrupt 0

{

}

void ISR_Ep0out(void) interrupt 0

{

}

void ISR_Ep1in(void) interrupt 0

{

}

void ISR_Ep1out(void) interrupt 0

{ //the interrupt asserts when the host supplies a packet to the endpoint.(EP1-OUT has USB data)

if(in_enable==FALSE)

{ //if in_enable==false, this is the first EP1OUT transfer, so enable EP2 IN transfer

in_enable=TRUE;

SYNCDELAY;

// EP2CS &=0xFE; //Clear EP2 STALL bit.

SYNCDELAY;

IOA=0x80; //PORTA.3=0 release the FPGA.

//Reset EP2 FIFO

SYNCDELAY;

FIFORESET = 0x80; //Write 0x80 to this register to NAK all transfers from the host, then write 0x02, 0x04, 0x06, or 0x08

SYNCDELAY; //to reset an individual FIFO (i.e., to restore endpoint FIFO flags and byte counts to their default

FIFORESET = 0x02; //states), then write 0x00 to restore normal operation.

SYNCDELAY;

FIFORESET = 0x00;

}

while(EP24FIFOFLGS&0x04)

{ //waiting untill EP2FIFO Programable Flag is disasserted! (when it is idle for EP2 transfer)

;

}

EP1INBUF[0]=0x55;

SYNCDELAY;

EP1INBUF[1]=0xAA;

SYNCDELAY;

EP1INBC=2; //Arm EP1INBUF for IN-Transfer

//The BUSY bit in EP1INCS

//BUSY=1,means that the SIE "ownn" the buffer, so firmwave should not write (or read) the buffer.

//BUSY=0,means that the firmwave may write data into (or read from) the buffer.

//A 1-to-0 BUSY transition asserts the EP1IN interrupt request, signaling that the EP1IN buffer is

//free and ready to loaded with new data.

//The firmwave schedules an IN transfer by loading up to 64 bytes of data into EP1INBUF,

//then writing the byte count register EP1INBC with the number of bytes loaded.

//Writing the byte coun-register automatically sets BUSY=1.

//After the FX2 subsequently receives an IN token, sends the data, and successfully receives

//an ACK from the host, BUSY is automatically cleared to 0 to indicate that the buffer is ready

//to accept more data.

//After power-on, or whether a 0-to-1 transition occurs on the RESET pin, the BUSY bit is set to 0

SYNCDELAY;

SYNCDELAY;

EP1OUTBC=0; //Set the BUSY bit in EP1OUTCS by writing any value to EP1OUTBC; Arm the endpoint for EP1OUT transfer.

SYNCDELAY;

EZUSB_IRQ_CLEAR();

EPIRQ=0x08; //Clear the EP1out-USB IRQ bit by writing 1 to Bit-3. 0000 1000

}

void ISR_Ep2inout(void) interrupt 0

{

}

void ISR_Ep4inout(void) interrupt 0

{

}

void ISR_Ep6inout(void) interrupt 0

{

}

void ISR_Ep8inout(void) interrupt 0

{

}

void ISR_Ibn(void) interrupt 0

{

}

void ISR_Ep0pingnak(void) interrupt 0

{

}

void ISR_Ep1pingnak(void) interrupt 0

{

}

void ISR_Ep2pingnak(void) interrupt 0

{

}

void ISR_Ep4pingnak(void) interrupt 0

{

}

void ISR_Ep6pingnak(void) interrupt 0

{

}

void ISR_Ep8pingnak(void) interrupt 0

{

}

void ISR_Errorlimit(void) interrupt 0

{

}

void ISR_Ep2piderror(void) interrupt 0

{

}

void ISR_Ep4piderror(void) interrupt 0

{

}

void ISR_Ep6piderror(void) interrupt 0

{

}

void ISR_Ep8piderror(void) interrupt 0

{

}

void ISR_Ep2pflag(void) interrupt 0

{

}

void ISR_Ep4pflag(void) interrupt 0

{

}

void ISR_Ep6pflag(void) interrupt 0

{

}

void ISR_Ep8pflag(void) interrupt 0

{

}

void ISR_Ep2eflag(void) interrupt 0

{

}

void ISR_Ep4eflag(void) interrupt 0

{

}

void ISR_Ep6eflag(void) interrupt 0

{

}

void ISR_Ep8eflag(void) interrupt 0

{

}

void ISR_Ep2fflag(void) interrupt 0

{ //if EP2FIFOBUF is full, the error occurs!

in_enable=FALSE;

SYNCDELAY;

IOA=0x88; //PORTA.3=1 reset and suspend the FPGA.

// SYNCDELAY;

// EP2CS |=0x01; //Stall EP2.

SYNCDELAY; //EPxCFG where x=2,4,6,8

EP2CFG = 0xE8; // Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0

// VALID DIR TYPE1 TYPE0 SIZE 0 BUF1 BUF0

//DIR:0=OUT; 1=IN.

//TYPE[1:0], 00=Invalid, 01=ISOCHRONOUS, 10=BULK, 11=INTERRUPT

//SIZE: 0=512 bytes, 1=1024 bytes.

//BUF[1:0], 00=Quad, 01=Invalid, 10=Double, 11=Triple.

SYNCDELAY;

EXIF &=0xBF; //clear FIFO main interrupt request flag.

SYNCDELAY;

EP2FIFOIRQ=0x01; //**********EP2 Slave FIFO Flag Interrupt Request*********

// Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0

// 0 0 0 0 0 PF Empty-Flag Full-Flag

}

void ISR_Ep4fflag(void) interrupt 0

{

}

void ISR_Ep6fflag(void) interrupt 0

{

}

void ISR_Ep8fflag(void) interrupt 0

{

}

void ISR_GpifComplete(void) interrupt 0

{

}

void ISR_GpifWaveform(void) interrupt 0

{

}

void Setup_FLOWSTATE_Read ( void )

{

FLOWSTATE = FlowStates[18]; // 1000 0010b - FSE=1, FS[2:0]=002

SYNCDELAY;

FLOWEQ0CTL = FlowStates[20]; // CTL0 = 0 when flow condition equals zero (data flows)

SYNCDELAY;

FLOWEQ1CTL = FlowStates[21]; // CTL0 = 1 when flow condition equals one (data does not flow)

SYNCDELAY;

}

tsuneo's picture
User
3 posts
So whenever the host is too busy to receive the data from UBS, the overflow will occur in the CY7C68013A.

No overflow occurs on the FX2LP, thanking to USB intrinsic NAK (or NYET) flow control. So, you don't need to worry about overflow. While the device is NAKing, the "Write" call doesn't complete on the host app.

STALL is not a good handshake for this purpose. STALL means heavy error, which requires serious error recovery. STALL is not used positively on bulk/interrupt endpoints for most of USB classes, just except for Mass storage class.

Tsuneo

andrewsobotka's picture
User
44 posts

Hi Tsuneo,

I think by "overflow", he means that the peripheral domain (the non-PC side of the USB) has no flow control. It will continue to spit out data while the FX2LP is NAKing.

yanzhisheng, you need to modify your FPGA to check the full flag and not send data when the FX2LP's endpoint buffer is full. It is the responsibility of the external master to avoid putting data into the buffer while it is full.

Cheers,

Andrew

tsuneo's picture
User
3 posts

In any slave FIFO mode, FX2LP doesn't "spit out" data, positively.

The external master "reads out" data from the slave FIFO, controlled by SLOE, SLRD lines and IFCLK clock. Master and Slave are named after in this role.

While the external master is busy, it doesn't read out data from the FIFO by dropping the SLRD/SLOE control lines. As I said in above post, no overflow occurs on FX2LP by NAK flow control, while data stream is paused.

IFCONFIG=0x13; // external inverted IFCLK, synchronous, slave FIFO

In OP's setup, FX2LP is configured as synchronous slave FIFO with externally sourced IFCLK

In this mode, the external master flips SLRD synchronized to IFCLK, to read out data from FD bus. Just stopping SLRD flip, the master pauses to read the slave FIFO.

The master monitors FLAGC-EMPTY pin rather than FLAGB-FULL, to know if any data remains on the FIFO or not.

Tsuneo

tsuneo's picture
User
3 posts

Ah, sorry,

I've mistaken the transfer direction.

the data streams continuously into the CY7C68013A from the extern master logic and the extern master logic can NOT stopped.

In this condition, that is, the external master can NOT be stopped,

AND you don't want any data drop, the host should have another thread to support uninterruptible data stream, other than busy main thread.

If you allow data drop, just don't write to the FIFO when the FIFO is full (FF), as suggested by Andrew.

Tsuneo

yanzhisheng's picture
User
4 posts

many thanks to tsuneo and andrew!

andrewsobotka's picture
User
44 posts

I suppose I should have specified above, when I said "it will continue to spit out data", I was referring to it = FPGA.

yanzhisheng, in addition to using a multi-threaded approach, you should also look into using the asynchronous begin/wait/end transfer functions so that you can queue up multiple transfers. Use a big buffer size, like 32k or 64k. If you use the C# library, don't forget to pin the underlying data buffers using GCHandle while doing begin/wait/end.

Log in to post new comments.