November 10, 2023

Let's learn USB! -- Frames

This is some of the USB stuff that a programmer isn't supposed to have to care about or know about. I got lured into learning about it when I noticed that the F103 usb controller has an SOF interrupt. Talking about all of this sort of violates my own rule about ignoring everything I can't directly "touch" from software, but if I can't break my own rules, who can?

SOF is "start of frame". As it turns out, USB communication is based on frames and every frame begins with an SOF packet. All very well and good. Why should we care? Do we care? I don't know yet.

Being curious, I enabled the SOF interrupt and simply counted them, reporting every second how many had arrived in the past second. I learned two things:

First, you don't get any (on a USB device like the F103) unless the cable is plugged in. These things originate on the host.

Second you get 1000 of them every second, without fail. Printing a message every time you get one is annoying and unproductive.

USB frames and "full speed" USB

The F103 does full speed (12 Mb/sec) and by golly that is exactly what they say will happen. There is a frame every millisecond. If you go to high speed you get them 8 times faster, but we aren't talking about high speed here. Also interesting is the statement I find that full speed allows a maximum of 64 bytes in a frame. This means that we can send 64*1000 = 64K bytes per second as a maximum, if we do everything correctly and have a tail wind.

Note that for something like a 115200 baud uart, this is entirely adequate. If we figure 10 bits per character for a uart (a rule of thumb I always use) this would be 11,520 characters per second. We could handle several of these over a single full speed link.

But I thought full speed was 12 Megabits/second

It is!

What I find surprising is that we don't do better than 64K bytes per second. We are told that full speed is 12 Mb/second and again, figuring 10 bits per character (which allows for various forms of overhead), this would allow for 1.2 M bytes per second, i.e. 1200 Kbytes per second. And we just learned that we will only get 64Kbytes per second for full speed.

Some additional reading allowed me to learn several thing. There is more to the story. For one thing "isochronous" USB connections can have 1023 byte packets, and 1000 of these each seconds would give 1.02 Mbyte/sec. Also I am told that "bulk" USB packets can pack 19 of these 64 byte packets into a frame, which would give us exactly 1.2 Mbyte/sec.

So, they didn't lie to us after all, there is just more to the story. Exactly how to arrange things so we get those 19 packets into a frame is unknown to me thus far. I also don't know yet if an ACM flavor serial link works in "bulk" or some other mode. But it doesn't matter given that 64 Kbytes/sec will handle our serial port anyway.


Feedback? Questions? Drop me a line!

Tom's Computer Info / tom@mmto.org