1pub mod debug;
8
9#[allow(unused_imports)]
10use self::debug::{HexBuf, UdintFlags, UeconFlags, UestaFlags};
11use crate::pm;
12use crate::pm::{disable_clock, enable_clock, Clock, HSBClock, PBBClock};
13use crate::scif;
14use core::cell::Cell;
15use core::ptr;
16use core::slice;
17use kernel::debug as debugln;
18use kernel::hil;
19use kernel::hil::usb::TransferType;
20use kernel::utilities::cells::{OptionalCell, VolatileCell};
21use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable};
22use kernel::utilities::registers::{
23    register_bitfields, FieldValue, InMemoryRegister, LocalRegisterCopy, ReadOnly, ReadWrite,
24    WriteOnly,
25};
26use kernel::utilities::StaticRef;
27
28macro_rules! client_warn {
33    [ $( $arg:expr ),+ ] => {
34        debugln!($( $arg ),+)
35    };
36}
37
38macro_rules! client_err {
39    [ $( $arg:expr ),+ ] => {
40        panic!($( $arg ),+)
41    };
42}
43
44macro_rules! debug1 {
45    [ $( $arg:expr ),+ ] => {
46        {} };
48}
49
50macro_rules! internal_err {
51    [ $( $arg:expr ),+ ] => {
52        panic!($( $arg ),+)
53    };
54}
55
56#[repr(C)]
57struct UsbcRegisters {
58    udcon: ReadWrite<u32, DeviceControl::Register>,
59    udint: ReadOnly<u32, DeviceInterrupt::Register>,
60    udintclr: WriteOnly<u32, DeviceInterrupt::Register>,
61    udintset: WriteOnly<u32, DeviceInterrupt::Register>,
62    udinte: ReadOnly<u32, DeviceInterrupt::Register>,
63    udinteclr: WriteOnly<u32, DeviceInterrupt::Register>,
64    udinteset: WriteOnly<u32, DeviceInterrupt::Register>,
65    uerst: ReadWrite<u32>,
66    udfnum: ReadOnly<u32>,
67    _reserved0: [u8; 0xdc], uecfg: [ReadWrite<u32, EndpointConfig::Register>; 12],
72    uesta: [ReadOnly<u32, EndpointStatus::Register>; 12],
73    uestaclr: [WriteOnly<u32, EndpointStatus::Register>; 12],
74    uestaset: [WriteOnly<u32, EndpointStatus::Register>; 12],
75    uecon: [ReadOnly<u32, EndpointControl::Register>; 12],
76    ueconset: [WriteOnly<u32, EndpointControl::Register>; 12],
77    ueconclr: [WriteOnly<u32, EndpointControl::Register>; 12],
78    _reserved1: [u8; 0x1b0], uhcon: ReadWrite<u32>,
81    uhint: ReadOnly<u32>,
82    uhintclr: WriteOnly<u32>,
83    uhintset: WriteOnly<u32>,
84    uhinte: ReadOnly<u32>,
85    uhinteclr: WriteOnly<u32>,
86    uhinteset: WriteOnly<u32>,
87    uprst: ReadWrite<u32>,
88    uhfnum: ReadWrite<u32>,
89    uhsofc: ReadWrite<u32>,
90    _reserved2: [u8; 0xd8], upcfg: [ReadWrite<u32>; 12],
93    upsta: [ReadOnly<u32>; 12],
94    upstaclr: [WriteOnly<u32>; 12],
95    upstaset: [WriteOnly<u32>; 12],
96    upcon: [ReadOnly<u32>; 12],
97    upconset: [WriteOnly<u32>; 12],
98    upconclr: [WriteOnly<u32>; 12],
99    upinrq: [ReadWrite<u32>; 12],
100    _reserved3: [u8; 0x180], usbcon: ReadWrite<u32, Control::Register>,
103    usbsta: ReadOnly<u32, Status::Register>,
104    usbstaclr: WriteOnly<u32>,
105    usbstaset: WriteOnly<u32>,
106    _reserved4: [u8; 8],
107    uvers: ReadOnly<u32>,
109    ufeatures: ReadOnly<u32>,
110    uaddrsize: ReadOnly<u32>,
111    uname1: ReadOnly<u32>,
112    uname2: ReadOnly<u32>,
113    usbfsm: ReadOnly<u32>,
114    udesc: ReadWrite<u32>,
115}
116
117register_bitfields![u32,
118    Control [
119        UIMOD OFFSET(25) NUMBITS(1) [
120            HostMode = 0,
121            DeviceMode = 1
122        ],
123        USBE OFFSET(15) NUMBITS(1) [],
124        FRZCLK OFFSET(14) NUMBITS(1) []
125    ],
126    Status [
127        SUSPEND OFFSET(16) NUMBITS(1) [],
128        CLKUSABLE OFFSET(14) NUMBITS(1) [],
129        SPEED OFFSET(12) NUMBITS(2) [
130            SpeedFull = 0b00,
131            SpeedLow = 0b10
132        ],
133        VBUSRQ OFFSET(9) NUMBITS(1) []
134    ],
135    DeviceControl [
136        GNAK OFFSET(17) NUMBITS(1) [],
137        LS OFFSET(12) NUMBITS(1) [
138            FullSpeed = 0,
139            LowSpeed = 1
140        ],
141        RMWKUP OFFSET(9) NUMBITS(1) [],
142        DETACH OFFSET(8) NUMBITS(1) [],
143        ADDEN OFFSET(7) NUMBITS(1) [],
144        UADD OFFSET(0) NUMBITS(7) []
145    ],
146    DeviceInterrupt [
147        EPINT OFFSET(12) NUMBITS(8),
148        UPRSM OFFSET(6) NUMBITS(1),
149        EORSM OFFSET(5) NUMBITS(1),
150        WAKEUP OFFSET(4) NUMBITS(1),
151        EORST OFFSET(3) NUMBITS(1),
152        SOF OFFSET(2) NUMBITS(1),
153        SUSP OFFSET(0) NUMBITS(1)
154    ],
155    EndpointConfig [
156        REPNB OFFSET(16) NUMBITS(4) [
157            NotRedirected = 0
158        ],
159        EPTYPE OFFSET(11) NUMBITS(2) [
160            Control = 0,
161            Isochronous = 1,
162            Bulk = 2,
163            Interrupt = 3
164        ],
165        EPDIR OFFSET(8) NUMBITS(1) [
166            Out = 0,
167            In = 1
168        ],
169        EPSIZE OFFSET(4) NUMBITS(3) [
170            Bytes8 = 0,
171            Bytes16 = 1,
172            Bytes32 = 2,
173            Bytes64 = 3,
174            Bytes128 = 4,
175            Bytes256 = 5,
176            Bytes512 = 6,
177            Bytes1024 = 7
178        ],
179        EPBK OFFSET(2) NUMBITS(1) [
180            Single = 0,
181            Double = 1
182        ]
183    ],
184    EndpointStatus [
185        CTRLDIR OFFSET(17) NUMBITS(1) [
186            Out = 0,
187            In = 1
188        ],
189        CURRBK OFFSET(14) NUMBITS(2) [
190            Bank0 = 0,
191            Bank1 = 1
192        ],
193        NBUSYBK OFFSET(12) NUMBITS(2) [],
194        RAMACER OFFSET(11) NUMBITS(1) [],
195        DTSEQ OFFSET(8) NUMBITS(2) [
196            Data0 = 0,
197            Data1 = 1
198        ],
199        STALLED OFFSET(6) NUMBITS(1) [],
200        CRCERR OFFSET(6) NUMBITS(1) [],
201        NAKIN OFFSET(4) NUMBITS(1) [],
202        NAKOUT OFFSET(3) NUMBITS(1) [],
203        ERRORF OFFSET(2) NUMBITS(1) [],
204        RXSTP OFFSET(2) NUMBITS(1) [],
205        RXOUT OFFSET(1) NUMBITS(1) [],
206        TXIN OFFSET(0) NUMBITS(1) []
207    ],
208    EndpointControl [
209        BUSY1E 25,
210        BUSY0E 24,
211        STALLRQ 19,
212        RSTDT 18,
213        FIFOCON 14,
214        KILLBK 13,
215        NBUSYBKE 12,
216        RAMACERE 11,
217        NREPLY 8,
218        STALLEDE 6,
219        CRCERRE 6,
220        NAKINE 4,
221        NAKOUTE 3,
222        RXSTPE 2,
223        ERRORFE 2,
224        RXOUTE 1,
225        TXINE 0
226    ]
227];
228
229const USBC_BASE: StaticRef<UsbcRegisters> =
230    unsafe { StaticRef::new(0x400A5000 as *const UsbcRegisters) };
231
232#[inline]
233fn usbc_regs() -> &'static UsbcRegisters {
234    &USBC_BASE
235}
236
237pub const N_ENDPOINTS: usize = 8;
240
241#[repr(C)]
243#[repr(align(8))]
245pub struct Usbc<'a> {
246    descriptors: [Endpoint; N_ENDPOINTS],
247    state: OptionalCell<State>,
248    requests: [Cell<Requests>; N_ENDPOINTS],
249    client: OptionalCell<&'a dyn hil::usb::Client<'a>>,
250    pm: &'a pm::PowerManager,
251}
252
253#[derive(Copy, Clone, Default, Debug)]
254pub struct Requests {
255    pub resume_in: bool,
256    pub resume_out: bool,
257}
258
259impl Requests {
260    pub const fn new() -> Self {
261        Requests {
262            resume_in: false,
263            resume_out: false,
264        }
265    }
266}
267
268#[derive(Copy, Clone, Debug)]
269pub enum State {
270    Reset,
272
273    Idle(Mode),
277
278    Active(Mode),
280}
281
282#[derive(Copy, Clone, Debug)]
283pub enum Mode {
284    Host,
285    Device {
286        speed: Speed,
287        config: DeviceConfig,
288        state: DeviceState,
289    },
290}
291
292type EndpointConfigValue = LocalRegisterCopy<u32, EndpointConfig::Register>;
293type EndpointStatusValue = LocalRegisterCopy<u32, EndpointStatus::Register>;
294
295#[derive(Copy, Clone, Debug, Default)]
296pub struct DeviceConfig {
297    pub endpoint_configs: [Option<EndpointConfigValue>; N_ENDPOINTS],
298}
299
300#[derive(Copy, Clone, Debug, Default)]
301pub struct DeviceState {
302    pub endpoint_states: [EndpointState; N_ENDPOINTS],
303}
304
305#[derive(Copy, Clone, Debug, Default)]
306pub enum EndpointState {
307    #[default]
308    Disabled,
309    Ctrl(CtrlState),
310    BulkIn(BulkInState),
311    BulkOut(BulkOutState),
312}
313
314#[derive(Copy, Clone, PartialEq, Debug)]
315pub enum CtrlState {
316    Init,
317    ReadIn,
318    ReadStatus,
319    WriteOut,
320    WriteStatus,
321    WriteStatusWait,
322    InDelay,
323}
324
325#[derive(Copy, Clone, PartialEq, Debug)]
326pub enum BulkInState {
327    Init,
328    Delay,
329}
330
331#[derive(Copy, Clone, PartialEq, Debug)]
332pub enum BulkOutState {
333    Init,
334    Delay,
335}
336
337#[derive(Copy, Clone, PartialEq, Debug)]
338pub enum Speed {
339    Full,
340    Low,
341}
342
343pub enum BankIndex {
344    Bank0,
345    Bank1,
346}
347
348impl From<BankIndex> for usize {
349    fn from(bi: BankIndex) -> usize {
350        match bi {
351            BankIndex::Bank0 => 0,
352            BankIndex::Bank1 => 1,
353        }
354    }
355}
356
357pub struct EndpointIndex(u8);
358
359impl EndpointIndex {
360    pub fn new(index: usize) -> EndpointIndex {
361        EndpointIndex(index as u8 & 0xf)
362    }
363
364    pub fn to_u32(self) -> u32 {
365        self.0 as u32
366    }
367}
368
369impl From<EndpointIndex> for usize {
370    fn from(ei: EndpointIndex) -> usize {
371        ei.0 as usize
372    }
373}
374
375pub type Endpoint = [Bank; 2];
376
377pub const fn new_endpoint() -> Endpoint {
378    [Bank::new(), Bank::new()]
379}
380
381#[repr(C)]
382pub struct Bank {
383    addr: VolatileCell<*mut u8>,
384
385    pub packet_size: InMemoryRegister<u32, PacketSize::Register>,
390    pub control_status: InMemoryRegister<u32, ControlStatus::Register>,
391
392    _reserved: u32,
393}
394
395impl Bank {
396    pub const fn new() -> Bank {
397        Bank {
398            addr: VolatileCell::new(ptr::null_mut()),
399            packet_size: InMemoryRegister::new(0),
400            control_status: InMemoryRegister::new(0),
401            _reserved: 0,
402        }
403    }
404
405    pub fn set_addr(&self, addr: *mut u8) {
406        self.addr.set(addr);
407    }
408}
409
410register_bitfields![u32,
411    PacketSize [
412        AUTO_ZLP OFFSET(31) NUMBITS(1) [
413            No = 0,
414            Yes = 1
415        ],
416        MULTI_PACKET_SIZE OFFSET(16) NUMBITS(15) [],
417        BYTE_COUNT OFFSET(0) NUMBITS(15) []
418    ],
419    ControlStatus [
420        UNDERF 18,
421        OVERF 17,
422        CRCERR 16,
423        STALLRQ_NEXT 0
424    ]
425];
426
427impl<'a> Usbc<'a> {
428    pub const fn new(pm: &'a pm::PowerManager) -> Self {
429        Usbc {
430            client: OptionalCell::empty(),
431            state: OptionalCell::new(State::Reset),
432            descriptors: [
433                new_endpoint(),
434                new_endpoint(),
435                new_endpoint(),
436                new_endpoint(),
437                new_endpoint(),
438                new_endpoint(),
439                new_endpoint(),
440                new_endpoint(),
441            ],
442            requests: [
443                Cell::new(Requests::new()),
444                Cell::new(Requests::new()),
445                Cell::new(Requests::new()),
446                Cell::new(Requests::new()),
447                Cell::new(Requests::new()),
448                Cell::new(Requests::new()),
449                Cell::new(Requests::new()),
450                Cell::new(Requests::new()),
451            ],
452            pm,
453        }
454    }
455
456    fn map_state<F, R>(&self, closure: F) -> R
457    where
458        F: FnOnce(&mut State) -> R,
459    {
460        let mut state = self.state.take().unwrap(); let result = closure(&mut state);
462        self.state.set(state);
463        result
464    }
465
466    fn get_state(&self) -> State {
467        self.state.unwrap_or_panic() }
469
470    fn set_state(&self, state: State) {
471        self.state.set(state);
472    }
473
474    fn endpoint_bank_set_buffer(
477        &self,
478        endpoint: EndpointIndex,
479        bank: BankIndex,
480        buf: &[VolatileCell<u8>],
481    ) {
482        let e: usize = From::from(endpoint);
483        let b: usize = From::from(bank);
484        let p = buf.as_ptr() as *const u8 as *mut u8;
485
486        debug1!("Set Endpoint{}/Bank{} addr={:8?}", e, b, p);
487        self.descriptors[e][b].set_addr(p);
488        self.descriptors[e][b].packet_size.write(
489            PacketSize::BYTE_COUNT.val(0)
490                + PacketSize::MULTI_PACKET_SIZE.val(0)
491                + PacketSize::AUTO_ZLP::No,
492        );
493    }
494
495    fn enable(&self, mode: Mode) {
497        match self.get_state() {
498            State::Reset => {
499                enable_clock(Clock::HSB(HSBClock::USBC));
504                enable_clock(Clock::PBB(PBBClock::USBC));
505
506                if let Mode::Device { speed, .. } = mode {
511                    usbc_regs().udcon.modify(match speed {
512                        Speed::Full => DeviceControl::LS::FullSpeed,
513                        Speed::Low => DeviceControl::LS::LowSpeed,
514                    });
515                }
516
517                usbc_regs().usbcon.modify(Control::UIMOD::DeviceMode);
519                usbc_regs().usbcon.modify(Control::FRZCLK::CLEAR);
520                usbc_regs().usbcon.modify(Control::USBE::SET);
521
522                usbc_regs()
524                    .udesc
525                    .set(core::ptr::addr_of!(self.descriptors) as u32);
526
527                usbc_regs().udintclr.write(
529                    DeviceInterrupt::SUSP::SET
530                        + DeviceInterrupt::SOF::SET
531                        + DeviceInterrupt::EORST::SET
532                        + DeviceInterrupt::EORSM::SET
533                        + DeviceInterrupt::UPRSM::SET,
534                );
535
536                usbc_regs().udinteset.write(
543                    DeviceInterrupt::EORST::SET
544                        + DeviceInterrupt::EORSM::SET
545                        + DeviceInterrupt::UPRSM::SET,
546                );
547
548                debug1!("Enabled");
549
550                self.set_state(State::Idle(mode));
551            }
552            _ => internal_err!("Already enabled"),
553        }
554    }
555
556    fn _disable(&self) {
558        if let State::Active(_) = self.get_state() {
560            self.detach();
561        }
562
563        match self.get_state() {
565            State::Idle(..) => {
566                usbc_regs().usbcon.modify(Control::USBE::CLEAR);
567
568                disable_clock(Clock::PBB(PBBClock::USBC));
569                disable_clock(Clock::HSB(HSBClock::USBC));
570
571                self.set_state(State::Reset);
572            }
573            _ => internal_err!("Disable called from wrong state"),
574        }
575    }
576
577    fn attach(&self) {
579        match self.get_state() {
580            State::Idle(mode) => {
581                if self.pm.get_system_frequency() != 48000000 {
582                    internal_err!("The system clock does not support USB");
583                }
584
585                scif::generic_clock_enable(scif::GenericClock::GCLK7, scif::ClockSource::CLK_HSB);
587
588                while !usbc_regs().usbsta.is_set(Status::CLKUSABLE) {}
589
590                usbc_regs().udcon.modify(DeviceControl::DETACH::CLEAR);
591
592                debug1!("Attached");
593
594                self.set_state(State::Active(mode));
595            }
596            _ => internal_err!("Attach called in wrong state"),
597        }
598    }
599
600    fn detach(&self) {
602        if let State::Active(mode) = self.get_state() {
603            usbc_regs().udcon.modify(DeviceControl::DETACH::SET);
604
605            scif::generic_clock_disable(scif::GenericClock::GCLK7);
606
607            self.set_state(State::Idle(mode));
608        }
609    }
610
611    fn endpoint_enable(&self, endpoint: usize, endpoint_config: EndpointConfigValue) {
613        self.endpoint_record_config(endpoint, endpoint_config);
614        self.endpoint_write_config(endpoint, endpoint_config);
615
616        usbc_regs()
619            .uerst
620            .set(usbc_regs().uerst.get() | (1 << endpoint));
621
622        self.endpoint_init(endpoint, endpoint_config);
623
624        usbc_regs().udinteset.set(1 << (12 + endpoint));
626
627        debug1!("Enabled endpoint {}", endpoint);
628    }
629
630    fn endpoint_record_config(&self, endpoint: usize, endpoint_config: EndpointConfigValue) {
631        self.map_state(|state| match *state {
633            State::Reset => {
634                client_err!("Not enabled");
635            }
636            State::Idle(Mode::Device { ref mut config, .. }) => {
637                config.endpoint_configs[endpoint] = Some(endpoint_config);
639            }
640            State::Active(Mode::Device { ref mut config, .. }) => {
641                config.endpoint_configs[endpoint] = Some(endpoint_config);
643            }
644            _ => client_err!("Not in Device mode"),
645        });
646    }
647
648    fn endpoint_write_config(&self, endpoint: usize, config: EndpointConfigValue) {
649        usbc_regs().uecfg[endpoint].set(From::from(config));
653
654        debug1!("Configured endpoint {}", endpoint);
655    }
656
657    fn endpoint_init(&self, endpoint: usize, config: EndpointConfigValue) {
658        self.map_state(|state| match *state {
659            State::Idle(Mode::Device { ref mut state, .. }) => {
660                self.endpoint_init_with_device_state(state, endpoint, config);
661            }
662            State::Active(Mode::Device { ref mut state, .. }) => {
663                self.endpoint_init_with_device_state(state, endpoint, config);
664            }
665            _ => internal_err!("Not reached"),
666        });
667    }
668
669    fn endpoint_init_with_device_state(
670        &self,
671        state: &mut DeviceState,
672        endpoint: usize,
673        config: EndpointConfigValue,
674    ) {
675        endpoint_enable_interrupts(
678            endpoint,
679            EndpointControl::RAMACERE::SET + EndpointControl::STALLEDE::SET,
680        );
681
682        if config.matches_all(EndpointConfig::EPTYPE::Control) {
683            endpoint_enable_interrupts(endpoint, EndpointControl::RXSTPE::SET);
684            state.endpoint_states[endpoint] = EndpointState::Ctrl(CtrlState::Init);
685        } else if config.matches_all(EndpointConfig::EPTYPE::Bulk + EndpointConfig::EPDIR::In) {
686            endpoint_enable_interrupts(endpoint, EndpointControl::TXINE::SET);
687            state.endpoint_states[endpoint] = EndpointState::BulkIn(BulkInState::Init);
688        } else if config.matches_all(EndpointConfig::EPTYPE::Bulk + EndpointConfig::EPDIR::Out) {
689            endpoint_enable_interrupts(endpoint, EndpointControl::RXOUTE::SET);
690            state.endpoint_states[endpoint] = EndpointState::BulkOut(BulkOutState::Init);
691        } else {
692            }
694
695        debug1!("Initialized endpoint {}", endpoint);
696    }
697
698    fn endpoint_resume_in(&self, endpoint: usize) {
699        self.map_state(|state| match *state {
700            State::Active(Mode::Device { ref mut state, .. }) => {
701                let endpoint_state = &mut state.endpoint_states[endpoint];
702                match *endpoint_state {
703                    EndpointState::BulkIn(BulkInState::Delay) => {
704                        endpoint_enable_interrupts(endpoint, EndpointControl::TXINE::SET);
706                        *endpoint_state = EndpointState::BulkIn(BulkInState::Init);
707                    }
708                    _ => debugln!("Ignoring superfluous resume_in"),
710                }
711            }
712            _ => debugln!("Ignoring inappropriate resume_in"),
713        });
714    }
715
716    fn endpoint_resume_out(&self, endpoint: usize) {
717        self.map_state(|state| match *state {
718            State::Active(Mode::Device { ref mut state, .. }) => {
719                let endpoint_state = &mut state.endpoint_states[endpoint];
720                match *endpoint_state {
721                    EndpointState::BulkOut(BulkOutState::Delay) => {
722                        endpoint_enable_interrupts(endpoint, EndpointControl::RXOUTE::SET);
724                        *endpoint_state = EndpointState::BulkOut(BulkOutState::Init);
725                    }
726                    _ => debugln!("Ignoring superfluous resume_out"),
728                }
729            }
730            _ => debugln!("Ignoring inappropriate resume_out"),
731        });
732    }
733
734    fn handle_requests(&self) {
735        for endpoint in 0..N_ENDPOINTS {
736            let mut requests = self.requests[endpoint].get();
737
738            if requests.resume_in {
739                self.endpoint_resume_in(endpoint);
740                requests.resume_in = false;
741            }
742            if requests.resume_out {
743                self.endpoint_resume_out(endpoint);
744                requests.resume_out = false;
745            }
746
747            self.requests[endpoint].set(requests);
748        }
749    }
750
751    pub fn handle_interrupt(&self) {
753        self.map_state(|state| match *state {
754            State::Reset => internal_err!("Received interrupt in Reset"),
755            State::Idle(_) => {
756                debug1!("Received interrupt in Idle");
758            }
759            State::Active(ref mut mode) => match *mode {
760                Mode::Device {
761                    speed,
762                    ref config,
763                    ref mut state,
764                } => self.handle_device_interrupt(speed, config, state),
765                Mode::Host => internal_err!("Host mode unimplemented"),
766            },
767        });
768
769        self.handle_requests();
771    }
772
773    fn handle_device_interrupt(
775        &self,
776        speed: Speed,
777        device_config: &DeviceConfig,
778        device_state: &mut DeviceState,
779    ) {
780        let udint = usbc_regs().udint.extract();
781
782        debug1!("--> UDINT={:?}", UdintFlags(udint.get()));
783
784        if udint.is_set(DeviceInterrupt::EORST) {
785            debug1!("USB Bus Reset");
787
788            usbc_regs().udcon.modify(match speed {
790                Speed::Full => DeviceControl::LS::FullSpeed,
791                Speed::Low => DeviceControl::LS::LowSpeed,
792            });
793
794            *device_state = DeviceState::default();
796
797            for i in 0..N_ENDPOINTS {
799                if let Some(endpoint_config) = device_config.endpoint_configs[i] {
800                    self.endpoint_write_config(i, endpoint_config);
801                    self.endpoint_init_with_device_state(device_state, i, endpoint_config);
802                }
803            }
804
805            self.client.map(|client| {
807                client.bus_reset();
808            });
809
810            usbc_regs().udintclr.write(DeviceInterrupt::EORST::SET);
812
813            return;
815        }
816
817        if udint.is_set(DeviceInterrupt::SUSP) {
818            usbc_regs().udinteset.write(DeviceInterrupt::WAKEUP::SET);
835
836            usbc_regs().udintclr.write(DeviceInterrupt::SUSP::SET);
838        }
839
840        if udint.is_set(DeviceInterrupt::WAKEUP) {
841            usbc_regs().udinteclr.write(DeviceInterrupt::WAKEUP::SET);
845
846            usbc_regs().udintclr.write(DeviceInterrupt::WAKEUP::SET);
848
849            }
851
852        if udint.is_set(DeviceInterrupt::SOF) {
853            usbc_regs().udintclr.write(DeviceInterrupt::SOF::SET);
855        }
856
857        if udint.is_set(DeviceInterrupt::EORSM) {
858            debug1!("UDINT EORSM");
860        }
861
862        if udint.is_set(DeviceInterrupt::UPRSM) {
863            debug1!("UDINT UPRSM");
865        }
866
867        for endpoint in 0..N_ENDPOINTS {
869            if udint.get() & (1 << (12 + endpoint)) == 0 {
870                continue;
872            }
873
874            self.handle_endpoint_interrupt(endpoint, &mut device_state.endpoint_states[endpoint]);
875        }
876    }
877
878    fn handle_endpoint_interrupt(&self, endpoint: usize, endpoint_state: &mut EndpointState) {
879        let status = usbc_regs().uesta[endpoint].extract();
880        debug1!("  UESTA{}={:?}", endpoint, UestaFlags(status.get()));
881
882        if status.is_set(EndpointStatus::STALLED) {
883            debug1!("\tep{}: STALLED/CRCERR", endpoint);
884
885            usbc_regs().uestaclr[endpoint].write(EndpointStatus::STALLED::SET);
887        }
888
889        if status.is_set(EndpointStatus::RAMACER) {
890            debug1!("\tep{}: RAMACER", endpoint);
891
892            usbc_regs().uestaclr[endpoint].write(EndpointStatus::RAMACER::SET);
894        }
895
896        match *endpoint_state {
897            EndpointState::Ctrl(ref mut ctrl_state) => {
898                self.handle_ctrl_endpoint_interrupt(endpoint, ctrl_state, status)
899            }
900            EndpointState::BulkIn(ref mut bulk_in_state) => {
901                self.handle_bulk_in_endpoint_interrupt(endpoint, bulk_in_state, status)
902            }
903            EndpointState::BulkOut(ref mut bulk_out_state) => {
904                self.handle_bulk_out_endpoint_interrupt(endpoint, bulk_out_state, status)
905            }
906            EndpointState::Disabled => {
907                debug1!("Ignoring interrupt for disabled endpoint {}", endpoint);
908            }
909        }
910    }
911
912    fn handle_ctrl_endpoint_interrupt(
913        &self,
914        endpoint: usize,
915        ctrl_state: &mut CtrlState,
916        status: EndpointStatusValue,
917    ) {
918        let mut again = true;
919        while again {
920            again = false;
921            debug1!(
926                "  ep{}: Ctrl({:?})  UECON={:?}",
927                endpoint,
928                *ctrl_state,
929                UeconFlags(usbc_regs().uecon[endpoint].get())
930            );
931
932            match *ctrl_state {
933                CtrlState::Init => {
934                    if status.is_set(EndpointStatus::RXSTP) {
935                        debug1!("\tep{}: RXSTP", endpoint);
938                        let bank = 0;
941                        let packet_bytes = self.descriptors[endpoint][bank]
942                            .packet_size
943                            .read(PacketSize::BYTE_COUNT);
944                        let result = if packet_bytes == 8 {
945                            self.client.map(|c| c.ctrl_setup(endpoint))
946                        } else {
947                            Some(hil::usb::CtrlSetupResult::ErrBadLength)
948                        };
949
950                        match result {
951                            Some(hil::usb::CtrlSetupResult::Ok)
952                            | Some(hil::usb::CtrlSetupResult::OkSetAddress) => {
953                                endpoint_disable_interrupts(endpoint, EndpointControl::RXSTPE::SET);
955
956                                if status.matches_all(EndpointStatus::CTRLDIR::In) {
957                                    usbc_regs().uestaclr[endpoint]
964                                        .write(EndpointStatus::NAKOUT::SET);
965                                    endpoint_enable_interrupts(
966                                        endpoint,
967                                        EndpointControl::TXINE::SET + EndpointControl::NAKOUTE::SET,
968                                    );
969                                    *ctrl_state = CtrlState::ReadIn;
970                                } else {
971                                    usbc_regs().uestaclr[endpoint]
976                                        .write(EndpointStatus::NAKIN::SET);
977                                    endpoint_enable_interrupts(
978                                        endpoint,
979                                        EndpointControl::RXOUTE::SET + EndpointControl::NAKINE::SET,
980                                    );
981                                    *ctrl_state = CtrlState::WriteOut;
982                                }
983                            }
984                            failure => {
985                                usbc_regs().ueconset[endpoint].write(EndpointControl::STALLRQ::SET);
988
989                                match failure {
990                                    None => debug1!("\tep{}: No client to handle Setup", endpoint),
991                                    Some(_err) => {
992                                        debug1!("\tep{}: Client err on Setup: {:?}", endpoint, _err)
993                                    }
994                                }
995
996                                }
998                        }
999
1000                        usbc_regs().uestaclr[endpoint].write(EndpointStatus::RXSTP::SET);
1002                    }
1003                }
1004                CtrlState::ReadIn => {
1005                    if status.is_set(EndpointStatus::NAKOUT) {
1009                        endpoint_disable_interrupts(
1012                            endpoint,
1013                            EndpointControl::TXINE::SET + EndpointControl::NAKOUTE::SET,
1014                        );
1015
1016                        debug1!("\tep{}: NAKOUT", endpoint);
1017                        self.client.map(|c| c.ctrl_status(endpoint));
1018
1019                        endpoint_enable_interrupts(endpoint, EndpointControl::RXOUTE::SET);
1021
1022                        usbc_regs().uestaclr[endpoint].write(EndpointStatus::NAKOUT::SET);
1024
1025                        *ctrl_state = CtrlState::ReadStatus;
1026
1027                        again = true;
1029                    } else if status.is_set(EndpointStatus::TXIN) {
1030                        debug1!("\tep{}: TXIN", endpoint);
1032
1033                        let result = self.client.map(|c| {
1034                            c.ctrl_in(endpoint)
1036                        });
1037                        match result {
1038                            Some(hil::usb::CtrlInResult::Packet(
1039                                packet_bytes,
1040                                transfer_complete,
1041                            )) => {
1042                                let packet_size = if packet_bytes == 64 && transfer_complete {
1047                                    PacketSize::BYTE_COUNT.val(64) + PacketSize::AUTO_ZLP::Yes
1051                                } else {
1052                                    PacketSize::BYTE_COUNT.val(packet_bytes as u32)
1056                                };
1057                                let bank = 0;
1058                                self.descriptors[endpoint][bank]
1059                                    .packet_size
1060                                    .write(packet_size);
1061
1062                                debug1!(
1063                                    "\tep{}: Send CTRL IN packet ({} bytes)",
1064                                    endpoint,
1065                                    packet_bytes
1066                                );
1067                                if transfer_complete {
1070                                    endpoint_disable_interrupts(
1073                                        endpoint,
1074                                        EndpointControl::TXINE::SET,
1075                                    );
1076                                } else {
1077                                    }
1079
1080                                usbc_regs().uestaclr[endpoint].write(EndpointStatus::TXIN::SET);
1083                            }
1084                            Some(hil::usb::CtrlInResult::Delay) => {
1085                                endpoint_disable_interrupts(endpoint, EndpointControl::TXINE::SET);
1086
1087                                debug1!("*** Client NAK");
1088
1089                                *ctrl_state = CtrlState::InDelay;
1092                            }
1093                            _ => {
1094                                usbc_regs().ueconset[endpoint].write(EndpointControl::STALLRQ::SET);
1096
1097                                debug1!("\tep{}: Client IN err => STALL", endpoint);
1098
1099                                endpoint_disable_interrupts(
1101                                    endpoint,
1102                                    EndpointControl::NAKOUTE::SET,
1103                                );
1104                                endpoint_enable_interrupts(endpoint, EndpointControl::RXSTPE::SET);
1105                                *ctrl_state = CtrlState::Init;
1106                            }
1107                        }
1108                    }
1109                }
1110                CtrlState::ReadStatus => {
1111                    if status.is_set(EndpointStatus::RXOUT) {
1112                        debug1!("\tep{}: RXOUT: End of Control Read transaction", endpoint);
1115
1116                        endpoint_disable_interrupts(endpoint, EndpointControl::RXOUTE::SET);
1118                        endpoint_enable_interrupts(endpoint, EndpointControl::RXSTPE::SET);
1119                        *ctrl_state = CtrlState::Init;
1120
1121                        usbc_regs().uestaclr[endpoint].write(EndpointStatus::RXOUT::SET);
1123
1124                        self.client.map(|c| c.ctrl_status_complete(endpoint));
1125                    }
1126                }
1127                CtrlState::WriteOut => {
1128                    if status.is_set(EndpointStatus::RXOUT) {
1129                        debug1!("\tep{}: RXOUT: Received Control Write data", endpoint);
1132                        let bank = 0;
1136                        let result = self.client.map(|c| {
1137                            c.ctrl_out(
1138                                endpoint,
1139                                self.descriptors[endpoint][bank]
1140                                    .packet_size
1141                                    .read(PacketSize::BYTE_COUNT),
1142                            )
1143                        });
1144                        match result {
1145                            Some(hil::usb::CtrlOutResult::Ok) => {
1146                                usbc_regs().uestaclr[endpoint].write(EndpointStatus::RXOUT::SET);
1148                            }
1149                            Some(hil::usb::CtrlOutResult::Delay) => {
1150                                endpoint_disable_interrupts(endpoint, EndpointControl::RXOUTE::SET);
1155                            }
1156                            _ => {
1157                                usbc_regs().ueconset[endpoint].write(EndpointControl::STALLRQ::SET);
1160
1161                                debug1!("\tep{}: Client OUT err => STALL", endpoint);
1162
1163                                endpoint_disable_interrupts(
1165                                    endpoint,
1166                                    EndpointControl::RXOUTE::SET + EndpointControl::NAKINE::SET,
1167                                );
1168                                endpoint_enable_interrupts(endpoint, EndpointControl::RXSTPE::SET);
1169                                *ctrl_state = CtrlState::Init;
1170                            }
1171                        }
1172                    }
1173                    if status.is_set(EndpointStatus::NAKIN) {
1174                        debug1!("\tep{}: NAKIN: Control Write -> Status stage", endpoint);
1176
1177                        usbc_regs().uestaclr[endpoint].write(EndpointStatus::NAKIN::SET);
1179
1180                        endpoint_disable_interrupts(
1182                            endpoint,
1183                            EndpointControl::RXOUTE::SET + EndpointControl::NAKINE::SET,
1184                        );
1185                        endpoint_enable_interrupts(endpoint, EndpointControl::TXINE::SET);
1186                        *ctrl_state = CtrlState::WriteStatus;
1187
1188                        again = true;
1190                    }
1191                }
1192                CtrlState::WriteStatus => {
1193                    if status.is_set(EndpointStatus::TXIN) {
1194                        debug1!(
1195                            "\tep{}: TXIN for Control Write Status (will send ZLP)",
1196                            endpoint
1197                        );
1198
1199                        self.client.map(|c| c.ctrl_status(endpoint));
1200
1201                        let bank = 0;
1203                        self.descriptors[endpoint][bank]
1204                            .packet_size
1205                            .write(PacketSize::BYTE_COUNT.val(0));
1206
1207                        usbc_regs().uestaclr[endpoint].write(EndpointStatus::TXIN::SET);
1209
1210                        *ctrl_state = CtrlState::WriteStatusWait;
1212                    }
1213                }
1214                CtrlState::WriteStatusWait => {
1215                    if status.is_set(EndpointStatus::TXIN) {
1216                        debug1!("\tep{}: TXIN: Control Write Status Complete", endpoint);
1217
1218                        endpoint_disable_interrupts(endpoint, EndpointControl::TXINE::SET);
1220                        endpoint_enable_interrupts(endpoint, EndpointControl::RXSTPE::SET);
1221                        *ctrl_state = CtrlState::Init;
1222
1223                        self.client.map(|c| c.ctrl_status_complete(endpoint));
1225                    }
1226                }
1227                CtrlState::InDelay => internal_err!("Not reached"),
1228            }
1229
1230            }
1235    }
1236
1237    fn handle_bulk_out_endpoint_interrupt(
1238        &self,
1239        endpoint: usize,
1240        bulk_out_state: &mut BulkOutState,
1241        status: EndpointStatusValue,
1242    ) {
1243        match *bulk_out_state {
1244            BulkOutState::Init => {
1245                if status.is_set(EndpointStatus::RXOUT) {
1246                    debug1!("\tep{}: RXOUT", endpoint);
1249
1250                    if !usbc_regs().uecon[endpoint].is_set(EndpointControl::FIFOCON) {
1251                        debugln!("Got RXOUT but not FIFOCON");
1252                        return;
1253                    }
1254                    let bank = 0;
1257                    let packet_bytes = self.descriptors[endpoint][bank]
1258                        .packet_size
1259                        .read(PacketSize::BYTE_COUNT);
1260
1261                    let result = self.client.map(|c| {
1262                        c.packet_out(TransferType::Bulk, endpoint, packet_bytes)
1264                    });
1265                    match result {
1266                        Some(hil::usb::OutResult::Ok) => {
1267                            usbc_regs().uestaclr[endpoint].write(EndpointStatus::RXOUT::SET);
1269
1270                            usbc_regs().ueconclr[endpoint].write(EndpointControl::FIFOCON::SET);
1272
1273                            debug1!(
1274                                "\tep{}: Recv BULK OUT packet ({} bytes)",
1275                                endpoint,
1276                                packet_bytes
1277                            );
1278
1279                            }
1281                        Some(hil::usb::OutResult::Delay) => {
1282                            endpoint_disable_interrupts(endpoint, EndpointControl::RXOUTE::SET);
1285
1286                            *bulk_out_state = BulkOutState::Delay;
1287                        }
1288                        _ => {
1289                            debug1!("\tep{}: Client OUT err => STALL", endpoint);
1290
1291                            usbc_regs().ueconset[endpoint].write(EndpointControl::STALLRQ::SET);
1293
1294                            }
1298                    }
1299                }
1300            }
1301            BulkOutState::Delay => internal_err!("Not reached"),
1302        }
1303    }
1304
1305    fn handle_bulk_in_endpoint_interrupt(
1306        &self,
1307        endpoint: usize,
1308        bulk_in_state: &mut BulkInState,
1309        status: EndpointStatusValue,
1310    ) {
1311        match *bulk_in_state {
1312            BulkInState::Init => {
1313                if status.is_set(EndpointStatus::TXIN) {
1314                    debug1!("\tep{}: TXIN", endpoint);
1317
1318                    if !usbc_regs().uecon[endpoint].is_set(EndpointControl::FIFOCON) {
1319                        debugln!("Got TXIN but not FIFOCON");
1320                        return;
1321                    }
1322                    let result = self.client.map(|c| {
1325                        c.packet_in(TransferType::Bulk, endpoint)
1327                    });
1328                    match result {
1329                        Some(hil::usb::InResult::Packet(packet_bytes)) => {
1330                            usbc_regs().uestaclr[endpoint].write(EndpointStatus::TXIN::SET);
1332
1333                            let bank = 0;
1335                            self.descriptors[endpoint][bank]
1336                                .packet_size
1337                                .write(PacketSize::BYTE_COUNT.val(packet_bytes as u32));
1338
1339                            usbc_regs().ueconclr[endpoint].write(EndpointControl::FIFOCON::SET);
1341
1342                            debug1!(
1343                                "\tep{}: Send BULK IN packet ({} bytes)",
1344                                endpoint,
1345                                packet_bytes
1346                            );
1347
1348                            }
1350                        Some(hil::usb::InResult::Delay) => {
1351                            endpoint_disable_interrupts(endpoint, EndpointControl::TXINE::SET);
1354
1355                            *bulk_in_state = BulkInState::Delay;
1356                        }
1357                        _ => {
1358                            debug1!("\tep{}: Client IN err => STALL", endpoint);
1359
1360                            usbc_regs().ueconset[endpoint].write(EndpointControl::STALLRQ::SET);
1362
1363                            }
1367                    }
1368                }
1369            }
1370            BulkInState::Delay => {
1371                internal_err!("Not reached");
1373            }
1374        }
1375    }
1376
1377    #[allow(dead_code)]
1378    fn debug_show_d0(&self) {
1379        for bi in 0..1 {
1380            let b = &self.descriptors[0][bi];
1381            let addr = b.addr.get();
1382            let _buf = if addr.is_null() {
1383                None
1384            } else {
1385                unsafe {
1386                    Some(slice::from_raw_parts(
1387                        addr,
1388                        b.packet_size.read(PacketSize::BYTE_COUNT) as usize,
1389                    ))
1390                }
1391            };
1392
1393            debug1!(
1394                "B_0_{} \
1395                 \n     {:?}\
1396                 \n     {:?}\
1397                 \n     {:?}",
1398                bi, b.packet_size.get(),
1400                b.control_status.get(),
1401                _buf.map(HexBuf)
1402            );
1403        }
1404    }
1405
1406    pub fn mode(&self) -> Option<Mode> {
1407        match self.get_state() {
1408            State::Idle(mode) => Some(mode),
1409            State::Active(mode) => Some(mode),
1410            _ => None,
1411        }
1412    }
1413
1414    pub fn speed(&self) -> Option<Speed> {
1415        match self.mode() {
1416            Some(mode) => {
1417                match mode {
1418                    Mode::Device { speed, .. } => Some(speed),
1419                    Mode::Host => {
1420                        None }
1422                }
1423            }
1424            _ => None,
1425        }
1426    }
1427
1428    }
1430
1431#[inline]
1432fn endpoint_disable_interrupts(endpoint: usize, mask: FieldValue<u32, EndpointControl::Register>) {
1433    usbc_regs().ueconclr[endpoint].write(mask);
1434}
1435
1436#[inline]
1437fn endpoint_enable_interrupts(endpoint: usize, mask: FieldValue<u32, EndpointControl::Register>) {
1438    usbc_regs().ueconset[endpoint].write(mask);
1439}
1440
1441impl<'a> hil::usb::UsbController<'a> for Usbc<'a> {
1442    fn set_client(&self, client: &'a dyn hil::usb::Client<'a>) {
1443        self.client.set(client);
1444    }
1445
1446    fn endpoint_set_ctrl_buffer(&self, buf: &'a [VolatileCell<u8>]) {
1447        if buf.len() < 8 {
1448            client_err!("Bad endpoint buffer size");
1449        }
1450
1451        self.endpoint_bank_set_buffer(EndpointIndex::new(0), BankIndex::Bank0, buf);
1452    }
1453
1454    fn endpoint_set_in_buffer(&self, endpoint: usize, buf: &'a [VolatileCell<u8>]) {
1455        if buf.len() < 8 {
1456            client_err!("Bad endpoint buffer size");
1457        }
1458
1459        self.endpoint_bank_set_buffer(EndpointIndex::new(endpoint), BankIndex::Bank0, buf);
1460    }
1461
1462    fn endpoint_set_out_buffer(&self, endpoint: usize, buf: &'a [VolatileCell<u8>]) {
1463        if buf.len() < 8 {
1464            client_err!("Bad endpoint buffer size");
1465        }
1466
1467        self.endpoint_bank_set_buffer(EndpointIndex::new(endpoint), BankIndex::Bank0, buf);
1469    }
1470
1471    fn enable_as_device(&self, speed: hil::usb::DeviceSpeed) {
1472        let speed = match speed {
1473            hil::usb::DeviceSpeed::Full => Speed::Full,
1474            hil::usb::DeviceSpeed::Low => Speed::Low,
1475        };
1476
1477        match self.get_state() {
1478            State::Reset => self.enable(Mode::Device {
1479                speed,
1480                config: DeviceConfig::default(),
1481                state: DeviceState::default(),
1482            }),
1483            _ => client_err!("Already enabled"),
1484        }
1485    }
1486
1487    fn attach(&self) {
1488        match self.get_state() {
1489            State::Reset => client_warn!("Not enabled"),
1490            State::Active(_) => client_warn!("Already attached"),
1491            State::Idle(_) => self.attach(),
1492        }
1493    }
1494
1495    fn detach(&self) {
1496        match self.get_state() {
1497            State::Reset => client_warn!("Not enabled"),
1498            State::Idle(_) => client_warn!("Not attached"),
1499            State::Active(_) => self.detach(),
1500        }
1501    }
1502
1503    fn set_address(&self, addr: u16) {
1504        usbc_regs()
1505            .udcon
1506            .modify(DeviceControl::UADD.val(addr as u32));
1507
1508        debug1!("Set Address = {}", addr);
1509    }
1510
1511    fn enable_address(&self) {
1512        usbc_regs().udcon.modify(DeviceControl::ADDEN::SET);
1513
1514        debug1!(
1515            "Enable Address = {}",
1516            usbc_regs().udcon.read(DeviceControl::UADD)
1517        );
1518    }
1519
1520    fn endpoint_in_enable(&self, transfer_type: TransferType, endpoint: usize) {
1521        let endpoint_cfg = match transfer_type {
1522            TransferType::Control => {
1523                panic!("There is no IN control endpoint");
1524            }
1525            TransferType::Bulk => LocalRegisterCopy::new(From::from(
1526                EndpointConfig::EPTYPE::Bulk
1527                    + EndpointConfig::EPDIR::In
1528                    + EndpointConfig::EPSIZE::Bytes8
1529                    + EndpointConfig::EPBK::Single,
1530            )),
1531            TransferType::Interrupt | TransferType::Isochronous => unimplemented!(),
1532        };
1533
1534        self.endpoint_enable(endpoint, endpoint_cfg)
1535    }
1536
1537    fn endpoint_out_enable(&self, transfer_type: TransferType, endpoint: usize) {
1538        let endpoint_cfg = match transfer_type {
1539            TransferType::Control => LocalRegisterCopy::new(From::from(
1540                EndpointConfig::EPTYPE::Control
1541                    + EndpointConfig::EPDIR::Out
1542                    + EndpointConfig::EPSIZE::Bytes8
1543                    + EndpointConfig::EPBK::Single,
1544            )),
1545            TransferType::Bulk => LocalRegisterCopy::new(From::from(
1546                EndpointConfig::EPTYPE::Bulk
1547                    + EndpointConfig::EPDIR::Out
1548                    + EndpointConfig::EPSIZE::Bytes8
1549                    + EndpointConfig::EPBK::Single,
1550            )),
1551            TransferType::Interrupt | TransferType::Isochronous => unimplemented!(),
1552        };
1553
1554        self.endpoint_enable(endpoint, endpoint_cfg)
1555    }
1556
1557    fn endpoint_in_out_enable(&self, _transfer_type: TransferType, _endpoint: usize) {
1558        unimplemented!()
1559    }
1560
1561    fn endpoint_resume_in(&self, endpoint: usize) {
1562        let mut requests = self.requests[endpoint].get();
1563        requests.resume_in = true;
1564        self.requests[endpoint].set(requests);
1565
1566        self.handle_requests();
1568    }
1569
1570    fn endpoint_resume_out(&self, endpoint: usize) {
1571        let mut requests = self.requests[endpoint].get();
1572        requests.resume_out = true;
1573        self.requests[endpoint].set(requests);
1574
1575        self.handle_requests();
1577    }
1578}