aboutsummaryrefslogtreecommitdiffstats
path: root/usb-host/src/lib.rs
blob: 831a67c5f586a663c0710ae54d4845565672c70a (plain)
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
mod descriptor;
mod setup;

pub use descriptor::*;
pub use setup::*;

pub enum Error {
    Retry(&'static str),
    Permanent(&'static str),
}

pub trait USBHost {
    fn control_transfer(
        &mut self,
        ep: &mut dyn Endpoint,
        bm_request_type: RequestType,
        b_request: RequestCode,
        w_value: WValue,
        w_index: u16,
        buf: Option<&mut [u8]>,
    ) -> Result<usize, Error>;

    fn in_transfer(&mut self, ep: &mut dyn Endpoint, buf: &mut [u8]) -> Result<usize, Error>;

    fn out_transfer(&mut self, ep: &mut dyn Endpoint, buf: &[u8]) -> Result<usize, Error>;
}

// cf §9.6.6 of USB 2.0
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum TransferType {
    Control = 0,
    Isochronous = 1,
    Bulk = 2,
    Interrupt = 3,
}

// ibid
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Direction {
    Out,
    In,
}
pub trait Endpoint {
    fn address(&self) -> u8;

    fn endpoint_num(&self) -> u8;

    fn transfer_type(&self) -> TransferType;

    fn direction(&self) -> Direction;

    fn max_packet_size(&self) -> u16;

    fn in_toggle(&self) -> bool;

    fn set_in_toggle(&mut self, toggle: bool);

    fn out_toggle(&self) -> bool;

    fn set_out_toggle(&mut self, toggle: bool);
}

pub trait Driver {
    fn want_device(&self, device: &DeviceDescriptor) -> bool;

    fn add_device(&mut self, device: DeviceDescriptor, address: u8) -> Result<(), Error>;

    fn remove_device(&mut self, address: u8);

    fn tick_device(
        &mut self,
        address: u8,
        millis: usize,
        usbhost: &mut dyn USBHost,
    ) -> Result<(), Error>;
}