1use super::Descriptors;
9use crate::calibration::{usb_transn_cal, usb_transp_cal, usb_trim_cal};
10use crate::clock;
11use crate::gpio::{AlternateG, AnyPin, Pin, PA24, PA25};
12use crate::pac::usb::Device;
13use crate::pac::{Pm, Usb};
14use crate::usb::buffer::*;
15use crate::usb::devicedesc::DeviceDescBank;
16use atsamd_hal_macros::{hal_cfg, hal_macro_helper};
17use core::cell::{Ref, RefCell, RefMut};
18use core::marker::PhantomData;
19use critical_section::{Mutex, with as disable_interrupts};
20use usb_device::bus::PollResult;
21use usb_device::endpoint::{EndpointAddress, EndpointType};
22use usb_device::{Result as UsbResult, UsbDirection, UsbError};
23
24#[derive(Debug, Default, PartialEq, Eq, Clone, Copy)]
27pub enum EndpointTypeBits {
28 #[default]
29 Disabled = 0,
30 Control = 1,
31 Isochronous = 2,
32 Bulk = 3,
33 Interrupt = 4,
34 #[allow(unused)]
35 DualBank = 5,
36}
37
38impl From<EndpointType> for EndpointTypeBits {
39 fn from(ep_type: EndpointType) -> EndpointTypeBits {
40 match ep_type {
41 EndpointType::Control => EndpointTypeBits::Control,
42 EndpointType::Isochronous { .. } => EndpointTypeBits::Isochronous,
43 EndpointType::Bulk => EndpointTypeBits::Bulk,
44 EndpointType::Interrupt => EndpointTypeBits::Interrupt,
45 }
46 }
47}
48
49#[derive(Default, Clone, Copy)]
51struct EPConfig {
52 ep_type: EndpointTypeBits,
53 allocated_size: u16,
54 max_packet_size: u16,
55 addr: usize,
56}
57
58impl EPConfig {
59 fn new(
60 ep_type: EndpointType,
61 allocated_size: u16,
62 max_packet_size: u16,
63 buffer_addr: *mut u8,
64 ) -> Self {
65 Self {
66 ep_type: ep_type.into(),
67 allocated_size,
68 max_packet_size,
69 addr: buffer_addr as usize,
70 }
71 }
72}
73
74#[derive(Default)]
76struct EndpointInfo {
77 bank0: EPConfig,
78 bank1: EPConfig,
79}
80
81impl EndpointInfo {
82 fn new() -> Self {
83 Default::default()
84 }
85}
86
87struct AllEndpoints {
90 endpoints: [EndpointInfo; 8],
91}
92
93impl AllEndpoints {
94 fn new() -> Self {
95 Self {
96 endpoints: [
97 EndpointInfo::new(),
98 EndpointInfo::new(),
99 EndpointInfo::new(),
100 EndpointInfo::new(),
101 EndpointInfo::new(),
102 EndpointInfo::new(),
103 EndpointInfo::new(),
104 EndpointInfo::new(),
105 ],
106 }
107 }
108
109 fn find_free_endpoint(&self, dir: UsbDirection) -> UsbResult<usize> {
110 for idx in 1..8 {
112 let ep_type = match dir {
113 UsbDirection::Out => self.endpoints[idx].bank0.ep_type,
114 UsbDirection::In => self.endpoints[idx].bank1.ep_type,
115 };
116 if ep_type == EndpointTypeBits::Disabled {
117 return Ok(idx);
118 }
119 }
120 Err(UsbError::EndpointOverflow)
121 }
122
123 #[allow(clippy::too_many_arguments)]
124 fn allocate_endpoint(
125 &mut self,
126 dir: UsbDirection,
127 idx: usize,
128 ep_type: EndpointType,
129 allocated_size: u16,
130 max_packet_size: u16,
131 _interval: u8,
132 buffer_addr: *mut u8,
133 ) -> UsbResult<EndpointAddress> {
134 let bank = match dir {
135 UsbDirection::Out => &mut self.endpoints[idx].bank0,
136 UsbDirection::In => &mut self.endpoints[idx].bank1,
137 };
138 if bank.ep_type != EndpointTypeBits::Disabled {
139 return Err(UsbError::EndpointOverflow);
140 }
141
142 *bank = EPConfig::new(ep_type, allocated_size, max_packet_size, buffer_addr);
143
144 Ok(EndpointAddress::from_parts(idx, dir))
145 }
146}
147
148struct Inner {
149 desc: RefCell<Descriptors>,
150 _dm_pad: Pin<PA24, AlternateG>,
151 _dp_pad: Pin<PA25, AlternateG>,
152 endpoints: RefCell<AllEndpoints>,
153 buffers: RefCell<BufferAllocator>,
154}
155
156pub struct UsbBus {
157 inner: Mutex<RefCell<Inner>>,
158}
159
160struct Bank<'a, T> {
161 address: EndpointAddress,
162 usb: &'a Device,
163 desc: RefMut<'a, super::Descriptors>,
164 _phantom: PhantomData<T>,
165 endpoints: Ref<'a, AllEndpoints>,
166}
167
168impl<T> Bank<'_, T> {
169 fn usb(&self) -> &Device {
170 self.usb
171 }
172
173 #[inline]
174 fn index(&self) -> usize {
175 self.address.index()
176 }
177
178 #[inline]
179 fn config(&mut self) -> &EPConfig {
180 let ep = &self.endpoints.endpoints[self.address.index()];
181 if self.address.is_out() {
182 &ep.bank0
183 } else {
184 &ep.bank1
185 }
186 }
187}
188
189struct InBank;
191
192struct OutBank;
194
195impl Bank<'_, InBank> {
196 fn desc_bank(&mut self) -> &mut DeviceDescBank {
197 let idx = self.index();
198 self.desc.bank(idx, 1)
199 }
200
201 #[inline]
203 fn is_ready(&self) -> bool {
204 self.usb().epstatus(self.index()).read().bk1rdy().bit()
205 }
206
207 #[inline]
210 fn set_ready(&self, ready: bool) {
211 if ready {
212 self.usb()
213 .epstatusset(self.index())
214 .write(|w| w.bk1rdy().set_bit());
215 } else {
216 self.usb()
217 .epstatusclr(self.index())
218 .write(|w| w.bk1rdy().set_bit());
219 }
220 }
221
222 #[inline]
224 fn clear_transfer_complete(&self) {
225 self.usb()
227 .epintflag(self.index())
228 .write(|w| w.trcpt1().set_bit().trfail1().set_bit());
229 }
230
231 #[inline]
233 fn is_transfer_complete(&self) -> bool {
234 self.usb().epintflag(self.index()).read().trcpt1().bit()
235 }
236
237 fn flush_config(&mut self) {
239 let config = *self.config();
240 {
241 let desc = self.desc_bank();
242 desc.set_address(config.addr as *mut u8);
243 desc.set_endpoint_size(config.max_packet_size);
244 desc.set_multi_packet_size(0);
245 desc.set_byte_count(0);
246 }
247 }
248
249 fn setup_ep_interrupts(&mut self) {
251 self.usb()
252 .epintenset(self.index())
253 .write(|w| w.trcpt1().set_bit());
254 }
255
256 pub fn write(&mut self, buf: &[u8]) -> UsbResult<usize> {
260 let size = buf.len().min(self.config().allocated_size as usize);
261 let desc = self.desc_bank();
262
263 unsafe {
264 buf.as_ptr()
265 .copy_to_nonoverlapping(desc.get_address(), size);
266 }
267
268 desc.set_multi_packet_size(0);
269 desc.set_byte_count(size as u16);
270
271 Ok(size)
272 }
273
274 fn is_stalled(&self) -> bool {
275 self.usb().epintflag(self.index()).read().stall1().bit()
276 }
277
278 fn set_stall(&mut self, stall: bool) {
279 if stall {
280 self.usb()
281 .epstatusset(self.index())
282 .write(|w| w.stallrq1().set_bit())
283 } else {
284 self.usb()
285 .epstatusclr(self.index())
286 .write(|w| w.stallrq1().set_bit())
287 }
288 }
289}
290
291impl Bank<'_, OutBank> {
292 fn desc_bank(&mut self) -> &mut DeviceDescBank {
293 let idx = self.index();
294 self.desc.bank(idx, 0)
295 }
296
297 #[inline]
299 fn is_ready(&self) -> bool {
300 self.usb().epstatus(self.index()).read().bk0rdy().bit()
301 }
302
303 #[inline]
306 fn set_ready(&self, ready: bool) {
307 if ready {
308 self.usb()
309 .epstatusset(self.index())
310 .write(|w| w.bk0rdy().set_bit());
311 } else {
312 self.usb()
313 .epstatusclr(self.index())
314 .write(|w| w.bk0rdy().set_bit());
315 }
316 }
317
318 #[inline]
320 fn clear_transfer_complete(&self) {
321 self.usb()
323 .epintflag(self.index())
324 .write(|w| w.trcpt0().set_bit().trfail0().set_bit());
325 }
326
327 #[inline]
330 fn received_setup_interrupt(&self) -> bool {
331 self.usb().epintflag(self.index()).read().rxstp().bit()
332 }
333
334 #[inline]
337 fn clear_received_setup_interrupt(&self) {
338 self.usb()
340 .epintflag(self.index())
341 .write(|w| w.rxstp().set_bit());
342 }
343
344 fn flush_config(&mut self) {
346 let config = *self.config();
347 {
348 let desc = self.desc_bank();
349 desc.set_address(config.addr as *mut u8);
350 desc.set_endpoint_size(config.max_packet_size);
351 desc.set_multi_packet_size(0);
352 desc.set_byte_count(0);
353 }
354 }
355
356 fn setup_ep_interrupts(&mut self) {
358 self.usb()
359 .epintenset(self.index())
360 .write(|w| w.rxstp().set_bit().trcpt0().set_bit());
361 }
362
363 pub fn read(&mut self, buf: &mut [u8]) -> UsbResult<usize> {
367 let desc = self.desc_bank();
368 let size = desc.get_byte_count() as usize;
369
370 if size > buf.len() {
371 return Err(UsbError::BufferOverflow);
372 }
373 unsafe {
374 desc.get_address()
375 .copy_to_nonoverlapping(buf.as_mut_ptr(), size);
376 }
377
378 desc.set_byte_count(0);
379 desc.set_multi_packet_size(0);
380
381 Ok(size)
382 }
383
384 fn is_stalled(&self) -> bool {
385 self.usb().epintflag(self.index()).read().stall0().bit()
386 }
387
388 fn set_stall(&mut self, stall: bool) {
389 if stall {
390 self.usb()
391 .epstatusset(self.index())
392 .write(|w| w.stallrq0().set_bit())
393 } else {
394 self.usb()
395 .epstatusclr(self.index())
396 .write(|w| w.stallrq0().set_bit())
397 }
398 }
399}
400
401impl Inner {
402 fn bank0(&'_ self, ep: EndpointAddress) -> UsbResult<Bank<'_, OutBank>> {
403 if ep.is_in() {
404 return Err(UsbError::InvalidEndpoint);
405 }
406 let endpoints = self.endpoints.borrow();
407
408 if endpoints.endpoints[ep.index()].bank0.ep_type == EndpointTypeBits::Disabled {
409 return Err(UsbError::InvalidEndpoint);
410 }
411 Ok(Bank {
412 address: ep,
413 usb: self.usb(),
414 desc: self.desc.borrow_mut(),
415 endpoints,
416 _phantom: PhantomData,
417 })
418 }
419
420 fn bank1(&'_ self, ep: EndpointAddress) -> UsbResult<Bank<'_, InBank>> {
421 if ep.is_out() {
422 return Err(UsbError::InvalidEndpoint);
423 }
424 let endpoints = self.endpoints.borrow();
425
426 if endpoints.endpoints[ep.index()].bank1.ep_type == EndpointTypeBits::Disabled {
427 return Err(UsbError::InvalidEndpoint);
428 }
429 Ok(Bank {
430 address: ep,
431 usb: self.usb(),
432 desc: self.desc.borrow_mut(),
433 endpoints,
434 _phantom: PhantomData,
435 })
436 }
437}
438
439impl UsbBus {
440 pub fn new(
441 _clock: &clock::UsbClock,
442 pm: &mut Pm,
443 dm_pad: impl AnyPin<Id = PA24>,
444 dp_pad: impl AnyPin<Id = PA25>,
445 _usb: Usb,
446 ) -> Self {
447 pm.apbbmask().modify(|_, w| w.usb_().set_bit());
448
449 let desc = RefCell::new(Descriptors::new());
450
451 let inner = Inner {
452 _dm_pad: dm_pad.into().into_mode::<AlternateG>(),
453 _dp_pad: dp_pad.into().into_mode::<AlternateG>(),
454 desc,
455 buffers: RefCell::new(BufferAllocator::default()),
456 endpoints: RefCell::new(AllEndpoints::new()),
457 };
458
459 Self {
460 inner: Mutex::new(RefCell::new(inner)),
461 }
462 }
463}
464
465impl Inner {
466 #[hal_cfg("usb-d11")]
467 fn usb(&self) -> &Device {
468 unsafe { (*Usb::ptr()).device() }
469 }
470
471 #[hal_cfg("usb-d21")]
472 fn usb(&self) -> &Device {
473 unsafe { (*Usb::ptr()).device() }
474 }
475
476 fn set_stall<EP: Into<EndpointAddress>>(&self, ep: EP, stall: bool) {
477 let ep = ep.into();
478 if ep.is_out() {
479 if let Ok(mut bank) = self.bank0(ep) {
480 bank.set_stall(stall);
481 }
482 } else if let Ok(mut bank) = self.bank1(ep) {
483 bank.set_stall(stall);
484 }
485 }
486}
487
488#[derive(Copy, Clone)]
489enum FlushConfigMode {
490 Full,
492 ProtocolReset,
494}
495
496impl Inner {
497 #[hal_macro_helper]
498 fn enable(&mut self) {
499 let usb = self.usb();
500 usb.ctrla().modify(|_, w| w.swrst().set_bit());
501 while usb.syncbusy().read().swrst().bit_is_set() {}
502
503 let addr = self.desc.borrow().address();
504 usb.descadd().write(|w| unsafe { w.descadd().bits(addr) });
505 usb.padcal().modify(|_, w| unsafe {
506 w.transn().bits(usb_transn_cal());
507 w.transp().bits(usb_transp_cal());
508 w.trim().bits(usb_trim_cal())
509 });
510
511 #[hal_cfg("usb-d11")]
512 usb.qosctrl().modify(|_, w| unsafe {
513 w.dqos().bits(0b11);
514 w.cqos().bits(0b11)
515 });
516 #[hal_cfg("usb-d21")]
517 usb.qosctrl().modify(|_, w| unsafe {
518 w.dqos().bits(0b11);
519 w.cqos().bits(0b11)
520 });
521
522 usb.ctrla().modify(|_, w| {
523 w.mode().device();
524 w.runstdby().set_bit()
525 });
526 usb.ctrlb().modify(|_, w| w.spdconf().fs());
528
529 usb.ctrla().modify(|_, w| w.enable().set_bit());
530 while usb.syncbusy().read().enable().bit_is_set() {}
531
532 usb.intflag()
534 .write(|w| unsafe { w.bits(usb.intflag().read().bits()) });
535 usb.intenset().write(|w| w.eorst().set_bit());
536
537 self.flush_eps(FlushConfigMode::Full);
540
541 usb.ctrlb().modify(|_, w| w.detach().clear_bit());
542 }
543
544 fn sof_interrupt(&self, enable: bool) {
546 if enable {
547 self.usb().intenset().write(|w| w.sof().set_bit());
548 } else {
549 self.usb().intenclr().write(|w| w.sof().set_bit());
550 }
551 }
552
553 fn flush_eps(&self, mode: FlushConfigMode) {
555 for idx in 0..8 {
556 match (mode, idx) {
557 (FlushConfigMode::ProtocolReset, 0) => {
560 self.setup_ep_interrupts(EndpointAddress::from_parts(idx, UsbDirection::Out));
561 self.setup_ep_interrupts(EndpointAddress::from_parts(idx, UsbDirection::In));
562 }
563 (FlushConfigMode::Full, _) | (FlushConfigMode::ProtocolReset, _) => {
566 self.flush_ep(idx);
568 self.setup_ep_interrupts(EndpointAddress::from_parts(idx, UsbDirection::Out));
579 self.setup_ep_interrupts(EndpointAddress::from_parts(idx, UsbDirection::In));
580 }
581 }
582 }
583 }
584
585 fn flush_ep(&self, idx: usize) {
588 let cfg = self.usb().epcfg(idx);
589 let info = &self.endpoints.borrow().endpoints[idx];
590 if let Ok(mut bank) = self.bank0(EndpointAddress::from_parts(idx, UsbDirection::Out)) {
593 bank.flush_config();
594 }
595 if let Ok(mut bank) = self.bank1(EndpointAddress::from_parts(idx, UsbDirection::In)) {
596 bank.flush_config();
597 }
598
599 cfg.modify(|_, w| unsafe {
601 w.eptype0()
602 .bits(info.bank0.ep_type as u8)
603 .eptype1()
604 .bits(info.bank1.ep_type as u8)
605 });
606 }
607
608 fn setup_ep_interrupts(&self, ep_addr: EndpointAddress) {
610 if ep_addr.is_out() {
611 if let Ok(mut bank) = self.bank0(ep_addr) {
612 bank.setup_ep_interrupts();
613 }
614 } else if let Ok(mut bank) = self.bank1(ep_addr) {
615 bank.setup_ep_interrupts();
616 }
617 }
618
619 fn protocol_reset(&self) {
622 self.flush_eps(FlushConfigMode::ProtocolReset);
623 }
624
625 fn suspend(&self) {}
626
627 fn resume(&self) {}
628
629 fn alloc_ep(
630 &mut self,
631 dir: UsbDirection,
632 addr: Option<EndpointAddress>,
633 ep_type: EndpointType,
634 max_packet_size: u16,
635 interval: u8,
636 ) -> UsbResult<EndpointAddress> {
637 let allocated_size = match max_packet_size {
641 1..=8 => 8,
642 9..=16 => 16,
643 17..=32 => 32,
644 33..=64 => 64,
645 65..=128 => 128,
646 129..=256 => 256,
647 257..=512 => 512,
648 513..=1023 => 1024,
649 _ => return Err(UsbError::Unsupported),
650 };
651
652 if allocated_size > ALLOC_SIZE_MAX_PER_EP as u16 {
654 return Err(UsbError::EndpointMemoryOverflow);
655 }
656
657 let buffer = self.buffers.borrow_mut().allocate_buffer()?;
658
659 let mut endpoints = self.endpoints.borrow_mut();
660
661 let idx = match addr {
662 None => endpoints.find_free_endpoint(dir)?,
663 Some(addr) => addr.index(),
664 };
665
666 let addr = endpoints.allocate_endpoint(
667 dir,
668 idx,
669 ep_type,
670 allocated_size,
671 max_packet_size,
672 interval,
673 buffer,
674 )?;
675
676 Ok(addr)
677 }
678
679 fn set_device_address(&self, addr: u8) {
680 self.usb()
681 .dadd()
682 .write(|w| unsafe { w.dadd().bits(addr).adden().set_bit() });
683 }
684
685 fn check_sof_interrupt(&self) -> bool {
686 if self.usb().intflag().read().sof().bit() {
687 self.usb().intflag().write(|w| w.sof().set_bit());
688 return true;
689 }
690 false
691 }
692
693 fn poll(&self) -> PollResult {
694 let intflags = self.usb().intflag().read();
695 if intflags.eorst().bit() {
696 self.usb().intflag().write(|w| w.eorst().set_bit());
698 return PollResult::Reset;
699 }
700 let mut ep_out = 0;
705 let mut ep_in_complete = 0;
706 let mut ep_setup = 0;
707
708 let intbits = self.usb().epintsmry().read().bits();
709
710 for ep in 0..8u16 {
711 let mask = 1 << ep;
712
713 let idx = ep as usize;
714
715 if (intbits & mask) != 0 {
716 if let Ok(bank1) = self.bank1(EndpointAddress::from_parts(idx, UsbDirection::In)) {
717 if bank1.is_transfer_complete() {
718 bank1.clear_transfer_complete();
719 ep_in_complete |= mask;
720 }
721 }
722 }
723
724 if let Ok(bank0) = self.bank0(EndpointAddress::from_parts(idx, UsbDirection::Out)) {
726 if bank0.received_setup_interrupt() {
727 ep_setup |= mask;
728
729 }
739
740 bank0.clear_transfer_complete();
747
748 if bank0.is_ready() {
754 ep_out |= mask;
755 }
756 }
757 }
758
759 if ep_out == 0 && ep_in_complete == 0 && ep_setup == 0 {
760 PollResult::None
761 } else {
762 PollResult::Data {
763 ep_out,
764 ep_in_complete,
765 ep_setup,
766 }
767 }
768 }
769
770 fn write(&self, ep: EndpointAddress, buf: &[u8]) -> UsbResult<usize> {
771 let mut bank = self.bank1(ep)?;
772
773 if bank.is_ready() {
774 return Err(UsbError::WouldBlock);
776 }
777
778 let size = bank.write(buf);
779
780 bank.clear_transfer_complete();
781 bank.set_ready(true); size
784 }
785
786 fn read(&self, ep: EndpointAddress, buf: &mut [u8]) -> UsbResult<usize> {
787 let mut bank = self.bank0(ep)?;
788 let rxstp = bank.received_setup_interrupt();
789
790 if bank.is_ready() || rxstp {
791 let size = bank.read(buf);
792
793 if rxstp {
794 bank.clear_received_setup_interrupt();
795 }
796
797 bank.clear_transfer_complete();
798 bank.set_ready(false);
799
800 size
801 } else {
802 Err(UsbError::WouldBlock)
803 }
804 }
805
806 fn is_stalled(&self, ep: EndpointAddress) -> bool {
807 if ep.is_out() {
808 self.bank0(ep).unwrap().is_stalled()
809 } else {
810 self.bank1(ep).unwrap().is_stalled()
811 }
812 }
813
814 fn set_stalled(&self, ep: EndpointAddress, stalled: bool) {
815 self.set_stall(ep, stalled);
816 }
817}
818
819impl UsbBus {
820 pub fn enable_sof_interrupt(&self) {
822 disable_interrupts(|cs| self.inner.borrow(cs).borrow_mut().sof_interrupt(true))
823 }
824
825 pub fn disable_sof_interrupt(&self) {
827 disable_interrupts(|cs| self.inner.borrow(cs).borrow_mut().sof_interrupt(false))
828 }
829
830 pub fn check_sof_interrupt(&self) -> bool {
832 disable_interrupts(|cs| self.inner.borrow(cs).borrow_mut().check_sof_interrupt())
833 }
834}
835
836impl usb_device::bus::UsbBus for UsbBus {
837 fn enable(&mut self) {
838 disable_interrupts(|cs| self.inner.borrow(cs).borrow_mut().enable())
839 }
840
841 fn reset(&self) {
842 disable_interrupts(|cs| self.inner.borrow(cs).borrow().protocol_reset())
843 }
844
845 fn suspend(&self) {
846 disable_interrupts(|cs| self.inner.borrow(cs).borrow().suspend())
847 }
848
849 fn resume(&self) {
850 disable_interrupts(|cs| self.inner.borrow(cs).borrow().resume())
851 }
852
853 fn alloc_ep(
854 &mut self,
855 dir: UsbDirection,
856 addr: Option<EndpointAddress>,
857 ep_type: EndpointType,
858 max_packet_size: u16,
859 interval: u8,
860 ) -> UsbResult<EndpointAddress> {
861 disable_interrupts(|cs| {
862 self.inner.borrow(cs).borrow_mut().alloc_ep(
863 dir,
864 addr,
865 ep_type,
866 max_packet_size,
867 interval,
868 )
869 })
870 }
871
872 fn set_device_address(&self, addr: u8) {
873 disable_interrupts(|cs| self.inner.borrow(cs).borrow().set_device_address(addr))
874 }
875
876 fn poll(&self) -> PollResult {
877 disable_interrupts(|cs| self.inner.borrow(cs).borrow().poll())
878 }
879
880 fn write(&self, ep: EndpointAddress, buf: &[u8]) -> UsbResult<usize> {
881 disable_interrupts(|cs| self.inner.borrow(cs).borrow().write(ep, buf))
882 }
883
884 fn read(&self, ep: EndpointAddress, buf: &mut [u8]) -> UsbResult<usize> {
885 disable_interrupts(|cs| self.inner.borrow(cs).borrow().read(ep, buf))
886 }
887
888 fn set_stalled(&self, ep: EndpointAddress, stalled: bool) {
889 disable_interrupts(|cs| self.inner.borrow(cs).borrow().set_stalled(ep, stalled))
890 }
891
892 fn is_stalled(&self, ep: EndpointAddress) -> bool {
893 disable_interrupts(|cs| self.inner.borrow(cs).borrow().is_stalled(ep))
894 }
895}