Skip to main content

sam4l/usbc/
mod.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! SAM4L USB controller
6
7pub mod debug;
8
9#[allow(unused_imports)]
10use self::debug::{HexBuf, UdintFlags, UeconFlags, UestaFlags};
11use crate::pm;
12use crate::pm::{Clock, HSBClock, PBBClock, disable_clock, enable_clock};
13use crate::scif;
14use core::cell::Cell;
15use core::slice;
16use kernel::debug as debugln;
17use kernel::hil;
18use kernel::hil::usb::TransferType;
19use kernel::utilities::StaticRef;
20use kernel::utilities::cells::OptionalCell;
21use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable};
22use kernel::utilities::registers::{
23    FieldValue, InMemoryRegister, LocalRegisterCopy, ReadOnly, ReadWrite, WriteOnly,
24    register_bitfields, register_structs,
25};
26
27// The following macros provide some diagnostics and panics(!)
28// while this module is experimental and should eventually be removed or
29// replaced with better error handling.
30
31macro_rules! client_warn {
32    [ $( $arg:expr ),+ ] => {
33        debugln!($( $arg ),+)
34    };
35}
36
37macro_rules! client_err {
38    [ $( $arg:expr ),+ ] => {
39        panic!($( $arg ),+)
40    };
41}
42
43macro_rules! debug1 {
44    [ $( $arg:expr ),+ ] => {
45        {} // debugln!($( $arg ),+)
46    };
47}
48
49macro_rules! internal_err {
50    [ $( $arg:expr ),+ ] => {
51        panic!($( $arg ),+)
52    };
53}
54
55register_structs! {
56    UsbcRegisters {
57        (0x000 => udcon: ReadWrite<u32, DeviceControl::Register>),
58        (0x004 => udint: ReadOnly<u32, DeviceInterrupt::Register>),
59        (0x008 => udintclr: WriteOnly<u32, DeviceInterrupt::Register>),
60        (0x00C => udintset: WriteOnly<u32, DeviceInterrupt::Register>),
61        (0x010 => udinte: ReadOnly<u32, DeviceInterrupt::Register>),
62        (0x014 => udinteclr: WriteOnly<u32, DeviceInterrupt::Register>),
63        (0x018 => udinteset: WriteOnly<u32, DeviceInterrupt::Register>),
64        (0x01C => uerst: ReadWrite<u32>),
65        (0x020 => udfnum: ReadOnly<u32>),
66        (0x024 => _reserved0: [u8; 0xdc]),
67        (0x100 => uecfg: [ReadWrite<u32, EndpointConfig::Register>; 12]),
68        (0x130 => uesta: [ReadOnly<u32, EndpointStatus::Register>; 12]),
69        (0x160 => uestaclr: [WriteOnly<u32, EndpointStatus::Register>; 12]),
70        (0x190 => uestaset: [WriteOnly<u32, EndpointStatus::Register>; 12]),
71        (0x1C0 => uecon: [ReadOnly<u32, EndpointControl::Register>; 12]),
72        (0x1F0 => ueconset: [WriteOnly<u32, EndpointControl::Register>; 12]),
73        (0x220 => ueconclr: [WriteOnly<u32, EndpointControl::Register>; 12]),
74        (0x250 => _reserved1: [u8; 0x1b0]),
75        (0x400 => uhcon: ReadWrite<u32>),
76        (0x404 => uhint: ReadOnly<u32>),
77        (0x408 => uhintclr: WriteOnly<u32>),
78        (0x40C => uhintset: WriteOnly<u32>),
79        (0x410 => uhinte: ReadOnly<u32>),
80        (0x414 => uhinteclr: WriteOnly<u32>),
81        (0x418 => uhinteset: WriteOnly<u32>),
82        (0x41C => uprst: ReadWrite<u32>),
83        (0x420 => uhfnum: ReadWrite<u32>),
84        (0x424 => uhsofc: ReadWrite<u32>),
85        (0x428 => _reserved2: [u8; 0xd8]),
86        (0x500 => upcfg: [ReadWrite<u32>; 12]),
87        (0x530 => upsta: [ReadOnly<u32>; 12]),
88        (0x560 => upstaclr: [WriteOnly<u32>; 12]),
89        (0x590 => upstaset: [WriteOnly<u32>; 12]),
90        (0x5C0 => upcon: [ReadOnly<u32>; 12]),
91        (0x5F0 => upconset: [WriteOnly<u32>; 12]),
92        (0x620 => upconclr: [WriteOnly<u32>; 12]),
93        (0x650 => upinrq: [ReadWrite<u32>; 12]),
94        (0x680 => _reserved3: [u8; 0x180]),
95        (0x800 => usbcon: ReadWrite<u32, Control::Register>),
96        (0x804 => usbsta: ReadOnly<u32, Status::Register>),
97        (0x808 => usbstaclr: WriteOnly<u32>),
98        (0x80C => usbstaset: WriteOnly<u32>),
99        (0x810 => _reserved4: [u8; 8]),
100        (0x818 => uvers: ReadOnly<u32>),
101        (0x81C => ufeatures: ReadOnly<u32>),
102        (0x820 => uaddrsize: ReadOnly<u32>),
103        (0x824 => uname1: ReadOnly<u32>),
104        (0x828 => uname2: ReadOnly<u32>),
105        (0x82C => usbfsm: ReadOnly<u32>),
106        (0x830 => udesc: ReadWrite<u32>),
107        (0x834 => @END),
108    }
109}
110
111register_bitfields![u32,
112    Control [
113        UIMOD OFFSET(25) NUMBITS(1) [
114            HostMode = 0,
115            DeviceMode = 1
116        ],
117        USBE OFFSET(15) NUMBITS(1) [],
118        FRZCLK OFFSET(14) NUMBITS(1) []
119    ],
120    Status [
121        SUSPEND OFFSET(16) NUMBITS(1) [],
122        CLKUSABLE OFFSET(14) NUMBITS(1) [],
123        SPEED OFFSET(12) NUMBITS(2) [
124            SpeedFull = 0b00,
125            SpeedLow = 0b10
126        ],
127        VBUSRQ OFFSET(9) NUMBITS(1) []
128    ],
129    DeviceControl [
130        GNAK OFFSET(17) NUMBITS(1) [],
131        LS OFFSET(12) NUMBITS(1) [
132            FullSpeed = 0,
133            LowSpeed = 1
134        ],
135        RMWKUP OFFSET(9) NUMBITS(1) [],
136        DETACH OFFSET(8) NUMBITS(1) [],
137        ADDEN OFFSET(7) NUMBITS(1) [],
138        UADD OFFSET(0) NUMBITS(7) []
139    ],
140    DeviceInterrupt [
141        EPINT OFFSET(12) NUMBITS(8),
142        UPRSM OFFSET(6) NUMBITS(1),
143        EORSM OFFSET(5) NUMBITS(1),
144        WAKEUP OFFSET(4) NUMBITS(1),
145        EORST OFFSET(3) NUMBITS(1),
146        SOF OFFSET(2) NUMBITS(1),
147        SUSP OFFSET(0) NUMBITS(1)
148    ],
149    EndpointConfig [
150        REPNB OFFSET(16) NUMBITS(4) [
151            NotRedirected = 0
152        ],
153        EPTYPE OFFSET(11) NUMBITS(2) [
154            Control = 0,
155            Isochronous = 1,
156            Bulk = 2,
157            Interrupt = 3
158        ],
159        EPDIR OFFSET(8) NUMBITS(1) [
160            Out = 0,
161            In = 1
162        ],
163        EPSIZE OFFSET(4) NUMBITS(3) [
164            Bytes8 = 0,
165            Bytes16 = 1,
166            Bytes32 = 2,
167            Bytes64 = 3,
168            Bytes128 = 4,
169            Bytes256 = 5,
170            Bytes512 = 6,
171            Bytes1024 = 7
172        ],
173        EPBK OFFSET(2) NUMBITS(1) [
174            Single = 0,
175            Double = 1
176        ]
177    ],
178    EndpointStatus [
179        CTRLDIR OFFSET(17) NUMBITS(1) [
180            Out = 0,
181            In = 1
182        ],
183        CURRBK OFFSET(14) NUMBITS(2) [
184            Bank0 = 0,
185            Bank1 = 1
186        ],
187        NBUSYBK OFFSET(12) NUMBITS(2) [],
188        RAMACER OFFSET(11) NUMBITS(1) [],
189        DTSEQ OFFSET(8) NUMBITS(2) [
190            Data0 = 0,
191            Data1 = 1
192        ],
193        STALLED OFFSET(6) NUMBITS(1) [],
194        CRCERR OFFSET(6) NUMBITS(1) [],
195        NAKIN OFFSET(4) NUMBITS(1) [],
196        NAKOUT OFFSET(3) NUMBITS(1) [],
197        ERRORF OFFSET(2) NUMBITS(1) [],
198        RXSTP OFFSET(2) NUMBITS(1) [],
199        RXOUT OFFSET(1) NUMBITS(1) [],
200        TXIN OFFSET(0) NUMBITS(1) []
201    ],
202    EndpointControl [
203        BUSY1E 25,
204        BUSY0E 24,
205        STALLRQ 19,
206        RSTDT 18,
207        FIFOCON 14,
208        KILLBK 13,
209        NBUSYBKE 12,
210        RAMACERE 11,
211        NREPLY 8,
212        STALLEDE 6,
213        CRCERRE 6,
214        NAKINE 4,
215        NAKOUTE 3,
216        RXSTPE 2,
217        ERRORFE 2,
218        RXOUTE 1,
219        TXINE 0
220    ]
221];
222
223const USBC_BASE: StaticRef<UsbcRegisters> =
224    unsafe { StaticRef::new(0x400A5000 as *const UsbcRegisters) };
225
226#[inline]
227fn usbc_regs() -> &'static UsbcRegisters {
228    &USBC_BASE
229}
230
231// Datastructures for tracking USB controller state
232
233pub const N_ENDPOINTS: usize = 8;
234
235// This ensures the `descriptors` field is laid out first
236#[repr(C)]
237// This provides the required alignment for the `descriptors` field
238#[repr(align(8))]
239pub struct Usbc<'a> {
240    descriptors: [Endpoint; N_ENDPOINTS],
241    state: OptionalCell<State>,
242    requests: [Cell<Requests>; N_ENDPOINTS],
243    client: OptionalCell<&'a dyn hil::usb::Client<'a>>,
244    pm: &'a pm::PowerManager,
245}
246
247#[derive(Copy, Clone, Default, Debug)]
248pub struct Requests {
249    pub resume_in: bool,
250    pub resume_out: bool,
251}
252
253impl Requests {
254    pub const fn new() -> Self {
255        Requests {
256            resume_in: false,
257            resume_out: false,
258        }
259    }
260}
261
262#[derive(Copy, Clone, Debug)]
263pub enum State {
264    // Controller disabled
265    Reset,
266
267    // Controller enabled, detached from bus
268    // (We may go to this state when the Host
269    // controller suspends the bus.)
270    Idle(Mode),
271
272    // Controller enabled, attached to bus
273    Active(Mode),
274}
275
276#[derive(Copy, Clone, Debug)]
277pub enum Mode {
278    Host,
279    Device {
280        speed: Speed,
281        config: DeviceConfig,
282        state: DeviceState,
283    },
284}
285
286type EndpointConfigValue = LocalRegisterCopy<u32, EndpointConfig::Register>;
287type EndpointStatusValue = LocalRegisterCopy<u32, EndpointStatus::Register>;
288
289#[derive(Copy, Clone, Debug, Default)]
290pub struct DeviceConfig {
291    pub endpoint_configs: [Option<EndpointConfigValue>; N_ENDPOINTS],
292}
293
294#[derive(Copy, Clone, Debug, Default)]
295pub struct DeviceState {
296    pub endpoint_states: [EndpointState; N_ENDPOINTS],
297}
298
299#[derive(Copy, Clone, Debug, Default)]
300pub enum EndpointState {
301    #[default]
302    Disabled,
303    Ctrl(CtrlState),
304    BulkIn(BulkInState),
305    BulkOut(BulkOutState),
306}
307
308#[derive(Copy, Clone, PartialEq, Debug)]
309pub enum CtrlState {
310    Init,
311    ReadIn,
312    ReadStatus,
313    WriteOut,
314    WriteStatus,
315    WriteStatusWait,
316    InDelay,
317}
318
319#[derive(Copy, Clone, PartialEq, Debug)]
320pub enum BulkInState {
321    Init,
322    Delay,
323}
324
325#[derive(Copy, Clone, PartialEq, Debug)]
326pub enum BulkOutState {
327    Init,
328    Delay,
329}
330
331#[derive(Copy, Clone, PartialEq, Debug)]
332pub enum Speed {
333    Full,
334    Low,
335}
336
337pub enum BankIndex {
338    Bank0,
339    Bank1,
340}
341
342impl From<BankIndex> for usize {
343    fn from(bi: BankIndex) -> usize {
344        match bi {
345            BankIndex::Bank0 => 0,
346            BankIndex::Bank1 => 1,
347        }
348    }
349}
350
351pub struct EndpointIndex(u8);
352
353impl EndpointIndex {
354    pub fn new(index: usize) -> EndpointIndex {
355        EndpointIndex(index as u8 & 0xf)
356    }
357
358    pub fn to_u32(self) -> u32 {
359        self.0 as u32
360    }
361}
362
363impl From<EndpointIndex> for usize {
364    fn from(ei: EndpointIndex) -> usize {
365        ei.0 as usize
366    }
367}
368
369pub type Endpoint = [Bank; 2];
370
371pub const fn new_endpoint() -> Endpoint {
372    [Bank::new(), Bank::new()]
373}
374
375#[repr(C)]
376pub struct Bank {
377    addr: InMemoryRegister<u32>,
378
379    // The following fields are not actually registers
380    // (they may be placed anywhere in memory),
381    // but the register interface provides the volatile
382    // read/writes and bitfields that we need.
383    pub packet_size: InMemoryRegister<u32, PacketSize::Register>,
384    pub control_status: InMemoryRegister<u32, ControlStatus::Register>,
385
386    _reserved: u32,
387}
388
389impl Bank {
390    pub const fn new() -> Bank {
391        Bank {
392            addr: InMemoryRegister::new(0),
393            packet_size: InMemoryRegister::new(0),
394            control_status: InMemoryRegister::new(0),
395            _reserved: 0,
396        }
397    }
398
399    pub fn set_addr(&self, addr: *mut u8) {
400        self.addr.set(addr as u32);
401    }
402}
403
404register_bitfields![u32,
405    PacketSize [
406        AUTO_ZLP OFFSET(31) NUMBITS(1) [
407            No = 0,
408            Yes = 1
409        ],
410        MULTI_PACKET_SIZE OFFSET(16) NUMBITS(15) [],
411        BYTE_COUNT OFFSET(0) NUMBITS(15) []
412    ],
413    ControlStatus [
414        UNDERF 18,
415        OVERF 17,
416        CRCERR 16,
417        STALLRQ_NEXT 0
418    ]
419];
420
421impl<'a> Usbc<'a> {
422    pub const fn new(pm: &'a pm::PowerManager) -> Self {
423        Usbc {
424            client: OptionalCell::empty(),
425            state: OptionalCell::new(State::Reset),
426            descriptors: [
427                new_endpoint(),
428                new_endpoint(),
429                new_endpoint(),
430                new_endpoint(),
431                new_endpoint(),
432                new_endpoint(),
433                new_endpoint(),
434                new_endpoint(),
435            ],
436            requests: [
437                Cell::new(Requests::new()),
438                Cell::new(Requests::new()),
439                Cell::new(Requests::new()),
440                Cell::new(Requests::new()),
441                Cell::new(Requests::new()),
442                Cell::new(Requests::new()),
443                Cell::new(Requests::new()),
444                Cell::new(Requests::new()),
445            ],
446            pm,
447        }
448    }
449
450    fn map_state<F, R>(&self, closure: F) -> R
451    where
452        F: FnOnce(&mut State) -> R,
453    {
454        let mut state = self.state.take().unwrap(); // Unwrap fail = map_state: state value is in use
455        let result = closure(&mut state);
456        self.state.set(state);
457        result
458    }
459
460    fn get_state(&self) -> State {
461        self.state.unwrap_or_panic() // Unwrap fail = get_state: state value is in use
462    }
463
464    fn set_state(&self, state: State) {
465        self.state.set(state);
466    }
467
468    /// Provide a buffer for transfers in and out of the given endpoint
469    /// (The controller need not be enabled before calling this method.)
470    fn endpoint_bank_set_buffer(
471        &self,
472        endpoint: EndpointIndex,
473        bank: BankIndex,
474        buf: &[InMemoryRegister<u8>],
475    ) {
476        let e: usize = From::from(endpoint);
477        let b: usize = From::from(bank);
478        let p: *const InMemoryRegister<u8> = buf.as_ptr();
479        let p: *mut u8 = p.cast_mut().cast();
480
481        debug1!("Set Endpoint{}/Bank{} addr={:8?}", e, b, p);
482        self.descriptors[e][b].set_addr(p);
483        self.descriptors[e][b].packet_size.write(
484            PacketSize::BYTE_COUNT.val(0)
485                + PacketSize::MULTI_PACKET_SIZE.val(0)
486                + PacketSize::AUTO_ZLP::No,
487        );
488    }
489
490    /// Enable the controller's clocks and interrupt and transition to Idle state
491    fn enable(&self, mode: Mode) {
492        match self.get_state() {
493            State::Reset => {
494                // Are the USBC clocks enabled at reset?
495                //   10.7.4 says no, but 17.5.3 says yes
496                // Also, "Being in Idle state does not require the USB clocks to
497                //   be activated" (17.6.2)
498                enable_clock(Clock::HSB(HSBClock::USBC));
499                enable_clock(Clock::PBB(PBBClock::USBC));
500
501                // If we got to this state via disable() instead of chip reset,
502                // the values USBCON.FRZCLK, USBCON.UIMOD, UDCON.LS have *not* been
503                // reset to their default values.
504
505                if let Mode::Device { speed, .. } = mode {
506                    usbc_regs().udcon.modify(match speed {
507                        Speed::Full => DeviceControl::LS::FullSpeed,
508                        Speed::Low => DeviceControl::LS::LowSpeed,
509                    });
510                }
511
512                // Enable in device mode
513                usbc_regs().usbcon.modify(Control::UIMOD::DeviceMode);
514                usbc_regs().usbcon.modify(Control::FRZCLK::CLEAR);
515                usbc_regs().usbcon.modify(Control::USBE::SET);
516
517                // Set the pointer to the endpoint descriptors
518                usbc_regs()
519                    .udesc
520                    .set(core::ptr::addr_of!(self.descriptors) as u32);
521
522                // Clear pending device global interrupts
523                usbc_regs().udintclr.write(
524                    DeviceInterrupt::SUSP::SET
525                        + DeviceInterrupt::SOF::SET
526                        + DeviceInterrupt::EORST::SET
527                        + DeviceInterrupt::EORSM::SET
528                        + DeviceInterrupt::UPRSM::SET,
529                );
530
531                // Enable device global interrupts
532                // Note: SOF has been omitted as it is not presently used,
533                // Note: SUSP has been omitted as SUSPEND/WAKEUP is not yet
534                //   implemented.
535                // Note: SOF and SUSP may nevertheless be enabled here
536                //   without harm, but it makes debugging easier to omit them.
537                usbc_regs().udinteset.write(
538                    DeviceInterrupt::EORST::SET
539                        + DeviceInterrupt::EORSM::SET
540                        + DeviceInterrupt::UPRSM::SET,
541                );
542
543                debug1!("Enabled");
544
545                self.set_state(State::Idle(mode));
546            }
547            _ => internal_err!("Already enabled"),
548        }
549    }
550
551    /// Disable the controller, its interrupt, and its clocks
552    fn _disable(&self) {
553        // Detach if necessary
554        if let State::Active(_) = self.get_state() {
555            self.detach();
556        }
557
558        // Disable USBC and its clocks
559        match self.get_state() {
560            State::Idle(..) => {
561                usbc_regs().usbcon.modify(Control::USBE::CLEAR);
562
563                disable_clock(Clock::PBB(PBBClock::USBC));
564                disable_clock(Clock::HSB(HSBClock::USBC));
565
566                self.set_state(State::Reset);
567            }
568            _ => internal_err!("Disable called from wrong state"),
569        }
570    }
571
572    /// Attach to the USB bus after enabling USB bus clock
573    fn attach(&self) {
574        match self.get_state() {
575            State::Idle(mode) => {
576                if self.pm.get_system_frequency() != 48000000 {
577                    internal_err!("The system clock does not support USB");
578                }
579
580                // XX: not clear that this always results in a usable USB clock
581                scif::generic_clock_enable(scif::GenericClock::GCLK7, scif::ClockSource::CLK_HSB);
582
583                while !usbc_regs().usbsta.is_set(Status::CLKUSABLE) {}
584
585                usbc_regs().udcon.modify(DeviceControl::DETACH::CLEAR);
586
587                debug1!("Attached");
588
589                self.set_state(State::Active(mode));
590            }
591            _ => internal_err!("Attach called in wrong state"),
592        }
593    }
594
595    /// Detach from the USB bus.  Also disable USB bus clock to save energy.
596    fn detach(&self) {
597        if let State::Active(mode) = self.get_state() {
598            usbc_regs().udcon.modify(DeviceControl::DETACH::SET);
599
600            scif::generic_clock_disable(scif::GenericClock::GCLK7);
601
602            self.set_state(State::Idle(mode));
603        }
604    }
605
606    /// Configure and enable an endpoint
607    fn endpoint_enable(&self, endpoint: usize, endpoint_config: EndpointConfigValue) {
608        self.endpoint_record_config(endpoint, endpoint_config);
609        self.endpoint_write_config(endpoint, endpoint_config);
610
611        // Enable the endpoint (meaning the controller will respond to requests
612        // to this endpoint)
613        usbc_regs()
614            .uerst
615            .set(usbc_regs().uerst.get() | (1 << endpoint));
616
617        self.endpoint_init(endpoint, endpoint_config);
618
619        // Set EPnINTE, enabling interrupts for this endpoint
620        usbc_regs().udinteset.set(1 << (12 + endpoint));
621
622        debug1!("Enabled endpoint {}", endpoint);
623    }
624
625    fn endpoint_record_config(&self, endpoint: usize, endpoint_config: EndpointConfigValue) {
626        // Record config in case of later bus reset
627        self.map_state(|state| match *state {
628            State::Reset => {
629                client_err!("Not enabled");
630            }
631            State::Idle(Mode::Device { ref mut config, .. }) => {
632                // The endpoint will be active when we next attach
633                config.endpoint_configs[endpoint] = Some(endpoint_config);
634            }
635            State::Active(Mode::Device { ref mut config, .. }) => {
636                // The endpoint will be active immediately
637                config.endpoint_configs[endpoint] = Some(endpoint_config);
638            }
639            _ => client_err!("Not in Device mode"),
640        });
641    }
642
643    fn endpoint_write_config(&self, endpoint: usize, config: EndpointConfigValue) {
644        // This must be performed after each bus reset
645
646        // Configure the endpoint
647        usbc_regs().uecfg[endpoint].set(From::from(config));
648
649        debug1!("Configured endpoint {}", endpoint);
650    }
651
652    fn endpoint_init(&self, endpoint: usize, config: EndpointConfigValue) {
653        self.map_state(|state| match *state {
654            State::Idle(Mode::Device { ref mut state, .. }) => {
655                self.endpoint_init_with_device_state(state, endpoint, config);
656            }
657            State::Active(Mode::Device { ref mut state, .. }) => {
658                self.endpoint_init_with_device_state(state, endpoint, config);
659            }
660            _ => internal_err!("Not reached"),
661        });
662    }
663
664    fn endpoint_init_with_device_state(
665        &self,
666        state: &mut DeviceState,
667        endpoint: usize,
668        config: EndpointConfigValue,
669    ) {
670        // This must be performed after each bus reset (see 17.6.2.2)
671
672        endpoint_enable_interrupts(
673            endpoint,
674            EndpointControl::RAMACERE::SET + EndpointControl::STALLEDE::SET,
675        );
676
677        if config.matches_all(EndpointConfig::EPTYPE::Control) {
678            endpoint_enable_interrupts(endpoint, EndpointControl::RXSTPE::SET);
679            state.endpoint_states[endpoint] = EndpointState::Ctrl(CtrlState::Init);
680        } else if config.matches_all(EndpointConfig::EPTYPE::Bulk + EndpointConfig::EPDIR::In) {
681            endpoint_enable_interrupts(endpoint, EndpointControl::TXINE::SET);
682            state.endpoint_states[endpoint] = EndpointState::BulkIn(BulkInState::Init);
683        } else if config.matches_all(EndpointConfig::EPTYPE::Bulk + EndpointConfig::EPDIR::Out) {
684            endpoint_enable_interrupts(endpoint, EndpointControl::RXOUTE::SET);
685            state.endpoint_states[endpoint] = EndpointState::BulkOut(BulkOutState::Init);
686        } else {
687            // Other endpoint types unimplemented
688        }
689
690        debug1!("Initialized endpoint {}", endpoint);
691    }
692
693    fn endpoint_resume_in(&self, endpoint: usize) {
694        self.map_state(|state| match *state {
695            State::Active(Mode::Device { ref mut state, .. }) => {
696                let endpoint_state = &mut state.endpoint_states[endpoint];
697                match *endpoint_state {
698                    EndpointState::BulkIn(BulkInState::Delay) => {
699                        // Return to Init state
700                        endpoint_enable_interrupts(endpoint, EndpointControl::TXINE::SET);
701                        *endpoint_state = EndpointState::BulkIn(BulkInState::Init);
702                    }
703                    // XXX: Add support for EndpointState::Interrupt*
704                    _ => debugln!("Ignoring superfluous resume_in"),
705                }
706            }
707            _ => debugln!("Ignoring inappropriate resume_in"),
708        });
709    }
710
711    fn endpoint_resume_out(&self, endpoint: usize) {
712        self.map_state(|state| match *state {
713            State::Active(Mode::Device { ref mut state, .. }) => {
714                let endpoint_state = &mut state.endpoint_states[endpoint];
715                match *endpoint_state {
716                    EndpointState::BulkOut(BulkOutState::Delay) => {
717                        // Return to Init state
718                        endpoint_enable_interrupts(endpoint, EndpointControl::RXOUTE::SET);
719                        *endpoint_state = EndpointState::BulkOut(BulkOutState::Init);
720                    }
721                    // XXX: Add support for EndpointState::Interrupt*
722                    _ => debugln!("Ignoring superfluous resume_out"),
723                }
724            }
725            _ => debugln!("Ignoring inappropriate resume_out"),
726        });
727    }
728
729    fn handle_requests(&self) {
730        for endpoint in 0..N_ENDPOINTS {
731            let mut requests = self.requests[endpoint].get();
732
733            if requests.resume_in {
734                self.endpoint_resume_in(endpoint);
735                requests.resume_in = false;
736            }
737            if requests.resume_out {
738                self.endpoint_resume_out(endpoint);
739                requests.resume_out = false;
740            }
741
742            self.requests[endpoint].set(requests);
743        }
744    }
745
746    /// Handle an interrupt from the USBC
747    pub fn handle_interrupt(&self) {
748        self.map_state(|state| match *state {
749            State::Reset => internal_err!("Received interrupt in Reset"),
750            State::Idle(_) => {
751                // We might process WAKEUP here
752                debug1!("Received interrupt in Idle");
753            }
754            State::Active(ref mut mode) => match *mode {
755                Mode::Device {
756                    speed,
757                    ref config,
758                    ref mut state,
759                } => self.handle_device_interrupt(speed, config, state),
760                Mode::Host => internal_err!("Host mode unimplemented"),
761            },
762        });
763
764        // Client callbacks invoked above may have generated state-changing requests
765        self.handle_requests();
766    }
767
768    /// Handle an interrupt while in device mode
769    fn handle_device_interrupt(
770        &self,
771        speed: Speed,
772        device_config: &DeviceConfig,
773        device_state: &mut DeviceState,
774    ) {
775        let udint = usbc_regs().udint.extract();
776
777        debug1!("--> UDINT={:?}", UdintFlags(udint.get()));
778
779        if udint.is_set(DeviceInterrupt::EORST) {
780            // Bus reset
781            debug1!("USB Bus Reset");
782
783            // Reconfigure what has been reset in the USBC
784            usbc_regs().udcon.modify(match speed {
785                Speed::Full => DeviceControl::LS::FullSpeed,
786                Speed::Low => DeviceControl::LS::LowSpeed,
787            });
788
789            // Reset our record of the device state
790            *device_state = DeviceState::default();
791
792            // Reconfigure and initialize endpoints
793            for i in 0..N_ENDPOINTS {
794                if let Some(endpoint_config) = device_config.endpoint_configs[i] {
795                    self.endpoint_write_config(i, endpoint_config);
796                    self.endpoint_init_with_device_state(device_state, i, endpoint_config);
797                }
798            }
799
800            // Alert the client
801            self.client.map(|client| {
802                client.bus_reset();
803            });
804
805            // Acknowledge the interrupt
806            usbc_regs().udintclr.write(DeviceInterrupt::EORST::SET);
807
808            // Wait for the next interrupt before doing anything else
809            return;
810        }
811
812        if udint.is_set(DeviceInterrupt::SUSP) {
813            // The transceiver has been suspended due to the bus being idle for 3ms.
814            // This condition is over when WAKEUP is set.
815
816            // "To further reduce power consumption it is recommended to freeze the USB
817            // clock by writing a one to the Freeze USB Clock (FRZCLK) bit in USBCON when
818            // the USB bus is in suspend mode.
819            //
820            // To recover from the suspend mode, the user shall wait for the Wakeup
821            // (WAKEUP) interrupt bit, which is set when a non-idle event is detected, and
822            // then write a zero to FRZCLK.
823            //
824            // As the WAKEUP interrupt bit in UDINT is set when a non-idle event is
825            // detected, it can occur regardless of whether the controller is in the
826            // suspend mode or not."
827
828            // Subscribe to WAKEUP
829            usbc_regs().udinteset.write(DeviceInterrupt::WAKEUP::SET);
830
831            // Acknowledge the "suspend" event
832            usbc_regs().udintclr.write(DeviceInterrupt::SUSP::SET);
833        }
834
835        if udint.is_set(DeviceInterrupt::WAKEUP) {
836            // XX: If we were suspended: Unfreeze the clock (and unsleep the MCU)
837
838            // Unsubscribe from WAKEUP
839            usbc_regs().udinteclr.write(DeviceInterrupt::WAKEUP::SET);
840
841            // Acknowledge the interrupt
842            usbc_regs().udintclr.write(DeviceInterrupt::WAKEUP::SET);
843
844            // Continue processing, as WAKEUP is usually set
845        }
846
847        if udint.is_set(DeviceInterrupt::SOF) {
848            // Acknowledge Start of frame
849            usbc_regs().udintclr.write(DeviceInterrupt::SOF::SET);
850        }
851
852        if udint.is_set(DeviceInterrupt::EORSM) {
853            // Controller received End of Resume
854            debug1!("UDINT EORSM");
855        }
856
857        if udint.is_set(DeviceInterrupt::UPRSM) {
858            // Controller sent Upstream Resume
859            debug1!("UDINT UPRSM");
860        }
861
862        // Process per-endpoint interrupt flags
863        for endpoint in 0..N_ENDPOINTS {
864            if udint.get() & (1 << (12 + endpoint)) == 0 {
865                // No interrupts for this endpoint
866                continue;
867            }
868
869            self.handle_endpoint_interrupt(endpoint, &mut device_state.endpoint_states[endpoint]);
870        }
871    }
872
873    fn handle_endpoint_interrupt(&self, endpoint: usize, endpoint_state: &mut EndpointState) {
874        let status = usbc_regs().uesta[endpoint].extract();
875        debug1!("  UESTA{}={:?}", endpoint, UestaFlags(status.get()));
876
877        if status.is_set(EndpointStatus::STALLED) {
878            debug1!("\tep{}: STALLED/CRCERR", endpoint);
879
880            // Acknowledge
881            usbc_regs().uestaclr[endpoint].write(EndpointStatus::STALLED::SET);
882        }
883
884        if status.is_set(EndpointStatus::RAMACER) {
885            debug1!("\tep{}: RAMACER", endpoint);
886
887            // Acknowledge
888            usbc_regs().uestaclr[endpoint].write(EndpointStatus::RAMACER::SET);
889        }
890
891        match *endpoint_state {
892            EndpointState::Ctrl(ref mut ctrl_state) => {
893                self.handle_ctrl_endpoint_interrupt(endpoint, ctrl_state, status)
894            }
895            EndpointState::BulkIn(ref mut bulk_in_state) => {
896                self.handle_bulk_in_endpoint_interrupt(endpoint, bulk_in_state, status)
897            }
898            EndpointState::BulkOut(ref mut bulk_out_state) => {
899                self.handle_bulk_out_endpoint_interrupt(endpoint, bulk_out_state, status)
900            }
901            EndpointState::Disabled => {
902                debug1!("Ignoring interrupt for disabled endpoint {}", endpoint);
903            }
904        }
905    }
906
907    fn handle_ctrl_endpoint_interrupt(
908        &self,
909        endpoint: usize,
910        ctrl_state: &mut CtrlState,
911        status: EndpointStatusValue,
912    ) {
913        let mut again = true;
914        while again {
915            again = false;
916            // `again` may be set to true below when it would be
917            // advantageous to process more flags without waiting for
918            // another interrupt.
919
920            debug1!(
921                "  ep{}: Ctrl({:?})  UECON={:?}",
922                endpoint,
923                *ctrl_state,
924                UeconFlags(usbc_regs().uecon[endpoint].get())
925            );
926
927            match *ctrl_state {
928                CtrlState::Init => {
929                    if status.is_set(EndpointStatus::RXSTP) {
930                        // We received a SETUP transaction
931
932                        debug1!("\tep{}: RXSTP", endpoint);
933                        // self.debug_show_d0();
934
935                        let bank = 0;
936                        let packet_bytes = self.descriptors[endpoint][bank]
937                            .packet_size
938                            .read(PacketSize::BYTE_COUNT);
939                        let result = if packet_bytes == 8 {
940                            self.client.map(|c| c.ctrl_setup(endpoint))
941                        } else {
942                            Some(hil::usb::CtrlSetupResult::ErrBadLength)
943                        };
944
945                        match result {
946                            Some(hil::usb::CtrlSetupResult::Ok)
947                            | Some(hil::usb::CtrlSetupResult::OkSetAddress) => {
948                                // Unsubscribe from SETUP interrupts
949                                endpoint_disable_interrupts(endpoint, EndpointControl::RXSTPE::SET);
950
951                                if status.matches_all(EndpointStatus::CTRLDIR::In) {
952                                    // The following Data stage will be IN
953
954                                    // Wait until bank is clear to send (TXIN).
955                                    // Also wait for NAKOUT to signal end of IN
956                                    // stage (the datasheet incorrectly says
957                                    // NAKIN).
958                                    usbc_regs().uestaclr[endpoint]
959                                        .write(EndpointStatus::NAKOUT::SET);
960                                    endpoint_enable_interrupts(
961                                        endpoint,
962                                        EndpointControl::TXINE::SET + EndpointControl::NAKOUTE::SET,
963                                    );
964                                    *ctrl_state = CtrlState::ReadIn;
965                                } else {
966                                    // The following Data stage will be OUT
967
968                                    // Wait for OUT packets (RXOUT).  Also wait
969                                    // for NAKIN to signal end of OUT stage.
970                                    usbc_regs().uestaclr[endpoint]
971                                        .write(EndpointStatus::NAKIN::SET);
972                                    endpoint_enable_interrupts(
973                                        endpoint,
974                                        EndpointControl::RXOUTE::SET + EndpointControl::NAKINE::SET,
975                                    );
976                                    *ctrl_state = CtrlState::WriteOut;
977                                }
978                            }
979                            failure => {
980                                // Respond with STALL to any following
981                                // transactions in this request
982                                usbc_regs().ueconset[endpoint].write(EndpointControl::STALLRQ::SET);
983
984                                match failure {
985                                    None => debug1!("\tep{}: No client to handle Setup", endpoint),
986                                    Some(_err) => {
987                                        debug1!("\tep{}: Client err on Setup: {:?}", endpoint, _err)
988                                    }
989                                }
990
991                                // Remain in Init state for next SETUP
992                            }
993                        }
994
995                        // Acknowledge SETUP interrupt
996                        usbc_regs().uestaclr[endpoint].write(EndpointStatus::RXSTP::SET);
997                    }
998                }
999                CtrlState::ReadIn => {
1000                    // TODO: Handle Abort as described in 17.6.2.15
1001                    // (for Control and Isochronous only)
1002
1003                    if status.is_set(EndpointStatus::NAKOUT) {
1004                        // The host has completed the IN stage by sending an OUT token
1005
1006                        endpoint_disable_interrupts(
1007                            endpoint,
1008                            EndpointControl::TXINE::SET + EndpointControl::NAKOUTE::SET,
1009                        );
1010
1011                        debug1!("\tep{}: NAKOUT", endpoint);
1012                        self.client.map(|c| c.ctrl_status(endpoint));
1013
1014                        // Await end of Status stage
1015                        endpoint_enable_interrupts(endpoint, EndpointControl::RXOUTE::SET);
1016
1017                        // Acknowledge
1018                        usbc_regs().uestaclr[endpoint].write(EndpointStatus::NAKOUT::SET);
1019
1020                        *ctrl_state = CtrlState::ReadStatus;
1021
1022                        // Run handler again in case the RXOUT has already arrived
1023                        again = true;
1024                    } else if status.is_set(EndpointStatus::TXIN) {
1025                        // The data bank is ready to receive another IN payload
1026                        debug1!("\tep{}: TXIN", endpoint);
1027
1028                        let result = self.client.map(|c| {
1029                            // Allow client to write a packet payload to buffer
1030                            c.ctrl_in(endpoint)
1031                        });
1032                        match result {
1033                            Some(hil::usb::CtrlInResult::Packet(
1034                                packet_bytes,
1035                                transfer_complete,
1036                            )) => {
1037                                // Check if the entire buffer is full, and
1038                                // handle that case slightly differently. Note,
1039                                // this depends on the length of the buffer
1040                                // used. Right now, that is 64 bytes.
1041                                let packet_size = if packet_bytes == 64 && transfer_complete {
1042                                    // Send a complete final packet, and request
1043                                    // that the controller also send a zero-length
1044                                    // packet to signal the end of transfer
1045                                    PacketSize::BYTE_COUNT.val(64) + PacketSize::AUTO_ZLP::Yes
1046                                } else {
1047                                    // Send either a complete but not-final
1048                                    // packet, or a short and final packet (which
1049                                    // itself signals end of transfer)
1050                                    PacketSize::BYTE_COUNT.val(packet_bytes as u32)
1051                                };
1052                                let bank = 0;
1053                                self.descriptors[endpoint][bank]
1054                                    .packet_size
1055                                    .write(packet_size);
1056
1057                                debug1!(
1058                                    "\tep{}: Send CTRL IN packet ({} bytes)",
1059                                    endpoint,
1060                                    packet_bytes
1061                                );
1062                                // self.debug_show_d0();
1063
1064                                if transfer_complete {
1065                                    // IN data completely sent.  Unsubscribe from TXIN.
1066                                    // (Continue awaiting NAKOUT to indicate end of Data stage)
1067                                    endpoint_disable_interrupts(
1068                                        endpoint,
1069                                        EndpointControl::TXINE::SET,
1070                                    );
1071                                } else {
1072                                    // Continue waiting for next TXIN
1073                                }
1074
1075                                // Clear TXIN to signal to the controller that the IN payload is
1076                                // ready to send
1077                                usbc_regs().uestaclr[endpoint].write(EndpointStatus::TXIN::SET);
1078                            }
1079                            Some(hil::usb::CtrlInResult::Delay) => {
1080                                endpoint_disable_interrupts(endpoint, EndpointControl::TXINE::SET);
1081
1082                                debug1!("*** Client NAK");
1083
1084                                // XXX set busy bits?
1085
1086                                *ctrl_state = CtrlState::InDelay;
1087                            }
1088                            _ => {
1089                                // Respond with STALL to any following IN/OUT transactions
1090                                usbc_regs().ueconset[endpoint].write(EndpointControl::STALLRQ::SET);
1091
1092                                debug1!("\tep{}: Client IN err => STALL", endpoint);
1093
1094                                // Wait for next SETUP
1095                                endpoint_disable_interrupts(
1096                                    endpoint,
1097                                    EndpointControl::NAKOUTE::SET,
1098                                );
1099                                endpoint_enable_interrupts(endpoint, EndpointControl::RXSTPE::SET);
1100                                *ctrl_state = CtrlState::Init;
1101                            }
1102                        }
1103                    }
1104                }
1105                CtrlState::ReadStatus => {
1106                    if status.is_set(EndpointStatus::RXOUT) {
1107                        // Host has completed Status stage by sending an OUT packet
1108
1109                        debug1!("\tep{}: RXOUT: End of Control Read transaction", endpoint);
1110
1111                        // Wait for next SETUP
1112                        endpoint_disable_interrupts(endpoint, EndpointControl::RXOUTE::SET);
1113                        endpoint_enable_interrupts(endpoint, EndpointControl::RXSTPE::SET);
1114                        *ctrl_state = CtrlState::Init;
1115
1116                        // Acknowledge
1117                        usbc_regs().uestaclr[endpoint].write(EndpointStatus::RXOUT::SET);
1118
1119                        self.client.map(|c| c.ctrl_status_complete(endpoint));
1120                    }
1121                }
1122                CtrlState::WriteOut => {
1123                    if status.is_set(EndpointStatus::RXOUT) {
1124                        // Received data
1125
1126                        debug1!("\tep{}: RXOUT: Received Control Write data", endpoint);
1127                        // self.debug_show_d0();
1128
1129                        // Pass the data to the client and see how it reacts
1130                        let bank = 0;
1131                        let result = self.client.map(|c| {
1132                            c.ctrl_out(
1133                                endpoint,
1134                                self.descriptors[endpoint][bank]
1135                                    .packet_size
1136                                    .read(PacketSize::BYTE_COUNT),
1137                            )
1138                        });
1139                        match result {
1140                            Some(hil::usb::CtrlOutResult::Ok) => {
1141                                // Acknowledge
1142                                usbc_regs().uestaclr[endpoint].write(EndpointStatus::RXOUT::SET);
1143                            }
1144                            Some(hil::usb::CtrlOutResult::Delay) => {
1145                                // Don't acknowledge; hardware will have to send NAK
1146
1147                                // Unsubscribe from RXOUT until client says it is ready
1148                                // (But there is not yet any interface for that)
1149                                endpoint_disable_interrupts(endpoint, EndpointControl::RXOUTE::SET);
1150                            }
1151                            _ => {
1152                                // Respond with STALL to any following transactions
1153                                // in this request
1154                                usbc_regs().ueconset[endpoint].write(EndpointControl::STALLRQ::SET);
1155
1156                                debug1!("\tep{}: Client OUT err => STALL", endpoint);
1157
1158                                // Wait for next SETUP
1159                                endpoint_disable_interrupts(
1160                                    endpoint,
1161                                    EndpointControl::RXOUTE::SET + EndpointControl::NAKINE::SET,
1162                                );
1163                                endpoint_enable_interrupts(endpoint, EndpointControl::RXSTPE::SET);
1164                                *ctrl_state = CtrlState::Init;
1165                            }
1166                        }
1167                    }
1168                    if status.is_set(EndpointStatus::NAKIN) {
1169                        // The host has completed the Data stage by sending an IN token
1170                        debug1!("\tep{}: NAKIN: Control Write -> Status stage", endpoint);
1171
1172                        // Acknowledge
1173                        usbc_regs().uestaclr[endpoint].write(EndpointStatus::NAKIN::SET);
1174
1175                        // Wait for bank to be free so we can write ZLP to acknowledge transfer
1176                        endpoint_disable_interrupts(
1177                            endpoint,
1178                            EndpointControl::RXOUTE::SET + EndpointControl::NAKINE::SET,
1179                        );
1180                        endpoint_enable_interrupts(endpoint, EndpointControl::TXINE::SET);
1181                        *ctrl_state = CtrlState::WriteStatus;
1182
1183                        // Can probably send the ZLP immediately
1184                        again = true;
1185                    }
1186                }
1187                CtrlState::WriteStatus => {
1188                    if status.is_set(EndpointStatus::TXIN) {
1189                        debug1!(
1190                            "\tep{}: TXIN for Control Write Status (will send ZLP)",
1191                            endpoint
1192                        );
1193
1194                        self.client.map(|c| c.ctrl_status(endpoint));
1195
1196                        // Send zero-length packet to acknowledge transaction
1197                        let bank = 0;
1198                        self.descriptors[endpoint][bank]
1199                            .packet_size
1200                            .write(PacketSize::BYTE_COUNT.val(0));
1201
1202                        // Signal to the controller that the IN payload is ready to send
1203                        usbc_regs().uestaclr[endpoint].write(EndpointStatus::TXIN::SET);
1204
1205                        // Wait for TXIN again to confirm that IN payload has been sent
1206                        *ctrl_state = CtrlState::WriteStatusWait;
1207                    }
1208                }
1209                CtrlState::WriteStatusWait => {
1210                    if status.is_set(EndpointStatus::TXIN) {
1211                        debug1!("\tep{}: TXIN: Control Write Status Complete", endpoint);
1212
1213                        // Wait for next SETUP
1214                        endpoint_disable_interrupts(endpoint, EndpointControl::TXINE::SET);
1215                        endpoint_enable_interrupts(endpoint, EndpointControl::RXSTPE::SET);
1216                        *ctrl_state = CtrlState::Init;
1217
1218                        // for SetAddress, client must enable address after STATUS stage
1219                        self.client.map(|c| c.ctrl_status_complete(endpoint));
1220                    }
1221                }
1222                CtrlState::InDelay => internal_err!("Not reached"),
1223            }
1224
1225            // Uncomment the following line to run the above while loop only once per interrupt,
1226            // which can make debugging easier.
1227            //
1228            // again = false;
1229        }
1230    }
1231
1232    fn handle_bulk_out_endpoint_interrupt(
1233        &self,
1234        endpoint: usize,
1235        bulk_out_state: &mut BulkOutState,
1236        status: EndpointStatusValue,
1237    ) {
1238        match *bulk_out_state {
1239            BulkOutState::Init => {
1240                if status.is_set(EndpointStatus::RXOUT) {
1241                    // We got an OUT request from the host
1242
1243                    debug1!("\tep{}: RXOUT", endpoint);
1244
1245                    if !usbc_regs().uecon[endpoint].is_set(EndpointControl::FIFOCON) {
1246                        debugln!("Got RXOUT but not FIFOCON");
1247                        return;
1248                    }
1249                    // A bank is full of an OUT packet
1250
1251                    let bank = 0;
1252                    let packet_bytes = self.descriptors[endpoint][bank]
1253                        .packet_size
1254                        .read(PacketSize::BYTE_COUNT);
1255
1256                    let result = self.client.map(|c| {
1257                        // Allow client to consume the packet
1258                        c.packet_out(TransferType::Bulk, endpoint, packet_bytes)
1259                    });
1260                    match result {
1261                        Some(hil::usb::OutResult::Ok) => {
1262                            // Acknowledge
1263                            usbc_regs().uestaclr[endpoint].write(EndpointStatus::RXOUT::SET);
1264
1265                            // Clear FIFOCON to signal that the packet was consumed
1266                            usbc_regs().ueconclr[endpoint].write(EndpointControl::FIFOCON::SET);
1267
1268                            debug1!(
1269                                "\tep{}: Recv BULK OUT packet ({} bytes)",
1270                                endpoint,
1271                                packet_bytes
1272                            );
1273
1274                            // Remain in Init state
1275                        }
1276                        Some(hil::usb::OutResult::Delay) => {
1277                            // The client is not ready to consume data; wait for resume
1278
1279                            endpoint_disable_interrupts(endpoint, EndpointControl::RXOUTE::SET);
1280
1281                            *bulk_out_state = BulkOutState::Delay;
1282                        }
1283                        _ => {
1284                            debug1!("\tep{}: Client OUT err => STALL", endpoint);
1285
1286                            // Respond with STALL to any following IN/OUT transactions
1287                            usbc_regs().ueconset[endpoint].write(EndpointControl::STALLRQ::SET);
1288
1289                            // XXX: interrupts?
1290
1291                            // Remain in Init state?
1292                        }
1293                    }
1294                }
1295            }
1296            BulkOutState::Delay => internal_err!("Not reached"),
1297        }
1298    }
1299
1300    fn handle_bulk_in_endpoint_interrupt(
1301        &self,
1302        endpoint: usize,
1303        bulk_in_state: &mut BulkInState,
1304        status: EndpointStatusValue,
1305    ) {
1306        match *bulk_in_state {
1307            BulkInState::Init => {
1308                if status.is_set(EndpointStatus::TXIN) {
1309                    // We got an IN request from the host
1310
1311                    debug1!("\tep{}: TXIN", endpoint);
1312
1313                    if !usbc_regs().uecon[endpoint].is_set(EndpointControl::FIFOCON) {
1314                        debugln!("Got TXIN but not FIFOCON");
1315                        return;
1316                    }
1317                    // A bank is free to write an IN packet
1318
1319                    let result = self.client.map(|c| {
1320                        // Allow client to write a packet payload to the buffer
1321                        c.packet_in(TransferType::Bulk, endpoint)
1322                    });
1323                    match result {
1324                        Some(hil::usb::InResult::Packet(packet_bytes)) => {
1325                            // Acknowledge
1326                            usbc_regs().uestaclr[endpoint].write(EndpointStatus::TXIN::SET);
1327
1328                            // Tell the controller the size of the packet
1329                            let bank = 0;
1330                            self.descriptors[endpoint][bank]
1331                                .packet_size
1332                                .write(PacketSize::BYTE_COUNT.val(packet_bytes as u32));
1333
1334                            // Clear FIFOCON to signal data ready to send
1335                            usbc_regs().ueconclr[endpoint].write(EndpointControl::FIFOCON::SET);
1336
1337                            debug1!(
1338                                "\tep{}: Send BULK IN packet ({} bytes)",
1339                                endpoint,
1340                                packet_bytes
1341                            );
1342
1343                            // Remain in Init state
1344                        }
1345                        Some(hil::usb::InResult::Delay) => {
1346                            // The client is not ready to send data; wait for resume
1347
1348                            endpoint_disable_interrupts(endpoint, EndpointControl::TXINE::SET);
1349
1350                            *bulk_in_state = BulkInState::Delay;
1351                        }
1352                        _ => {
1353                            debug1!("\tep{}: Client IN err => STALL", endpoint);
1354
1355                            // Respond with STALL to any following IN/OUT transactions
1356                            usbc_regs().ueconset[endpoint].write(EndpointControl::STALLRQ::SET);
1357
1358                            // XXX: interrupts?
1359
1360                            // Remain in Init state?
1361                        }
1362                    }
1363                }
1364            }
1365            BulkInState::Delay => {
1366                // Endpoint interrupts should be handled already or disabled
1367                internal_err!("Not reached");
1368            }
1369        }
1370    }
1371
1372    #[allow(dead_code)]
1373    fn debug_show_d0(&self) {
1374        for bi in 0..1 {
1375            let b = &self.descriptors[0][bi];
1376            let addr = b.addr.get() as *const u8;
1377            let _buf = if addr.is_null() {
1378                None
1379            } else {
1380                unsafe {
1381                    Some(slice::from_raw_parts(
1382                        addr,
1383                        b.packet_size.read(PacketSize::BYTE_COUNT) as usize,
1384                    ))
1385                }
1386            };
1387
1388            debug1!(
1389                "B_0_{} \
1390                 \n     {:?}\
1391                 \n     {:?}\
1392                 \n     {:?}",
1393                bi, // core::ptr::addr_of!(b.addr), b.addr.get(),
1394                b.packet_size.get(),
1395                b.control_status.get(),
1396                _buf.map(HexBuf)
1397            );
1398        }
1399    }
1400
1401    pub fn mode(&self) -> Option<Mode> {
1402        match self.get_state() {
1403            State::Idle(mode) => Some(mode),
1404            State::Active(mode) => Some(mode),
1405            _ => None,
1406        }
1407    }
1408
1409    pub fn speed(&self) -> Option<Speed> {
1410        match self.mode() {
1411            Some(mode) => {
1412                match mode {
1413                    Mode::Device { speed, .. } => Some(speed),
1414                    Mode::Host => {
1415                        None // XX USBSTA.SPEED
1416                    }
1417                }
1418            }
1419            _ => None,
1420        }
1421    }
1422
1423    // TODO: Remote wakeup (Device -> Host, after receiving DEVICE_REMOTE_WAKEUP)
1424}
1425
1426#[inline]
1427fn endpoint_disable_interrupts(endpoint: usize, mask: FieldValue<u32, EndpointControl::Register>) {
1428    usbc_regs().ueconclr[endpoint].write(mask);
1429}
1430
1431#[inline]
1432fn endpoint_enable_interrupts(endpoint: usize, mask: FieldValue<u32, EndpointControl::Register>) {
1433    usbc_regs().ueconset[endpoint].write(mask);
1434}
1435
1436impl<'a> hil::usb::UsbController<'a> for Usbc<'a> {
1437    fn set_client(&self, client: &'a dyn hil::usb::Client<'a>) {
1438        self.client.set(client);
1439    }
1440
1441    fn endpoint_set_ctrl_buffer(&self, buf: &'a [InMemoryRegister<u8>]) {
1442        if buf.len() < 8 {
1443            client_err!("Bad endpoint buffer size");
1444        }
1445
1446        self.endpoint_bank_set_buffer(EndpointIndex::new(0), BankIndex::Bank0, buf);
1447    }
1448
1449    fn endpoint_set_in_buffer(&self, endpoint: usize, buf: &'a [InMemoryRegister<u8>]) {
1450        if buf.len() < 8 {
1451            client_err!("Bad endpoint buffer size");
1452        }
1453
1454        self.endpoint_bank_set_buffer(EndpointIndex::new(endpoint), BankIndex::Bank0, buf);
1455    }
1456
1457    fn endpoint_set_out_buffer(&self, endpoint: usize, buf: &'a [InMemoryRegister<u8>]) {
1458        if buf.len() < 8 {
1459            client_err!("Bad endpoint buffer size");
1460        }
1461
1462        // XXX: when implementing in_out endpoints, this should probably set a different slice than endpoint_set_in_buffer.
1463        self.endpoint_bank_set_buffer(EndpointIndex::new(endpoint), BankIndex::Bank0, buf);
1464    }
1465
1466    fn enable_as_device(&self, speed: hil::usb::DeviceSpeed) {
1467        let speed = match speed {
1468            hil::usb::DeviceSpeed::Full => Speed::Full,
1469            hil::usb::DeviceSpeed::Low => Speed::Low,
1470        };
1471
1472        match self.get_state() {
1473            State::Reset => self.enable(Mode::Device {
1474                speed,
1475                config: DeviceConfig::default(),
1476                state: DeviceState::default(),
1477            }),
1478            _ => client_err!("Already enabled"),
1479        }
1480    }
1481
1482    fn attach(&self) {
1483        match self.get_state() {
1484            State::Reset => client_warn!("Not enabled"),
1485            State::Active(_) => client_warn!("Already attached"),
1486            State::Idle(_) => self.attach(),
1487        }
1488    }
1489
1490    fn detach(&self) {
1491        match self.get_state() {
1492            State::Reset => client_warn!("Not enabled"),
1493            State::Idle(_) => client_warn!("Not attached"),
1494            State::Active(_) => self.detach(),
1495        }
1496    }
1497
1498    fn set_address(&self, addr: u16) {
1499        usbc_regs()
1500            .udcon
1501            .modify(DeviceControl::UADD.val(addr as u32));
1502
1503        debug1!("Set Address = {}", addr);
1504    }
1505
1506    fn enable_address(&self) {
1507        usbc_regs().udcon.modify(DeviceControl::ADDEN::SET);
1508
1509        debug1!(
1510            "Enable Address = {}",
1511            usbc_regs().udcon.read(DeviceControl::UADD)
1512        );
1513    }
1514
1515    fn endpoint_in_enable(&self, transfer_type: TransferType, endpoint: usize) {
1516        let endpoint_cfg = match transfer_type {
1517            TransferType::Control => {
1518                panic!("There is no IN control endpoint");
1519            }
1520            TransferType::Bulk => LocalRegisterCopy::new(From::from(
1521                EndpointConfig::EPTYPE::Bulk
1522                    + EndpointConfig::EPDIR::In
1523                    + EndpointConfig::EPSIZE::Bytes8
1524                    + EndpointConfig::EPBK::Single,
1525            )),
1526            TransferType::Interrupt | TransferType::Isochronous => unimplemented!(),
1527        };
1528
1529        self.endpoint_enable(endpoint, endpoint_cfg)
1530    }
1531
1532    fn endpoint_out_enable(&self, transfer_type: TransferType, endpoint: usize) {
1533        let endpoint_cfg = match transfer_type {
1534            TransferType::Control => LocalRegisterCopy::new(From::from(
1535                EndpointConfig::EPTYPE::Control
1536                    + EndpointConfig::EPDIR::Out
1537                    + EndpointConfig::EPSIZE::Bytes8
1538                    + EndpointConfig::EPBK::Single,
1539            )),
1540            TransferType::Bulk => LocalRegisterCopy::new(From::from(
1541                EndpointConfig::EPTYPE::Bulk
1542                    + EndpointConfig::EPDIR::Out
1543                    + EndpointConfig::EPSIZE::Bytes8
1544                    + EndpointConfig::EPBK::Single,
1545            )),
1546            TransferType::Interrupt | TransferType::Isochronous => unimplemented!(),
1547        };
1548
1549        self.endpoint_enable(endpoint, endpoint_cfg)
1550    }
1551
1552    fn endpoint_in_out_enable(&self, _transfer_type: TransferType, _endpoint: usize) {
1553        unimplemented!()
1554    }
1555
1556    fn endpoint_resume_in(&self, endpoint: usize) {
1557        let mut requests = self.requests[endpoint].get();
1558        requests.resume_in = true;
1559        self.requests[endpoint].set(requests);
1560
1561        // Immediately handle the request to resume the endpoint.
1562        self.handle_requests();
1563    }
1564
1565    fn endpoint_resume_out(&self, endpoint: usize) {
1566        let mut requests = self.requests[endpoint].get();
1567        requests.resume_out = true;
1568        self.requests[endpoint].set(requests);
1569
1570        // Immediately handle the request to resume the endpoint.
1571        self.handle_requests();
1572    }
1573}