recember 4, 2023

Let's learn USB! -- endpoint registers

First a progress report. I am now running my own code entirely and have left behind all dependence on the papoon C++ code. I am thankful for things it taught me. I am equally thankful for the "daed" code.

I also have tracked down a nasty bug. The bug itself was almost trivial, when I finally found it. But it had me absolutely discouraged for several days. I was looking in the wrong places because the symptoms were that I would receive a "set address" command, then the show slammed to a stop. Naturally I figured there was something crazy about the set address. And there was -- you can't set the address when you get the command, but need to wait until the next transaction. I fixed that, but things still did not work, but the problem was elsewhere.

The problem is in the truly weird nature of the F103 endpoint registers. Unlike almost every other register on the planet, this register is composed of 3 different kinds of bits. No, you can't just read the register, clear and set the bits you want then write it back.
The three flavors are as follows (see page 45 of the F103 tech. manual).

The rc_w0 bits are the CTR_Rx and CTR_Tx bits. They don't change if you write a "1" on top of them, but they clear if you write a "0".

The toggle bits don't change if you write a "0", but they flip if you write a "1".

This mix of bits requires you to be a bit fancy in order to change the bits you want to change in this register. And yes, I got it wrong in one case and it took me a while to realize that was my problem.

I have built up a little collection of routines to perform various manipulations on the endpoint registers. They all need a careful audit after finding the one bug that I did.

The exciting part is that my enumeration log now looks like this!!

0 Enum Reset
1 Enum Rx S AB10 EA60 8 8006000100004000
2 Enum Tx   AB00 72A0 18 120100020200004083044057000201020301
3 Enum Rx   AB10 A220 0
4 Enum Reset
5 Enum Rx S AB10 EA60 8 0005360000000000
6 Enum Tx   AB00 72A0 0
7 Enum Rx S AB10 EA60 8 8006000100001200
8 Enum Tx   AB00 72A0 18 120100020200004083044057000201020301
9 Enum Rx   AB10 A220 0
10 Enum Rx S AB10 EA60 8 8006000600000A00
11 Enum Tx   AB00 72A0 0
12 Enum Rx   AB10 A220 0
13 Enum Rx S AB10 EA60 8 8006000600000A00
14 Enum Tx   AB00 72A0 0
15 Enum Rx   AB10 A220 0
16 Enum Rx S AB10 EA60 8 8006000600000A00
17 Enum Tx   AB00 72A0 0
18 Enum Rx   AB10 A220 0
19 Enum Rx S AB10 EA60 8 8006000200000900
20 Enum Tx   AB00 72A0 9 09024300020100C032
21 Enum Rx   AB10 A220 0
22 Enum Rx S AB10 EA60 8 8006000200004300
23 Enum Tx   AB00 72A0 64 09024300020100C03209040000010202010005240010010524010001042402020524060001070582030800FF09040100020A0000000705030240000007058102
24 Enum Tx   AB00 72E0 3 400000
25 Enum Rx   AB10 A260 0
26 Enum Rx S AB10 EA60 8 800600030000FF000400063003 
It is truncated due to another issue I will work on soon, but seeing it rip along like this means I can go to sleep tonight a happy man.

The linux log shows this:

Dec  4 21:37:28 trona kernel: usb 2-1.2: new full-speed USB device number 54 using ehci-pci
Dec  4 21:37:28 trona kernel: usb 2-1.2: New USB device found, idVendor=0483, idProduct=5740, bcdDevice= 2.00
Dec  4 21:37:28 trona kernel: usb 2-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
Dec  4 21:37:28 trona kernel: usb 2-1.2: Product: Stupid ACM por
Dec  4 21:37:28 trona kernel: usb 2-1.2: Manufacturer: ACME computer
Dec  4 21:37:28 trona kernel: usb 2-1.2: SerialNumber: 123
In other words, enumeration is almost working!! Pretty exciting.
Feedback? Questions? Drop me a line!

Tom's Computer Info / tom@mmto.org