December 5, 2020

USB - Basics

USB is based on a tiered star topology.

So you have a host connected to hubs connected to devices. USB uses a 7 bit address, which gives us 128 devices, but zero is used for special things, so we can (in theory) have 127 devices connected to a single host.

You can have hubs and hubs connected to hubs. But hubs can only go 5 deep. The scheme is limited to a 6 deep tier and the final device takes up tier 6 if you go that crazy. Cables are limited to 5 meters. So if you are going crazy with hubs you could put your device at most 30 meters from the host by using 5 hubs.

The host is master and initiates everything. Devices cannot talk to each other directly. And devices only talk when told to by the host. The only exception is when a sleeping device wakes up and signals a "remote wakeup". OTG changes this somewhat, allowing devices to take on a host role in a limited way. There is an OTG (On the Go) supplement to the USB 2.0 spec that describes all this.

Due to some industry squabbles, there are two host interfaces in the USB 1 world (OHCI and UHCI). When USB 2 rolled around, they made peace and settled on EHCI. We don't care much about all of this because we are working on software for slave devices, not hosts.

Conectors

Recent revisions (USB-C) have changed all of this, but once upon a time it was like this:

The flat thing everyone (especially me) hates is the "A" Plug. The square thing you hardly see any more is the "B" plug. We also have mini and micro plugs.

Cables have 4 wires. We have power (5v) and ground and D+ and D-.

100 mA is the standard current limit and a device may be supplied with 500 mA if this is agreed on.

The Bus

At any time only the host and one device can be talking. Lots of devices may see the data, but if they are not being addressed, they ignore it.

The bus basically runs on 3.3 volt levels.
A device with a 1.5K pull up resistor on D- is a low speed device.
A device with a 1.5K pull up resistor on D+ is a high speed device.

Bus states

Detached - nothing plugged in, the host has 15K resistors pulling both D lines low.
Attached - either D- or D+ goes high
Idle - one line or the other is high, as per "attached" above.

Suspend - any time the host does not talk to a device for 3 ms or longer, the device goes into a suspend state. The host normally sends an SOF packet (if full speed) or a "keep alive" (if low speed) to keep the device awake. A suspended device must respond to Resume or Reset signals.

With 2 lines, we can have 4 states:

SE0 - both lines low (single ended zero)
J state - same as idle state for the given speed.
K state - inverse of the J state.
SE1 - illegal state with both lines high.

The host starts the show with a "Reset" by pulling both lines low for at least 10ms.

EOP - end of packet -- SE0 for 2 bit times, then J for 1 bit time.

Resume - the host reverses the signal for at least 20 ms, then finishes with a low speed EOP.

Keep Alive = a low speed EOP.

Packets

A packet is a certain number of bytes. Note that data fields are sent with the low byte first. Hardware handles the packet details generating and recognizing start and end of packets. A packet looks like:
[Sync] [Data bytes] [EOP}

Endpoints

A device can have up to 16 IN and 16 OUT endpoints. An endpoint is either a source or sink of data. Endpoint 0 is special. It is both IN and OUT and is used to control the device. The host sets up a "pipe" to each endpoint it wants to talk to.

It is very important to note a convention about the names IN and OUT. It is always from the perspective of the host. So when you are a device, your IN endpoint is sending data to the host, and your OUT endpoint is receiving data coming out of the host.

Packet formats

The first byte in every packet is a PID (packet ID). It is actually 4 bits followed by the 4 bits complemented. At this point you need a table of the 16 values, and one value gets used in 2 different ways depending on context, so there are really 17 possible PID cases. This is set up as 4 packet types, each with 4 (or 5) cases.

Token packet - for SETUP, OUT, IN packets, always first in a transaction.
Data packet - for DATA0, DATA1, DATA2, and MDATA packets
Handshake packet - ACK, NAK, STALL, NYET packets, status stage of a transaction.
SOF - special "start of frame" token packet, sent every 1 ms on full speed links.

And then we have 4 "special packets". PID = 0 is reserved.

Transactions

A transaction is a 3 packet sequence that transfers data.

OUT - a token and data are sent, an ACK is received.
IN - a token is send, data received, an ACK is sent
SETUP - a token and data are sent, an ACK is received.

There are 4 transaction "types" that refer to data flow.

Control - always to endpoint 0
Bulk - for high volume, no bandwidth guarantee, low priority.
Interrupt - regular handshaking and status
Isochronous - guaranteed fixed bandwidth

Bulk transfers can send 8, 16, 32, or 64 bytes at full speed (512 for high speed).
Interrupt transfers have nothing to do with interrupts, but they are scheduled at regular intervals. They contain from 1 to 64 bytes at full speed. Ideal for mice or keyboards.
Isochronous transfers are not guaranteed error free, but bandwidth is guaranteed. The contain up to 1023 bytes at full speed. No ACK. Ideal for audio.

Control is bidirectional and uses both the IN and OUT endpoint 0. We have SETUP, then optional DATA (DATA1 alternates with DATA0), then STATUS in the opposite direction from the SETUP and DATA. The size can be 8,16,32, or 64 at full speed.


Feedback? Questions? Drop me a line!

Tom's Computer Info / tom@mmto.org