1use crate::{buffer, gpt, ral};
8use usb_device::{
9 UsbDirection, UsbError,
10 bus::PollResult,
11 endpoint::{EndpointAddress, EndpointType},
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::AnyUsbInstance,
50 phy: ral::AnyUsbphyInstance,
51 buffer_allocator: buffer::Allocator,
52 ep_allocator: crate::state::EndpointAllocator<'static>,
53 ep_out: u16,
63}
64
65impl Driver {
66 pub fn new<const N: u8, const SIZE: usize, const EP_COUNT: usize>(
76 instances: crate::Instances<N>,
77 buffer: &'static crate::buffer::EndpointMemory<SIZE>,
78 state: &'static crate::state::EndpointState<EP_COUNT>,
79 ) -> Self {
80 let ral::ErasedInstances { usb, usbphy: phy } = ral::erase_instances(instances);
81 let ep_allocator = state.allocator().expect("Endpoint state already assigned");
82 Driver {
83 usb,
84 phy,
85 buffer_allocator: buffer
86 .allocator()
87 .expect("Endpoint memory already assigned"),
88 ep_allocator,
89 ep_out: 0,
90 }
91 }
92
93 pub fn initialize(&mut self, speed: Speed) {
100 ral::write_reg!(ral::usbphy, self.phy, CTRL_SET, SFTRST: 1);
101 ral::write_reg!(ral::usbphy, self.phy, CTRL_CLR, SFTRST: 1);
102 ral::write_reg!(ral::usbphy, self.phy, CTRL_CLR, CLKGATE: 1);
103 ral::write_reg!(ral::usbphy, self.phy, PWD, 0);
104
105 ral::write_reg!(ral::usb, self.usb, USBCMD, RST: 1);
106 while ral::read_reg!(ral::usb, self.usb, USBCMD, RST == 1) {}
107 ral::write_reg!(ral::usb, self.usb, USBCMD, ITC: 0);
110
111 ral::write_reg!(ral::usb, self.usb, USBMODE, CM: CM_2, SLOM: 1);
112 ral::modify_reg!(ral::usb, self.usb, PORTSC1, PFSC: (speed == Speed::LowFull) as u32);
113
114 ral::modify_reg!(ral::usb, self.usb, USBSTS, |usbsts| usbsts);
115 ral::write_reg!(ral::usb, self.usb, USBINTR, 0);
117
118 ral::write_reg!(
119 ral::usb,
120 self.usb,
121 ASYNCLISTADDR,
122 self.ep_allocator.qh_list_addr() as u32
123 )
124 }
125
126 pub fn enable_zlt(&mut self, ep_addr: EndpointAddress) {
136 if let Some(ep) = self.ep_allocator.endpoint_mut(ep_addr) {
137 ep.enable_zlt();
138 }
139 }
140
141 pub fn set_interrupts(&mut self, interrupts: bool) {
143 if interrupts {
144 ral::modify_reg!(ral::usb, self.usb, USBINTR, UE: 1, URE: 1);
146 } else {
147 ral::modify_reg!(ral::usb, self.usb, USBINTR, UE: 0, URE: 0);
148 }
149 }
150
151 pub fn gpt_mut<R>(&mut self, instance: gpt::Instance, f: impl FnOnce(&mut gpt::Gpt) -> R) -> R {
153 let mut gpt = gpt::Gpt::new(&mut self.usb, instance);
154 f(&mut gpt)
155 }
156
157 pub fn set_address(&mut self, address: u8) {
158 ral::write_reg!(ral::usb, self.usb, DEVICEADDR, USBADR: address as u32, USBADRA: 1);
161 debug!("ADDRESS {=u8}", address);
162 }
163
164 pub fn attach(&mut self) {
165 ral::modify_reg!(ral::usb, self.usb, USBCMD, RS: 1);
166 }
167
168 pub fn bus_reset(&mut self) {
169 ral::modify_reg!(ral::usb, self.usb, ENDPTSTAT, |endptstat| endptstat);
170
171 ral::modify_reg!(ral::usb, self.usb, ENDPTCOMPLETE, |endptcomplete| {
172 endptcomplete
173 });
174 ral::modify_reg!(ral::usb, self.usb, ENDPTNAK, |endptnak| endptnak);
175 ral::write_reg!(ral::usb, self.usb, ENDPTNAKEN, 0);
176
177 while ral::read_reg!(ral::usb, self.usb, ENDPTPRIME) != 0 {}
178 ral::write_reg!(ral::usb, self.usb, ENDPTFLUSH, u32::MAX);
179 while ral::read_reg!(ral::usb, self.usb, ENDPTFLUSH) != 0 {}
180
181 debug_assert!(
182 ral::read_reg!(ral::usb, self.usb, PORTSC1, PR == 1),
183 "Took too long to handle bus reset"
184 );
185 debug!("RESET");
186
187 self.initialize_endpoints();
188 }
189
190 pub fn is_allocated(&self, addr: EndpointAddress) -> bool {
192 self.ep_allocator.endpoint(addr).is_some()
193 }
194
195 pub fn ctrl0_read(&mut self, buffer: &mut [u8]) -> Result<usize, UsbError> {
201 let ctrl_out = self.ep_allocator.endpoint_mut(ctrl_ep0_out()).unwrap();
202 if ctrl_out.has_setup(&self.usb) && buffer.len() >= 8 {
203 debug!("EP0 Out SETUP");
204 let setup = ctrl_out.read_setup(&self.usb);
205 buffer[..8].copy_from_slice(&setup.to_le_bytes());
206
207 if !ctrl_out.is_primed(&self.usb) {
208 ctrl_out.clear_nack(&self.usb);
209 let max_packet_len = ctrl_out.max_packet_len();
210 ctrl_out.schedule_transfer(&self.usb, max_packet_len);
211 }
212
213 Ok(8)
214 } else {
215 ctrl_out.check_errors()?;
216
217 if ctrl_out.is_primed(&self.usb) {
218 return Err(UsbError::WouldBlock);
219 }
220
221 ctrl_out.clear_complete(&self.usb);
222 ctrl_out.clear_nack(&self.usb);
223
224 let read = ctrl_out.read(buffer);
225 debug!("EP0 Out {=usize}", read);
226 let max_packet_len = ctrl_out.max_packet_len();
227 ctrl_out.schedule_transfer(&self.usb, max_packet_len);
228
229 Ok(read)
230 }
231 }
232
233 pub fn ctrl0_write(&mut self, buffer: &[u8]) -> Result<usize, UsbError> {
241 let ctrl_in = self.ep_allocator.endpoint_mut(ctrl_ep0_in()).unwrap();
242 debug!("EP0 In {=usize}", buffer.len());
243 ctrl_in.check_errors()?;
244
245 if ctrl_in.is_primed(&self.usb) {
246 return Err(UsbError::WouldBlock);
247 }
248
249 ctrl_in.clear_nack(&self.usb);
250
251 let written = ctrl_in.write(buffer);
252 ctrl_in.schedule_transfer(&self.usb, written);
253
254 let ctrl_out = self.ep_allocator.endpoint_mut(ctrl_ep0_out()).unwrap();
256 if !ctrl_out.is_primed(&self.usb) {
257 ctrl_out.clear_complete(&self.usb);
258 ctrl_out.clear_nack(&self.usb);
259 ctrl_out.schedule_transfer(&self.usb, 0);
260 }
261
262 Ok(written)
263 }
264
265 pub fn ep_read(&mut self, buffer: &mut [u8], addr: EndpointAddress) -> Result<usize, UsbError> {
271 let ep = self.ep_allocator.endpoint_mut(addr).unwrap();
272 debug!("EP{=usize} Out", ep.address().index());
273 ep.check_errors()?;
274
275 if ep.is_primed(&self.usb) || (self.ep_out & (1 << ep.address().index()) == 0) {
276 return Err(UsbError::WouldBlock);
277 }
278
279 ep.clear_complete(&self.usb); ep.clear_nack(&self.usb);
281
282 let read = ep.read(buffer);
283
284 let max_packet_len = ep.max_packet_len();
285 ep.schedule_transfer(&self.usb, max_packet_len);
286
287 Ok(read)
288 }
289
290 pub fn ep_write(&mut self, buffer: &[u8], addr: EndpointAddress) -> Result<usize, UsbError> {
296 let ep = self.ep_allocator.endpoint_mut(addr).unwrap();
297 ep.check_errors()?;
298
299 if ep.is_primed(&self.usb) {
300 return Err(UsbError::WouldBlock);
301 }
302
303 ep.clear_nack(&self.usb);
304
305 let written = ep.write(buffer);
306 ep.schedule_transfer(&self.usb, written);
307
308 Ok(written)
309 }
310
311 pub fn ep_stall(&mut self, stall: bool, addr: EndpointAddress) {
317 let ep = self.ep_allocator.endpoint_mut(addr).unwrap();
318 ep.set_stalled(&self.usb, stall);
319
320 if !stall
326 && addr.direction() == UsbDirection::Out
327 && ep.is_enabled(&self.usb)
328 && !ep.is_primed(&self.usb)
329 {
330 let max_packet_len = ep.max_packet_len();
331 ep.schedule_transfer(&self.usb, max_packet_len);
332 }
333 }
334
335 pub fn is_ep_stalled(&self, addr: EndpointAddress) -> bool {
341 self.ep_allocator
342 .endpoint(addr)
343 .unwrap()
344 .is_stalled(&self.usb)
345 }
346
347 pub fn allocate_buffer(&mut self, max_packet_len: usize) -> Option<buffer::Buffer> {
349 self.buffer_allocator.allocate(max_packet_len)
350 }
351
352 pub fn allocate_ep(
358 &mut self,
359 addr: EndpointAddress,
360 buffer: buffer::Buffer,
361 kind: EndpointType,
362 ) {
363 self.ep_allocator
364 .allocate_endpoint(addr, buffer, kind)
365 .unwrap();
366
367 debug!(
368 "ALLOC EP{=usize} {} {}",
369 addr.index(),
370 addr.direction(),
371 kind
372 );
373 }
374
375 pub fn on_configured(&mut self) {
377 self.enable_endpoints();
378 self.prime_endpoints();
379 }
380
381 fn enable_endpoints(&mut self) {
385 for ep in self.ep_allocator.nonzero_endpoints_iter_mut() {
386 ep.enable(&self.usb);
387 }
388 }
389
390 fn prime_endpoints(&mut self) {
392 for ep in self.ep_allocator.nonzero_endpoints_iter_mut() {
393 if ep.is_enabled(&self.usb) && ep.address().direction() == UsbDirection::Out {
394 let max_packet_len = ep.max_packet_len();
395 ep.schedule_transfer(&self.usb, max_packet_len);
396 }
397 }
398 }
399
400 fn initialize_endpoints(&mut self) {
402 for ep in self.ep_allocator.nonzero_endpoints_iter_mut() {
403 ep.initialize(&self.usb);
404 }
405 }
406
407 pub fn poll(&mut self) -> PollResult {
409 let usbsts = ral::read_reg!(ral::usb, self.usb, USBSTS);
410 use ral::usb::USBSTS;
411
412 if usbsts & USBSTS::URI::mask != 0 {
413 ral::write_reg!(ral::usb, self.usb, USBSTS, URI: 1);
414 return PollResult::Reset;
415 }
416
417 if usbsts & USBSTS::UI::mask != 0 {
418 ral::write_reg!(ral::usb, self.usb, USBSTS, UI: 1);
419
420 trace!(
421 "ENDPTSETUPSTAT: {=u32:#010X} ENDPTCOMPLETE: {=u32:#010X}",
422 ral::read_reg!(ral::usb, self.usb, ENDPTSETUPSTAT),
423 ral::read_reg!(ral::usb, self.usb, ENDPTCOMPLETE)
424 );
425 self.ep_out = ral::read_reg!(ral::usb, self.usb, ENDPTCOMPLETE, ERCE) as u16;
428
429 let ep_in_complete = ral::read_reg!(ral::usb, self.usb, ENDPTCOMPLETE, ETCE);
430 ral::write_reg!(ral::usb, self.usb, ENDPTCOMPLETE, ETCE: ep_in_complete);
431
432 let ep_setup = ral::read_reg!(ral::usb, self.usb, ENDPTSETUPSTAT) as u16;
433
434 PollResult::Data {
435 ep_out: self.ep_out,
436 ep_in_complete: ep_in_complete as u16,
437 ep_setup,
438 }
439 } else {
440 PollResult::None
441 }
442 }
443}