kernel/hil/
usb.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! Interface to USB controller hardware
6
7use crate::utilities::cells::VolatileCell;
8
9/// USB controller interface
10pub trait UsbController<'a> {
11    fn set_client(&self, client: &'a dyn Client<'a>);
12
13    // Should be called before `enable_as_device()`
14    fn endpoint_set_ctrl_buffer(&self, buf: &'a [VolatileCell<u8>]);
15    fn endpoint_set_in_buffer(&self, endpoint: usize, buf: &'a [VolatileCell<u8>]);
16    fn endpoint_set_out_buffer(&self, endpoint: usize, buf: &'a [VolatileCell<u8>]);
17
18    // Must be called before `attach()`
19    fn enable_as_device(&self, speed: DeviceSpeed);
20
21    fn attach(&self);
22
23    fn detach(&self);
24
25    fn set_address(&self, addr: u16);
26
27    fn enable_address(&self);
28
29    fn endpoint_in_enable(&self, transfer_type: TransferType, endpoint: usize);
30
31    fn endpoint_out_enable(&self, transfer_type: TransferType, endpoint: usize);
32
33    fn endpoint_in_out_enable(&self, transfer_type: TransferType, endpoint: usize);
34
35    fn endpoint_resume_in(&self, endpoint: usize);
36
37    fn endpoint_resume_out(&self, endpoint: usize);
38}
39
40#[derive(Clone, Copy, Debug)]
41pub enum TransferType {
42    Control = 0,
43    Isochronous,
44    Bulk,
45    Interrupt,
46}
47
48#[derive(Clone, Copy, Debug)]
49pub enum DeviceSpeed {
50    Full,
51    Low,
52}
53
54/// USB controller client interface
55pub trait Client<'a> {
56    fn enable(&'a self);
57    fn attach(&'a self);
58    fn bus_reset(&'a self);
59
60    fn ctrl_setup(&'a self, endpoint: usize) -> CtrlSetupResult;
61    fn ctrl_in(&'a self, endpoint: usize) -> CtrlInResult;
62    fn ctrl_out(&'a self, endpoint: usize, packet_bytes: u32) -> CtrlOutResult;
63    fn ctrl_status(&'a self, endpoint: usize);
64    fn ctrl_status_complete(&'a self, endpoint: usize);
65
66    fn packet_in(&'a self, transfer_type: TransferType, endpoint: usize) -> InResult;
67    fn packet_out(
68        &'a self,
69        transfer_type: TransferType,
70        endpoint: usize,
71        packet_bytes: u32,
72    ) -> OutResult;
73
74    fn packet_transmitted(&'a self, endpoint: usize);
75}
76
77#[derive(Debug)]
78pub enum CtrlSetupResult {
79    /// The Setup request was handled successfully
80    Ok,
81    OkSetAddress,
82
83    // The Setup request cannot be handled; abort this transfer with STALL
84    ErrBadLength,
85    ErrNoParse,
86    ErrNonstandardRequest,
87    ErrUnrecognizedDescriptorType,
88    ErrUnrecognizedRequestType,
89    ErrNoDeviceQualifier,
90    ErrInvalidDeviceIndex,
91    ErrInvalidConfigurationIndex,
92    ErrInvalidInterfaceIndex,
93    ErrInvalidStringIndex,
94
95    ErrGeneric,
96}
97
98pub enum CtrlInResult {
99    /// A packet of the given size was written into the endpoint buffer
100    Packet(usize, bool),
101
102    /// The client is not yet able to provide data to the host, but may
103    /// be able to in the future.  This result causes the controller
104    /// to send a NAK token to the host.
105    Delay,
106
107    /// The client does not support the request.  This result causes the
108    /// controller to send a STALL token to the host.
109    Error,
110}
111
112pub enum CtrlOutResult {
113    /// Data received (send ACK)
114    Ok,
115
116    /// Not ready yet (send NAK)
117    Delay,
118
119    /// In halt state (send STALL)
120    Halted,
121}
122
123/// Result for IN packets sent on bulk or interrupt endpoints.
124#[derive(Debug)]
125pub enum InResult {
126    /// A packet of the given size was written into the endpoint buffer
127    Packet(usize),
128
129    /// The client is not yet able to provide data to the host, but may
130    /// be able to in the future.  This result causes the controller
131    /// to send a NAK token to the host.
132    Delay,
133
134    /// The client does not support the request.  This result causes the
135    /// controller to send a STALL token to the host.
136    Error,
137}
138
139/// Result for OUT packets sent on bulk or interrupt endpoints.
140#[derive(Debug)]
141pub enum OutResult {
142    /// The OUT packet was consumed
143    Ok,
144
145    /// The client is not yet able to consume data from the host, but may
146    /// be able to in the future.  This result causes the controller
147    /// to send a NAK token to the host.
148    Delay,
149
150    /// The client does not support the request.  This result causes the
151    /// controller to send a STALL token to the host.
152    Error,
153}