1pub use ehci::EhciError;
5use server::{AsScalar, FromScalar};
6
7#[derive(Debug, Clone, Copy, thiserror::Error, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
8pub enum UsbError {
9 #[error("OS error: {:?}", xous::Error::from_usize(*.0))]
10 XousError(usize),
11 #[error("EHCI error: {0:?}")]
12 EhciError(EhciError),
13 #[error("Other Usb error")]
14 Other,
15 #[error("Usb device not found")]
16 NotFound,
17 #[error("Device was not claimed")]
18 NotClaimed,
19 #[error("Data buffer was too large")]
20 DataTooLarge,
21 #[error("An interface was already registered")]
22 AlreadyRegistered,
23 #[error("An endpoint operation was attempted in the wrong direction (e.g. read on an IN endpoint)")]
24 WrongDirection,
25 #[error("The endpoint already has a queued operation")]
26 Busy,
27 #[error("The usb host has disconnected")]
28 HostDisconnected,
29 #[error("One of the parameters had a wrong value")]
30 InvalidParameter,
31 #[error("The USB interface is disabled")]
32 InterfaceDisabled,
33}
34
35impl From<xous::Error> for UsbError {
36 fn from(value: xous::Error) -> Self { UsbError::XousError(value.to_usize()) }
37}
38
39impl From<EhciError> for UsbError {
40 fn from(value: EhciError) -> Self { UsbError::EhciError(value) }
41}
42
43impl AsScalar<2> for UsbError {
44 fn as_scalar(&self) -> [u32; 2] {
45 match self {
46 UsbError::XousError(e) => [1, *e as u32],
47 UsbError::EhciError(e) => [
48 2,
49 match e {
50 EhciError::InvalidCapsLen => 1,
51 EhciError::EndpointNotOpen => 2,
52 EhciError::InvalidAddress => 3,
53 EhciError::Disconnected => 4,
54 EhciError::DescriptorError => 5,
55 EhciError::OutOfPoolItems => 6,
56 EhciError::SetupUnsuccessful => 7,
57 EhciError::Stalled => 8,
58 EhciError::ControllerDisabled => 9,
59 },
60 ],
61 UsbError::Other => [3, 0],
62 UsbError::NotFound => [4, 0],
63 UsbError::NotClaimed => [5, 0],
64 UsbError::DataTooLarge => [6, 0],
65 UsbError::AlreadyRegistered => [7, 0],
66 UsbError::WrongDirection => [8, 0],
67 UsbError::Busy => [9, 0],
68 UsbError::HostDisconnected => [10, 0],
69 UsbError::InvalidParameter => [11, 0],
70 UsbError::InterfaceDisabled => [12, 0],
71 }
72 }
73}
74
75impl FromScalar<2> for UsbError {
76 fn from_scalar(value: [u32; 2]) -> Self {
77 match value[0] {
78 1 => UsbError::XousError(value[1] as usize),
79 2 => UsbError::EhciError(match value[1] {
80 1 => EhciError::InvalidCapsLen,
81 2 => EhciError::EndpointNotOpen,
82 3 => EhciError::InvalidAddress,
83 4 => EhciError::Disconnected,
84 5 => EhciError::DescriptorError,
85 6 => EhciError::OutOfPoolItems,
86 7 => EhciError::SetupUnsuccessful,
87 8 => EhciError::Stalled,
88 9 => EhciError::ControllerDisabled,
89 _ => EhciError::Disconnected,
90 }),
91 3 => UsbError::Other,
92 4 => UsbError::NotFound,
93 5 => UsbError::NotClaimed,
94 6 => UsbError::DataTooLarge,
95 7 => UsbError::AlreadyRegistered,
96 8 => UsbError::WrongDirection,
97 9 => UsbError::Busy,
98 10 => UsbError::HostDisconnected,
99 11 => UsbError::InvalidParameter,
100 12 => UsbError::InterfaceDisabled,
101 _ => UsbError::Other,
102 }
103 }
104}
105
106impl From<usize> for UsbError {
107 fn from(value: usize) -> Self { Self::from_scalar([value as u32, 0]) }
108}
109
110impl From<UsbError> for usize {
111 fn from(value: UsbError) -> Self { server::AsScalar::<2>::as_scalar(&value)[0] as usize }
112}