My code has been uploaded to xuesongshu/ht1: Learn and study CYUSB3014 (github.com)
The third and forth end point defined here:
New DMA handle:
And configured in CyFxBulkSrcSinkApplnStart function:
But it always failed with code 64(CY_U3P_ERROR_BAD_ARGUMENT). I don't know which config is bad. Please point out. Thank you.
Show LessWe've created a custom board containing a CYUSB3014-BZXC with a GPIF interface attached to a Spartan 7 FPGA. My GPIF state machine is very similar to the SlaveFifo design desribed in AN65974, with two primary differences:
1. I've removed the SLCS signal. We use a GPIO pin to tell the FPGA when the host application has enabled the interface. The FX3 still provides FLAGA and FLAGB and they are connected to Current_Thread_DMA_Ready and Current_Thread_DMA_Watermark. The FPGA controls the remaining signals (SLRD#, SLOE#, SLWR#, PKTEND#, and A[1:0]).
2. The FX3 sources PCLK but it is still a slave design. This was done so that a separate GPIF design can be used to configure the FPGA in Slave SelectMap mode.
When the host initiates a data transfer the FX3 firmware creates a multichannel DMA between USB OUT endpoint 3 and GPIF threads 2 and 3 and allocates two 16K buffers if the transfer involves OUT data. If the transfer involves IN data then the firmware creates a multichannel DMA between USB IN endpoint 4 and GPIF threads 0 and 1 and allocates two 16K buffers. If the transfer is bi-directional then both DMA channels are created and the buffer sizes are the same as in the unidirectional case.
When the host wants to transfer data it first sends a command to the FX3 to tell it to enable the GPIF interface. This will cause the PIB clocks to be configured and the state machine to be loaded, and then the enable signal to the FPGA is driven to a '1'.
The host test application can be configured to perform OUT only transfers, IN only transfers, or bidirectional transfers with data verification in a loop. Each time the host enters this loop it sends a 16 byte command to the FPGA that tells it which direction the transfer will be, and if data is to be written too/read from a 16K BRAM FIFO that exists inside the FPGA or data read from the FPGA Is simply discarded, and data written from the FPGA is from a counter instead of the FIFO. The command includes OUT and IN byte counts so that the FPGA knows how much data to transfer in each direction.
After the command is downloaded the bulk data transfer begins. For OUT only transfers the data is read by the FPGA over the Slave Fifo interface and discarded. For IN only transfers the FPGA will writes the value of an internal counter to the FX3. For bidirectional transfers the FPGA first reads a buffer of data from the FX3 (address 2 or 3, alternating on each FX3 read, always start on address 2) into the BRAM FIFO and then writes the BRAM FIFO to the FX3 (address 0 or 1, always starting on address 0, alternates on each FX3 write, always starting on address 0). The process is repeated with addresses toggling between each transfer until all data is transferred.
Once the bulk data transfer completes several smaller transfers are performed to read statistic registers that are inside the FPGA. Those statistics include how many times the FPGA thinks that it asserted SLOE, SLRD, SLWR, and PKTEND. They also include the last 32 OUT addresses, the last 32 IN addresses, and in the case that the transaction is aborted by the host due to timeout, it also includes the address that the FPGA thinks that it will read or write next and the count of words presently in the BRAM FIFO.
If the test is supposed to be performed for more than one iteration then it loops.
Testing has shown that unidirectional OUT transfers and unidirectional IN transfer work reliably at 100 MHz. Bidirectional transfers work reliably at 89.6 MHz, but will fail randomly when PCLK is set to 100 MHz (100.8).
When the bidirectional transfers fail the statistics collected from the FPGA show that the FPGA last received a buffer from the FX3 and wrote it into the BRAM FIFO and is in a state where it's waiting for FLAGA to indicate that there is an IN buffer available to write data to. The count of words in the BRAM FIFO is equal to 4096 and I can see that during the last 32 OUT's and IN's there have been now repeated READS or WRITES to the same address two times in a row, meaning that it correctly toggles the address each time. I can also see that the FPGA logic is waiting for an IN buffer on the correct address. However, it never receives one.
In the FX3 firmware I've setup a DMA callback on the producer endpoint (consumer was never signaled) of both the OUT and IN DMA channels. Each time the producer event occurs I increment the count of bytes transfered by 16K, but never exceeding the total size of the transfer, which may not be a multiple of 16K. The host application receives these counts after the transaction completes, or is aborted (fails). From this I can see that the FX3 thinks that it received one less 16K buffer than the FPGA thinks that it sent. This makes me think that the signal timing may be off and that a SLWR is being missed by the FX3. Is there a way for me to determine how many bytes are stored in the DMA buffer associated with socket 0 and socket 1 so that I can see if a word was missed?
Some other observations:
Our firmware outputs the USB PHY and Link error counts over UART once per second. During an OUT only transfer the error count stays at 0 when I run a large number of transfers. This is also true for an IN only transfer. However, when I perform the bidirectional transfer I see PHY errors reported each second. Why are there PHY errors during bi-directional transfers but not the uni-directional transfers?
1000 ms PHY errors = 12
1000 ms LINK errors = 0
1000 ms PHY errors = 6
1000 ms LINK errors = 0
1000 ms PHY errors = 11
1000 ms LINK errors = 0
1000 ms PHY errors = 12
1000 ms LINK errors = 0
1000 ms PHY errors = 6
1000 ms LINK errors = 0
1000 ms PHY errors = 12
1000 ms LINK errors = 0
1000 ms PHY errors = 12
1000 ms LINK errors = 0
1000 ms PHY errors = 6
1000 ms LINK errors = 0
1000 ms PHY errors = 10
1000 ms LINK errors = 0
1000 ms PHY errors = 11
1000 ms LINK errors = 0
1000 ms PHY errors = 12
I've registered a callback function to see if CYU3P_USBEP_SS_RESET_EVT occurs, but it does not.
Larger (160MB) bidirectional transfers fail much more frequently than small (16MB).
Our firmware sets the OUT and IN endpoint burst size to 16 by default. If I change it to 1 (disable burst) on both of the endpoints then bidirectional transfers NEVER fail, even at 100 MHz. I still see the same number of PHY errors that I did at 100 MHz so I'm not sure that the PHY error count is what ultimately causes IN transfers to stop.
Are the PHY errors what ultimately causes the IN transfers to stop, or is it something else?
Any suggestions on how to further debug this problem? I tried to capture the bus traffic with the Ellisys EX350 but that's very difficult because it seems to prevent the data transfer from failing, or at least makes it fail much less often, and the amount of data is so large that the capture stops.
Thanks,
Michael
My hardware is a sensor connected to 3014 via DVP. The problem is the DVP signals are good(frame/line valid and the pixel clock). And we can see the firmware enter the CyFxUvcApplnDmaCallback(), however, then get the buffer from CyU3PDmaMultiChannelGetBuffer(), we found the dmaBuffer.count is zero for every callback. The consequence is that the USB host receives many empty USB packages, and no image is presented.
The interesting thing is if we try to reset 3014(may need a few times), it is probably recovering from the exception state.
Any idea for what's going on under this phenomenon? Many thanks
Rossi
Show LessHow CyAPI recovers data transmission after accidental USB reconnection
我们当前的解决方案是手动触发CYAPI通过Control End Point通道向CYUSB3014发送一条命令,CYUSB3014固件执行CyU3PDeviceReset函数。这个解决方案存在2个问题。
Our current solution is to manually trigger the CyAPI to send a command to CYUSB3014 through the EP0(Control End Point) channel. The CYUSB3014 firmware executes the CyU3PDeviceReset function. There are two problems with this solution.
第1个:USB连接恢复后的第一次传输异常(后续的传输是成功的)。我们的分析认为CYUSB3014没有清空上次传输失败的数据。如果不调用CyU3PDeviceReset函数,我们就不知道有什么办法恢复CYUSB3014的数据传输。我们尝试过调用CyU3PUsbResetEndpointMemories函数和CyU3PUsbResetEp函数,都没有解决问题。
First: The first transmission fails after the USB connection is restored (the subsequent transmission is successful). Our analysis shows that CYUSB3014 does not clear the data that failed in the last transmission. If the CyU3PDeviceReset function is not called, we do not know how to recover the data transmission of CYUSB3014. We tried to call the CyU3PUsbResetEndpointMemories function and CyU3PUsbResetEp function, but they didn't solve the problem.
第2个:Windows设备管理器会再次刷新。USB连接重连造成Windows设备管理器第1次刷新,CYUSB3014固件执行CyU3PDeviceReset函数后Windows设备管理器发生第2次刷新。我们不希望Windows设备管理器第2次刷新。
Second: Windows Device Manager will refresh again. The reconnection of the USB connection caused the first refresh of the Windows Device Manager, and the second refresh of the Windows Device Manager occurred after the CYUSB3014 firmware executed the CyU3PDeviceReset function. We do not want Windows Device Manager to refresh for the second time.
请指点。谢谢!
Please point out. Thank you!
Show LessI designed a USB test module using CYUSB3014. This USB test module is used to test the USB HUB. The module runs the cyfxbulksrcsink example, and the circuit design completely refers to CYUSB3KIT-003.
I simulated some open-circuit and short-circuit faults of the superspeed signal on the USB HUB side, and then verified whether these faults can be detected by the CYUSB3014 module, and found that the following three fault tests failed:
What's the problem?
Is it possible to modify the firmware to solve all or some of the above problems?
If it can't be solved by modifying the firmware, what hardware circuit can solve the above problems, I hope to get your suggestions.
Show LessCyU3PMemSet((uint8_t *)&dmaConfig,0,sizeof(CyU3PDmaChannelConfig_t));
dmaConfig.size = CY_FX_UVC_STREAM_BUF_SIZE;
dmaConfig.count = CY_FX_UVC_STREAM_BUF_COUNT;
dmaConfig.prodSckId = (CyU3PDmaSocketId_t)CY_U3P_PIB_SOCKET_0;
dmaConfig.consSckId = (CyU3PDmaSocketId_t)(CY_U3P_UIB_SOCKET_CONS_0 |CY_FX_EP_VIDEO_CONS_SOCKET);
dmaConfig.prodAvailCount = 0;
dmaConfig.prodHeader = 12; /* 要添加的 12 字节 UVC 标头。 */
dmaConfig.prodFooter = 4; /* 4 字节页脚以补偿 12 字节标头。 */
dmaConfig.consHeader = 0;
dmaConfig.dmaMode = CY_U3P_DMA_MODE_BYTE;
dmaConfig.notification = CY_U3P_DMA_CB_PROD_EVENT;//CY_U3P_DMA_CB_PROD_EVENT ;;
dmaConfig.cb = CyFxUvcApplnDmaCallback;
apiRetStatus = CyU3PDmaChannelCreate (&glChHandleUVCStream,/*CY_U3P_DMA_TYPE_AUTO_SIGNAL*/ CY_U3P_DMA_TYPE_MANUAL,
&dmaConfig);
if (apiRetStatus != CY_U3P_SUCCESS)
{
/* 错误处理 */
CyU3PDebugPrint (4, “DMA 通道创建失败, 错误代码 = %d\n”, apiRetStatus);
CyFxAppErrorHandler (apiRetStatus);
}
Hi,
I've written a custom bootloader for the CYUSB3014-BZXC using the Cypress Boot API. We've been using this bootloader without issue for the past couple of months. However, someone recently plugged the board into a USB 3.1 host controller using a USB 2.0 cable. Upon doing so we discovered that in USB 2.0 mode the device stops responding to standard requests after being suspended and then resumed. The traffic on the USB bus was captured with an Ellisys EX350 and shows the following transactions:
1. get device descriptor (success)
2. set address (success)
3. get device descriptor (success)
4. get configuration descriptor (success)
5. get BOS ddescriptor (success)
6. get serial number descriptor (success)
7. get language ID descriptor (success)
8. get product descriptor (success)
9. set configuration 1 (success)
10. LPM transaction (success)
11. Suspended
12. Resume
13. get language ID descriptor x 6 (failure)
14. get manufacturer descriptor x 6 (failure)
15. get product descriptor x 6 (failure)
UART Debug message prints from the firmware show the following:
Initializing FX3 Boot Firmware 1.6
Boot FW Event: CY_FX3_BOOT_USB_IN_SS_DISCONNECT
Boot FW Event: CY_FX3_BOOT_USB_SUSPEND
Boot FW Event: CY_FX3_BOOT_USB_RESET
Boot FW Event: CY_FX3_BOOT_USB_RESET
Boot FW Event: CY_FX3_BOOT_USB_RESUME
Are there any special actions that the firmware must take when it receives CY_FX3_BOOT_USB_SUSPEND or CY_FX3_BOOT_USB_RESUME in order to get the FX3 to ACK the control requests that take place after the the suspend and resume operations?
We also seem to experience the same problem when running the application firmware (uses Cypress full API) when the device is plugged in with a USB 2.0 cable. The bus activity is similar:
1. get device descriptor (success)
2. set address (success)
3. get device descriptor (success)
4. get configuration descriptor (success)
5. get BOS ddescriptor (success)
6. get serial number descriptor (success)
7. get language ID descriptor (success)
8. get product descriptor (success)
9. LPM transaction (success)
10. Suspended
11. Resume
12. set configuration 1 x 3 (failure)
13. Suspended
So the same question applies for the application firmware: what steps must we take in firmware in order for control transfers to succeed after the device has been suspended and then resumed?
Some other information that you may find useful:
Operating system: Windows 10
Host Controller: Asmedia ASM3142
Hub: none
I appreciate any help you can provide.
Thanks,
Michael
Hi,
I've created a custom bootloader for the CYUSB3014-BZXC using the Cypress Boot API. The bootloader supports application firmware download to RAM using a vendor request very similar to the Fx3BootAppGcc example. The host downloads the application firmware to the device in 4096 byte chunks. Testing has shown that application firmware download works reliably across many different hardware configurations and operating systems. However, I have identified a system and OS where firmware download fails unless I reduce the chunk size to 512 bytes.
I have a system that runs both Ubuntu 20.04.4 LTS 64-bit and Windows 10 64-bit. Firmware download works correctly under Windows 10, regardless of connection speed. However, it fails under Ubuntu when the device is connected through a USB 3 cable to a USB 3 port. I performed a packet capture with the Ellisys EX350 and found that the bootloader acks the first 512 bytes of a 4096 byte setup request but then fails to acknowledge the next 512 bytes of the data stage after previously sending an ERDY for control endpoint 0.
I added some UART debug prints and found that the firmware is getting stuck inside of CyFx3BootUsbDmaXferData and will eventually return CY_FX3_BOOT_ERROR_ABORTED, but only after the next setup packet is received, which doesn't happen until our software is restarted because it errors out when the host is unable to complete the previous control transfer.
If I connect the board to the same USB port using a USB 2.0 cable then firmware download is successful.
If I connect the board to the same USB port using a USB 3.0 cable and run the software in Windows 10 instead of Linux, then the firmware download is successful.
If I modify our host software to send data in 512 byte chunks then firmware download succeeds but it takes approximately 2.2 seconds to complete instead of 286 milliseconds. Therefore, reducing the transfer size is not an acceptable solution.
I performed packet captures in both Windows and Linux but couldn't identify any notable differences in the first control transfer, other than it succeeds in Windows and the device fails to respond to the OUT packets in Linux.
Can someone please help me figure out why this is failing in Linux? Obviously the host controller driver is different, but like I said I can't see any obvious differences in bus activity.
I can send the bus activity log but the files are too large to attach so they will need to be sent via OneDrive, which requires an email address.
Thanks,
Michael
I have a project which requires FX3 to use USB3 Vision to send camera images to PC.
So, I use the FX3 firmware which use UVC as a base and try to modify to USB3 Vision. But it takes
quite a lot of effort. So, I wonder if Cypress have any application note or example code regarding FX3 to use USB3 Vision?
Show LessThe problem for the Intel PCH out of the USB3.0 device connected to this device,in the first link can be normal link on,
when the PCH closed the USB3.0 port and then open again, can not identify the device, only re-hardware reset can be,
we want to know there are other ways to solve this problem
CPU: Intel's EAGLE STREAM
Operating system: Linux 7.8
Show Less