1#![no_std]
4mod pipe;
5
6use pipe::{PipeErr, PipeTable};
7
8use usb_host::{
9 DescriptorType, DeviceDescriptor, Direction, Driver, DriverError, Endpoint, RequestCode,
10 RequestDirection, RequestKind, RequestRecipient, RequestType, TransferError, TransferType,
11 USBHost, WValue,
12};
13
14use atsamd_hal::{
15 calibration::{usb_transn_cal, usb_transp_cal, usb_trim_cal},
16 clock::{ClockGenId, ClockSource, GenericClockController},
17 gpio::{self, Floating, Input, OpenDrain, Output},
18 target_device::{PM, USB},
19};
20use embedded_hal::digital::v2::OutputPin;
21use log::{debug, error, info, trace, warn};
22use starb::{Reader, RingBuffer, Writer};
23
24#[derive(Clone, Copy, Debug, PartialEq)]
25pub enum Event {
26 Error,
27 Detached,
28 Attached,
29}
30type Events = RingBuffer<Event>;
31type EventReader = Reader<'static, Event>;
32type EventWriter = Writer<'static, Event>;
33
34const NAK_LIMIT: usize = 15;
35
36static mut EVENTS: Events = Events::new();
38
39#[derive(Clone, Copy, Debug, PartialEq)]
40enum DetachedState {
41 Initialize,
42 WaitForDevice,
43 Illegal,
44}
45
46#[derive(Clone, Copy, Debug, PartialEq)]
47enum AttachedState {
48 ResetBus,
49 WaitResetComplete,
50 WaitSOF(usize),
51}
52
53#[derive(Clone, Copy, Debug, PartialEq)]
54enum SteadyState {
55 Configuring,
56 Running,
57 ErrorUntil(usize),
58}
59
60#[derive(Clone, Copy, Debug, PartialEq)]
61enum TaskState {
62 Detached(DetachedState),
63 Attached(AttachedState),
64 Steady(SteadyState),
65}
66
67use core::mem::{self, MaybeUninit};
68use core::ptr;
69
70const ERROR_RESET_DELAY: usize = 200;
73
74const MAX_DEVICES: usize = 4;
75struct DeviceTable {
76 tbl: [Option<Device>; MAX_DEVICES],
77}
78impl DeviceTable {
79 fn new() -> Self {
80 let tbl = {
81 let mut devs: [MaybeUninit<Option<Device>>; MAX_DEVICES] =
82 unsafe { MaybeUninit::uninit().assume_init() };
83 for d in &mut devs[..] {
84 unsafe { ptr::write(d.as_mut_ptr(), None) }
85 }
86 unsafe { mem::transmute(devs) }
87 };
88
89 Self { tbl }
90 }
91
92 fn next(&mut self) -> Option<&mut Device> {
96 for i in 1..self.tbl.len() {
97 if self.tbl[i].is_none() {
98 let d = Device { addr: i as u8 };
99 self.tbl[i] = Some(d);
100 return self.tbl[i].as_mut();
101 }
102 }
103 None
104 }
105
106 fn remove(&mut self, addr: u8) -> Option<Device> {
108 core::mem::replace(&mut self.tbl[addr as usize], None)
109 }
110}
111
112struct Device {
113 addr: u8,
114}
115
116pub struct SAMDHost<'a, F> {
117 usb: USB,
118
119 events: EventReader,
120 task_state: TaskState,
121
122 pipe_table: PipeTable,
125
126 devices: DeviceTable,
127
128 _dm_pad: gpio::Pa24<gpio::PfG>,
129 _dp_pad: gpio::Pa25<gpio::PfG>,
130 _sof_pad: Option<gpio::Pa23<gpio::PfG>>,
131 host_enable_pin: Option<gpio::Pa28<Output<OpenDrain>>>,
132
133 millis: &'a F,
135}
136
137pub struct Pins {
138 dm_pin: gpio::Pa24<Input<Floating>>,
139 dp_pin: gpio::Pa25<Input<Floating>>,
140 sof_pin: Option<gpio::Pa23<Input<Floating>>>,
141 host_enable_pin: Option<gpio::Pa28<Input<Floating>>>,
142}
143impl Pins {
144 pub fn new(
145 dm_pin: gpio::Pa24<Input<Floating>>,
146 dp_pin: gpio::Pa25<Input<Floating>>,
147 sof_pin: Option<gpio::Pa23<Input<Floating>>>,
148 host_enable_pin: Option<gpio::Pa28<Input<Floating>>>,
149 ) -> Self {
150 Self {
151 dm_pin,
152 dp_pin,
153 sof_pin,
154 host_enable_pin,
155 }
156 }
157}
158
159impl<'a, F> SAMDHost<'a, F>
160where
161 F: Fn() -> usize,
162{
163 pub fn new(
164 usb: USB,
165 pins: Pins,
166 port: &mut gpio::Port,
167 clocks: &mut GenericClockController,
168 pm: &mut PM,
169 millis: &'a F,
170 ) -> (Self, impl FnMut()) {
171 let (eventr, mut eventw) = unsafe { EVENTS.split() };
172
173 let rc = Self {
174 usb,
175
176 events: eventr,
177 task_state: TaskState::Detached(DetachedState::Initialize),
178
179 pipe_table: PipeTable::new(),
180
181 devices: DeviceTable::new(),
182
183 _dm_pad: pins.dm_pin.into_function_g(port),
184 _dp_pad: pins.dp_pin.into_function_g(port),
185 _sof_pad: pins.sof_pin.map(|p| p.into_function_g(port)),
186 host_enable_pin: pins.host_enable_pin.map(|p| p.into_open_drain_output(port)),
187
188 millis,
189 };
190
191 pm.apbbmask.modify(|_, w| w.usb_().set_bit());
192
193 clocks.configure_gclk_divider_and_source(ClockGenId::GCLK6, 1, ClockSource::DFLL48M, false);
195 let gclk6 = clocks
196 .get_gclk(ClockGenId::GCLK6)
197 .expect("Could not get clock 6");
198 clocks.usb(&gclk6);
199
200 let usbp = &rc.usb as *const _ as usize;
201 (rc, move || handler(usbp, &mut eventw))
202 }
203
204 pub fn reset_periph(&mut self) {
205 debug!("resetting usb");
206 self.usb.host().ctrla.write(|w| w.swrst().set_bit());
208 while self.usb.host().syncbusy.read().swrst().bit_is_set() {}
209
210 self.usb.host().ctrla.modify(|_, w| w.mode().host());
212
213 unsafe {
215 self.usb.host().padcal.write(|w| {
216 w.transn().bits(usb_transn_cal());
217 w.transp().bits(usb_transp_cal());
218 w.trim().bits(usb_trim_cal())
219 });
220 }
221
222 self.usb.host().ctrlb.modify(|_, w| w.spdconf().normal());
224 self.usb.host().ctrla.modify(|_, w| w.runstdby().set_bit()); unsafe {
232 self.usb
233 .host()
234 .descadd
235 .write(|w| w.bits(&self.pipe_table as *const _ as u32));
236 }
237
238 if let Some(he_pin) = &mut self.host_enable_pin {
239 he_pin.set_high().expect("turning on usb host enable pin");
240 }
241
242 self.usb.host().intenset.write(|w| {
243 w.dconn().set_bit();
244 w.ddisc().set_bit()
245 });
246
247 self.usb.host().ctrla.modify(|_, w| w.enable().set_bit());
248 while self.usb.host().syncbusy.read().enable().bit_is_set() {}
249
250 self.usb.host().ctrlb.modify(|_, w| w.vbusok().set_bit());
252 debug!("...done");
253 }
254
255 pub fn task(&mut self, drivers: &mut [&mut dyn Driver]) {
256 static mut LAST_TASK_STATE: TaskState = TaskState::Detached(DetachedState::Illegal);
257
258 if let Some(event) = self.events.shift() {
259 trace!("Found event: {:?}", event);
260 self.task_state = match event {
261 Event::Error => TaskState::Detached(DetachedState::Illegal),
262 Event::Detached => {
263 if let TaskState::Detached(_) = self.task_state {
264 self.task_state
265 } else {
266 TaskState::Detached(DetachedState::Initialize)
267 }
268 }
269 Event::Attached => {
270 if let TaskState::Detached(_) = self.task_state {
271 TaskState::Attached(AttachedState::ResetBus)
272 } else {
273 self.task_state
274 }
275 }
276 };
277 }
278
279 static mut LAST_CBITS: u16 = 0;
280 static mut LAST_FLAGS: u16 = 0;
281 let cbits = self.usb.host().ctrlb.read().bits();
282 let bits = self.usb.host().intflag.read().bits();
283 unsafe {
284 if LAST_CBITS != cbits || LAST_FLAGS != bits || LAST_TASK_STATE != self.task_state {
285 trace!(
286 "cb: {:x}, f: {:x} changing state {:?} -> {:?}",
287 cbits,
288 bits,
289 LAST_TASK_STATE,
290 self.task_state,
291 );
292 }
293 LAST_CBITS = cbits;
294 LAST_FLAGS = bits;
295 LAST_TASK_STATE = self.task_state
296 };
297
298 self.fsm(drivers);
299 }
300
301 fn fsm(&mut self, drivers: &mut [&mut dyn Driver]) {
302 match self.task_state {
304 TaskState::Detached(s) => self.detached_fsm(s),
305 TaskState::Attached(s) => self.attached_fsm(s),
306 TaskState::Steady(s) => self.steady_fsm(s, drivers),
307 };
308 }
309
310 fn detached_fsm(&mut self, s: DetachedState) {
311 match s {
312 DetachedState::Initialize => {
313 self.reset_periph();
314 self.task_state = TaskState::Detached(DetachedState::WaitForDevice);
317 }
318
319 DetachedState::WaitForDevice => {}
322
323 DetachedState::Illegal => {}
325 }
326 }
327
328 fn attached_fsm(&mut self, s: AttachedState) {
329 match s {
330 AttachedState::ResetBus => {
331 self.usb.host().ctrlb.modify(|_, w| w.busreset().set_bit());
332 self.task_state = TaskState::Attached(AttachedState::WaitResetComplete);
333 }
334
335 AttachedState::WaitResetComplete => {
336 if self.usb.host().intflag.read().rst().bit_is_set() {
337 trace!("reset was sent");
338 self.usb.host().intflag.write(|w| w.rst().set_bit());
339
340 self.usb.host().ctrlb.modify(|_, w| w.sofe().set_bit());
343 self.task_state =
345 TaskState::Attached(AttachedState::WaitSOF((self.millis)() + 20));
346 }
347 }
348
349 AttachedState::WaitSOF(until) => {
350 if self.usb.host().intflag.read().hsof().bit_is_set() {
351 self.usb.host().intflag.write(|w| w.hsof().set_bit());
352 if (self.millis)() >= until {
353 self.task_state = TaskState::Steady(SteadyState::Configuring);
354 }
355 }
356 }
357 }
358 }
359
360 fn steady_fsm(&mut self, s: SteadyState, drivers: &mut [&mut dyn Driver]) {
361 match s {
362 SteadyState::Configuring => {
363 self.task_state = match self.configure_dev(drivers) {
364 Ok(_) => TaskState::Steady(SteadyState::Running),
365 Err(e) => {
366 warn!("Enumeration error: {:?}", e);
367 TaskState::Steady(SteadyState::ErrorUntil(
368 (self.millis)() + ERROR_RESET_DELAY,
369 ))
370 }
371 }
372 }
373
374 SteadyState::Running => {
375 for d in &mut drivers[..] {
376 if let Err(e) = d.tick((self.millis)(), self) {
377 warn!("running driver {:?}: {:?}", d, e);
378 if let DriverError::Permanent(a, _) = e {
379 d.remove_device(a);
380 self.devices.remove(a);
381 self.task_state = TaskState::Steady(SteadyState::ErrorUntil(
382 (self.millis)() + ERROR_RESET_DELAY,
383 ))
384 }
385 }
386 }
387 }
388
389 SteadyState::ErrorUntil(when) => {
392 if (self.millis)() >= when {
393 self.task_state = TaskState::Detached(DetachedState::Initialize);
394 }
395 }
396 }
397 }
398
399 fn configure_dev(&mut self, drivers: &mut [&mut dyn Driver]) -> Result<(), TransferError> {
400 let none: Option<&mut [u8]> = None;
401 let max_packet_size: u16 = match self.usb.host().status.read().speed().bits() {
402 0x0 => 64,
403 _ => 8,
404 };
405 let mut a0ep0 = Addr0EP0 {
406 max_packet_size,
407 in_toggle: true,
408 out_toggle: true,
409 };
410
411 let mut dev_desc: MaybeUninit<DeviceDescriptor> = MaybeUninit::uninit();
412 let len = self.control_transfer(
413 &mut a0ep0,
414 RequestType::from((
415 RequestDirection::DeviceToHost,
416 RequestKind::Standard,
417 RequestRecipient::Device,
418 )),
419 RequestCode::GetDescriptor,
420 WValue::from((0, DescriptorType::Device as u8)),
421 0,
422 Some(unsafe { to_slice_mut(&mut dev_desc) }),
423 )?;
424 assert!(len == mem::size_of::<DeviceDescriptor>());
425 let dev_desc = unsafe { dev_desc.assume_init() };
426
427 trace!(" -- dev_desc: {:?}", dev_desc);
428
429 let addr = self
431 .devices
432 .next()
433 .ok_or(TransferError::Permanent("out of devices"))?
434 .addr;
435 debug!("Setting address to {}.", addr);
436 self.control_transfer(
437 &mut a0ep0,
438 RequestType::from((
439 RequestDirection::HostToDevice,
440 RequestKind::Standard,
441 RequestRecipient::Device,
442 )),
443 RequestCode::SetAddress,
444 WValue::from((addr, 0)),
445 0,
446 none,
447 )?;
448
449 for d in &mut drivers[..] {
452 if d.want_device(&dev_desc) {
453 info!("{:?} will take address {}.", d, addr);
454 let res = d.add_device(dev_desc, addr);
455 match res {
456 Ok(_) => return Ok(()),
457 Err(_) => return Err(TransferError::Permanent("out of addresses")),
458 }
459 }
460 }
461 Ok(())
462 }
463}
464
465struct Addr0EP0 {
466 max_packet_size: u16,
467 in_toggle: bool,
468 out_toggle: bool,
469}
470impl Endpoint for Addr0EP0 {
471 fn address(&self) -> u8 {
472 0
473 }
474
475 fn endpoint_num(&self) -> u8 {
476 0
477 }
478
479 fn transfer_type(&self) -> TransferType {
480 TransferType::Control
481 }
482
483 fn direction(&self) -> Direction {
484 Direction::In
485 }
486
487 fn max_packet_size(&self) -> u16 {
488 self.max_packet_size
489 }
490
491 fn in_toggle(&self) -> bool {
492 self.in_toggle
493 }
494
495 fn set_in_toggle(&mut self, toggle: bool) {
496 self.in_toggle = toggle;
497 }
498
499 fn out_toggle(&self) -> bool {
500 self.out_toggle
501 }
502
503 fn set_out_toggle(&mut self, toggle: bool) {
504 self.out_toggle = toggle;
505 }
506}
507
508pub fn handler(usbp: usize, events: &mut EventWriter) {
509 let usb: &mut USB = unsafe { core::mem::transmute(usbp) };
510 let flags = usb.host().intflag.read();
511
512 trace!("USB - {:x}", flags.bits());
513
514 let mut unshift_event = |e: Event| {
515 if let Err(e) = events.unshift(e) {
516 error!("Couldn't write USB event to queue: {:?}", e);
517 }
518 };
519
520 if flags.dconn().bit_is_set() {
521 trace!(" +dconn");
522 usb.host().intflag.write(|w| w.dconn().set_bit());
523 unshift_event(Event::Attached);
524 }
525
526 if flags.ddisc().bit_is_set() {
527 trace!(" +ddisc");
528 usb.host().intflag.write(|w| w.ddisc().set_bit());
529 unshift_event(Event::Detached);
530 }
531}
532
533impl From<PipeErr> for TransferError {
534 fn from(v: PipeErr) -> Self {
535 match v {
536 PipeErr::TransferFail => Self::Retry("transfer failed"),
537 PipeErr::Flow => Self::Retry("data flow"),
538 PipeErr::DataToggle => Self::Retry("toggle sequence"),
539 PipeErr::ShortPacket => Self::Permanent("short packet"),
540 PipeErr::InvalidPipe => Self::Permanent("invalid pipe"),
541 PipeErr::InvalidToken => Self::Permanent("invalid token"),
542 PipeErr::Stall => Self::Permanent("stall"),
543 PipeErr::PipeErr => Self::Permanent("pipe error"),
544 PipeErr::HWTimeout => Self::Permanent("hardware timeout"),
545 PipeErr::SWTimeout => Self::Permanent("software timeout"),
546 PipeErr::PID => Self::Permanent("pid error"),
547 PipeErr::DataPID => Self::Permanent("data pid error"),
548 PipeErr::CRC16 => Self::Permanent("crc16 error"),
549 }
551 }
552}
553
554impl<F> USBHost for SAMDHost<'_, F>
555where
556 F: Fn() -> usize,
557{
558 fn control_transfer(
559 &mut self,
560 ep: &mut dyn Endpoint,
561 bm_request_type: RequestType,
562 b_request: RequestCode,
563 w_value: WValue,
564 w_index: u16,
565 buf: Option<&mut [u8]>,
566 ) -> Result<usize, TransferError> {
567 let mut pipe = self.pipe_table.pipe_for(self.usb.host_mut(), ep);
568 let len = pipe.control_transfer(
569 ep,
570 bm_request_type,
571 b_request,
572 w_value,
573 w_index,
574 buf,
575 self.millis,
576 )?;
577 Ok(len)
578 }
579
580 fn in_transfer(
581 &mut self,
582 ep: &mut dyn Endpoint,
583 buf: &mut [u8],
584 ) -> Result<usize, TransferError> {
585 let mut pipe = self.pipe_table.pipe_for(self.usb.host_mut(), ep);
586 let len = pipe.in_transfer(ep, buf, NAK_LIMIT, self.millis)?;
587 Ok(len)
588 }
589
590 fn out_transfer(&mut self, ep: &mut dyn Endpoint, buf: &[u8]) -> Result<usize, TransferError> {
591 let mut pipe = self.pipe_table.pipe_for(self.usb.host_mut(), ep);
592 let len = pipe.out_transfer(ep, buf, NAK_LIMIT, self.millis)?;
593 Ok(len)
594 }
595}
596
597unsafe fn to_slice_mut<T>(v: &mut T) -> &mut [u8] {
598 let ptr = v as *mut T as *mut u8;
599 let len = mem::size_of::<T>();
600 core::slice::from_raw_parts_mut(ptr, len)
601}