USB superspeed peripherals Forum Discussions
In another thread I mentioned testing recovery from error conditions on the FX3. To better test this, I made a short test driver that setups up a large number of buffers with BeginDataXfer and copies a fixed number of buffers from device to host. It then checks for host errors, sends a vendor command to reset the GPIF to its initial state (rearmAcquisition()), and then repeats the cycle:
for (int arm = 0; arm < numRearm; arm++)
{
for (int k = 0; k < devices; k++)
{
if(arm ==0)
startAcquisition(USBDevices[k]);
else
{
//check for erors on device - this corrupts bulk transfers
//getRearmStatus(USBDevices[k]);
Sleep(100);
rearmAcquisition(USBDevices[k]);
}
}
long rLen;
for (i = 0; i < totalTransfers; i++)
{
for (int k = 0; k < devices; k++)
{
if (WaitForSingleObject(inOvLapList[k][nextBuffer].hEvent, 2000) != WAIT_OBJECT_0)
{
printf("WaitForXfer failed!\n");
fail = true;
goto End;
}
rLen = bufferSize;
if (USBDevices[k]->BulkInEndPt->FinishDataXfer(bufferList[k][nextBuffer], rLen, &(inOvLapList[k][nextBuffer]), contextslist[k][nextBuffer]))
{
double triggers = rLen / (triggerLength *sampleSize);
printf("%d: Got %d bytes (%f triggers) (hEvent: %d)!\n", i, rLen, triggers, inOvLapList[k][nextBuffer].hEvent);
bytesReceivedList[k] += rLen;
if (i + QueueSize < totalTransfers*numRearm)
{
contextslist[k][nextBuffer] = USBDevices[k]->BulkInEndPt->BeginDataXfer(bufferList[k][nextBuffer], bufferSize, &(inOvLapList[k][nextBuffer]));
if (USBDevices[k]->BulkInEndPt->NtStatus) // BeginDataXfer failed
{
printf("Xfer request rejected");
return -1;
}
}
}
else
{
printf("FinishDataXfer failed on buffer %d!\n", i);
goto End;
}
}
//increment the circular buffer
++nextBuffer;
nextBuffer %= QueueSize;
}
}
This test program can run for 10,000s of iterations without errors and seems reliable.
Next I added a function called getRearmStatus to check if the device had any buffer overflows or other errors between iterations (see commented out call above):
int getRearmStatus(CCyUSBDevice *USBDevice)
{
CCyControlEndPoint *ept = USBDevice->ControlEndPt;
ept->Target = TGT_DEVICE;
ept->ReqType = REQ_VENDOR;
ept->Direction = DIR_FROM_DEVICE;
ept->ReqCode = 0xA7; //get device status
ept->Value = 0;
ept->Index = 0;
INT32 RearmStatus[2]; //number of overflows and DMA transfers in 4 byte words
long len = 8;
ept->XferData((PUCHAR)RearmStatus, len);
printf("Overflows since last rearm: %d\n",RearmStatus[0]);
printf("Total FX3 DMA transfers Produced this rearm: %d\n",RearmStatus[1]);
return RearmStatus[0];
}
And here is the firmware for that vendor command:
//poll to see what the status of the previous acquisition was, returns [overflows,DMA transfers]
case 0xA7:
CyU3PDebugPrint (4, "Poll overflow status\r\n");
if(wLength == 8)
{
int *returnBuf = (int*) glEp0Buffer;
*returnBuf = overflows;
returnBuf = (int*) &glEp0Buffer[4];
*returnBuf = dmacount;
status = CyU3PUsbSendEP0Data (wLength, glEp0Buffer);
if (status != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (2, "Send data failed\r\n");
}
else
{
CyU3PDebugPrint (2, "CyU3PUsbSendEP0Data success! \r\n");
}
}
else
{
CyU3PUsbAckSetup ();
}
isHandled = CyTrue;
break;
It takes the buffer overflow and total dma count, puts into an 8 byte buffer and sends it back to the host with CyU3PUsbSendEP0Data() . This works and the host gets the correct values, but afterwards it is very likely that the bulk transfer will not be able to restart. Usually within 1-5 cycles the transfers will error out.
For example, here is a log where it fails on the first time:
found 3 devices
USB-Serial (Dual Channel) Vendor 1 - 1204 - 7 -
USB-Serial (Dual Channel) Vendor MFG - 1204 - 7 -
Cypress FX3 USB StreamerExample Device - 1204 - 241 -
Configuring FX3 acquisition with parameters:
Number of triggers: 1024
Total acquisition size: 20447232 bytes (19 MB)
CYUSB bufferSize: 20447232 , 19968.000000 USB packets (16 total buffers)
Total CYUSB buffers per acquisition: 1 (1024.000000 triggers per buffer)
Beginning Transfer...
0: Got 20447232 bytes (1024.000000 triggers) (hEvent: 872)!
Overflows since last rearm: 0
Total FX3 DMA transfers Produced this rearm: 512
[above is the vendor command checking for device errors]
Rearming the ADC!
[reset the GPIF to the initial state]
FinishDataXfer failed on buffer 0!
NTSTATUS = c0000001
status string: [state=STALLED status=UNKNOWN]
acquisition failed!
And here is the serial output:
Start ACQUIRE!
Poll overflow status
CyU3PUsbSendEP0Data success!
Rearming acquisition
CYU3P_PIB_ERR_THR1_WR_OVERRUN: 1 (PROD: 937, CONS: 0) commit fail: 0 (code: 0) DMA: 937
CYU3P_PIB_ERR_THR1_WR_OVERRUN: 2 (PROD: 937, CONS: 0) commit fail: 0 (code: 0) DMA: 937
CYU3P_PIB_ERR_THR0_WR_OVERRUN: 3 (PROD: 937, CONS: 0) commit fail: 0 (code: 0) DMA: 937
CYU3P_PIB_ERR_THR0_WR_OVERRUN: 4 (PROD: 937, CONS: 0) commit fail: 0 (code: 0) DMA: 937
CYU3P_PIB_ERR_THR0_WR_OVERRUN: 5 (PROD: 937, CONS: 0) commit fail: 0 (code: 0) DMA: 937
CYU3P_PIB_ERR_THR1_WR_OVERRUN: 6 (PROD: 937, CONS: 0) commit fail: 0 (code: 0) DMA: 937
CYU3P_PIB_ERR_THR1_WR_OVERRUN: 7 (PROD: 937, CONS: 0) commit fail: 0 (code: 0) DMA: 937
CYU3P_PIB_ERR_THR0_WR_OVERRUN: 8 (PROD: 937, CONS: 0) commit fail: 0 (code: 0) DMA: 937
CYU3P_PIB_ERR_THR0_WR_OVERRUN: 9 (PROD: 937, CONS: 0) commit fail: 0 (code: 0) DMA: 937
CYU3P_PIB_ERR_THR0_WR_OVERRUN: 10 (PROD: 937, CONS: 0) commit fail: 0 (code: 0) DMA: 937
Stopping acquisition!
Overflows: 10 (PROD: 937, CONS: 0)
Received a clear feature request!
So CyU3PUsbSendEP0Data returns success, the host sends a vendor command to restart the acquisition, but the bulk endpoint never responds (status is stalled). Commenting out the call to CyU3PUsbSendEP0Data completely fixed the error (can run for hours), but then I don't have any way to get the number of buffer overflows from the device, at least without resetting the bulk endpoint.
Note that the GPIF state machine has reached its DONE state when the vendor command is issued (although DMA is still configured), so no bulk transfer is currently in progress. The rearm command moves the GPIF back to its initial state to restart the next round of testing, which quickly fails.
To summarize how to reproduce:
1) Copy data from GPIF with bulk endpoint to host using USB3.
2) Pause GPIF but leave DMA configured
3) Call CyU3PUsbSendEP0Data
4) Restart GPIF (e.g. CyU3PGpifSMSwitch) and try to receive data on host through bulk endpoint.
After 4 the bulk endpoint will usually stop responding, although I have seen it work for as many as 6 cycles before terminating. If 3) is skipped the program can transfer data forever.
I do not understand this error. Other threads mentioned not calling CyU3PUsbAckSetup after CyU3PUsbSendEP0Data, which I do not do. I also saw issues with USB2 and the control endpoint, but I am not using USB2. It seems like the control endpoint should not break transfers on the bulk end point?
If helpful, here is the entire firmware file: GpifToUsbFixedBuffer_EP0_fail.zip
Show LessHi team,
Customer needs information for USB bridge controller CYUSB3065 regarding ESD data ( Machine Model ) & Read / Write cycles .
Thanks & regards,
Harsha
Show LessHi,
I got an issue related to FX3 GPIF II DMA buffer filling and/or transfer.
The data flow of my application are as follows:
Image sensor -> FGPA -> FX3 GPIF II -> FX3 DMA buffer.
I allocated 3 DMA buffer, each is 32768 (32KB) size. The max video resolution is 1936x1096. The FPGA sends 32 bytes frame header to GPIF II before sending real frame data for every frames. In most cases it worked fine unless I changed image width to 1452 and each pixel is configured to 8 bits.
The problem can be described as follows:
1、Image is abnormal starting from line 678.
2、The received frame data size is 4 byte bigger than expected.
Attached please find the captured image.
After checking the image, I noticed that there are 4 bytes inserted between end of line 677 and beginning of line 678. The 4 bytes are not expected to be received.
I did some calculation:
32 + 1452 x 677 = 983036 = 30 x 32768 - 4
Where:
1) 32 is the size of frame header.
2) 1452 is the line width
3) 677 is the count of lines
4) 32768 is the size of DMA buffer
It seems that:
At the end of line 677, the DMA buffer is filled with (32KB - 4) bytes. As I understand at this moment the DMA buffer will not be committed, instead it should wait next line to fill the last 4 bytes and then to commit. But based on the test result it seems the DMA buffer is commited immediately after line 677 is filled and 4 byte redundant data is incorrectly appended into the frame data.
Could anyone please help explain if this behaviour of FX3 is normal or not. And what fix or workaround should I add to get correct frame data for above configrations. Thanks.
Regards,
Frank
Show LessHi,
I have read CX3 TRM, and found there is a fifo to buffer MIPI data before GPIF II as below shown
So the fifo level 0x1FF means that the fifo depth is 511 bytes? Or anyone could clarify the fifo depth of CX3? Thanks!
Show LessHi ,
Customer Tesseract requesting for MTBF and Environmental condition ( Pb free / Halogen free) details for high speed USB controller CYUSB3065-BZXC .
Kindly share relevant details.
Thanks & regards,
Harsha
Show LessHi, I'm having trouble again.I am using FX3's slavefifo program for bidirectional communication between FPGA and PC.It works very well,but we want to make a little improvement.Now consider such a transmission path:
FPGA->FX3->PC,
For fpga,we set[A1:A0]=00,and then the data is written.In cyfxslfifosync.h,the sample program has the following lines of code:
#define CY_FX_EP_PRODUCER 0x01 /* EP 1 OUT */
#define CY_FX_EP_CONSUMER 0x81 /* EP 1 IN */
#define CY_FX_PRODUCER_USB_SOCKET CY_U3P_UIB_SOCKET_PROD_1 /* USB Socket 1 is producer */
#define CY_FX_CONSUMER_USB_SOCKET CY_U3P_UIB_SOCKET_CONS_1 /* USB Socket 1 is consumer */
#define CY_FX_PRODUCER_PPORT_SOCKET CY_U3P_PIB_SOCKET_0 /* P-port Socket 0 is producer */
#define CY_FX_CONSUMER_PPORT_SOCKET CY_U3P_PIB_SOCKET_3 /* P-port Socket 3 is consumer */
So far everything is perfect.But we want to use two producers.For example, the FPGA first writes data (size=one dma buffer)to address 0, and then quickly switches to address 2 to continue writing(if address 2 is available), which can avoid bandwidth loss caused by DMA switching.Of course, FPGA will monitor the value of flag to avoid errors.The problem is, we don't know what parts of FX3 need to be modified.For example, how to define two producers of P port?How two producers map to one consumer?(We don't care about the order of the data packets.)I'm very sorry, I didn't find the relevant information, I have to say that the design of FX3 is very different from FPGA and software.Please tell me how to do this. Thank you very much!
by the way ,we use auto DMA channel.
Sincere learner
Show LessAccording to this knowledge base article: FX3: Error in CyU3PDmaMultiChannelCommitBuffer: code 71 - KBA218830, it's possible to increase the size of the DMA buffer. How can I do this?
Presumably, this is the definition of the DMA buffer size:
#ifdef UVC_APPLICATION
#define CX3_UVC_DATA_BUF_SIZE (0x8FD0)
#else
#define CX3_UVC_DATA_BUF_SIZE (0x8000)
#endif
I have tried changing the size to various things, but values work, other than the original ones.
How can I calculate a larger value that will work?
I am using a monochrome camera with a resolution of 1280x480 x 10bits, and a frame rate of 100 FPS.
Many thanks
Show Less
Hello,
I'm trying to use the FX3 driver with Windows11. The Windows 10 driver works but every time I connect the camera I need to re-install the driver.
Is there a solution for it? or when a driver for Windows 11 is scheduled to be released?
All the best,
Ofer.
Show LessHi all,
Now I'm using CX3 24-bit GPIF II for YUV422_8 sensor image, how the YUV422_8 pixel will be packed in 24-bit parallel bus? I found a description in CX3 TRM as below, it shown that the upper bits are padded with 0s, is this right or is there other packing format? If I want to use 24-bit GPIF buf for YUV422_8 with none padding, is this can be done? And how to do?
Show Less