Cypress Perform

Home > Design Support > Cypress Developer CommunityTM > Cypress Forums > USB Controllers > CY7C68013A USB Camera problem

Bookmark and Share
Cypress Developer CommunityTM
Forums | Videos | Blogs | Training | Rewards Program | Community Components



CY7C68013A USB Camera problem
Moderator:
RSKV

Post Reply
Follow this topic



CY7C68013A USB Camera problem

simongregory posted on 16 Mar 2010 8:09 AM PST
Member
4 Forum Posts
I am developing a USB camera using a Micron Tech. (Aptina) CMOS image sensor and a CY7C68013 to interface it to a PC.

At the Hardware level:-

Image Sensor CY7C68013
PIXCLK------------>IFCLK
LINE_VALID-------->SLWR (active high)
FRAME_VALID------->ORed EP2 Empty--->PKTEND (active low)
D0..D11----------->FD0..FD11


PIXCLK is running at 5MHz, can be run up to 40MHz.
Each line consists of 648 pixels x 2 bytes, the maximum burst data rate is 10MB/s for ~129us. There is then a blanking period (LINE_VALID de-asserted) of 90-819us
for a line period of 219-1038us.

Note that the data from the sensor cannot be stopped during the frame. There is no flow control between the sensor and the FX2LP.

I am using EP2IN, AutoIN,BULK transfers, 512 byte 4x buffered. The device enumerates correctly, and I can receive data at the host. AutoINbytes is set to 0x0200
Theoretically, this is well within the capabilities of the FX2LP in High speed mode.

