Using user-space USB drivers: Part 5

Feature image

I think I have finally figured out the problem with my TUSB3410 driver, including why it's not working on my USB host shield. In short, the chip requires that you upload its firmware into the chip every time it is plugged in.

I noticed today that sometimes when I plug it into a host PC, there is only one USB configuration with only an OUT endpoint. There should be two configurations with the second one having multiple endpoints, including an IN endpoint.

This made me realise that it's possible that when I plug the device into a system with a working kernel driver, that driver is loading the firmware into the chip, so that when I then unload the kernel driver I see the two configurations when connecting with the user-space driver.

To confirm this I added the ti_usb_3410_5052 Linux kernel driver to the kernel module blacklist (/etc/modprobe.d/blacklist.conf) to prevent it from loading. I then verified this by running usb-devices[1] and checking that it says Driver=(none) next to the device description.

I then checked the number of configurations and low and behold, there was only one this time.

Luckily Texas Instruments has made the source code for their macOS driver available online, even though the macOS driver itself was never officially released. The source code also contains the chip firmware, so I just had to look at the source code to see how to write the firmware to the chip. Basically you just write a bulk out transfer, with the firmware bytes prepended by three special bytes: [size & 0xFF, (size >> 8) & 0xFF, checksum & 0xFF], where size is the length of the firmware byte array, and checksum is just adding all the bytes in the firmware array together.

I've got this working on Linux now. macOS is the next step, and then I can go back to my Espruino code and get it working on the USB host shield.


  1. part of the usbutils package on Ubuntu/Debian ↩︎