usb_host/lib.rs
1//! This crate defines a set of traits for use on the host side of the
2//! USB.
3//!
4//! The `USBHost` defines the Host Controller Interface that can be
5//! used by the `Driver` interface.
6//!
7//! The `Driver` interface defines the set of functions necessary to
8//! use devices plugged into the host.
9
10#![no_std]
11
12pub mod descriptor;
13pub mod setup;
14
15pub use descriptor::*;
16pub use setup::*;
17
18/// Errors that can be generated when attempting to do a USB transfer.
19#[derive(Debug)]
20pub enum TransferError {
21 /// An error that may be retried.
22 Retry(&'static str),
23
24 /// A permanent error.
25 Permanent(&'static str),
26}
27
28/// Trait for host controller interface.
29pub trait USBHost {
30 /// Issue a control transfer with an optional data stage to
31 /// `ep`. The data stage direction is determined by the direction
32 /// of `bm_request_type`.
33 ///
34 /// On success, the amount of data transferred into `buf` is
35 /// returned.
36 fn control_transfer(
37 &mut self,
38 ep: &mut dyn Endpoint,
39 bm_request_type: RequestType,
40 b_request: RequestCode,
41 w_value: WValue,
42 w_index: u16,
43 buf: Option<&mut [u8]>,
44 ) -> Result<usize, TransferError>;
45
46 /// Issue a transfer from `ep` to the host.
47 ///
48 /// On success, the amount of data transferred into `buf` is
49 /// returned.
50 fn in_transfer(
51 &mut self,
52 ep: &mut dyn Endpoint,
53 buf: &mut [u8],
54 ) -> Result<usize, TransferError>;
55
56 /// Issue a transfer from the host to `ep`.
57 ///
58 /// On success, the amount of data transferred from `buf` is
59 /// returned. This should always be equal to `buf.len()`.
60 fn out_transfer(&mut self, ep: &mut dyn Endpoint, buf: &[u8]) -> Result<usize, TransferError>;
61}
62
63/// The type of transfer to use when talking to USB devices.
64///
65/// cf §9.6.6 of USB 2.0
66#[derive(Copy, Clone, Debug, PartialEq)]
67pub enum TransferType {
68 Control = 0,
69 Isochronous = 1,
70 Bulk = 2,
71 Interrupt = 3,
72}
73
74/// The direction of the transfer with the USB device.
75///
76/// cf §9.6.6 of USB 2.0
77#[derive(Copy, Clone, Debug, PartialEq)]
78pub enum Direction {
79 Out,
80 In,
81}
82
83/// `Endpoint` defines the USB endpoint for various transfers.
84pub trait Endpoint {
85 /// Address of the device owning this endpoint. Must be between 0
86 /// and 127.
87 fn address(&self) -> u8;
88
89 /// Endpoint number, irrespective of direction. (e.g., for both
90 /// endpoint addresses, `0x81` and `0x01`, this function would
91 /// return `0x01`).
92 fn endpoint_num(&self) -> u8;
93
94 /// The type of transfer this endpoint uses.
95 fn transfer_type(&self) -> TransferType;
96
97 /// The direction of transfer this endpoint accepts.
98 fn direction(&self) -> Direction;
99
100 /// The maximum packet size for this endpoint.
101 fn max_packet_size(&self) -> u16;
102
103 /// The data toggle sequence bit for the next transfer from the
104 /// device to the host.
105 fn in_toggle(&self) -> bool;
106
107 /// The `USBHost` will, when required, update the data toggle
108 /// sequence bit for the next device to host transfer.
109 fn set_in_toggle(&mut self, toggle: bool);
110
111 /// The data toggle sequence bit for the next transfer from the
112 /// host to the device.
113 fn out_toggle(&self) -> bool;
114
115 /// The `USBHost` will, when required, update the data toggle
116 /// sequence bit for the next host to device transfer.
117 fn set_out_toggle(&mut self, toggle: bool);
118}
119
120/// Types of errors that can be returned from a `Driver`.
121#[derive(Copy, Clone, Debug)]
122pub enum DriverError {
123 /// An error that may be retried.
124 Retry(u8, &'static str),
125
126 /// A permanent error.
127 Permanent(u8, &'static str),
128}
129
130/// Trait for drivers on the USB host.
131pub trait Driver: core::fmt::Debug {
132 /// Does this driver want `device`?
133 ///
134 /// Answering `true` to this not necessarily mean the driver will
135 /// get `device`.
136 fn want_device(&self, device: &DeviceDescriptor) -> bool;
137
138 /// Add `device` with address `address` to the driver's registry,
139 /// if necessary.
140 fn add_device(&mut self, device: DeviceDescriptor, address: u8) -> Result<(), DriverError>;
141
142 /// Remove the device at address `address` from the driver's
143 /// registry, if necessary.
144 fn remove_device(&mut self, address: u8);
145
146 /// Called regularly by the USB host to allow the driver to do any
147 /// work necessary on its registered devices.
148 ///
149 /// `millis` is the current time, in milliseconds from some
150 /// arbitrary starting point. It should be expected that after a
151 /// long enough run-time, this value will wrap.
152 ///
153 /// `usbhost` may be used for communication with the USB when
154 /// required.
155 fn tick(&mut self, millis: usize, usbhost: &mut dyn USBHost) -> Result<(), DriverError>;
156}