1use crate::{buffer, gpt, ral};
8use usb_device::{
9 bus::PollResult,
10 endpoint::{EndpointAddress, EndpointType},
11 UsbDirection, UsbError,
12};
13
14fn ctrl_ep0_out() -> EndpointAddress {
16 EndpointAddress::from_parts(0, UsbDirection::Out)
19}
20
21fn ctrl_ep0_in() -> EndpointAddress {
23 EndpointAddress::from_parts(0, UsbDirection::In)
24}
25
26#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
28pub enum Speed {
29 LowFull,
34 #[default]
39 High,
40}
41
42pub struct Driver {
49 usb: ral::usb::Instance,
50 phy: ral::usbphy::Instance,
51 buffer_allocator: buffer::Allocator,
52 ep_allocator: crate::state::EndpointAllocator<'static>,
53 ep_out: u16,
63}
64
65impl Driver {
66 pub fn new<P: crate::Peripherals, const SIZE: usize, const EP_COUNT: usize>(
76 peripherals: P,
77 buffer: &'static crate::buffer::EndpointMemory<SIZE>,
78 state: &'static crate::state::EndpointState<EP_COUNT>,
79 ) -> Self {
80 let ral::Instances { usb, usbphy: phy } = ral::instances(peripherals);
84 let ep_allocator = state.allocator().expect("Endpoint state already assigned");
85 Driver {
86 usb,
87 phy,
88 buffer_allocator: buffer
89 .allocator()
90 .expect("Endpoint memory already assigned"),
91 ep_allocator,
92 ep_out: 0,
93 }
94 }
95
96 pub fn initialize(&mut self, speed: Speed) {
103 ral::write_reg!(ral::usbphy, self.phy, CTRL_SET, SFTRST: 1);
104 ral::write_reg!(ral::usbphy, self.phy, CTRL_CLR, SFTRST: 1);
105 ral::write_reg!(ral::usbphy, self.phy, CTRL_CLR, CLKGATE: 1);
106 ral::write_reg!(ral::usbphy, self.phy, PWD, 0);
107
108 ral::write_reg!(ral::usb, self.usb, USBCMD, RST: 1);
109 while ral::read_reg!(ral::usb, self.usb, USBCMD, RST == 1) {}
110 ral::write_reg!(ral::usb, self.usb, USBCMD, ITC: 0);
113
114 ral::write_reg!(ral::usb, self.usb, USBMODE, CM: CM_2, SLOM: 1);
115 ral::modify_reg!(ral::usb, self.usb, PORTSC1, PFSC: (speed == Speed::LowFull) as u32);
116
117 ral::modify_reg!(ral::usb, self.usb, USBSTS, |usbsts| usbsts);
118 ral::write_reg!(ral::usb, self.usb, USBINTR, 0);
120
121 ral::write_reg!(
122 ral::usb,
123 self.usb,
124 ASYNCLISTADDR,
125 self.ep_allocator.qh_list_addr() as u32
126 )
127 }
128
129 pub fn enable_zlt(&mut self, ep_addr: EndpointAddress) {
139 if let Some(ep) = self.ep_allocator.endpoint_mut(ep_addr) {
140 ep.enable_zlt();
141 }
142 }
143
144 pub fn set_interrupts(&mut self, interrupts: bool) {
146 if interrupts {
147 ral::modify_reg!(ral::usb, self.usb, USBINTR, UE: 1, URE: 1);
149 } else {
150 ral::modify_reg!(ral::usb, self.usb, USBINTR, UE: 0, URE: 0);
151 }
152 }
153
154 pub fn gpt_mut<R>(&mut self, instance: gpt::Instance, f: impl FnOnce(&mut gpt::Gpt) -> R) -> R {
156 let mut gpt = gpt::Gpt::new(&mut self.usb, instance);
157 f(&mut gpt)
158 }
159
160 pub fn set_address(&mut self, address: u8) {
161 ral::write_reg!(ral::usb, self.usb, DEVICEADDR, USBADR: address as u32, USBADRA: 1);
164 debug!("ADDRESS {=u8}", address);
165 }
166
167 pub fn attach(&mut self) {
168 ral::modify_reg!(ral::usb, self.usb, USBCMD, RS: 1);
169 }
170
171 pub fn bus_reset(&mut self) {
172 ral::modify_reg!(ral::usb, self.usb, ENDPTSTAT, |endptstat| endptstat);
173
174 ral::modify_reg!(ral::usb, self.usb, ENDPTCOMPLETE, |endptcomplete| {
175 endptcomplete
176 });
177 ral::modify_reg!(ral::usb, self.usb, ENDPTNAK, |endptnak| endptnak);
178 ral::write_reg!(ral::usb, self.usb, ENDPTNAKEN, 0);
179
180 while ral::read_reg!(ral::usb, self.usb, ENDPTPRIME) != 0 {}
181 ral::write_reg!(ral::usb, self.usb, ENDPTFLUSH, u32::max_value());
182 while ral::read_reg!(ral::usb, self.usb, ENDPTFLUSH) != 0 {}
183
184 debug_assert!(
185 ral::read_reg!(ral::usb, self.usb, PORTSC1, PR == 1),
186 "Took too long to handle bus reset"
187 );
188 debug!("RESET");
189
190 self.initialize_endpoints();
191 }
192
193 pub fn is_allocated(&self, addr: EndpointAddress) -> bool {
195 self.ep_allocator.endpoint(addr).is_some()
196 }
197
198 pub fn ctrl0_read(&mut self, buffer: &mut [u8]) -> Result<usize, UsbError> {
204 let ctrl_out = self.ep_allocator.endpoint_mut(ctrl_ep0_out()).unwrap();
205 if ctrl_out.has_setup(&self.usb) && buffer.len() >= 8 {
206 debug!("EP0 Out SETUP");
207 let setup = ctrl_out.read_setup(&self.usb);
208 buffer[..8].copy_from_slice(&setup.to_le_bytes());
209
210 if !ctrl_out.is_primed(&self.usb) {
211 ctrl_out.clear_nack(&self.usb);
212 let max_packet_len = ctrl_out.max_packet_len();
213 ctrl_out.schedule_transfer(&self.usb, max_packet_len);
214 }
215
216 Ok(8)
217 } else {
218 ctrl_out.check_errors()?;
219
220 if ctrl_out.is_primed(&self.usb) {
221 return Err(UsbError::WouldBlock);
222 }
223
224 ctrl_out.clear_complete(&self.usb);
225 ctrl_out.clear_nack(&self.usb);
226
227 let read = ctrl_out.read(buffer);
228 debug!("EP0 Out {=usize}", read);
229 let max_packet_len = ctrl_out.max_packet_len();
230 ctrl_out.schedule_transfer(&self.usb, max_packet_len);
231
232 Ok(read)
233 }
234 }
235
236 pub fn ctrl0_write(&mut self, buffer: &[u8]) -> Result<usize, UsbError> {
244 let ctrl_in = self.ep_allocator.endpoint_mut(ctrl_ep0_in()).unwrap();
245 debug!("EP0 In {=usize}", buffer.len());
246 ctrl_in.check_errors()?;
247
248 if ctrl_in.is_primed(&self.usb) {
249 return Err(UsbError::WouldBlock);
250 }
251
252 ctrl_in.clear_nack(&self.usb);
253
254 let written = ctrl_in.write(buffer);
255 ctrl_in.schedule_transfer(&self.usb, written);
256
257 let ctrl_out = self.ep_allocator.endpoint_mut(ctrl_ep0_out()).unwrap();
259 if !ctrl_out.is_primed(&self.usb) {
260 ctrl_out.clear_complete(&self.usb);
261 ctrl_out.clear_nack(&self.usb);
262 ctrl_out.schedule_transfer(&self.usb, 0);
263 }
264
265 Ok(written)
266 }
267
268 pub fn ep_read(&mut self, buffer: &mut [u8], addr: EndpointAddress) -> Result<usize, UsbError> {
274 let ep = self.ep_allocator.endpoint_mut(addr).unwrap();
275 debug!("EP{=usize} Out", ep.address().index());
276 ep.check_errors()?;
277
278 if ep.is_primed(&self.usb) || (self.ep_out & (1 << ep.address().index()) == 0) {
279 return Err(UsbError::WouldBlock);
280 }
281
282 ep.clear_complete(&self.usb); ep.clear_nack(&self.usb);
284
285 let read = ep.read(buffer);
286
287 let max_packet_len = ep.max_packet_len();
288 ep.schedule_transfer(&self.usb, max_packet_len);
289
290 Ok(read)
291 }
292
293 pub fn ep_write(&mut self, buffer: &[u8], addr: EndpointAddress) -> Result<usize, UsbError> {
299 let ep = self.ep_allocator.endpoint_mut(addr).unwrap();
300 ep.check_errors()?;
301
302 if ep.is_primed(&self.usb) {
303 return Err(UsbError::WouldBlock);
304 }
305
306 ep.clear_nack(&self.usb);
307
308 let written = ep.write(buffer);
309 ep.schedule_transfer(&self.usb, written);
310
311 Ok(written)
312 }
313
314 pub fn ep_stall(&mut self, stall: bool, addr: EndpointAddress) {
320 let ep = self.ep_allocator.endpoint_mut(addr).unwrap();
321 ep.set_stalled(&self.usb, stall);
322
323 if !stall && addr.direction() == UsbDirection::Out && !ep.is_primed(&self.usb) {
325 let max_packet_len = ep.max_packet_len();
326 ep.schedule_transfer(&self.usb, max_packet_len);
327 }
328 }
329
330 pub fn is_ep_stalled(&self, addr: EndpointAddress) -> bool {
336 self.ep_allocator
337 .endpoint(addr)
338 .unwrap()
339 .is_stalled(&self.usb)
340 }
341
342 pub fn allocate_buffer(&mut self, max_packet_len: usize) -> Option<buffer::Buffer> {
344 self.buffer_allocator.allocate(max_packet_len)
345 }
346
347 pub fn allocate_ep(
353 &mut self,
354 addr: EndpointAddress,
355 buffer: buffer::Buffer,
356 kind: EndpointType,
357 ) {
358 self.ep_allocator
359 .allocate_endpoint(addr, buffer, kind)
360 .unwrap();
361
362 debug!(
363 "ALLOC EP{=usize} {} {}",
364 addr.index(),
365 addr.direction(),
366 kind
367 );
368 }
369
370 pub fn on_configured(&mut self) {
372 self.enable_endpoints();
373 self.prime_endpoints();
374 }
375
376 fn enable_endpoints(&mut self) {
380 for ep in self.ep_allocator.nonzero_endpoints_iter_mut() {
381 ep.enable(&self.usb);
382 }
383 }
384
385 fn prime_endpoints(&mut self) {
387 for ep in self.ep_allocator.nonzero_endpoints_iter_mut() {
388 if ep.is_enabled(&self.usb) && ep.address().direction() == UsbDirection::Out {
389 let max_packet_len = ep.max_packet_len();
390 ep.schedule_transfer(&self.usb, max_packet_len);
391 }
392 }
393 }
394
395 fn initialize_endpoints(&mut self) {
397 for ep in self.ep_allocator.nonzero_endpoints_iter_mut() {
398 ep.initialize(&self.usb);
399 }
400 }
401
402 pub fn poll(&mut self) -> PollResult {
404 let usbsts = ral::read_reg!(ral::usb, self.usb, USBSTS);
405 use ral::usb::USBSTS;
406
407 if usbsts & USBSTS::URI::mask != 0 {
408 ral::write_reg!(ral::usb, self.usb, USBSTS, URI: 1);
409 return PollResult::Reset;
410 }
411
412 if usbsts & USBSTS::UI::mask != 0 {
413 ral::write_reg!(ral::usb, self.usb, USBSTS, UI: 1);
414
415 trace!(
416 "ENDPTSETUPSTAT: {=u32:#010X} ENDPTCOMPLETE: {=u32:#010X}",
417 ral::read_reg!(ral::usb, self.usb, ENDPTSETUPSTAT),
418 ral::read_reg!(ral::usb, self.usb, ENDPTCOMPLETE)
419 );
420 self.ep_out = ral::read_reg!(ral::usb, self.usb, ENDPTCOMPLETE, ERCE) as u16;
423
424 let ep_in_complete = ral::read_reg!(ral::usb, self.usb, ENDPTCOMPLETE, ETCE);
425 ral::write_reg!(ral::usb, self.usb, ENDPTCOMPLETE, ETCE: ep_in_complete);
426
427 let ep_setup = ral::read_reg!(ral::usb, self.usb, ENDPTSETUPSTAT) as u16;
428
429 PollResult::Data {
430 ep_out: self.ep_out,
431 ep_in_complete: ep_in_complete as u16,
432 ep_setup,
433 }
434 } else {
435 PollResult::None
436 }
437 }
438}