|
From: Tim R. <ti...@pr...> - 2013-12-30 18:21:31
|
Abhishek Madaan wrote:
>
> We are developing a camera to talk with Raspberry Pi. The issue we
> are facing is that sometimes we are not able to receive full frame. We
> are using the bulk mode transfer. The camera resolution is 640x480
> with 2 bits per pixel.
2 BYTES per pixel...
Is this actually a USB Video Class device? Or is this an entirely
custom camera?
> So I am calling the filling the bulk loop with an array of unsigned
> short 640x480 with a size of 614400.
And are you sending a short packet when the frame is complete?
> The problem I am receiving that sometimes I able to only get 606208
> bytes before the bulk transfer times out. Is the speed of the CPU
> matters in the transfer?
You should be able to tell that. When you get a successful transfer,
what is the timing? Does it transfer as quickly as possible, or does it
get spread out? A USB 2 device should be able to send 614k bytes in
about 20ms. Does it take way longer than that? What's your timeout?
Ah, looking at your code, I see the bulk transfer timeout is 1s. That
should be enough, even with retries.
> At the firmware level, we are using end point 2 with Quad buffering
> with packsize = 1024.
I'm not sure what you mean by "packsize = 1024". A USB 2 bulk endpoint
is required to have a max packet size of 512. There is no other
choice. You are using an FX2, so quad buffering means you have 2048
bytes of FIFO.
> We are using Cypress GPIF to receive the frame from the camera. We are
> Auto In mode with 512 bytes. Here’s my code snippet. Can anyone
> explain me what might be different reasons that i am not able to
> receive the full frame? Is Raspberry PI CPU is too slow? If yes, but
> how it is interfering with IO? Why I receive full frames sometimes and
> sometimes not?
How are you doing the handshaking? Is your GPIF monitoring the FIFO
flags to make sure you don't keep shoving data in after the FIFO fills?
Remember that a bulk endpoint can experience retries, and while the USB
engine is retrying, it won't be emptying the FIFO. Does your camera
just keep sending pixels continuously, or does that camera have its own
frame buffer that holds the frame while you empty it at a slower rate?
Allow me to make a couple of comments about your code. You pass the
image size as "nSize", but the value you're passing to
libusb_fill_bulk_transfer is "size". I don't see "size" defined anywhere:
> void AllocTransfer(USBHandler *pUSBHandler,unsigned short
> *imageData,int nSize)
> {
> if(pUSBHandler!=NULL)
> {
> if(pUSBHandler->m_USBDevHandle==NULL)
> {
> VDBG("Null USB Handler\n");
> return EINVAL;
> }
> //Allocating the Bulk Transfer.
>
> pUSBHandler->m_BulkTransfer = libusb_alloc_transfer(0);
> libusb_fill_bulk_transfer(pUSBHandler->m_BulkTransfer_0,pUSBHandler->m_USBDevHandle,(0x2|LIBUSB_ENDPOINT_IN),imageData,size,cb_response,&completed,1000);
>
You do have one potentially dangerous thing in your code. You are
passing &_completed as the user_data value to
libusb_fill_control_transfer, but _completed is a stack variable in your
function. Immediately after libusb_fill_control_transfer, the function
exits, and that address will no longer be valid. It will belong to some
other piece of stack data. If you don't need any context info, then
just pass NULL. (Similarly, if you don't need a data buffer in your
vendor request, just pass NULL instead of a one-byte dummy array.)
> int _completed=0;
> ...
> libusb_fill_control_transfer(pUSBHandler->m_ControlTransfer,
> pUSBHandler->m_USBDevHandle, buffer,ctrl_transfer_cb, &_completed,
> timeout);
--
Tim Roberts, ti...@pr...
Providenza & Boekelheide, Inc.
|