EmbeddedRelated.com
Forums
Memfault Beyond the Launch

Cypress EZ USB FX2 I/O Problems

Started by stiggz August 4, 2009
Hi,

I'm trying to read data from I/O port C on the FX2 development board into
my computer and then immediately write the received data back onto port E
using the CyAPI library. I'd like to be able to run this cycle of data
transfer (IOC->BulkInEndPt->PC console application->BulkOutEndPt->IOE) at a
few kHz, but so far I've had no luck. I'm using two 512 byte 4x buffered
bulk endpoints. My TD_Poll() function in my firmware looks like this: 

void TD_Poll(void)              // Called repeatedly while the device is
idle
{
    xdata unsigned char test = IOC & 0x01;

    //Reads status of pins on i/o port C and readys the data to be
transferred to the computer
    if(!(EP2468STAT & bmEP6FULL))
    {  
        FIFORESET = 0x80;
        SYNCDELAY;
        FIFORESET = 0x06;
        SYNCDELAY;
        EP6FIFOBUF[0] = test;
        SYNCDELAY;
        EP6BCH = 0x02; //BCL and BCH regard endpoint buffer size
        SYNCDELAY;
        EP6BCL = 0x00;
        SYNCDELAY;
        EP6BCL = 0x00;
        SYNCDELAY;
        EP6BCL = 0x00;            
        SYNCDELAY;
        EP6BCL = 0x00;
        SYNCDELAY;
        OUTPKTEND = 0x82;
        SYNCDELAY;
        FIFORESET = 0x00;
        SYNCDELAY;
     }

    //Reads data sent from the computer and writes it into i/o port E.
    if(!(EP2468STAT & bmEP2EMPTY))
    {                          
        xdata unsigned char *src = EP2FIFOBUF;
        xdata unsigned char value = *src;

        IOE = value;
        
        FIFORESET = 0x80;
        SYNCDELAY;
        FIFORESET = 0x02;
        SYNCDELAY;
        FIFORESET = 0x00;
        SYNCDELAY;
        EP2BCL = 0x80;
        SYNCDELAY;
        EP2BCL = 0x80;
        SYNCDELAY;
        EP2BCL = 0x80;
        SYNCDELAY;
        EP2BCL = 0x80;
        SYNCDELAY;
    }
}

And the following is the relevant code in my console application:

if(USBDevice->BulkOutEndPt && USBDevice->BulkInEndPt) {
        cout << "Beginning bulk data transfer.\n";
        unsigned char buffer[512];
        unsigned char data;
        LONG length = 512;
        while(1) {
            USBDevice->BulkInEndPt->XferData(buffer, length);
            USBDevice->BulkOutEndPt->XferData(buffer, length);
        }
}

As you can see, whatever data is on port C should be immediately looped
through the endpoints and computer to port E. However, I get about a 500
microsecond delay delay between the rising edge of a generated waveform on
port C and the corresponding edge on port E. Can you make any suggestions
for speeding this up? I'd like to get the delay as small as possible, so
that port E can effectively follow port C at a higher frequency like 8 kHz.
Let me know if you need any clarification.

Thanks so much, 
Zach


On Aug 4, 7:40 pm, "stiggz" <zstiggelb...@gmail.com> wrote:

> I'm trying to read data from I/O port C on the FX2 development board into > my computer and then 0immediately write the received data back onto port E > using the CyAPI library. I'd like to be able to run this cycle of data > transfer (IOC->BulkInEndPt->PC console application->BulkOutEndPt->IOE) at a > few kHz, but so far I've had no luck.
It don't work that way... though like you I only figured that out after getting less than expected performance (from a USB<>serial) and searching for the explanation. USB has high throughput, but it also has high latency. It's great for pushing large amounts of data per comparatively small amounts of time, but it's not designed to move small amounts of data immediately. In a way, this isn't even a uniquely USB problem - as processor cores get faster, they tend to get more decoupled from relatively slow I/O, and unless careful attention is paid throughout the design process you end up with a blindingly fast computer that can be crippled by relatively high I/O servicing latency the minute someone tries to get it to interact in a constant bi-directional conversation with an external device. Since you can't really change the design of USB, you'll need to look at finding a way to move some of the smarts of your application down to the fx2, so that it can act as a kind of executive engine on behalf of the PC and get more work done per each send/receive cycle on the wire. Sometimes that's as simple as making a bit-banging application a byte-banging one and letting the fx2 clock out the bits, other times if more "thought" is necessary to figure out how to respond to the external input it will be more tricky.
That's disappointing to hear, I appreciate your response though. I'll need
to look into redesigning my firmware. I may post a new response in the
future if I tun into any more similar difficulty.

Thanks again for your help,
Zach
> That's disappointing to hear, I appreciate your response though. I'll need > to look into redesigning my firmware. I may post a new response in the > future if I tun into any more similar difficulty. > > Thanks again for your help,
Try using the DLL's asynchronous routines so that the read is set up just before the write. Andrew
That's disappointing to hear, I appreciate your response though. I'll need
to look into redesigning my firmware. I may post a new response in the
future if I tun into any more similar difficulty.

Thanks again for your help,
Zach

Memfault Beyond the Launch