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