At the Host end, I am running a separate dedicated thread using CyAPI from C++.
(Code appended). It manages transfers using Begin...Wait...End transfer, with a queue depth of 8 (Queuedepth, and transfer/buffer size are settable in the #defines). This is pretty much adapted from the Streamer example.

However, multiple times during the frame, the FIFO becomes full (FF asserts) and data is lost. It appears that the Host is not reading from the FIFO fast/often enough. Even reading one 512byte packet per uFrame should be plenty. Is there any way to prevent this from happening?

FX2 Init Code

WORD i;
// bit res;

REVCTL=0x03;
SYNCDELAY;
// set the CPU clock to 12MHz
CPUCS=0x12; //0x02

// set the slave FIFO interface to Slave
IFCONFIG = 0x03;


EP1OUTCFG = 0xA0;
EP1INCFG = 0xA0;
SYNCDELAY;
EP6CFG = 0x00;
SYNCDELAY;
EP4CFG = 0x00;
SYNCDELAY;
EP8CFG = 0x00;
SYNCDELAY;

EP2AUTOINLENH = 0x02; // EZ-USB automatically commits data in 512-byte chunks
SYNCDELAY;
EP2AUTOINLENL = 0x00;
SYNCDELAY;

EP2CFG = 0xe0; // sets EP2 valid for IN's
// and defines the endpoint for 512 byte packets, 4x buffered
SYNCDELAY;
// EP2ISOINPKTS=2;
// SYNCDELAY;
FIFORESET = 0x80; // reset all FIFOs
SYNCDELAY;
FIFORESET = 0x02;
SYNCDELAY;
FIFORESET = 0x04;
SYNCDELAY;
FIFORESET = 0x06;
SYNCDELAY;
FIFORESET = 0x08;
SYNCDELAY;
FIFORESET = 0x00;
SYNCDELAY; // this defines the external interface to be the following:
EP2FIFOCFG = 0x0d; // this lets the EZ-USB auto commit IN packets, gives the
// ability to send zero length packets,
// and sets the slave FIFO data interface to 16-bits
SYNCDELAY;
PINFLAGSAB = 0x4c; // defines FLAGA as EP2 full flag
SYNCDELAY; // FLAGB as part full flag, as pointed to by FIFOADR[1:0] (not used)
PINFLAGSCD = 0x08; // FLAGC as EP2Empty
// won't generally need FLAGD
PORTACFG = 0x00; // used PA7/FLAGD as a port pin, not as a FIFO flag
SYNCDELAY;

FIFOPINPOLAR = 0x07; // set PKTEND Active LOW, SLWR Active HIGH,EF Active HIGH,
SYNCDELAY; //all other slave FIFO interface pins as active LOW

EP2FIFOPFH = 0x01; // you can define the programmable flag (FLAGA)
SYNCDELAY; // to be active at the level you wish
EP2FIFOPFL = 0x00;



Xfer Thread Code

CCyCam2Dlg *dlg = (CCyCam2Dlg *) params;
unsigned short *inbuf=dlg->inbuf;
OVERLAPPED ol[QUEUESIZE];
UCHAR *buffer[QUEUESIZE];
UCHAR *inContext[QUEUESIZE];
long len;
int qctr;
CCyUSBEndPoint *InEndpt;

InEndpt=dlg->InEndpt; //Get endpoint from calling dlg
InEndpt->SetXferSize(BUFFSIZE); //Set transfer size to buffer size
InEndpt->TimeOut=200;

// Set up buffers/overlapped structures
for(qctr=0;qctr<QUEUESIZE;qctr++)
{
buffer[qctr]=(PUCHAR)malloc(BUFFSIZE);
memset(buffer[qctr],0,BUFFSIZE);
ol[qctr].hEvent = CreateEvent(NULL, false, false, L"CYUSB_OUT");
}
// Start initial transfers
for(qctr=0;qctr<QUEUESIZE;qctr++)
{
len=BUFFSIZE;
inContext[qctr]=InEndpt->BeginDataXfer(buffer[qctr],len,&ol[qctr]);
dlg->LastUSBError=dlg->USBDevice->UsbdStatus;
}
//set destination buffer pointer to 0
dlg->inbufptr=0;

//start with queue entry 0

qctr=0;
for (;dlg->bLooping; )
{
//Wait for current transfer to complete
if (!InEndpt->WaitForXfer(&ol[qctr],2000))
{
InEndpt->Abort();
if (InEndpt->LastError == ERROR_IO_PENDING)
WaitForSingleObject(ol[qctr].hEvent,2000);

}
//Finish the transfer
len=BUFFSIZE;
if (InEndpt->FinishDataXfer(buffer[qctr],len,&ol[qctr],inContext[qctr]))
{
if (len) //we have data
{
memcpy(&dlg->inbuf[dlg->inbufptr],buffer[qctr],len); //copy to dest. buffer
dlg->inbufptr+=len/2; //buffer is array of WORD's
dlg->nLastBytes+=len; //update counters
dlg->nTotBytes+=len;
if (len!=BUFFSIZE) // Last packet in frame
{
dlg->nLastTrans=dlg->nLastBytes; //update count of bytes this frame
dlg->nLastBytes=0; //reset counter
dlg->inbufptr=0; //reset dest. buffer pointer
}
if (dlg->inbufptr>(MAXINBUF-BUFFSIZE)) //ensure don't overrun dest. buffer
dlg->inbufptr=(MAXINBUF-BUFFSIZE); //in case we miss end of frame
}
}
//Start new transfer
len=BUFFSIZE;
inContext[qctr]=InEndpt->BeginDataXfer(buffer[qctr],len,&ol[qctr]);
dlg->LastUSBError=InEndpt->NtStatus;

//update queue counter
qctr++;
if (qctr>=QUEUESIZE)
qctr=0;
}
//de-allocate buffers
for(qctr=0;qctr<QUEUESIZE;qctr++)
if (buffer[qctr])
free(buffer[qctr]);

//we are exiting
dlg->XferThread = NULL;

return true;


Edit: - escape "<" char to restore for loops.


Re: CY7C68013A USB Camera problem

andrewsobotka posted on 16 Mar 2010 02:34 PM PST
Top Contributor
40 Forum Posts

malloc in C++? You must be old school...

A 5 MHz FIFO clock is very, very slow. That's one thing that stands out to me. But that would make your buffer fill up slowly, I don't see why it would slow the host down.

How big is BUFFSIZE? Typically, you want the USB driver to transfer data in big quantities, like a few KB at a time.

It looks like you're properly queuing transfers. I would get a statistical measure on overflows, like how long it takes to get 5 overflows on average. Then double or triple the queue size and see if it takes you longer to get overflows. If it does, then it looks like the host is just being slow.

Do you have other things plugged into the USB? Are you sure you're running at Hi-Speed and not Full-Speed? Are there any Low- or Full- speed devices on the same bus? Are you going through a hub?

You could also try not using auto-in. When you manually commit transfers, toggle a GPIO. You can use this method to see how fast the host is pulling data off of the device.



Re: CY7C68013A USB Camera problem

simongregory posted on 17 Mar 2010 07:24 AM PST
Member
4 Forum Posts

Definately old school.  Would much prefer not to use C++ at all, but UI design is a pain without it

The 5 MHz FIFO clock is just for testing. Will probably use 24MHz for the final version. The PLL on the image sensor is very flexible.

I tried various sizes for BUFFSIZE (up to 8k) & QUEUESIZE (up to 128), but I think I wasn't being bold enough.

Setting BUFFSIZE to ~64k, QUEUESIZE to 8 seems to mostly cure the problem. I think windows scheduling is the cause, need enough work to last 'till the next time slice for the transfer thread. This is my first High Speed device, didn't have this problem before with Full Speed devices. Still getting the occasional FIFO overflow, but I think that this is just a matter of tuning.

Thanks for the suggestions.



Re: CY7C68013A USB Camera problem

rushilnoronha posted on 24 Mar 2010 12:11 PM PST
Member
3 Forum Posts
Hey,
I'm sure this is going to sound real stupid, but here goes: I just got started with the USB controller and I'm pretty much doing the same thing( building a camera module). I understood the part about the FX2 Initialization Code, I however don't quite understand the transfer thread code....what exactly is it doing and where do we need to use it?

Re: CY7C68013A USB Camera problem

andrewsobotka posted on 25 Mar 2010 08:22 AM PST
Top Contributor
40 Forum Posts
Simon: I don't have any problems with double-buffered 64kB transfers, but I'm only doing 192 kB/s, so it takes like 333 ms to fill up just one of the buffers. Try tuning your buffer/queue sizes so that you can go up to 500 ms or so without your thread running.

rush: the transfer thread is using non-blocking asynchronous IO. It queues up several transfers without waiting for any of them to finish. Then, as a transfer finishes, the thread starts the transfer again. A more thorough discussion of async IO is beyond the scope of this post.

Re: CY7C68013A USB Camera problem

simongregory posted on 04 Apr 2010 03:59 PM PST
Member
4 Forum Posts

Thanks Andrew. Up to 256k buffers, with a queue size of 32, interrupt transfers with a 1024byte packet size. 14.5MB/s sustained without corrupted frames. (1600x1200 16bit ~3.7fps). I think this is as fast as I can sensibly go without writing a full kernel mode driver. This is an order of magnitude better in both speed and reliability than the previous, FullSpeed version.
rush: The XferThread code is basically a modified version of the screamer example. Just noticed that many of the initialising for loops are missing "<" in a code section



Re: CY7C68013A USB Camera problem

alecha posted on 10 Feb 2011 08:39 AM PST
Senior Member
11 Forum Posts

Hi! I've a question: what is CCyCam2Dlgclass??






ALL CONTENT AND MATERIALS ON THIS SITE ARE PROVIDED "AS IS". CYPRESS SEMICONDUCTOR AND ITS RESPECTIVE SUPPLIERS MAKE NO REPRESENTATIONS ABOUT THE SUITABILITY OF THESE MATERIALS FOR ANY PURPOSE AND DISCLAIM ALL WARRANTIES AND CONDITIONS WITH REGARD TO THESE MATERIALS, INCLUDING BUT NOT LIMITED TO, ALL IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT OF ANY THIRD PARTY INTELLECTUAL PROPERTY RIGHT. NO LICENSE, EITHER EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, IS GRANTED BY CYPRESS SEMICONDUCTOR. USE OF THE INFORMATION ON THIS SITE MAY REQUIRE A LICENSE FROM A THIRD PARTY, OR A LICENSE FROM CYPRESS SEMICONDUCTOR.

Content on this site may contain or be subject to specific guidelines or limitations on use. All postings and use of the content on this site are subject to the Terms and Conditions of the site; third parties using this content agree to abide by any limitations or guidelines and to comply with the Terms and Conditions of this site. Cypress Semiconductor and its suppliers reserve the right to make corrections, deletions, modifications, enhancements, improvements and other changes to the content and materials, its products, programs and services at any time or to move or discontinue any content, products, programs, or services without notice.

Spec No: None; Sunset Owner: KXP; Secondary Owner: VWA; Sunset Date: 01/01/20