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