Application firmware download fails with custom bootloader under Linux in USB3 mode

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
mialc_1106291
Level 4
Level 4
10 questions asked 50 sign-ins 50 replies posted

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

0 Likes
1 Solution

Hi AliAsgar,

Sorry I didn't respond sooner I must have overlooked the email notification. The error code you reported indicates that firmware download was successful and that another image cannot be downloaded to the device because it's presently executing an image that's running in the application's address space. This means everything is working correctly on your setup.

I ordered a PCI Express card that has an Asmedia 3.1 controller and installed that in the same system that contains the Asmedia 3.0 controller. When our board is attached to the Asmedia 3.1 port the application firmware is successfully downloaded in 4096 byte chunks. We are also able to perform bulk data transfers without error.

The same cannot be said for the Asmedia 3.0 port. We can successfully download the firmware with the Asmedia 3.0 controller using 512 byte chunks but there are issues with IN and bidirectional data transfers when the board is connected to any of the Asmedia 3.0 ports. Out transfers work without issue, but IN transfers fail. We split our bulk data transfers into a predefined chunk size (the #defined value used to be 16K but now it's 4MB because 8MB makes libusb_submit_transfer fail with erc -1). The test I typically run involves transfer 164000000 bytes and with the Asmedia 3.0 controller libusb reports that the transaction has completed a transfer, but it only transfers half of the requested data before reporting a successful transfer. Subsequent transfers fail. I didn't learn anything useful with the packet analyzer captures but I think this is likely an issue with the Asmedia 3.0 driver included with Ubuntu 20 since these data transfers work correctly with Asmedia 3.1 on the same host PC. I also found that bulk data transfer and firmware download work correctly on the Asmedia 3.0 using a USB 2.0 cable.

At this point I intend to document the issue with the only known workaround being to use a USB 2.0 cable.

Thanks,
Michael

View solution in original post

0 Likes
8 Replies
AliAsgar
Moderator
Moderator
Moderator
1000 replies posted 250 solutions authored 750 replies posted

Hi Michael,

Could you let me know if the fourth parameter of the 

CyFx3BootUsbDmaXferData() API used in the VendorCmdHandler of your custom bootloader is WAIT_FOREVER? If yes could you change the value to a finite number(ex. 1000) and then perform the following tests.
 
When the 4096 byte setup transaction is received, (VendorCmdHandler API executed for this setup transaction), read the registers given below:
IEPM_CS - addr : 0xE0031C04
IEPM_ENDPOINT - addr : 0xE0031C80
IEPM_FIFO - addr : 0xE0031CC0.
 
After reading these values, when CyFx3BootUsbDmaXferData() API fails with a timeout error, read those register again and share with us the reading of the registers both before and after.
 
Best Regards,
AliAsgar
0 Likes

Hi AliAsgar,

Yes, I had it set to WAIT_FOREVER. I changed the timeout value to 1000, added register read and debug  prints of the values before each call to CyFx3BootUsbDmaXferData in the firmware download function and I'm also reading and printing them if the call fails. Here is the result when connected to Linux with a USB 3 cable:

writing ram...
IEPM_CS = 0x0
IEPM_ENDPOINT = 0x200
IEPM_FIFO = 0x0

CyFx3BootUsbDmaXferData failed, erc = 3
IEPM_CS = 0x2000200
IEPM_ENDPOINT = 0x403A00
IEPM_FIFO = 0x0

I sent you the Windows and Linux traces via OneDrive. The vendor command used for download is 0xA0 (same as Cypress).

Thanks,
Michael

0 Likes

Hi Michael,

Could you share with us the source code for the host application used by you on the linux asmedia host?

Best Regards,
AliAsgar

0 Likes

Hi AliAsgar,

We may be able to share it under NDA but the code is complex, as we have a subset of libraries that manage communication with all of our USB and network devices. I sent you the runtime libraries and another application that can be used to replicate the behavior I'm sending through OneDrive.

Thanks,
Michael

0 Likes

Hi Michael,

This is the error message I received on my Ubuntu machine:

System Time     Process     Thread        ERC     ERC String                  Message
3730266298      4385        3986344128    3080    ercInternalError            USBC::FDevFX3Validate device is executing from APP section of RAM
3730266299      4385        3986344128    4       ercCapabilityNotEnabled     not jtag port enabled

We suspect that your host application may be having issues in firmware download, that is the reason I wanted your host application. 

Is it possible for you to share the logic part for the firmware download source code with us?

Best Regards,
AliAsgar

0 Likes
AliAsgar
Moderator
Moderator
Moderator
1000 replies posted 250 solutions authored 750 replies posted

Hi Michael, 

Could you please reply to the questions above?

Best Regards,
AliAsgar

0 Likes

Hi AliAsgar,

Sorry I didn't respond sooner I must have overlooked the email notification. The error code you reported indicates that firmware download was successful and that another image cannot be downloaded to the device because it's presently executing an image that's running in the application's address space. This means everything is working correctly on your setup.

I ordered a PCI Express card that has an Asmedia 3.1 controller and installed that in the same system that contains the Asmedia 3.0 controller. When our board is attached to the Asmedia 3.1 port the application firmware is successfully downloaded in 4096 byte chunks. We are also able to perform bulk data transfers without error.

The same cannot be said for the Asmedia 3.0 port. We can successfully download the firmware with the Asmedia 3.0 controller using 512 byte chunks but there are issues with IN and bidirectional data transfers when the board is connected to any of the Asmedia 3.0 ports. Out transfers work without issue, but IN transfers fail. We split our bulk data transfers into a predefined chunk size (the #defined value used to be 16K but now it's 4MB because 8MB makes libusb_submit_transfer fail with erc -1). The test I typically run involves transfer 164000000 bytes and with the Asmedia 3.0 controller libusb reports that the transaction has completed a transfer, but it only transfers half of the requested data before reporting a successful transfer. Subsequent transfers fail. I didn't learn anything useful with the packet analyzer captures but I think this is likely an issue with the Asmedia 3.0 driver included with Ubuntu 20 since these data transfers work correctly with Asmedia 3.1 on the same host PC. I also found that bulk data transfer and firmware download work correctly on the Asmedia 3.0 using a USB 2.0 cable.

At this point I intend to document the issue with the only known workaround being to use a USB 2.0 cable.

Thanks,
Michael

0 Likes

Hi Michael,

I understand that the issue is related to the Asmedia host controller in USB 3. 

Do you have any other queries from FX3/CYUSB3014 side?

Best Regards,
AliAsgar