You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
122 lines
11 KiB
122 lines
11 KiB
\chapter{Universal Serial Bus}
|
|
|
|
This chapter presents an overview of the \gls{USB} Full Speed interface, with focus on the features used in the GEX firmware. \gls{USB} is a versatile but complex interface, thus explaining it in its entirety is beyond the scope of this text. References to external material which explains the protocol in greater detail will be provided where appropriate.\todo{add those refs}
|
|
|
|
\begin{figure}[h]
|
|
\centering
|
|
\includegraphics[scale=1] {img/usb-hierarchy-redraw.pdf}
|
|
\caption[USB hierarchical structure]{\label{fig:usb-hierarchy}The hierarchical structure of the USB bus}
|
|
\end{figure}
|
|
|
|
\section{Basic Principles and Terminology}
|
|
|
|
\todo[inline]{review and correct inaccuracies}
|
|
|
|
\gls{USB} is a hierarchical bus with a single master (\textit{host}) and multiple slave devices. A \gls{USB} device that provides functionality to the host is called a \textit{function}. Communication between the host and a function is organized into virtual channels called \textit{pipes}. Each pipe is identified by an \textit{endpoint} number.
|
|
|
|
\begin{figure}[h]
|
|
\centering
|
|
\includegraphics[scale=1] {img/usb-logical-redraw.pdf}
|
|
\caption{\label{fig:usb-logical}The logical structure of USB}
|
|
\end{figure}
|
|
|
|
Endpoints can be either unidirectional or bidirectional; the direction from the host to a function is called OUT, the other direction (function the host) is called IN. A bidirectional endpoint is technically composed of a IN and OUT endpoint with the same number. All transactions (both IN and OUT) are initiated by the host; functions have to wait for their turn. Endpoint 0 is bidirectional, always enabled, and serves as a \textit{control endpoint}. The host uses the control endpoint to read information about the device and configure it as needed.
|
|
|
|
There are four types of transfers: control, bulk, isochronous, and interrupt. Each endpoint is configured for a fixed transfer type:
|
|
|
|
\begin{itemize}
|
|
\item \textit{Control} - initial configuration after device plug-in; also used for other aplication-specific control messages that can affect other pipes.
|
|
\item \textit{Bulk} - used for burst transfers of large messages, commonly e.g. for mass storage devices
|
|
\item \textit{Isochronous} - streaming with guaranteed low latency; designed for audio or video streams where some data loss is preferred over stuttering
|
|
\item \textit{Interrupt} - low latency short messages, used for human interface devices like mice and keyboards
|
|
\end{itemize}
|
|
|
|
The endpoint transfer type and other characteristics, together with other information about the device, such as the serial number, are defined in a \textit{descriptor table}. This is a tree-like binary structure defined in the function's memory. The descriptor table is loaded by the host to learn about the used endpoints and to attach the right driver to it.
|
|
|
|
The function's endpoints are grouped into \textit{interfaces}. An interface describes a logical connection of endpoints, such as the reception and transmission endpoint that belong together. An interface is assigned a \textit{class} defining how it should be used. Standard classes are defined by the USB specification to provide a uniform way of interfacing devices of the same type, such as human-interface devices (mice, keyboards, gamepads) or mass storage devices. The use of standard classes makes it possible to re-use the same driver software for devices from different manufacturers. The class used for the GEX's ``virtual COM port'' function was originally meant for telephone modems, a common way of connecting to the Internet at the time the first versions of USB were developed. A device using this class will show as \verb|/dev/ttyACM0| on Linux and as a COM port on Windows, provided the system supports it natively or the right driver is installed.
|
|
|
|
\todo[inline]{add reference to the document}
|
|
|
|
% function - https://technet.microsoft.com/en-us/library/cc939102.aspx}
|
|
|
|
\newpage
|
|
\input{fig.gex-descriptors}
|
|
|
|
\section{USB Physical Layer}
|
|
|
|
\gls{USB} uses differential signaling with \gls{NRZI} encoding and bit stuffing (the insertion of dummy bits to prevent long intervals in the same \gls{DC} level). The encoding, together with frame formatting, checksum verification, retransmission, and other low level aspects of the \gls{USB} connection are entirely handled by the \gls{USB} physical interface block in the microcontroller's silicon; normally we do not need to worry about those details. What needs more attention are the electrical characteristics of the bus, which need to be understood correctly for a successful schematic and \gls{PCB} design.
|
|
|
|
\noindent
|
|
The \gls{USB} cable contains 4 conductors: V$_\mathrm{BUS}$ (+5\,V), D+, D--, and \gls{GND}. The data lines, D+ and D--, are also commonly labeled DP and DM. This differential pair should be routed in parallel on the \gls{PCB} and kept at the same length.
|
|
|
|
\gls{USB} versions are often backwards compatible, even keeping the same connector shape. The bus speed to use is requested by the device using a 1.5\,k$\Omega$ pull-up resistor to 3.3\,V on one of the data lines: for Full Speed, D+ is pulled high (figure \ref{fig:usb-pullup-fs}), for Low Speed it's on D--. The polarity of the differential signals is inverted depending on the used speed. Some microcontrollers integrate the correct pull-up resistor inside the \gls{USB} block (including out STM32F072), removing the need for an external resistor.
|
|
|
|
\begin{figure}
|
|
\centering
|
|
\includegraphics[width=.8\textwidth]{img/usb-pullup-fs.png}
|
|
\caption[USB pull-ups]{\label{fig:usb-pullup-fs}Pull-up and pull-down resistors of a Full Speed function, as prescribed by the USB specification rev. 2.0}
|
|
\end{figure}
|
|
|
|
When a function wants to be re-enumerated by the host, which is needed to reload the descriptors and re-attach the correct drivers, it can momentarily remove the pull-up resistor, which the host will interpret as if the device was plugged out. With an internal pull-up this can be done by flipping a bit in a control register. An external resistor can be connected through a transistor controlled by a \gls{GPIO} pin.
|
|
|
|
\todo[inline]{https://www.eevblog.com/forum/projects/driving-the-1k5-usb-pull-up-resistor-on-d/}
|
|
\todo[inline]{http://www.beyondlogic.org/usbnutshell/usb2.shtml}
|
|
|
|
The V$_\mathrm{BUS}$ line supplies power to \textit{bus-powered} devices. \textit{Self-powered} devices can leave this pin unconnected and instead use an external power supply. The maximal current drawn from the V$_\mathrm{BUS}$ line is configured using a descriptor and should not be exceeded, but experiments suggest this is often not enforced.
|
|
|
|
\section{USB Classes}
|
|
|
|
This section explains the \gls{MSC} and the \gls{CDCACM} that are used in the GEX firmware. A list of all standard classes with a more detailed explanation can be found on the USB.org website at \url{http://www.usb.org/developers/defined\_class}.\todo{move to references}
|
|
|
|
\subsection{Mass Storage Class}
|
|
|
|
The \gls{MSC} is supported by all modern operating systems (MS Windows, MacOS, GNU/Linux, FreeBSD etc.) to support thumb drives, external disks, memory card readers and other storage devices.
|
|
|
|
\todo[inline]{references}
|
|
%http://www.usb.org/developers/docs/devclass_docs/Mass_Storage_Specification_Overview_v1.4_2-19-2010.pdf
|
|
%http://www.usb.org/developers/docs/devclass_docs/usbmassbulk_10.pdf
|
|
|
|
The \gls{MSC} specification defines multiple \textit{transport protocols} that can be selected using the descriptors. For it's simplicity, the \gls{BOT} will be used. \gls{BOT} uses two bulk endpoints for reading and writing blocks of data and for the exchange of control commands and status messages. For the device to be recognized by the operating system, it must also implement a \textit{command set}. Most mass storage devices use the \textit{\gls{SCSI} Transparent command set}
|
|
\footnote{To confirm this assertion, the descriptors of five thumb drives and an external hard disk were analyzed using \verb|lsusb|. All but one device used the SCSI command set, one (the oldest thumb drive) used \textit{SFF-8070i}. A list of possible command sets can be found in TODO (usb spec overview)}.
|
|
The command set's commands let the host read information about the attached storage, such as its capacity, and check for media presence and readiness to write or detach. This is used e.g. for the "Safely Remove" function which checks that all internal buffers have been written to Flash.
|
|
|
|
\todo[inline]{links}
|
|
|
|
% weird flash - SFF-8070i subclass
|
|
|
|
% usb spec overview https://cscott.net/usb_dev/data/devclass/msco_v109.pdf
|
|
|
|
%https://bits4device.wordpress.com/2013/05/24/usb-mass-storage-class-msc-bulk-only-transfer-bot/
|
|
|
|
%http://janaxelson.com/mass_storage_faq.htm
|
|
|
|
The \gls{MSC} together with the \gls{SCSI} command set are implemented in a \gls{USB} Device library provided by ST Microelectronics. The library also includes a basic \gls{CDCACM} implementation (see below).
|
|
|
|
In order to emulate a mass storage device without having a physical storage medium, we need to generate and parse the filesystem on-the-fly as the host \gls{OS} tries to access it. This will be discussed in chapter \ref{sec:fat16}.
|
|
|
|
\subsection{CDC/ACM Class} \label{sec:cdc-acm}
|
|
|
|
%https://www.keil.com/pack/doc/mw/USB/html/group__usbd__cdc_functions__acm.html
|
|
|
|
Historically meant for modem communication, this class is now the de facto standard way of making \gls{USB} devices appear as serial ports on the host \gls{OS}. The \gls{CDC} uses three endpoints: bulk IN and OUT, and an interrupt endpoint.
|
|
|
|
\todo{verify this vvv}
|
|
The interrupt endpoint is used for control commands and notifications while the bulk endpoints are used for useful data. \gls{ACM} stands for \textit{Abstract Control Model} and it's a \gls{CDC}'s subclass that defines the control messages format. Since we don't use a physical UART and the line is virtual both on the PC and in the end device, the control commands can be ignored.
|
|
|
|
An interesting property of this class is that the bulk endpoints transport raw data without any wrapping frames. By changing the device class in the descriptor table to 255 (\textit{Vendor Specific Class}), we can retain the messaging functionality of the designated endpoints and access the device directly using e.g. libUSB, while the \gls{OS} will ignore it and won't try to attach any driver that could interfere otherwise. The same trick can be used to hide the mass storage class when not needed.
|
|
|
|
\subsection{Interface Association: Composite Class}
|
|
|
|
Since it's creation, the \gls{USB} specification expected that each function will have only one interface enabled at a time. After it became apparent that there is a need for having multiple unrelated interfaces work in parallel, a workaround called the \gls{IAD} was introduced. \gls{IAD} is an entry in the descriptor table that defines which interfaces belong together and should be handled by the same software driver.
|
|
|
|
To use the \gls{IAD}, the function's class must be set to 239 (0xEF), subclass 2 and protocol 1, so the \gls{OS} knows to look for the presence of \glspl{IAD} before binding drivers to any interfaces.
|
|
|
|
% TODO link to some references..
|
|
|
|
In GEX, the \gls{IAD} is used to tie together the \gls{CDC} and \gls{ACM} interfaces while leaving out the \gls{MSC} interface which should be handled by a different driver. To make this work, a new \textit{composite class} had to be created as a wrapper for the library-provided \gls{MSC} and \gls{CDCACM} implementations.
|
|
|
|
%http://www.usb.org/developers/docs/whitepapers/iadclasscode_r10.pdf
|
|
|
|
|
|
|
|
|
|
|