atsamd_hal/peripherals/usb/d5x/
devicedesc.rs

1use bitfield::bitfield;
2use core::fmt::{Debug, Error as FmtError, Formatter};
3use core::mem;
4use core::ptr::null_mut;
5
6type FmtResult = Result<(), FmtError>;
7
8bitfield! {
9    struct PckSize(u32);
10    impl Debug;
11    pub byte_count, set_byte_count: 13, 0;
12    pub multi_packet_size, set_multi_packet_size: 27, 14;
13    pub size, set_size: 30, 28;
14    pub auto_zlp, set_auto_zlp : 31;
15}
16
17bitfield! {
18    struct ExtReg(u16);
19    impl Debug;
20    pub subpid, set_subpid: 3, 0;
21    pub link_state, set_link_state: 7, 4;
22    pub besl, set_besl: 11, 8;
23    pub remote_wake, set_remote_wake: 12;
24}
25
26bitfield! {
27    struct StatusBk(u8);
28    impl Debug;
29    pub crc_error, set_crc_error: 0;
30    pub error_flow, set_error_flow: 1;
31}
32
33#[repr(C)]
34#[derive(Debug)]
35pub struct DeviceDescBank {
36    /// endpoint data buffer, must be 32-bit aligned
37    addr: *mut u8,
38    pcksize: PckSize,
39    extreg: ExtReg,
40    status_bk: StatusBk,
41    _reserved: [u8; 5],
42}
43
44impl DeviceDescBank {
45    fn new() -> Self {
46        debug_assert_eq!(16, mem::size_of::<DeviceDescBank>());
47        Self {
48            addr: null_mut(),
49            pcksize: PckSize(0),
50            extreg: ExtReg(0),
51            status_bk: StatusBk(0),
52            _reserved: [0, 0, 0, 0, 0],
53        }
54    }
55
56    #[allow(unused)]
57    /// This bit defines the automatic Zero Length Packet mode of the endpoint.
58    /// When enabled, the USB module will manage the ZLP handshake by hardware.
59    /// This bit is for IN endpoints only. When disabled the handshake should be
60    /// managed by firmware.
61    #[allow(unused_variables)]
62    pub fn set_auto_zlp(&mut self, enable: bool) {
63        self.pcksize.set_auto_zlp(enable);
64    }
65
66    /// These bits contains the maximum packet size of the endpoint.
67    ///
68    /// The maximum packet size is encoded in 3 bits; this method takes any u16
69    /// below 1024B and rounds up to the lowest endpoint size value which will
70    /// accommodate `size`.  Panics if a `size` > 1023 is supplied.
71    pub fn set_endpoint_size(&mut self, size: u16) {
72        let size = match size {
73            1..=8 => 0u32,
74            9..=16 => 1,
75            17..=32 => 2,
76            33..=64 => 3,
77            65..=128 => 4,
78            129..=256 => 5,
79            257..=512 => 6,
80            513..=1023 => 7,
81            _ => unreachable!(),
82        };
83        self.pcksize.set_size(size);
84    }
85
86    #[allow(unused)]
87    pub fn get_endpoint_size(&self) -> u16 {
88        let bits = self.pcksize.size();
89        match bits {
90            0 => 8,
91            1 => 16,
92            2 => 32,
93            3 => 64,
94            4 => 128,
95            5 => 256,
96            6 => 512,
97            7 => 1023,
98            _ => unreachable!(),
99        }
100    }
101
102    /// For IN endpoints, MULTI_PACKET_SIZE holds the total number of bytes
103    /// sent. MULTI_PACKET_SIZE should be written to zero when setting up a new
104    /// transfer.
105    pub fn set_multi_packet_size(&mut self, size: u16) {
106        self.pcksize.set_multi_packet_size(size.into());
107    }
108
109    /// For OUT endpoints, MULTI_PACKET_SIZE holds the total data
110    /// size for the complete transfer. This value must be a multiple of the
111    /// maximum packet size.
112    #[allow(dead_code)]
113    pub fn get_multi_packet_size(&self) -> u16 {
114        self.pcksize.multi_packet_size() as u16
115    }
116
117    /// For IN endpoints, BYTE_COUNT holds the number of bytes to be sent in the
118    /// next IN transaction.
119    /// For OUT endpoint or SETUP endpoints, BYTE_COUNT
120    /// holds the number of bytes received upon the last OUT or SETUP
121    /// transaction.
122    pub fn set_byte_count(&mut self, size: u16) {
123        self.pcksize.set_byte_count(size.into());
124    }
125
126    /// For IN endpoints, BYTE_COUNT holds the number of bytes to be sent in the
127    /// next IN transaction.
128    /// For OUT endpoint or SETUP endpoints, BYTE_COUNT
129    /// holds the number of bytes received upon the last OUT or SETUP
130    /// transaction.
131    pub fn get_byte_count(&self) -> u16 {
132        self.pcksize.byte_count() as u16
133    }
134
135    #[allow(unused)]
136    pub fn link_state(&self) -> u8 {
137        // every value except 1 (L1 sleep) is reserved
138        self.extreg.link_state() as u8
139    }
140
141    #[allow(unused)]
142    /// best effort service latency
143    pub fn besl(&self) -> u8 {
144        self.extreg.besl() as u8
145    }
146
147    #[allow(unused)]
148    pub fn remote_wake(&self) -> bool {
149        self.extreg.remote_wake()
150    }
151
152    #[allow(unused)]
153    /// These bits define the SUBPID field of a received extended token. These
154    /// bits are updated when the USB has answered by an handshake token
155    /// ACK to a LPM transaction
156    pub fn subpid(&self) -> u8 {
157        self.extreg.subpid() as u8
158    }
159
160    #[allow(unused)]
161    /// This bit defines the Error Flow Status.  This bit is set when a Error
162    /// Flow has been detected during transfer from/towards this bank.  For OUT
163    /// transfer, a NAK handshake has been sent.  For Isochronous OUT transfer,
164    /// an overrun condition has occurred.  For IN transfer, this bit is not
165    /// valid. EPSTATUS.TRFAIL0 and EPSTATUS.TRFAIL1 should reflect the flow
166    /// errors.
167    pub fn error_flow(&self) -> bool {
168        self.status_bk.error_flow()
169    }
170
171    #[allow(unused)]
172    /// This bit defines the CRC Error Status.  This bit is set when a CRC
173    /// error has been detected in an isochronous OUT endpoint bank
174    pub fn crc_error(&self) -> bool {
175        self.status_bk.crc_error()
176    }
177
178    pub fn set_address(&mut self, address: *mut u8) {
179        self.addr = address;
180    }
181
182    pub fn get_address(&self) -> *mut u8 {
183        self.addr
184    }
185}
186
187#[derive(Debug)]
188#[repr(C)]
189pub struct DeviceDescriptor {
190    bank: [DeviceDescBank; 2],
191}
192
193impl DeviceDescriptor {
194    fn new() -> Self {
195        debug_assert_eq!(32, mem::size_of::<DeviceDescriptor>());
196        Self {
197            bank: [DeviceDescBank::new(), DeviceDescBank::new()],
198        }
199    }
200}
201
202pub struct Descriptors {
203    desc: [DeviceDescriptor; 8],
204}
205
206impl Debug for Descriptors {
207    fn fmt(&self, fmt: &mut Formatter<'_>) -> FmtResult {
208        for ep in 0..8 {
209            write!(fmt, "\nep{}: {:?}", ep, &self.desc[ep])?;
210        }
211        Ok(())
212    }
213}
214
215impl Descriptors {
216    pub fn new() -> Self {
217        Self {
218            desc: [
219                DeviceDescriptor::new(),
220                DeviceDescriptor::new(),
221                DeviceDescriptor::new(),
222                DeviceDescriptor::new(),
223                DeviceDescriptor::new(),
224                DeviceDescriptor::new(),
225                DeviceDescriptor::new(),
226                DeviceDescriptor::new(),
227            ],
228        }
229    }
230
231    pub fn address(&self) -> u32 {
232        &self.desc as *const _ as u32
233    }
234
235    pub fn bank(&mut self, idx: usize, bank: usize) -> &mut DeviceDescBank {
236        &mut self.desc[idx].bank[bank]
237    }
238}
239
240unsafe impl Send for DeviceDescBank {}