December 9, 2023

Let's learn USB! -- CP2102 resources

We are now making good progress getting our code to act like a CP2102 "usb to uart bridge". We have 4 major resources as we learn how to do this: Each of these is valuable. I will point out that it is quite possible to examine and benefit from the linux host side driver once you see some of the interactions from my own code messages, as well as from Wireshark. I doubt that the driver would be as useful without actual USB transactions as a starting point.

Here is an interesting note on reprogramming an actual CP2102:

This chip and driver interact with various custom SETUP transaction exchanges. Most are just the usual 8 byte setup packet, but some have additional data. When I am asked for data, I just respond (sometimes with a zero length packet). When the host driver sends data, it will appear as subsequent CONTROL data. The two cases I have seen where I get subsequent data are:

Get part number

We get the 8 byte setup packet: C0FF0B3700000100

This is a vendor specific request, asking for the part number. We respond with a single byte with the character "2" indicating we claim to be a CP2102. We would send "4" if we wanted to claim we were a CP2104.

You can find the constant 0x370b in the linux sources where it is defined as follows:

#define CP210X_GET_PARTNUM      0x370B

Enable/disable uart

We get this 8 byte setup packet, which asks us to "enable the uart".
4100010000000000
If the value field inside was 0000 it would be asking us to disable the uart.

We are only asked to enable the uart when picocom opens a connection. In fact quite a bit goes on when picocom starts up as follows.
(This is debug output from my software.)
This is likely partially defective since I am not responding as I should to all of these requests, so many are forced to timeout and retry.

Setup packet: 8 bytes --  4100010000000000 - enable uart interface
Setup packet: 8 bytes --  411E000000000400 - set baud rate
Control packet: 4 bytes --  80250000
Setup packet: 8 bytes --  4103000800000000 - set line control
Setup packet: 8 bytes --  4119000000000600 - set chars
Control packet: 6 bytes --  000000001113
Setup packet: 8 bytes --  C114000000001000 - get flow control
Setup packet: 8 bytes --  4107030300000000 - set modem handshaking
Setup packet: 8 bytes --  C108000000000100 - get modem status
Setup packet: 8 bytes --  C110000000001300 - get serial status
Setup packet: 8 bytes --  4103000800000000 - set line control
Setup packet: 8 bytes --  C114000000001000 - get flow control
Setup packet: 8 bytes --  C108000000000100 - get modem status
Setup packet: 8 bytes --  C108000000000100 - get modem status
When picocom shuts down, we get all of this:
Setup packet: 8 bytes --  4103000800000000 - line control
Setup packet: 8 bytes --  4119000000000600 - set chars
Control packet: 6 bytes --  000000001113
Setup packet: 8 bytes --  C114000000001000 - get flow
Setup packet: 8 bytes --  C110000000001300 - get baud rate
Setup packet: 8 bytes --  4107000300000000 - set modem handshake
Setup packet: 8 bytes --  41120F0000000000 - purge
Setup packet: 8 bytes --  4100000000000000 - disable uart
I am able to interpret these requests by using AN571.
Feedback? Questions? Drop me a line!

Tom's Computer Info / tom@mmto.org