diff options
author | Brian Cully <bjc@kublai.com> | 2019-08-11 12:37:21 -0400 |
---|---|---|
committer | Brian Cully <bjc@kublai.com> | 2019-08-11 12:48:06 -0400 |
commit | e8739872b482872adf9b18ef2b5419098f8fadb3 (patch) | |
tree | 3956b680f26c495cdddf7b71ad656e2ed14c2cc0 /src/lib.rs | |
parent | b0be48424e81384de3280b5a5ac521d694b82e15 (diff) | |
download | usb-host-e8739872b482872adf9b18ef2b5419098f8fadb3.tar.gz usb-host-e8739872b482872adf9b18ef2b5419098f8fadb3.zip |
Add documentation and tests.
Diffstat (limited to 'src/lib.rs')
-rw-r--r-- | src/lib.rs | 86 |
1 files changed, 75 insertions, 11 deletions
@@ -1,20 +1,38 @@ -//! Traits for a hardware-agnostic USB host interface. +//! This crate defines a set of traits for use on the host side of the +//! USB. +//! +//! The `USBHost` defines the Host Controller Interface that can be +//! used by the `Driver` interface. +//! +//! The `Driver` interface defines the set of functions necessary to +//! use devices plugged into the host. #![no_std] -mod descriptor; -mod setup; +pub mod descriptor; +pub mod setup; pub use descriptor::*; pub use setup::*; +/// Errors that can be generated when attempting to do a USB transfer. #[derive(Debug)] pub enum TransferError { + /// An error that may be retried. Retry(&'static str), + + /// A permanent error. Permanent(&'static str), } +/// Trait for host controller interface. pub trait USBHost { + /// Issue a control transfer with an optional data stage to + /// `ep`. The data stage direction is determined by the direction + /// of `bm_request_type`. + /// + /// On success, the amount of data transferred into `buf` is + /// returned. fn control_transfer( &mut self, ep: &mut dyn Endpoint, @@ -25,16 +43,26 @@ pub trait USBHost { buf: Option<&mut [u8]>, ) -> Result<usize, TransferError>; + /// Issue a transfer from `ep` to the host. + /// + /// On success, the amount of data transferred into `buf` is + /// returned. fn in_transfer( &mut self, ep: &mut dyn Endpoint, buf: &mut [u8], ) -> Result<usize, TransferError>; + /// Issue a transfer from the host to `ep`. + /// + /// On success, the amount of data transferred from `buf` is + /// returned. This should always be equal to `buf.len()`. fn out_transfer(&mut self, ep: &mut dyn Endpoint, buf: &[u8]) -> Result<usize, TransferError>; } -// cf §9.6.6 of USB 2.0 +/// The type of transfer to use when talking to USB devices. +/// +/// cf §9.6.6 of USB 2.0 #[derive(Copy, Clone, Debug, PartialEq)] pub enum TransferType { Control = 0, @@ -43,50 +71,86 @@ pub enum TransferType { Interrupt = 3, } -// ibid +/// The direction of the transfer with the USB device. +/// +/// cf §9.6.6 of USB 2.0 #[derive(Copy, Clone, Debug, PartialEq)] pub enum Direction { Out, In, } +/// `Endpoint` defines the USB endpoint for various transfers. pub trait Endpoint { + /// Address of the device owning this endpoint. Must be between 0 + /// and 127. fn address(&self) -> u8; + /// Endpoint number, irrespective of direction. (e.g., for both + /// endpoint addresses, `0x81` and `0x01`, this function would + /// return `0x01`). fn endpoint_num(&self) -> u8; + /// The type of transfer this endpoint uses. fn transfer_type(&self) -> TransferType; + /// The direction of transfer this endpoint accepts. fn direction(&self) -> Direction; + /// The maximum packet size for this endpoint. fn max_packet_size(&self) -> u16; + /// The data toggle sequence bit for the next transfer from the + /// device to the host. fn in_toggle(&self) -> bool; + /// The `USBHost` will, when required, update the data toggle + /// sequence bit for the next device to host transfer. fn set_in_toggle(&mut self, toggle: bool); + /// The data toggle sequence bit for the next transfer from the + /// host to the device. fn out_toggle(&self) -> bool; + /// The `USBHost` will, when required, update the data toggle + /// sequence bit for the next host to device transfer. fn set_out_toggle(&mut self, toggle: bool); } +/// Types of errors that can be returned from a `Driver`. #[derive(Copy, Clone, Debug)] pub enum DriverError { + /// An error that may be retried. Retry(u8, &'static str), + + /// A permanent error. Permanent(u8, &'static str), } + +/// Trait for drivers on the USB host. pub trait Driver: core::fmt::Debug { + /// Does this driver want `device`? + /// + /// Answering `true` to this not necessarily mean the driver will + /// get `device`. fn want_device(&self, device: &DeviceDescriptor) -> bool; + /// Add `device` with address `address` to the driver's registry, + /// if necessary. fn add_device(&mut self, device: DeviceDescriptor, address: u8) -> Result<(), DriverError>; + /// Remove the device at address `address` from the driver's + /// registry, if necessary. fn remove_device(&mut self, address: u8); + /// Called regularly by the USB host to allow the driver to do any + /// work necessary on its registered devices. + /// + /// `millis` is the current time, in milliseconds from some + /// arbitrary starting point. It should be expected that after a + /// long enough run-time, this value will wrap. + /// + /// `usbhost` may be used for communication with the USB when + /// required. fn tick(&mut self, millis: usize, usbhost: &mut dyn USBHost) -> Result<(), DriverError>; } - -// TODO: There needs to be a per-interface/function driver trait, as -// well, since that's how most drivers will actually work. -// -// As a result, the host driver has to at least get the full -// configuration. |