109 lines
5.0 KiB
ReStructuredText
109 lines
5.0 KiB
ReStructuredText
|
=====================
|
||
|
USB Host-Side Drivers
|
||
|
=====================
|
||
|
|
||
|
- ``include/nuttx/usb/usbhost.h``. All structures and APIs
|
||
|
needed to work with USB host-side drivers are provided in this
|
||
|
header file.
|
||
|
|
||
|
- ``struct usbhost_driver_s`` and
|
||
|
``struct usbhost_connection_s``. Each USB host controller
|
||
|
driver must implement an instance of
|
||
|
``struct usbhost_driver_s`` and
|
||
|
``struct usbhost_connection_s``: ``struct usbhost_driver_s``
|
||
|
provides the interface between the USB host driver and the USB
|
||
|
class driver; ``struct usbhost_connection_s`` provides the
|
||
|
interface between the USB host driver and platform-specific
|
||
|
connection management and device enumeration logic. These
|
||
|
structures are defined in ``include/nuttx/usb/usbhost.h``.
|
||
|
|
||
|
**Examples**: ``arch/arm/src/lpc17xx_40xx/lpc17_40_usbhost.c``,
|
||
|
``arch/arm/src/stm32/stm32_otgfshost.c``,
|
||
|
``arch/arm/src/sama5/sam_ohci.c``, and
|
||
|
``arch/arm/src/sama5/sam_ehci.c``.
|
||
|
|
||
|
- ``struct usbhost_class_s``. Each USB host class driver must
|
||
|
implement an instance of ``struct usbhost_class_s``. This
|
||
|
structure is also defined in ``include/nuttx/usb/usbhost.h``.
|
||
|
|
||
|
**Examples**: ``drivers/usbhost/usbhost_storage.c``
|
||
|
|
||
|
- **USB Host Class Driver Registry**. The NuttX USB host
|
||
|
infrastructure includes a *registry*. During its
|
||
|
initialization, each USB host class driver must call the
|
||
|
interface, ``usbhost_registerclass()`` in order add its
|
||
|
interface to the registry. Later, when a USB device is
|
||
|
connected, the USB host controller will look up the USB host
|
||
|
class driver that is needed to support the connected device in
|
||
|
this registry.
|
||
|
|
||
|
**Examples**: ``drivers/usbhost/usbhost_registry.c``,
|
||
|
``drivers/usbhost/usbhost_registerclass.c``, and
|
||
|
``drivers/usbhost/usbhost_findclass.c``,
|
||
|
|
||
|
- **Detection and Enumeration of Connected Devices**. Each USB
|
||
|
host device controller supports two methods that are used to
|
||
|
detect and enumeration newly connected devices (and also detect
|
||
|
disconnected devices):
|
||
|
|
||
|
- ``int (*wait)(FAR struct usbhost_connection_s *drvr, FAR const bool *connected);``
|
||
|
|
||
|
Wait for a device to be connected or disconnected.
|
||
|
|
||
|
- ``int (*enumerate)(FAR struct usbhost_connection_s *drvr, int rhpndx);``
|
||
|
|
||
|
Enumerate the device connected to a root hub port. As part
|
||
|
of this enumeration process, the driver will (1) get the
|
||
|
device's configuration descriptor, (2) extract the class ID
|
||
|
info from the configuration descriptor, (3) call
|
||
|
``usbhost_findclass(``) to find the class that supports this
|
||
|
device, (4) call the ``create()`` method on the
|
||
|
``struct usbhost_registry_s interface`` to get a class
|
||
|
instance, and finally (5) call the ``connect()`` method of
|
||
|
the ``struct usbhost_class_s`` interface. After that, the
|
||
|
class is in charge of the sequence of operations.
|
||
|
|
||
|
- **Binding USB Host-Side Drivers**. USB host-side controller
|
||
|
drivers are not normally directly accessed by user code, but
|
||
|
are usually bound to another, higher level USB host class
|
||
|
driver. The class driver exports the standard NuttX device
|
||
|
interface so that the connected USB device can be accessed just
|
||
|
as with other, similar, on-board devices. For example, the USB
|
||
|
host mass storage class driver
|
||
|
(``drivers/usbhost/usbhost_storage.c``) will register a
|
||
|
standard, NuttX block driver interface (like ``/dev/sda``) that
|
||
|
can be used to mount a file system just as with any other other
|
||
|
block driver instance. In general, the binding sequence is:
|
||
|
|
||
|
#. Each USB host class driver includes an initialization entry
|
||
|
point that is called from the application at initialization
|
||
|
time. This driver calls ``usbhost_registerclass()`` during
|
||
|
this initialization in order to makes itself available in
|
||
|
the event the device that it supports is connected.
|
||
|
|
||
|
**Examples**: The function ``usbhost_msc_initialize()`` in
|
||
|
the file ``drivers/usbhost/usbhost_storage.c``
|
||
|
|
||
|
#. Each application must include a *waiter* thread thread that
|
||
|
(1) calls the USB host controller driver's ``wait()`` to
|
||
|
detect the connection of a device, and then (2) call the USB
|
||
|
host controller driver's ``enumerate`` method to bind the
|
||
|
registered USB host class driver to the USB host controller
|
||
|
driver.
|
||
|
|
||
|
**Examples**: The function ``nsh_waiter()`` in the file
|
||
|
``boards/arm/lpc17xx_40xx/olimex-lpc1766stk/src/lpc17_40_appinit.c``.
|
||
|
|
||
|
#. As part of its operation during the binding operation, the
|
||
|
USB host class driver will register an instances of a
|
||
|
standard NuttX driver under the ``/dev`` directory. To
|
||
|
repeat the above example, the USB host mass storage class
|
||
|
driver (``drivers/usbhost/usbhost_storage.c``) will register
|
||
|
a standard, NuttX block driver interface (like ``/dev/sda``)
|
||
|
that can be used to mount a file system just as with any
|
||
|
other other block driver instance.
|
||
|
|
||
|
**Examples**: See the call to ``register_blockdriver()`` in
|
||
|
the function ``usbhost_initvolume()`` in the file
|
||
|
``drivers/usbhost/usbhost_storage.c``.
|