Crates.io | cotton-usb-host |
lib.rs | cotton-usb-host |
version | |
source | src |
created_at | 2024-12-02 13:15:35.405884 |
updated_at | 2024-12-02 13:15:35.405884 |
description | USB host stack for embedded devices |
homepage | https://github.com/pdh11/cotton |
repository | https://github.com/pdh11/cotton |
max_upload_size | |
id | 1468630 |
Cargo.toml error: | TOML parse error at line 19, column 1 | 19 | autolib = false | ^^^^^^^ unknown field `autolib`, expected one of `name`, `version`, `edition`, `authors`, `description`, `readme`, `license`, `repository`, `homepage`, `documentation`, `build`, `resolver`, `links`, `default-run`, `default_dash_run`, `rust-version`, `rust_dash_version`, `rust_version`, `license-file`, `license_dash_file`, `license_file`, `licenseFile`, `license_capital_file`, `forced-target`, `forced_dash_target`, `autobins`, `autotests`, `autoexamples`, `autobenches`, `publish`, `metadata`, `keywords`, `categories`, `exclude`, `include` |
size | 0 |
Part of the Cotton project.
This crate enables the USB host-controller peripheral on the RP2040 microcontroller, allowing USB devices (memory sticks, keyboards, hubs, etc.) to be connected directly to the RP2040 and controlled by it.
USB operation is asynchronous and so this crate is suited for use with embedded asynchronous executors such as RTIC 2 and Embassy.
Includes:
Currently supports:
System-tests and examples:
Limitations:
Library documentation is on docs.rs.
This crate configures the Raspberry Pi Pico's USB peripheral for USB host mode only, and not USB device mode. So before running your code, make sure that the USB connector on your Raspberry Pi Pico is plugged into a USB device, and not into another USB host such as a laptop3. (You can still use a SWD connection via the 3-pin debug connector to program and debug your Raspberry Pi Pico -- just not the USB connection.)
If your Raspberry Pi Pico is itself powered by USB (perhaps via a Pico Debug Probe), then it will not have enough power to reliably supply USB power to downstream devices unless you power your Pico's VUSB/GND pins from a separate 5V power supply — and perhaps not even then. For best results with multiple devices, you should use a powered hub. (Powered hubs with micro-USB plugs, compatible with the Raspberry Pi Pico in host mode, are often sold as "OTG hubs".)
The crate is split between a generic (hardware-agnostic) [usb_bus::UsbBus
]
class, and a host-controller driver specific to the RP2040. So the
minimal code example would involve:
UsbShared
object, making sure it's shared between the
software tasks and the hardware interrupt handler;USBCTRL_IRQ
interrupt handler calls UsbShared::on_irq()
;UsbStatics
object, which needn't be shared, but must
be &'static
— for instance, by using the static-cell
crate;host::rp2040::Rp2040HostController
from the UsbShared,
the UsbStatics, and the USB register banks from rp2040-pac
;UsbBus
from the host-controller driver;UsbBus::device_events()
— or, alternatively,
UsbBus::device_events_no_hubs()
for smaller code-size if
supporting USB hubs isn't required;DeviceEvent::Connect
indicating that the device has been detected;UsbBus::control_transfer
to read descriptors,
UsbBus::configure
to configure the device appropriately, and
UsbBus::interrupt_endpoint
to read data from the device.This crate includes an example of identifying and communicating with a Plugable USB2-OTGE100 Ethernet adaptor based on the ASIX AX88772 chip. A more complete example driver, for USB mass-storage class devices, is in the cotton-usb-host-msc crate.
Once your code has successfully created the UsbBus
object and has
called UsbBus::device_events()
, it will receive DeviceInfo
objects
which allow your code to identify relevant devices either by class
code (for generic class drivers such as mass-storage or HID) or by VID
and PID (for device-specific drivers).
The UsbBus
code should be generic enough to be usable with other
microcontrollers' USB host peripherals. You'll need to implement the
host_controller::HostController
trait, which encapsulates all the
actual hardware interaction. Typically such host controllers have a
smallish, fixed number of "pipes" (actively-used endpoints) which can
be used simultaneously; you might find async_pool::Pool
, as used by
the RP2040 host-controller driver, to be a convenient way of
allocating those pipes as required.
The RP2040 support is in this repo to provide a convenient worked example; specific host-controller support for other microcontrollers probably belongs in those microcontrollers' HAL crates.
TODO before merge
TODO before 0.1.0:
TODO later:
The documentation describes this as "USB 2.0 LS and FS" (1.5 and 12Mbits/s), but as the only changes in USB 2.0 compared to 1.1 were related to the addition of HS (480Mbits/s), it seems more honest to describe it as USB 1.1. ↩
USB 3.0 explicitly limits hubs to 15 downstream ports; USB 2.0 and earlier did not, but even for USB 2.0 such wide hubs are either very rare or, quite possibly, non-existent. Most freestanding hubs which appear to have more than about 7 downstream ports, are in fact multiple hubs in a trenchcoat. ↩
The Raspberry Pi Pico (and the W5500-EVB-Pico for that matter) have USB Micro-B receptacles (sockets), capable of receiving Micro-B plugs only. Because they are capable of both USB device and USB host, they should arguably have had USB Micro-AB receptacles, capable of receiving both Micro-A (rectangular) and Micro-B (trapezium) plugs. But USB cables and adaptors with Micro-B plugs for their host side connection (instead of Micro-A which it should technically be) are common. Both ST and Renesas devboards get this right: they have Micro-AB receptacles (though the very newest ST ones have type-C instead). ↩