atsamd_hal/peripherals/usb/d5x/
bus.rs

1// This crate uses standard host-centric USB terminology for transfer
2// directions. Therefore an OUT transfer refers to a host-to-device transfer,
3// and an IN transfer refers to a device-to-host transfer. This is mainly a
4// concern for implementing new USB peripheral drivers and USB classes, and
5// people doing that should be familiar with the USB standard. http://ww1.microchip.com/downloads/en/DeviceDoc/60001507E.pdf
6// http://ww1.microchip.com/downloads/en/AppNotes/Atmel-42261-SAM-D21-USB_Application-Note_AT06475.pdf
7
8use super::Descriptors;
9use crate::calibration::{usb_transn_cal, usb_transp_cal, usb_trim_cal};
10use crate::clock;
11use crate::gpio::{AlternateH, AnyPin, Pin, PA24, PA25};
12use crate::pac;
13use crate::pac::usb::Device;
14use crate::pac::{Mclk, Usb};
15use crate::usb::devicedesc::DeviceDescBank;
16use core::cell::{Ref, RefCell, RefMut};
17use core::marker::PhantomData;
18use core::mem;
19use cortex_m::singleton;
20use critical_section::{with as disable_interrupts, Mutex};
21use usb_device::bus::PollResult;
22use usb_device::endpoint::{EndpointAddress, EndpointType};
23use usb_device::{Result as UsbResult, UsbDirection, UsbError};
24
25/// EndpointTypeBits represents valid values for the EPTYPE fields in
26/// the EPCFGn registers.
27#[derive(Debug, Default, PartialEq, Eq, Clone, Copy)]
28pub enum EndpointTypeBits {
29    #[default]
30    Disabled = 0,
31    Control = 1,
32    Isochronous = 2,
33    Bulk = 3,
34    Interrupt = 4,
35    #[allow(unused)]
36    DualBank = 5,
37}
38
39impl From<EndpointType> for EndpointTypeBits {
40    fn from(ep_type: EndpointType) -> EndpointTypeBits {
41        match ep_type {
42            EndpointType::Control => EndpointTypeBits::Control,
43            EndpointType::Isochronous { .. } => EndpointTypeBits::Isochronous,
44            EndpointType::Bulk => EndpointTypeBits::Bulk,
45            EndpointType::Interrupt => EndpointTypeBits::Interrupt,
46        }
47    }
48}
49
50/// EPConfig tracks the desired configuration for one side of an endpoint.
51#[derive(Default, Clone, Copy)]
52struct EPConfig {
53    ep_type: EndpointTypeBits,
54    allocated_size: u16,
55    max_packet_size: u16,
56    addr: usize,
57}
58
59impl EPConfig {
60    fn new(
61        ep_type: EndpointType,
62        allocated_size: u16,
63        max_packet_size: u16,
64        buffer_addr: *mut u8,
65    ) -> Self {
66        Self {
67            ep_type: ep_type.into(),
68            allocated_size,
69            max_packet_size,
70            addr: buffer_addr as usize,
71        }
72    }
73}
74
75// EndpointInfo represents the desired configuration for an endpoint pair.
76#[derive(Default)]
77struct EndpointInfo {
78    bank0: EPConfig,
79    bank1: EPConfig,
80}
81
82impl EndpointInfo {
83    fn new() -> Self {
84        Default::default()
85    }
86}
87
88/// AllEndpoints tracks the desired configuration of all endpoints managed
89/// by the USB peripheral.
90struct AllEndpoints {
91    endpoints: [EndpointInfo; 8],
92}
93
94impl AllEndpoints {
95    fn new() -> Self {
96        Self {
97            endpoints: [
98                EndpointInfo::new(),
99                EndpointInfo::new(),
100                EndpointInfo::new(),
101                EndpointInfo::new(),
102                EndpointInfo::new(),
103                EndpointInfo::new(),
104                EndpointInfo::new(),
105                EndpointInfo::new(),
106            ],
107        }
108    }
109
110    fn find_free_endpoint(&self, dir: UsbDirection) -> UsbResult<usize> {
111        // start with 1 because 0 is reserved for Control
112        for idx in 1..8 {
113            let ep_type = match dir {
114                UsbDirection::Out => self.endpoints[idx].bank0.ep_type,
115                UsbDirection::In => self.endpoints[idx].bank1.ep_type,
116            };
117            if ep_type == EndpointTypeBits::Disabled {
118                return Ok(idx);
119            }
120        }
121        Err(UsbError::EndpointOverflow)
122    }
123
124    #[allow(clippy::too_many_arguments)]
125    fn allocate_endpoint(
126        &mut self,
127        dir: UsbDirection,
128        idx: usize,
129        ep_type: EndpointType,
130        allocated_size: u16,
131        max_packet_size: u16,
132        _interval: u8,
133        buffer_addr: *mut u8,
134    ) -> UsbResult<EndpointAddress> {
135        let bank = match dir {
136            UsbDirection::Out => &mut self.endpoints[idx].bank0,
137            UsbDirection::In => &mut self.endpoints[idx].bank1,
138        };
139        if bank.ep_type != EndpointTypeBits::Disabled {
140            return Err(UsbError::EndpointOverflow);
141        }
142
143        *bank = EPConfig::new(ep_type, allocated_size, max_packet_size, buffer_addr);
144
145        Ok(EndpointAddress::from_parts(idx, dir))
146    }
147}
148
149// FIXME: replace with more general heap?
150const BUFFER_SIZE: usize = 2048;
151fn buffer() -> &'static mut [u8; BUFFER_SIZE] {
152    singleton!(: [u8; BUFFER_SIZE] = [0; BUFFER_SIZE] ).unwrap()
153}
154
155struct BufferAllocator {
156    buffers: &'static mut [u8; BUFFER_SIZE],
157    next_buf: u16,
158}
159
160impl BufferAllocator {
161    fn new() -> Self {
162        Self {
163            next_buf: 0,
164            buffers: buffer(),
165        }
166    }
167
168    fn allocate_buffer(&mut self, size: u16) -> UsbResult<*mut u8> {
169        debug_assert!(size & 1 == 0);
170
171        let start_addr = &mut self.buffers[self.next_buf as usize] as *mut u8;
172        let buf_end = unsafe { start_addr.add(BUFFER_SIZE) };
173
174        // The address must be 32-bit aligned, so allow for that here
175        // by offsetting by an appropriate alignment.
176        let offset = start_addr.align_offset(mem::align_of::<u32>());
177        let start_addr = unsafe { start_addr.add(offset) };
178
179        if start_addr >= buf_end {
180            return Err(UsbError::EndpointMemoryOverflow);
181        }
182
183        let end_addr = unsafe { start_addr.offset(size as isize) };
184        if end_addr > buf_end {
185            return Err(UsbError::EndpointMemoryOverflow);
186        }
187
188        self.next_buf = unsafe { end_addr.sub(self.buffers.as_ptr() as usize) as u16 };
189
190        Ok(start_addr)
191    }
192}
193
194struct Inner {
195    desc: RefCell<Descriptors>,
196    _dm_pad: Pin<PA24, AlternateH>,
197    _dp_pad: Pin<PA25, AlternateH>,
198    endpoints: RefCell<AllEndpoints>,
199    buffers: RefCell<BufferAllocator>,
200}
201
202pub struct UsbBus {
203    inner: Mutex<RefCell<Inner>>,
204}
205
206struct Bank<'a, T> {
207    address: EndpointAddress,
208    usb: &'a Device,
209    desc: RefMut<'a, super::Descriptors>,
210    _phantom: PhantomData<T>,
211    endpoints: Ref<'a, AllEndpoints>,
212}
213
214impl<T> Bank<'_, T> {
215    fn usb(&self) -> &Device {
216        self.usb
217    }
218
219    #[inline]
220    fn index(&self) -> usize {
221        self.address.index()
222    }
223
224    #[inline]
225    fn config(&mut self) -> &EPConfig {
226        let ep = &self.endpoints.endpoints[self.address.index()];
227        if self.address.is_out() {
228            &ep.bank0
229        } else {
230            &ep.bank1
231        }
232    }
233}
234
235/// InBank represents In direction banks, Bank #1
236struct InBank;
237
238/// OutBank represents Out direction banks, Bank #0
239struct OutBank;
240
241impl Bank<'_, InBank> {
242    fn desc_bank(&mut self) -> &mut DeviceDescBank {
243        let idx = self.index();
244        self.desc.bank(idx, 1)
245    }
246
247    /// Returns true if Bank 1 is Ready and thus has data that can be written
248    #[inline]
249    fn is_ready(&self) -> bool {
250        self.epstatus(self.index()).read().bk1rdy().bit()
251    }
252
253    /// Set Bank 1 Ready.
254    /// Ready means that the buffer contains data that can be sent.
255    #[inline]
256    fn set_ready(&self, ready: bool) {
257        if ready {
258            self.epstatusset(self.index())
259                .write(|w| w.bk1rdy().set_bit());
260        } else {
261            self.epstatusclr(self.index())
262                .write(|w| w.bk1rdy().set_bit());
263        }
264    }
265
266    /// Acknowledges the signal that the last packet was sent.
267    #[inline]
268    fn clear_transfer_complete(&self) {
269        // Clear bits in epintflag by writing them to 1
270        self.epintflag(self.index())
271            .write(|w| w.trcpt1().set_bit().trfail1().set_bit());
272    }
273
274    /// Indicates if a transfer is complete or pending.
275    #[inline]
276    fn is_transfer_complete(&self) -> bool {
277        self.epintflag(self.index()).read().trcpt1().bit()
278    }
279
280    /// Writes out endpoint configuration to its in-memory descriptor.
281    fn flush_config(&mut self) {
282        let config = *self.config();
283        {
284            let desc = self.desc_bank();
285            desc.set_address(config.addr as *mut u8);
286            desc.set_endpoint_size(config.max_packet_size);
287            desc.set_multi_packet_size(0);
288            desc.set_byte_count(0);
289        }
290    }
291
292    /// Enables endpoint-specific interrupts.
293    fn setup_ep_interrupts(&mut self) {
294        self.epintenset(self.index())
295            .write(|w| w.trcpt1().set_bit());
296    }
297
298    /// Prepares to transfer a series of bytes by copying the data into the
299    /// bank1 buffer. The caller must call set_ready() to finalize the
300    /// transfer.
301    pub fn write(&mut self, buf: &[u8]) -> UsbResult<usize> {
302        let size = buf.len().min(self.config().allocated_size as usize);
303        let desc = self.desc_bank();
304
305        unsafe {
306            buf.as_ptr()
307                .copy_to_nonoverlapping(desc.get_address(), size);
308        }
309
310        desc.set_multi_packet_size(0);
311        desc.set_byte_count(size as u16);
312
313        Ok(size)
314    }
315
316    fn is_stalled(&self) -> bool {
317        self.epintflag(self.index()).read().stall1().bit()
318    }
319
320    fn set_stall(&mut self, stall: bool) {
321        if stall {
322            self.epstatusset(self.index())
323                .write(|w| w.stallrq1().set_bit())
324        } else {
325            self.epstatusclr(self.index())
326                .write(|w| w.stallrq1().set_bit())
327        }
328    }
329}
330
331impl Bank<'_, OutBank> {
332    fn desc_bank(&mut self) -> &mut DeviceDescBank {
333        let idx = self.index();
334        self.desc.bank(idx, 0)
335    }
336
337    /// Returns true if Bank 0 is Ready and thus has data that can be read.
338    #[inline]
339    fn is_ready(&self) -> bool {
340        self.epstatus(self.index()).read().bk0rdy().bit()
341    }
342
343    /// Set Bank 0 Ready.
344    /// Ready means that the buffer contains data that can be read.
345    #[inline]
346    fn set_ready(&self, ready: bool) {
347        if ready {
348            self.epstatusset(self.index())
349                .write(|w| w.bk0rdy().set_bit());
350        } else {
351            self.epstatusclr(self.index())
352                .write(|w| w.bk0rdy().set_bit());
353        }
354    }
355
356    /// Acknowledges the signal that data has been received.
357    #[inline]
358    fn clear_transfer_complete(&self) {
359        // Clear bits in epintflag by writing them to 1
360        self.epintflag(self.index())
361            .write(|w| w.trcpt0().set_bit().trfail0().set_bit());
362    }
363
364    /// Returns true if a Received Setup interrupt has occurred.
365    /// This indicates that the read buffer holds a SETUP packet.
366    #[inline]
367    fn received_setup_interrupt(&self) -> bool {
368        self.epintflag(self.index()).read().rxstp().bit()
369    }
370
371    /// Acknowledges the signal that a SETUP packet was received
372    /// successfully.
373    #[inline]
374    fn clear_received_setup_interrupt(&self) {
375        // Clear bits in epintflag by writing them to 1
376        self.epintflag(self.index()).write(|w| w.rxstp().set_bit());
377    }
378
379    /// Writes out endpoint configuration to its in-memory descriptor.
380    fn flush_config(&mut self) {
381        let config = *self.config();
382        {
383            let desc = self.desc_bank();
384            desc.set_address(config.addr as *mut u8);
385            desc.set_endpoint_size(config.max_packet_size);
386            desc.set_multi_packet_size(0);
387            desc.set_byte_count(0);
388        }
389    }
390
391    /// Enables endpoint-specific interrupts.
392    fn setup_ep_interrupts(&mut self) {
393        self.epintenset(self.index())
394            .write(|w| w.rxstp().set_bit().trcpt0().set_bit());
395    }
396
397    /// Copies data from the bank0 buffer to the provided array. The caller
398    /// must call set_ready to indicate the buffer is free for the next
399    /// transfer.
400    pub fn read(&mut self, buf: &mut [u8]) -> UsbResult<usize> {
401        let desc = self.desc_bank();
402        let size = desc.get_byte_count() as usize;
403
404        if size > buf.len() {
405            return Err(UsbError::BufferOverflow);
406        }
407        unsafe {
408            desc.get_address()
409                .copy_to_nonoverlapping(buf.as_mut_ptr(), size);
410        }
411
412        desc.set_byte_count(0);
413        desc.set_multi_packet_size(0);
414
415        Ok(size)
416    }
417
418    fn is_stalled(&self) -> bool {
419        self.epintflag(self.index()).read().stall0().bit()
420    }
421
422    fn set_stall(&mut self, stall: bool) {
423        if stall {
424            self.epstatusset(self.index())
425                .write(|w| w.stallrq0().set_bit())
426        } else {
427            self.epstatusclr(self.index())
428                .write(|w| w.stallrq0().set_bit())
429        }
430    }
431}
432
433impl<T> Bank<'_, T> {
434    #[inline]
435    #[allow(dead_code)]
436    fn epcfg(&self, endpoint: usize) -> &pac::usb::device::device_endpoint::Epcfg {
437        self.usb().device_endpoint(endpoint).epcfg()
438    }
439
440    #[inline]
441    fn epstatusclr(&self, endpoint: usize) -> &pac::usb::device::device_endpoint::Epstatusclr {
442        self.usb().device_endpoint(endpoint).epstatusclr()
443    }
444
445    #[inline]
446    fn epstatusset(&self, endpoint: usize) -> &pac::usb::device::device_endpoint::Epstatusset {
447        self.usb().device_endpoint(endpoint).epstatusset()
448    }
449
450    #[inline]
451    fn epstatus(&self, endpoint: usize) -> &pac::usb::device::device_endpoint::Epstatus {
452        self.usb().device_endpoint(endpoint).epstatus()
453    }
454
455    #[inline]
456    fn epintflag(&self, endpoint: usize) -> &pac::usb::device::device_endpoint::Epintflag {
457        self.usb().device_endpoint(endpoint).epintflag()
458    }
459
460    #[inline]
461    #[allow(dead_code)]
462    fn epintenclr(&self, endpoint: usize) -> &pac::usb::device::device_endpoint::Epintenclr {
463        self.usb().device_endpoint(endpoint).epintenclr()
464    }
465
466    #[inline]
467    fn epintenset(&self, endpoint: usize) -> &pac::usb::device::device_endpoint::Epintenset {
468        self.usb().device_endpoint(endpoint).epintenset()
469    }
470}
471
472impl Inner {
473    #[inline]
474    fn epcfg(&self, endpoint: usize) -> &pac::usb::device::device_endpoint::Epcfg {
475        self.usb().device_endpoint(endpoint).epcfg()
476    }
477
478    #[inline]
479    #[allow(dead_code)]
480    fn epstatus(&self, endpoint: usize) -> &pac::usb::device::device_endpoint::Epstatus {
481        self.usb().device_endpoint(endpoint).epstatus()
482    }
483
484    #[inline]
485    #[allow(dead_code)]
486    fn epintflag(&self, endpoint: usize) -> &pac::usb::device::device_endpoint::Epintflag {
487        self.usb().device_endpoint(endpoint).epintflag()
488    }
489
490    fn bank0(&'_ self, ep: EndpointAddress) -> UsbResult<Bank<'_, OutBank>> {
491        if ep.is_in() {
492            return Err(UsbError::InvalidEndpoint);
493        }
494        let endpoints = self.endpoints.borrow();
495
496        if endpoints.endpoints[ep.index()].bank0.ep_type == EndpointTypeBits::Disabled {
497            return Err(UsbError::InvalidEndpoint);
498        }
499        Ok(Bank {
500            address: ep,
501            usb: self.usb(),
502            desc: self.desc.borrow_mut(),
503            endpoints,
504            _phantom: PhantomData,
505        })
506    }
507
508    fn bank1(&'_ self, ep: EndpointAddress) -> UsbResult<Bank<'_, InBank>> {
509        if ep.is_out() {
510            return Err(UsbError::InvalidEndpoint);
511        }
512        let endpoints = self.endpoints.borrow();
513
514        if endpoints.endpoints[ep.index()].bank1.ep_type == EndpointTypeBits::Disabled {
515            return Err(UsbError::InvalidEndpoint);
516        }
517        Ok(Bank {
518            address: ep,
519            usb: self.usb(),
520            desc: self.desc.borrow_mut(),
521            endpoints,
522            _phantom: PhantomData,
523        })
524    }
525}
526
527impl UsbBus {
528    pub fn new(
529        _clock: &clock::UsbClock,
530        mclk: &mut Mclk,
531        dm_pad: impl AnyPin<Id = PA24>,
532        dp_pad: impl AnyPin<Id = PA25>,
533        _usb: Usb,
534    ) -> Self {
535        mclk.ahbmask().modify(|_, w| w.usb_().set_bit());
536        mclk.apbbmask().modify(|_, w| w.usb_().set_bit());
537
538        let desc = RefCell::new(Descriptors::new());
539
540        let inner = Inner {
541            _dm_pad: dm_pad.into().into_mode::<AlternateH>(),
542            _dp_pad: dp_pad.into().into_mode::<AlternateH>(),
543            desc,
544            buffers: RefCell::new(BufferAllocator::new()),
545            endpoints: RefCell::new(AllEndpoints::new()),
546        };
547
548        Self {
549            inner: Mutex::new(RefCell::new(inner)),
550        }
551    }
552}
553
554impl Inner {
555    fn usb(&self) -> &Device {
556        unsafe { (*Usb::ptr()).device() }
557    }
558
559    fn set_stall<EP: Into<EndpointAddress>>(&self, ep: EP, stall: bool) {
560        let ep = ep.into();
561        if ep.is_out() {
562            if let Ok(mut bank) = self.bank0(ep) {
563                bank.set_stall(stall);
564            }
565        } else if let Ok(mut bank) = self.bank1(ep) {
566            bank.set_stall(stall);
567        }
568    }
569}
570
571#[derive(Copy, Clone)]
572enum FlushConfigMode {
573    // Write configuration to all configured endpoints.
574    Full,
575    // Refresh configuration which was reset due to a bus reset.
576    ProtocolReset,
577}
578
579impl Inner {
580    fn enable(&mut self) {
581        let usb = self.usb();
582        usb.ctrla().modify(|_, w| w.swrst().set_bit());
583        while usb.syncbusy().read().swrst().bit_is_set() {}
584
585        let addr = self.desc.borrow().address();
586        usb.descadd().write(|w| unsafe { w.descadd().bits(addr) });
587        usb.padcal().modify(|_, w| unsafe {
588            w.transn().bits(usb_transn_cal());
589            w.transp().bits(usb_transp_cal());
590            w.trim().bits(usb_trim_cal())
591        });
592        usb.qosctrl().modify(|_, w| unsafe {
593            w.dqos().bits(0b11);
594            w.cqos().bits(0b11)
595        });
596        usb.ctrla().modify(|_, w| {
597            w.mode().device();
598            w.runstdby().set_bit()
599        });
600        // full speed
601        usb.ctrlb().modify(|_, w| w.spdconf().fs());
602
603        usb.ctrla().modify(|_, w| w.enable().set_bit());
604        while usb.syncbusy().read().enable().bit_is_set() {}
605
606        // Clear pending.
607        usb.intflag()
608            .write(|w| unsafe { w.bits(usb.intflag().read().bits()) });
609        usb.intenset().write(|w| w.eorst().set_bit());
610
611        // Configure the endpoints before we attach, as hosts may enumerate
612        // before attempting a USB protocol reset.
613        self.flush_eps(FlushConfigMode::Full);
614
615        usb.ctrlb().modify(|_, w| w.detach().clear_bit());
616    }
617
618    /// Enables/disables the Start Of Frame (SOF) interrupt
619    fn sof_interrupt(&self, enable: bool) {
620        if enable {
621            self.usb().intenset().write(|w| w.sof().set_bit());
622        } else {
623            self.usb().intenclr().write(|w| w.sof().set_bit());
624        }
625    }
626
627    /// Configures all endpoints based on prior calls to alloc_ep().
628    fn flush_eps(&self, mode: FlushConfigMode) {
629        for idx in 0..8 {
630            match (mode, idx) {
631                // A flush due to a protocol reset need not reconfigure endpoint 0,
632                // except for enabling its interrupts.
633                (FlushConfigMode::ProtocolReset, 0) => {
634                    self.setup_ep_interrupts(EndpointAddress::from_parts(idx, UsbDirection::Out));
635                    self.setup_ep_interrupts(EndpointAddress::from_parts(idx, UsbDirection::In));
636                }
637                // A full flush configures all provisioned endpoints + enables interrupts.
638                // Endpoints 1-8 have identical behaviour when flushed due to protocol reset.
639                (FlushConfigMode::Full, _) | (FlushConfigMode::ProtocolReset, _) => {
640                    // Write bank configuration & endpoint type.
641                    self.flush_ep(idx);
642                    // Endpoint interrupts are configured after the write to EPTYPE, as it appears
643                    // writes to EPINTEN*[n] do not take effect unless the
644                    // endpoint is already somewhat configured. The datasheet is
645                    // ambiguous here, section 38.8.3.7 (Device Interrupt EndPoint Set n)
646                    // of the SAM D5x/E5x states:
647                    //    "This register is cleared by USB reset or when EPEN[n] is zero"
648                    // EPEN[n] is not a register that exists, nor does it align with any other
649                    // terminology. We assume this means setting EPCFG[n] to a
650                    // non-zero value, but we do interrupt configuration last to
651                    // be sure.
652                    self.setup_ep_interrupts(EndpointAddress::from_parts(idx, UsbDirection::Out));
653                    self.setup_ep_interrupts(EndpointAddress::from_parts(idx, UsbDirection::In));
654                }
655            }
656        }
657    }
658
659    /// flush_ep commits bank descriptor information for the endpoint pair,
660    /// and enables the endpoint according to its type.
661    fn flush_ep(&self, idx: usize) {
662        let cfg = self.epcfg(idx);
663        let info = &self.endpoints.borrow().endpoints[idx];
664        // Write bank descriptors first. We do this so there is no period in
665        // which the endpoint is enabled but has an invalid descriptor.
666        if let Ok(mut bank) = self.bank0(EndpointAddress::from_parts(idx, UsbDirection::Out)) {
667            bank.flush_config();
668        }
669        if let Ok(mut bank) = self.bank1(EndpointAddress::from_parts(idx, UsbDirection::In)) {
670            bank.flush_config();
671        }
672
673        // Set the endpoint type. At this point, the endpoint is enabled.
674        cfg.modify(|_, w| unsafe {
675            w.eptype0()
676                .bits(info.bank0.ep_type as u8)
677                .eptype1()
678                .bits(info.bank1.ep_type as u8)
679        });
680    }
681
682    /// setup_ep_interrupts enables interrupts for the given endpoint address.
683    fn setup_ep_interrupts(&self, ep_addr: EndpointAddress) {
684        if ep_addr.is_out() {
685            if let Ok(mut bank) = self.bank0(ep_addr) {
686                bank.setup_ep_interrupts();
687            }
688        } else if let Ok(mut bank) = self.bank1(ep_addr) {
689            bank.setup_ep_interrupts();
690        }
691    }
692
693    /// protocol_reset is called by the USB HAL when it detects the host has
694    /// performed a USB reset.
695    fn protocol_reset(&self) {
696        self.flush_eps(FlushConfigMode::ProtocolReset);
697    }
698
699    fn suspend(&self) {}
700    fn resume(&self) {}
701
702    fn alloc_ep(
703        &mut self,
704        dir: UsbDirection,
705        addr: Option<EndpointAddress>,
706        ep_type: EndpointType,
707        max_packet_size: u16,
708        interval: u8,
709    ) -> UsbResult<EndpointAddress> {
710        // The USB hardware encodes the maximum packet size in 3 bits, so
711        // reserve enough buffer that the hardware won't overwrite it even if
712        // the other side issues an overly-long transfer.
713        let allocated_size = match max_packet_size {
714            1..=8 => 8,
715            9..=16 => 16,
716            17..=32 => 32,
717            33..=64 => 64,
718            65..=128 => 128,
719            129..=256 => 256,
720            257..=512 => 512,
721            513..=1023 => 1024,
722            _ => return Err(UsbError::Unsupported),
723        };
724
725        let buffer = self.buffers.borrow_mut().allocate_buffer(allocated_size)?;
726
727        let mut endpoints = self.endpoints.borrow_mut();
728
729        let idx = match addr {
730            None => endpoints.find_free_endpoint(dir)?,
731            Some(addr) => addr.index(),
732        };
733
734        let addr = endpoints.allocate_endpoint(
735            dir,
736            idx,
737            ep_type,
738            allocated_size,
739            max_packet_size,
740            interval,
741            buffer,
742        )?;
743
744        Ok(addr)
745    }
746
747    fn set_device_address(&self, addr: u8) {
748        self.usb()
749            .dadd()
750            .write(|w| unsafe { w.dadd().bits(addr).adden().set_bit() });
751    }
752
753    fn check_sof_interrupt(&self) -> bool {
754        if self.usb().intflag().read().sof().bit() {
755            self.usb().intflag().write(|w| w.sof().set_bit());
756            return true;
757        }
758        false
759    }
760
761    fn poll(&self) -> PollResult {
762        let intflags = self.usb().intflag().read();
763        if intflags.eorst().bit() {
764            // end of reset interrupt
765            self.usb().intflag().write(|w| w.eorst().set_bit());
766            return PollResult::Reset;
767        }
768        // As the suspend & wakup interrupts/states cannot distinguish between
769        // unconnected & unsuspended, we do not handle them to avoid spurious
770        // transitions.
771
772        let mut ep_out = 0;
773        let mut ep_in_complete = 0;
774        let mut ep_setup = 0;
775
776        let intbits = self.usb().epintsmry().read().bits();
777
778        for ep in 0..8u16 {
779            let mask = 1 << ep;
780
781            let idx = ep as usize;
782
783            if (intbits & mask) != 0 {
784                if let Ok(bank1) = self.bank1(EndpointAddress::from_parts(idx, UsbDirection::In)) {
785                    if bank1.is_transfer_complete() {
786                        bank1.clear_transfer_complete();
787                        ep_in_complete |= mask;
788                    }
789                }
790            }
791
792            // Can't test intbits, because bk0rdy doesn't interrupt
793            if let Ok(bank0) = self.bank0(EndpointAddress::from_parts(idx, UsbDirection::Out)) {
794                if bank0.received_setup_interrupt() {
795                    ep_setup |= mask;
796
797                    // The RXSTP interrupt is not cleared here, because doing so
798                    // would allow the USB hardware to overwrite the received
799                    // data, potentially before it is `read()` - see SAMD5x
800                    // datasheet "38.6.2.6 Management of SETUP Transactions".
801                    // Setup events are only relevant for control endpoints, and
802                    // in typical USB devices, endpoint 0 is the only control
803                    // endpoint. The usb-device `poll()` method, which calls
804                    // this `poll()`, will immediately `read()` endpoint 0 when
805                    // its setup bit is set.
806                }
807
808                // Clear the transfer complete and transfer failed interrupt flags
809                // so that execution leaves the USB interrupt until the host makes
810                // another transaction.  The transfer failed flag may have been set
811                // if an OUT transaction wasn't read() from the endpoint by the
812                // Class; the hardware will have NAKed (unless the endpoint is
813                // isochronous) and the host may retry.
814                bank0.clear_transfer_complete();
815
816                // Use the bk0rdy flag via is_ready() to indicate that data has been
817                // received successfully, rather than the interrupting trcpt0 via
818                // is_transfer_ready(), because data may have been received on an
819                // earlier poll() which cleared trcpt0.  bk0rdy is cleared in the
820                // endpoint read().
821                if bank0.is_ready() {
822                    ep_out |= mask;
823                }
824            }
825        }
826
827        if ep_out == 0 && ep_in_complete == 0 && ep_setup == 0 {
828            PollResult::None
829        } else {
830            PollResult::Data {
831                ep_out,
832                ep_in_complete,
833                ep_setup,
834            }
835        }
836    }
837
838    fn write(&self, ep: EndpointAddress, buf: &[u8]) -> UsbResult<usize> {
839        let mut bank = self.bank1(ep)?;
840
841        if bank.is_ready() {
842            // Waiting for the host to pick up the existing data
843            return Err(UsbError::WouldBlock);
844        }
845
846        let size = bank.write(buf);
847
848        bank.clear_transfer_complete();
849        bank.set_ready(true); // ready to be sent
850
851        size
852    }
853
854    fn read(&self, ep: EndpointAddress, buf: &mut [u8]) -> UsbResult<usize> {
855        let mut bank = self.bank0(ep)?;
856        let rxstp = bank.received_setup_interrupt();
857
858        if bank.is_ready() || rxstp {
859            let size = bank.read(buf);
860
861            if rxstp {
862                bank.clear_received_setup_interrupt();
863            }
864
865            bank.clear_transfer_complete();
866            bank.set_ready(false);
867
868            size
869        } else {
870            Err(UsbError::WouldBlock)
871        }
872    }
873
874    fn is_stalled(&self, ep: EndpointAddress) -> bool {
875        if ep.is_out() {
876            self.bank0(ep).unwrap().is_stalled()
877        } else {
878            self.bank1(ep).unwrap().is_stalled()
879        }
880    }
881
882    fn set_stalled(&self, ep: EndpointAddress, stalled: bool) {
883        self.set_stall(ep, stalled);
884    }
885}
886
887impl UsbBus {
888    /// Enables the Start Of Frame (SOF) interrupt
889    pub fn enable_sof_interrupt(&self) {
890        disable_interrupts(|cs| self.inner.borrow(cs).borrow_mut().sof_interrupt(true))
891    }
892
893    /// Disables the Start Of Frame (SOF) interrupt
894    pub fn disable_sof_interrupt(&self) {
895        disable_interrupts(|cs| self.inner.borrow(cs).borrow_mut().sof_interrupt(false))
896    }
897
898    /// Checks, and clears if set, the Start Of Frame (SOF) interrupt flag
899    pub fn check_sof_interrupt(&self) -> bool {
900        disable_interrupts(|cs| self.inner.borrow(cs).borrow_mut().check_sof_interrupt())
901    }
902}
903
904impl usb_device::bus::UsbBus for UsbBus {
905    fn enable(&mut self) {
906        disable_interrupts(|cs| self.inner.borrow(cs).borrow_mut().enable())
907    }
908
909    fn reset(&self) {
910        disable_interrupts(|cs| self.inner.borrow(cs).borrow().protocol_reset())
911    }
912
913    fn suspend(&self) {
914        disable_interrupts(|cs| self.inner.borrow(cs).borrow().suspend())
915    }
916
917    fn resume(&self) {
918        disable_interrupts(|cs| self.inner.borrow(cs).borrow().resume())
919    }
920
921    fn alloc_ep(
922        &mut self,
923        dir: UsbDirection,
924        addr: Option<EndpointAddress>,
925        ep_type: EndpointType,
926        max_packet_size: u16,
927        interval: u8,
928    ) -> UsbResult<EndpointAddress> {
929        disable_interrupts(|cs| {
930            self.inner.borrow(cs).borrow_mut().alloc_ep(
931                dir,
932                addr,
933                ep_type,
934                max_packet_size,
935                interval,
936            )
937        })
938    }
939
940    fn set_device_address(&self, addr: u8) {
941        disable_interrupts(|cs| self.inner.borrow(cs).borrow().set_device_address(addr))
942    }
943
944    fn poll(&self) -> PollResult {
945        disable_interrupts(|cs| self.inner.borrow(cs).borrow().poll())
946    }
947
948    fn write(&self, ep: EndpointAddress, buf: &[u8]) -> UsbResult<usize> {
949        disable_interrupts(|cs| self.inner.borrow(cs).borrow().write(ep, buf))
950    }
951
952    fn read(&self, ep: EndpointAddress, buf: &mut [u8]) -> UsbResult<usize> {
953        disable_interrupts(|cs| self.inner.borrow(cs).borrow().read(ep, buf))
954    }
955
956    fn set_stalled(&self, ep: EndpointAddress, stalled: bool) {
957        disable_interrupts(|cs| self.inner.borrow(cs).borrow().set_stalled(ep, stalled))
958    }
959
960    fn is_stalled(&self, ep: EndpointAddress) -> bool {
961        disable_interrupts(|cs| self.inner.borrow(cs).borrow().is_stalled(ep))
962    }
963}