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
//! Interface to USB controller hardware

use common::VolatileCell;
use core::default::Default;

/// USB controller interface
pub trait UsbController {
    type EndpointState: Default;

    fn enable_device(&self, full_speed: bool);

    fn attach(&self);

    fn endpoint_configure(&self, &'static Self::EndpointState, index: u32);

    fn endpoint_set_buffer(&self, e: u32, buf: &[VolatileCell<u8>]);

    fn endpoint_ctrl_out_enable(&self, e: u32);

    fn set_address(&self, addr: u16);

    fn enable_address(&self);
}

/// USB controller client interface
pub trait Client {
    fn enable(&self);
    fn attach(&self);
    fn bus_reset(&self);

    fn ctrl_setup(&self) -> CtrlSetupResult;
    fn ctrl_in(&self) -> CtrlInResult;
    fn ctrl_out(&self, packet_bytes: u32) -> CtrlOutResult;
    fn ctrl_status(&self);
    fn ctrl_status_complete(&self);
}

#[derive(Debug)]
pub enum CtrlSetupResult {
    /// The Setup request was handled successfully
    Ok,

    // The Setup request cannot be handled; abort this transfer with STALL
    ErrBadLength,
    ErrNoParse,
    ErrNonstandardRequest,
    ErrUnrecognizedDescriptorType,
    ErrUnrecognizedRequestType,
    ErrNoDeviceQualifier,
    ErrInvalidDeviceIndex,
    ErrInvalidConfigurationIndex,
    ErrInvalidStringIndex,
}

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,
}