lowrisc/
usbdev.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//! USB Client driver.
6// [!! Untested !!]: This driver is out of date (functionality wise) with hw and
7// likely does not work. It's is currently not used with
8// the OpenTitan board.
9
10use core::cell::Cell;
11use kernel::hil;
12use kernel::hil::usb::TransferType;
13use kernel::utilities::cells::{OptionalCell, VolatileCell};
14use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable};
15use kernel::utilities::registers::{
16    register_bitfields, register_structs, LocalRegisterCopy, ReadOnly, ReadWrite, WriteOnly,
17};
18use kernel::utilities::StaticRef;
19
20pub const N_ENDPOINTS: usize = 12;
21pub const N_BUFFERS: usize = 32;
22
23register_structs! {
24    pub UsbRegisters {
25        (0x000 => intr_state: ReadWrite<u32, INTR::Register>),
26        (0x004 => intr_enable: ReadWrite<u32, INTR::Register>),
27        (0x008 => intr_test: WriteOnly<u32, INTR::Register>),
28        (0x00C => alert_test: WriteOnly<u32>),
29        (0x010 => usbctrl: ReadWrite<u32, USBCTRL::Register>),
30        (0x014 => ep_out_enable: ReadWrite<u32>),
31        (0x018 => ep_in_enable: ReadWrite<u32>),
32        (0x01C => usbstat: ReadOnly<u32, USBSTAT::Register>),
33        (0x020 => avbuffer: WriteOnly<u32, AVBUFFER::Register>),
34        (0x024 => rxfifo: ReadOnly<u32, RXFIFO::Register>),
35        (0x028 => rxenable_setup: ReadWrite<u32, RXENABLE_SETUP::Register>),
36        (0x02C => rxenable_out: ReadWrite<u32, RXENABLE_OUT::Register>),
37        (0x030 => set_nak_out: ReadWrite<u32>),
38        (0x034 => in_sent: ReadWrite<u32, IN_SENT::Register>),
39        (0x038 => out_stall: ReadWrite<u32, STALL::Register>),
40        (0x03C => in_stall: ReadWrite<u32, STALL::Register>),
41        (0x040 => configin: [ReadWrite<u32, CONFIGIN::Register>; N_ENDPOINTS]),
42        (0x070 => out_iso: ReadWrite<u32, ISO::Register>),
43        (0x074 => in_iso: ReadWrite<u32, ISO::Register>),
44        (0x078 => data_toggle_clear: WriteOnly<u32, DATA_TOGGLE_CLEAR::Register>),
45        (0x07C => phy_pins_sens: ReadOnly<u32>),
46        (0x080 => phy_pins_drive: ReadOnly<u32>),
47        (0x084 => phy_config: ReadWrite<u32, PHY_CONFIG::Register>),
48        (0x088 => wake_ctrl: WriteOnly<u32>),
49        (0x08C => wake_events: ReadOnly<u32>),
50        (0x090 => _reserved0),
51        (0x800 => buffer: [ReadWrite<u64, BUFFER::Register>; N_BUFFERS * 8]),
52        (0x1000 => @END),
53    }
54}
55
56register_bitfields![u32,
57    INTR [
58        PKT_RECEIVED OFFSET(0) NUMBITS(1) [],
59        PKT_SENT OFFSET(1) NUMBITS(1) [],
60        DISCONNECTED OFFSET(2) NUMBITS(1) [],
61        HOST_LOST OFFSET(3) NUMBITS(1) [],
62        LINK_RESET OFFSET(4) NUMBITS(1) [],
63        LINK_SUSPEND OFFSET(5) NUMBITS(1) [],
64        LINK_RESUME OFFSET(6) NUMBITS(1) [],
65        AV_EMPTY OFFSET(7) NUMBITS(1) [],
66        RX_FULL OFFSET(8) NUMBITS(1) [],
67        AV_OVERFLOW OFFSET(9) NUMBITS(1) [],
68        LINK_IN_ERR OFFSET(10) NUMBITS(1) [],
69        RX_CRC_ERR OFFSET(11) NUMBITS(1) [],
70        RX_PID_ERR OFFSET(12) NUMBITS(1) [],
71        RX_BITSTUFF_ERR OFFSET(13) NUMBITS(1) [],
72        FRAME OFFSET(14) NUMBITS(1) [],
73        CONNECTED OFFSET(15) NUMBITS(1) []
74    ],
75    USBCTRL [
76        ENABLE OFFSET(0) NUMBITS(1) [],
77        RESUME_LINK_ACTIVE OFFSET(1) NUMBITS(1) [],
78        DEVICE_ADDRESS OFFSET(16) NUMBITS(7) []
79    ],
80    USBSTAT [
81        FRAME OFFSET(0) NUMBITS(10) [],
82        HOST_LOST OFFSET(11) NUMBITS(1) [],
83        LINK_STATE OFFSET(12) NUMBITS(3) [],
84        SENSE OFFSET(15) NUMBITS(1) [],
85        AV_DEPTH OFFSET(16) NUMBITS(3) [],
86        AV_FULL OFFSET(23) NUMBITS(1) [],
87        RX_DEPTH OFFSET(24) NUMBITS(3) [],
88        RX_EMPTY OFFSET(31) NUMBITS(1) []
89    ],
90    AVBUFFER [
91        BUFFER OFFSET(0) NUMBITS(4) []
92    ],
93    RXFIFO [
94        BUFFER OFFSET(0) NUMBITS(4) [],
95        SIZE OFFSET(8) NUMBITS(7) [],
96        SETUP OFFSET(19) NUMBITS(1) [],
97        EP OFFSET(20) NUMBITS(4) []
98    ],
99    RXENABLE_SETUP [
100        SETUP0 OFFSET(0) NUMBITS(1) [],
101        SETUP1 OFFSET(1) NUMBITS(1) [],
102        SETUP2 OFFSET(2) NUMBITS(1) [],
103        SETUP3 OFFSET(3) NUMBITS(1) [],
104        SETUP4 OFFSET(4) NUMBITS(1) [],
105        SETUP5 OFFSET(5) NUMBITS(1) [],
106        SETUP6 OFFSET(6) NUMBITS(1) [],
107        SETUP7 OFFSET(7) NUMBITS(1) [],
108        SETUP8 OFFSET(8) NUMBITS(1) [],
109        SETUP9 OFFSET(9) NUMBITS(1) [],
110        SETUP10 OFFSET(10) NUMBITS(1) [],
111        SETUP11 OFFSET(11) NUMBITS(1) []
112    ],
113    RXENABLE_OUT [
114        OUT0 OFFSET(0) NUMBITS(1) [],
115        OUT1 OFFSET(1) NUMBITS(1) [],
116        OUT2 OFFSET(2) NUMBITS(1) [],
117        OUT3 OFFSET(3) NUMBITS(1) [],
118        OUT4 OFFSET(4) NUMBITS(1) [],
119        OUT5 OFFSET(5) NUMBITS(1) [],
120        OUT6 OFFSET(6) NUMBITS(1) [],
121        OUT7 OFFSET(7) NUMBITS(1) [],
122        OUT8 OFFSET(8) NUMBITS(1) [],
123        OUT9 OFFSET(9) NUMBITS(1) [],
124        OUT10 OFFSET(10) NUMBITS(1) [],
125        OUT11 OFFSET(11) NUMBITS(1) []
126    ],
127    IN_SENT [
128        SENT0 OFFSET(0) NUMBITS(1) [],
129        SENT1 OFFSET(1) NUMBITS(1) [],
130        SENT2 OFFSET(2) NUMBITS(1) [],
131        SENT3 OFFSET(3) NUMBITS(1) [],
132        SENT4 OFFSET(4) NUMBITS(1) [],
133        SENT5 OFFSET(5) NUMBITS(1) [],
134        SENT6 OFFSET(6) NUMBITS(1) [],
135        SENT7 OFFSET(7) NUMBITS(1) [],
136        SENT8 OFFSET(8) NUMBITS(1) [],
137        SENT9 OFFSET(9) NUMBITS(1) [],
138        SENT10 OFFSET(10) NUMBITS(1) [],
139        SENT11 OFFSET(11) NUMBITS(1) []
140    ],
141    STALL [
142        STALL0 OFFSET(0) NUMBITS(1) [],
143        STALL1 OFFSET(1) NUMBITS(1) [],
144        STALL2 OFFSET(2) NUMBITS(1) [],
145        STALL3 OFFSET(3) NUMBITS(1) [],
146        STALL4 OFFSET(4) NUMBITS(1) [],
147        STALL5 OFFSET(5) NUMBITS(1) [],
148        STALL6 OFFSET(6) NUMBITS(1) [],
149        STALL7 OFFSET(7) NUMBITS(1) [],
150        STALL8 OFFSET(8) NUMBITS(1) [],
151        STALL9 OFFSET(9) NUMBITS(1) [],
152        STALL10 OFFSET(10) NUMBITS(1) [],
153        STALL11 OFFSET(11) NUMBITS(1) []
154    ],
155    CONFIGIN [
156        BUFFER OFFSET(0) NUMBITS(4) [],
157        SIZE OFFSET(8) NUMBITS(7) [],
158        PEND OFFSET(30) NUMBITS(1) [],      //RW1C
159        RDY OFFSET(31) NUMBITS(1) []
160    ],
161    ISO [
162        ISO0 OFFSET(0) NUMBITS(1) [],
163        ISO1 OFFSET(1) NUMBITS(1) [],
164        ISO2 OFFSET(2) NUMBITS(1) [],
165        ISO3 OFFSET(3) NUMBITS(1) [],
166        ISO4 OFFSET(4) NUMBITS(1) [],
167        ISO5 OFFSET(5) NUMBITS(1) [],
168        ISO6 OFFSET(6) NUMBITS(1) [],
169        ISO7 OFFSET(7) NUMBITS(1) [],
170        ISO8 OFFSET(8) NUMBITS(1) [],
171        ISO9 OFFSET(9) NUMBITS(1) [],
172        ISO10 OFFSET(10) NUMBITS(1) [],
173        ISO11 OFFSET(11) NUMBITS(1) []
174    ],
175    DATA_TOGGLE_CLEAR [
176        CLEAR0 OFFSET(0) NUMBITS(1) [],
177        CLEAR1 OFFSET(1) NUMBITS(1) [],
178        CLEAR2 OFFSET(2) NUMBITS(1) [],
179        CLEAR3 OFFSET(3) NUMBITS(1) [],
180        CLEAR4 OFFSET(4) NUMBITS(1) [],
181        CLEAR5 OFFSET(5) NUMBITS(1) [],
182        CLEAR6 OFFSET(6) NUMBITS(1) [],
183        CLEAR7 OFFSET(7) NUMBITS(1) [],
184        CLEAR8 OFFSET(8) NUMBITS(1) [],
185        CLEAR9 OFFSET(9) NUMBITS(1) [],
186        CLEAR10 OFFSET(10) NUMBITS(1) [],
187        CLEAR11 OFFSET(11) NUMBITS(1) []
188    ],
189    PHY_CONFIG [
190        RX_DIFFERENTIAL_MODE OFFSET(0) NUMBITS(1) [],
191        TX_DIFFERENTIAL_MODE OFFSET(1) NUMBITS(1) [],
192        EOP_SINGLE_BIT OFFSET(2) NUMBITS(1) [],
193        PINFLIP OFFSET(5) NUMBITS(1) [],
194        USB_REF_DISABLE OFFSET(6) NUMBITS(1) [],
195        TX_OSC_TEST_MODE OFFSET(7) NUMBITS(1) []
196    ]
197];
198
199// This is only useful for decoding the data from the buffer
200// Don't use this to write.
201register_bitfields![u64,
202    BUFFER [
203        REQUEST_TYPE OFFSET(0) NUMBITS(8) [],
204        REQUEST OFFSET(8) NUMBITS(8) [],
205        VALUE OFFSET(16) NUMBITS(16) [],
206        INDEX OFFSET(32) NUMBITS(16) [],
207        LENGTH OFFSET(48) NUMBITS(16) []
208    ]
209];
210
211/// State of the control endpoint (endpoint 0).
212#[derive(Copy, Clone, PartialEq, Debug)]
213pub enum CtrlState {
214    /// Control endpoint is idle, and waiting for a command from the host.
215    Init,
216    /// Control endpoint has started an IN transfer.
217    ReadIn,
218    /// Control endpoint has moved to the status phase.
219    ReadStatus,
220    /// Control endpoint is handling a control write (OUT) transfer.
221    WriteOut,
222    /// Control endpoint needs to set the address in hardware
223    SetAddress,
224}
225
226#[derive(Copy, Clone, PartialEq, Debug)]
227pub enum BulkInState {
228    // The endpoint is ready to perform transactions.
229    Init,
230    // There is a pending IN packet transfer on this endpoint.
231    In(usize),
232}
233
234#[derive(Copy, Clone, PartialEq, Debug)]
235pub enum BulkOutState {
236    // The endpoint is ready to perform transactions.
237    Init,
238    // There is a pending OUT packet in this endpoint's buffer, to be read by
239    // the client application.
240    OutDelay,
241    // There is a pending EPDATA to reply to.
242    OutData(usize),
243}
244
245#[derive(Copy, Clone, PartialEq, Debug)]
246pub enum InterruptState {
247    // The endpoint is ready to perform transactions.
248    Init,
249    // There is a pending IN packet transfer on this endpoint.
250    In(usize),
251}
252
253#[derive(Copy, Clone, Debug)]
254pub enum EndpointState {
255    Disabled,
256    Ctrl(CtrlState),
257    Bulk(Option<BulkInState>, Option<BulkOutState>),
258    Interrupt(u32, InterruptState),
259    Iso,
260}
261
262type EndpointConfigValue = LocalRegisterCopy<u32, CONFIGIN::Register>;
263
264#[derive(Copy, Clone, Debug, Default)]
265pub struct DeviceConfig {
266    pub endpoint_configs: [Option<EndpointConfigValue>; N_ENDPOINTS],
267}
268
269#[derive(Copy, Clone, Debug)]
270pub enum Mode {
271    Host,
272    Device {
273        speed: hil::usb::DeviceSpeed,
274        config: DeviceConfig,
275    },
276}
277
278#[derive(Copy, Clone, Debug)]
279pub enum State {
280    // Controller disabled
281    Reset,
282
283    // Controller enabled, detached from bus
284    // (We may go to this state when the Host
285    // controller suspends the bus.)
286    Idle(Mode),
287
288    // Controller enabled, attached to bus
289    Active(Mode),
290}
291
292pub enum BankIndex {
293    Bank0,
294    Bank1,
295}
296
297impl From<BankIndex> for usize {
298    fn from(bi: BankIndex) -> usize {
299        match bi {
300            BankIndex::Bank0 => 0,
301            BankIndex::Bank1 => 1,
302        }
303    }
304}
305
306#[repr(C)]
307pub struct Endpoint<'a> {
308    slice_in: OptionalCell<&'a [VolatileCell<u8>]>,
309    slice_out: OptionalCell<&'a [VolatileCell<u8>]>,
310    state: Cell<EndpointState>,
311
312    _reserved: u32,
313}
314
315impl Endpoint<'_> {
316    pub const fn new() -> Self {
317        Endpoint {
318            slice_in: OptionalCell::empty(),
319            slice_out: OptionalCell::empty(),
320            state: Cell::new(EndpointState::Disabled),
321            _reserved: 0,
322        }
323    }
324}
325
326#[derive(Copy, Clone)]
327struct Buffer {
328    id: usize,
329    free: bool,
330}
331
332impl Buffer {
333    pub const fn new(id: usize) -> Self {
334        Buffer { id, free: true }
335    }
336}
337
338pub struct Usb<'a> {
339    registers: StaticRef<UsbRegisters>,
340    descriptors: [Endpoint<'a>; N_ENDPOINTS],
341    client: OptionalCell<&'a dyn hil::usb::Client<'a>>,
342    state: OptionalCell<State>,
343    bufs: Cell<[Buffer; N_BUFFERS]>,
344    addr: Cell<u16>,
345}
346
347impl<'a> Usb<'a> {
348    pub const fn new(base: StaticRef<UsbRegisters>) -> Self {
349        Usb {
350            registers: base,
351            descriptors: [
352                Endpoint::new(),
353                Endpoint::new(),
354                Endpoint::new(),
355                Endpoint::new(),
356                Endpoint::new(),
357                Endpoint::new(),
358                Endpoint::new(),
359                Endpoint::new(),
360                Endpoint::new(),
361                Endpoint::new(),
362                Endpoint::new(),
363                Endpoint::new(),
364            ],
365            client: OptionalCell::empty(),
366            state: OptionalCell::new(State::Reset),
367            bufs: Cell::new([
368                Buffer::new(0),
369                Buffer::new(1),
370                Buffer::new(2),
371                Buffer::new(3),
372                Buffer::new(4),
373                Buffer::new(5),
374                Buffer::new(6),
375                Buffer::new(7),
376                Buffer::new(8),
377                Buffer::new(9),
378                Buffer::new(10),
379                Buffer::new(11),
380                Buffer::new(12),
381                Buffer::new(13),
382                Buffer::new(14),
383                Buffer::new(15),
384                Buffer::new(16),
385                Buffer::new(17),
386                Buffer::new(18),
387                Buffer::new(19),
388                Buffer::new(20),
389                Buffer::new(21),
390                Buffer::new(22),
391                Buffer::new(23),
392                Buffer::new(24),
393                Buffer::new(25),
394                Buffer::new(26),
395                Buffer::new(27),
396                Buffer::new(28),
397                Buffer::new(29),
398                Buffer::new(30),
399                Buffer::new(31),
400            ]),
401            addr: Cell::new(0),
402        }
403    }
404
405    fn get_state(&self) -> State {
406        self.state.unwrap_or_panic() // Unwrap fail = get_state: state value is in use
407    }
408
409    fn set_state(&self, state: State) {
410        self.state.set(state);
411    }
412
413    fn get_transfer_type(&self, ep: usize) -> TransferType {
414        match self.descriptors[ep].state.get() {
415            EndpointState::Bulk(_, _) => TransferType::Bulk,
416            EndpointState::Iso => TransferType::Isochronous,
417            EndpointState::Interrupt(_, _) => TransferType::Interrupt,
418            EndpointState::Ctrl(_) => TransferType::Control,
419            EndpointState::Disabled => unreachable!(),
420        }
421    }
422
423    fn disable_interrupts(&self) {
424        self.registers.intr_enable.write(
425            INTR::PKT_RECEIVED::CLEAR
426                + INTR::PKT_SENT::CLEAR
427                + INTR::DISCONNECTED::CLEAR
428                + INTR::HOST_LOST::CLEAR
429                + INTR::LINK_RESET::CLEAR
430                + INTR::LINK_SUSPEND::CLEAR
431                + INTR::LINK_RESUME::CLEAR
432                + INTR::AV_EMPTY::CLEAR
433                + INTR::RX_FULL::CLEAR
434                + INTR::AV_OVERFLOW::CLEAR
435                + INTR::LINK_IN_ERR::CLEAR
436                + INTR::RX_CRC_ERR::CLEAR
437                + INTR::RX_PID_ERR::CLEAR
438                + INTR::RX_BITSTUFF_ERR::CLEAR
439                + INTR::FRAME::CLEAR
440                + INTR::CONNECTED::CLEAR,
441        );
442        self.registers.intr_state.set(0xFFFF_FFFF);
443    }
444
445    fn enable_interrupts(&self) {
446        self.registers.intr_enable.write(
447            INTR::PKT_RECEIVED::SET
448                + INTR::PKT_SENT::SET
449                + INTR::DISCONNECTED::SET
450                + INTR::HOST_LOST::SET
451                + INTR::LINK_RESET::SET
452                + INTR::LINK_SUSPEND::SET
453                + INTR::LINK_RESUME::SET
454                + INTR::AV_EMPTY::SET
455                + INTR::RX_FULL::SET
456                + INTR::AV_OVERFLOW::SET
457                + INTR::LINK_IN_ERR::SET
458                + INTR::RX_CRC_ERR::SET
459                + INTR::RX_PID_ERR::SET
460                + INTR::RX_BITSTUFF_ERR::SET
461                + INTR::FRAME::CLEAR
462                + INTR::CONNECTED::SET,
463        );
464    }
465
466    fn free_buffer(&self, buf_id: usize) {
467        let mut bufs = self.bufs.get();
468
469        for buf in bufs.iter_mut() {
470            if buf.id == buf_id {
471                buf.free = true;
472                break;
473            }
474        }
475
476        self.bufs.set(bufs);
477    }
478
479    fn in_stall(&self, endpoint: usize) {
480        self.registers
481            .in_stall
482            .set(1 << endpoint | self.registers.in_stall.get());
483    }
484
485    fn copy_slice_out_to_hw(&self, ep: usize, buf_id: usize, size: usize) {
486        // Get the slice
487        let slice = self.descriptors[ep].slice_out.unwrap_or_panic(); // Unwrap fail = No OUT slice set for this descriptor
488
489        let mut slice_start = 0;
490
491        for offset in 0..(size / 8) {
492            let slice_end = (offset + 1) * 8;
493
494            let mut to_write: u64 = 0;
495            for (i, buf) in slice[slice_start..slice_end].iter().enumerate() {
496                to_write |= (buf.get() as u64) << (i * 8);
497            }
498
499            // Write the data
500            self.registers.buffer[(buf_id * 8) + offset].set(to_write);
501
502            // Prepare for next loop
503            slice_start = slice_end;
504        }
505
506        // Check if there is any remainder less then 8
507        if slice_start < size {
508            let mut to_write: u64 = 0;
509            for (i, buf) in slice[slice_start..size].iter().enumerate() {
510                to_write |= (buf.get() as u64) << (i * 8);
511            }
512
513            // Write the data
514            self.registers.buffer[(buf_id * 8) + (slice_start / 8)].set(to_write);
515        }
516
517        self.registers.configin[ep].write(
518            CONFIGIN::BUFFER.val(buf_id as u32)
519                + CONFIGIN::SIZE.val(size as u32)
520                + CONFIGIN::RDY::SET,
521        );
522    }
523
524    fn copy_from_hw(&self, ep: usize, buf_id: usize, size: usize) {
525        // Get the slice
526        let slice = self.descriptors[ep].slice_in.unwrap_or_panic(); // Unwrap fail = No IN slice set for this descriptor
527
528        // Read the date to the buffer
529        // TODO: Handle long packets
530        for offset in 0..(size / 8) {
531            let data = self.registers.buffer[(buf_id * 8) + offset].get();
532
533            for (i, d) in data.to_ne_bytes().iter().enumerate() {
534                slice[(offset * 8) + i].set(*d);
535            }
536        }
537    }
538
539    fn complete_ctrl_status(&self) {
540        let endpoint = 0;
541
542        self.client.map(|client| {
543            client.ctrl_status(endpoint);
544            client.ctrl_status_complete(endpoint);
545            self.descriptors[endpoint]
546                .state
547                .set(EndpointState::Ctrl(CtrlState::Init));
548        });
549    }
550
551    fn control_ep_receive(&self, ep: usize, buf_id: usize, size: u32, setup: u32) {
552        let hw_buf = self.registers.buffer[buf_id * 8].extract();
553
554        match self.descriptors[ep].state.get() {
555            EndpointState::Disabled => unimplemented!(),
556            EndpointState::Ctrl(state) => {
557                let request_type = hw_buf.read(BUFFER::REQUEST_TYPE);
558                let length = hw_buf.read(BUFFER::LENGTH);
559
560                let ep_buf = &self.descriptors[ep].slice_out;
561                let ep_buf = ep_buf.unwrap_or_panic(); // Unwrap fail = No OUT slice set for this descriptor
562                if ep_buf.len() < 8 {
563                    panic!("EP0 DMA buffer length < 8");
564                }
565
566                // Re-construct the SETUP packet from various registers. The
567                // client's ctrl_setup() will parse it as a SetupData
568                // descriptor.
569                for (i, buf) in hw_buf.get().to_ne_bytes().iter().enumerate() {
570                    ep_buf[i].set(*buf);
571                }
572
573                match state {
574                    CtrlState::Init => {
575                        if setup != 0 && size == 8 {
576                            self.client.map(|client| {
577                                // Notify the client that the ctrl setup event has occurred.
578                                // Allow it to configure any data we need to send back.
579                                match client.ctrl_setup(ep) {
580                                    hil::usb::CtrlSetupResult::OkSetAddress => {
581                                        self.descriptors[ep]
582                                            .state
583                                            .set(EndpointState::Ctrl(CtrlState::SetAddress));
584                                    }
585                                    hil::usb::CtrlSetupResult::Ok => {
586                                        if length == 0 {
587                                            self.copy_slice_out_to_hw(0, 0, 0);
588                                            self.complete_ctrl_status();
589                                        } else {
590                                            let to_host = request_type & (1 << 7) != (1 << 7);
591                                            if to_host {
592                                                match client.ctrl_out(ep, hw_buf.get() as u32) {
593                                                    hil::usb::CtrlOutResult::Ok => {
594                                                        self.descriptors[ep].state.set(
595                                                            EndpointState::Ctrl(
596                                                                CtrlState::ReadStatus,
597                                                            ),
598                                                        );
599                                                        self.copy_slice_out_to_hw(ep, buf_id, 0);
600                                                    }
601                                                    hil::usb::CtrlOutResult::Delay => {
602                                                        unimplemented!()
603                                                    }
604                                                    hil::usb::CtrlOutResult::Halted => {
605                                                        unimplemented!()
606                                                    }
607                                                }
608                                            } else {
609                                                match client.ctrl_in(ep) {
610                                                    hil::usb::CtrlInResult::Packet(size, last) => {
611                                                        if size == 0 {
612                                                            panic!("Empty ctrl packet?");
613                                                        }
614
615                                                        self.copy_slice_out_to_hw(ep, buf_id, size);
616
617                                                        if last {
618                                                            self.descriptors[ep].state.set(
619                                                                EndpointState::Ctrl(
620                                                                    CtrlState::ReadStatus,
621                                                                ),
622                                                            );
623                                                        } else {
624                                                            self.descriptors[ep].state.set(
625                                                                EndpointState::Ctrl(
626                                                                    CtrlState::WriteOut,
627                                                                ),
628                                                            );
629                                                        }
630                                                    }
631                                                    hil::usb::CtrlInResult::Delay => {
632                                                        unimplemented!()
633                                                    }
634                                                    hil::usb::CtrlInResult::Error => unreachable!(),
635                                                }
636                                            }
637                                        }
638                                    }
639                                    _err => {
640                                        self.in_stall(ep);
641                                        self.free_buffer(buf_id);
642                                        self.descriptors[ep]
643                                            .state
644                                            .set(EndpointState::Ctrl(CtrlState::Init));
645                                    }
646                                }
647                            });
648                        }
649                    }
650                    CtrlState::ReadIn => {
651                        self.copy_from_hw(ep, buf_id, size as usize);
652                    }
653                    CtrlState::ReadStatus => {
654                        self.complete_ctrl_status();
655                    }
656                    CtrlState::WriteOut => unreachable!(),
657                    CtrlState::SetAddress => unreachable!(),
658                }
659            }
660            EndpointState::Bulk(_in_state, _out_state) => unimplemented!(),
661            EndpointState::Iso => unimplemented!(),
662            EndpointState::Interrupt(_, _) => unimplemented!(),
663        }
664    }
665
666    fn ep_receive(&self, ep: usize, buf_id: usize, size: u32, _setup: u32) {
667        let ep_buf = &self.descriptors[ep].slice_out;
668        let ep_buf = ep_buf.unwrap_or_panic(); // Unwrap fail = No OUT slice set for this descriptor
669        if ep_buf.len() < 8 {
670            panic!("EP0 DMA buffer length < 8");
671        }
672
673        self.client.map(|client| {
674            self.copy_from_hw(ep, buf_id, size as usize);
675            let result = client.packet_out(self.get_transfer_type(ep), ep, size);
676            match self.descriptors[ep].state.get() {
677                EndpointState::Disabled => unimplemented!(),
678                EndpointState::Ctrl(_state) => unimplemented!(),
679                EndpointState::Bulk(_in_state, _out_state) => {
680                    let new_out_state = match result {
681                        hil::usb::OutResult::Ok => BulkOutState::Init,
682
683                        hil::usb::OutResult::Delay => BulkOutState::OutDelay,
684
685                        hil::usb::OutResult::Error => BulkOutState::Init,
686                    };
687                    self.descriptors[ep]
688                        .state
689                        .set(EndpointState::Bulk(None, Some(new_out_state)));
690                }
691                EndpointState::Iso => unimplemented!(),
692                EndpointState::Interrupt(_, _) => {
693                    match result {
694                        hil::usb::OutResult::Ok => {}
695
696                        hil::usb::OutResult::Delay => {
697                            // Disable OUT so we don't get any more data
698                            self.registers
699                                .rxenable_out
700                                .set(!(1 << ep) & self.registers.rxenable_out.get());
701                        }
702
703                        hil::usb::OutResult::Error => unreachable!(),
704                    }
705                }
706            }
707        });
708    }
709
710    pub fn handle_interrupt(&self) {
711        let irqs = self.registers.intr_state.extract();
712
713        // Disable interrupts
714        self.disable_interrupts();
715
716        if !self.registers.usbstat.is_set(USBSTAT::AV_FULL) {
717            let mut bufs = self.bufs.get();
718
719            for buf in bufs.iter_mut() {
720                if !buf.free {
721                    continue;
722                }
723
724                if self.registers.usbstat.is_set(USBSTAT::AV_FULL) {
725                    break;
726                }
727
728                self.registers.avbuffer.set(buf.id as u32);
729                buf.free = false;
730            }
731
732            self.bufs.set(bufs);
733        }
734
735        if irqs.is_set(INTR::FRAME) {
736            for (ep, desc) in self.descriptors.iter().enumerate() {
737                match desc.state.get() {
738                    EndpointState::Disabled => {}
739                    EndpointState::Ctrl(_) => {}
740                    EndpointState::Bulk(_in_state, _out_state) => {}
741                    EndpointState::Iso => {}
742                    EndpointState::Interrupt(packet_size, state) => match state {
743                        InterruptState::Init => {}
744                        InterruptState::In(send_size) => {
745                            let buf = self.registers.configin[ep].read(CONFIGIN::BUFFER);
746                            self.free_buffer(buf as usize);
747
748                            self.client.map(|client| {
749                                match client.packet_in(TransferType::Interrupt, ep) {
750                                    hil::usb::InResult::Packet(size) => {
751                                        if size == 0 {
752                                            panic!("Empty ctrl packet?");
753                                        }
754
755                                        self.copy_slice_out_to_hw(ep, buf as usize, size);
756
757                                        if send_size == size {
758                                            self.descriptors[ep].state.set(
759                                                EndpointState::Interrupt(
760                                                    packet_size,
761                                                    InterruptState::Init,
762                                                ),
763                                            );
764                                        } else {
765                                            self.descriptors[ep].state.set(
766                                                EndpointState::Interrupt(
767                                                    packet_size,
768                                                    InterruptState::In(send_size - size),
769                                                ),
770                                            );
771                                        }
772                                    }
773                                    hil::usb::InResult::Delay => unimplemented!(),
774                                    hil::usb::InResult::Error => unreachable!(),
775                                }
776                            });
777                        }
778                    },
779                }
780            }
781        }
782
783        if irqs.is_set(INTR::PKT_SENT) {
784            let mut in_sent = self.registers.in_sent.get();
785
786            while in_sent != 0 {
787                let ep = in_sent.trailing_zeros();
788
789                // We are handling this case, clear it
790                self.registers.in_sent.set(1 << ep);
791                in_sent &= !(1 << ep);
792
793                let buf = self.registers.configin[ep as usize].read(CONFIGIN::BUFFER);
794
795                self.free_buffer(buf as usize);
796
797                self.client.map(|client| {
798                    client.packet_transmitted(ep as usize);
799                });
800
801                match self.descriptors[ep as usize].state.get() {
802                    EndpointState::Disabled => unimplemented!(),
803                    EndpointState::Ctrl(state) => match state {
804                        CtrlState::Init => {}
805                        CtrlState::ReadIn => {
806                            unimplemented!();
807                        }
808                        CtrlState::ReadStatus => {
809                            self.complete_ctrl_status();
810                        }
811                        CtrlState::WriteOut => {
812                            self.client.map(|client| match client.ctrl_in(ep as usize) {
813                                hil::usb::CtrlInResult::Packet(size, last) => {
814                                    if size == 0 {
815                                        panic!("Empty ctrl packet?");
816                                    }
817
818                                    self.copy_slice_out_to_hw(ep as usize, buf as usize, size);
819
820                                    if last {
821                                        self.descriptors[ep as usize]
822                                            .state
823                                            .set(EndpointState::Ctrl(CtrlState::ReadStatus));
824                                    } else {
825                                        self.descriptors[ep as usize]
826                                            .state
827                                            .set(EndpointState::Ctrl(CtrlState::WriteOut));
828                                    }
829                                }
830                                hil::usb::CtrlInResult::Delay => unimplemented!(),
831                                hil::usb::CtrlInResult::Error => unreachable!(),
832                            });
833                        }
834                        CtrlState::SetAddress => {
835                            self.registers
836                                .usbctrl
837                                .modify(USBCTRL::DEVICE_ADDRESS.val(self.addr.get() as u32));
838                            self.descriptors[ep as usize]
839                                .state
840                                .set(EndpointState::Ctrl(CtrlState::Init));
841                        }
842                    },
843                    EndpointState::Bulk(_in_state, _out_state) => {}
844                    EndpointState::Iso => unimplemented!(),
845                    EndpointState::Interrupt(_, _) => {}
846                }
847            }
848        }
849
850        if irqs.is_set(INTR::PKT_RECEIVED) {
851            if !self.registers.usbstat.is_set(USBSTAT::RX_EMPTY) {
852                let rxinfo = self.registers.rxfifo.extract();
853                let buf = rxinfo.read(RXFIFO::BUFFER);
854                let size = rxinfo.read(RXFIFO::SIZE);
855                let ep = rxinfo.read(RXFIFO::EP);
856                let setup = rxinfo.read(RXFIFO::SETUP);
857
858                // Check if it's the control endpoint
859                match ep {
860                    0 => {
861                        self.control_ep_receive(ep as usize, buf as usize, size, setup);
862                        self.free_buffer(buf as usize);
863                    }
864                    1..=7 => {
865                        let receive_size = match self.descriptors[ep as usize].state.get() {
866                            EndpointState::Disabled => size,
867                            EndpointState::Ctrl(_state) => size,
868                            EndpointState::Bulk(_in_state, _out_state) => size,
869                            EndpointState::Iso => size,
870                            EndpointState::Interrupt(packet_size, _state) => packet_size,
871                        };
872                        self.ep_receive(ep as usize, buf as usize, receive_size, setup);
873                        self.free_buffer(buf as usize);
874                    }
875                    8 => unimplemented!("isochronous endpoint"),
876                    _ => unimplemented!(),
877                }
878            }
879        }
880
881        if irqs.is_set(INTR::LINK_RESET) {
882            // The link was reset
883
884            self.descriptors[0]
885                .state
886                .set(EndpointState::Ctrl(CtrlState::Init));
887        }
888
889        self.enable_interrupts();
890    }
891
892    fn transmit_in(&self, ep: usize) {
893        self.client.map(|client| {
894            let result = client.packet_in(self.get_transfer_type(ep), ep);
895
896            let new_in_state = match result {
897                hil::usb::InResult::Packet(size) => {
898                    let mut buf_id = None;
899                    let mut bufs = self.bufs.get();
900
901                    for buf in bufs.iter_mut() {
902                        if !buf.free {
903                            continue;
904                        }
905
906                        self.registers.avbuffer.set(buf.id as u32);
907                        buf.free = false;
908                        buf_id = Some(buf.id);
909                        break;
910                    }
911
912                    self.bufs.set(bufs);
913                    match self.descriptors[ep].state.get() {
914                        EndpointState::Disabled => unreachable!(),
915                        EndpointState::Ctrl(_state) => unreachable!(),
916                        EndpointState::Bulk(_in_state, _out_state) => {
917                            if let Some(buf) = buf_id {
918                                self.copy_slice_out_to_hw(ep, buf, size)
919                            } else {
920                                panic!("No free bufs");
921                            }
922                            EndpointState::Bulk(Some(BulkInState::In(size)), None)
923                        }
924                        EndpointState::Iso => unreachable!(),
925                        EndpointState::Interrupt(packet_size, _state) => {
926                            EndpointState::Interrupt(packet_size, InterruptState::In(size))
927                        }
928                    }
929                }
930
931                hil::usb::InResult::Delay => {
932                    // No packet to send now. Wait for a resume call from the client.
933                    match self.descriptors[ep].state.get() {
934                        EndpointState::Disabled => unreachable!(),
935                        EndpointState::Ctrl(_state) => unreachable!(),
936                        EndpointState::Bulk(_in_state, _out_state) => {
937                            EndpointState::Bulk(Some(BulkInState::Init), None)
938                        }
939                        EndpointState::Iso => unreachable!(),
940                        EndpointState::Interrupt(packet_size, _state) => {
941                            EndpointState::Interrupt(packet_size, InterruptState::Init)
942                        }
943                    }
944                }
945
946                hil::usb::InResult::Error => {
947                    self.in_stall(ep);
948                    match self.descriptors[ep].state.get() {
949                        EndpointState::Disabled => unreachable!(),
950                        EndpointState::Ctrl(_state) => unreachable!(),
951                        EndpointState::Bulk(_in_state, _out_state) => {
952                            EndpointState::Bulk(Some(BulkInState::Init), None)
953                        }
954                        EndpointState::Iso => unreachable!(),
955                        EndpointState::Interrupt(packet_size, _state) => {
956                            EndpointState::Interrupt(packet_size, InterruptState::Init)
957                        }
958                    }
959                }
960            };
961
962            self.descriptors[ep].state.set(new_in_state);
963        });
964    }
965
966    /// Provide a buffer for transfers in and out of the given endpoint
967    /// (The controller need not be enabled before calling this method.)
968    fn endpoint_bank_set_buffer(&self, endpoint: usize, buf: &'a [VolatileCell<u8>]) {
969        self.descriptors[endpoint].slice_in.set(buf);
970        self.descriptors[endpoint].slice_out.set(buf);
971    }
972}
973
974impl<'a> hil::usb::UsbController<'a> for Usb<'a> {
975    fn set_client(&self, client: &'a dyn hil::usb::Client<'a>) {
976        self.client.set(client);
977    }
978
979    fn endpoint_set_ctrl_buffer(&self, buf: &'a [VolatileCell<u8>]) {
980        self.endpoint_bank_set_buffer(0, buf);
981    }
982
983    fn endpoint_set_in_buffer(&self, endpoint: usize, buf: &'a [VolatileCell<u8>]) {
984        self.endpoint_bank_set_buffer(endpoint, buf);
985    }
986
987    fn endpoint_set_out_buffer(&self, endpoint: usize, buf: &'a [VolatileCell<u8>]) {
988        self.endpoint_bank_set_buffer(endpoint, buf);
989    }
990
991    fn enable_as_device(&self, speed: hil::usb::DeviceSpeed) {
992        match self.get_state() {
993            State::Reset => {
994                self.registers.phy_config.write(
995                    PHY_CONFIG::PINFLIP::CLEAR
996                        + PHY_CONFIG::RX_DIFFERENTIAL_MODE::CLEAR
997                        + PHY_CONFIG::TX_DIFFERENTIAL_MODE::CLEAR
998                        + PHY_CONFIG::EOP_SINGLE_BIT::SET,
999                );
1000
1001                self.set_state(State::Idle(Mode::Device {
1002                    speed,
1003                    config: DeviceConfig::default(),
1004                }))
1005            }
1006            _ => panic!("Already enabled"),
1007        }
1008    }
1009
1010    fn attach(&self) {
1011        match self.get_state() {
1012            State::Reset => unreachable!("Not enabled"),
1013            State::Active(_) => unreachable!("Already attached"),
1014            State::Idle(mode) => {
1015                self.registers.usbctrl.write(USBCTRL::ENABLE::SET);
1016
1017                self.enable_interrupts();
1018
1019                self.set_state(State::Active(mode));
1020            }
1021        }
1022    }
1023
1024    fn detach(&self) {
1025        unimplemented!()
1026    }
1027
1028    fn set_address(&self, addr: u16) {
1029        self.addr.set(addr);
1030
1031        self.copy_slice_out_to_hw(0, 0, 0);
1032    }
1033
1034    fn enable_address(&self) {
1035        unimplemented!()
1036    }
1037
1038    fn endpoint_in_enable(&self, transfer_type: TransferType, endpoint: usize) {
1039        match transfer_type {
1040            TransferType::Control => {
1041                self.registers
1042                    .rxenable_setup
1043                    .set(1 << endpoint | self.registers.rxenable_setup.get());
1044                self.descriptors[endpoint]
1045                    .state
1046                    .set(EndpointState::Ctrl(CtrlState::Init));
1047            }
1048            TransferType::Bulk => {
1049                self.registers
1050                    .rxenable_setup
1051                    .set(1 << endpoint | self.registers.rxenable_setup.get());
1052                self.descriptors[endpoint]
1053                    .state
1054                    .set(EndpointState::Bulk(Some(BulkInState::Init), None));
1055            }
1056            TransferType::Interrupt => {
1057                self.registers
1058                    .rxenable_setup
1059                    .set(1 << endpoint | self.registers.rxenable_setup.get());
1060                self.descriptors[endpoint]
1061                    .state
1062                    .set(EndpointState::Interrupt(64, InterruptState::Init));
1063            }
1064            TransferType::Isochronous => {
1065                self.registers
1066                    .rxenable_setup
1067                    .set(1 << endpoint | self.registers.rxenable_setup.get());
1068                self.registers.in_iso.set(1 << endpoint);
1069                self.descriptors[endpoint].state.set(EndpointState::Iso);
1070            }
1071        }
1072    }
1073
1074    fn endpoint_out_enable(&self, transfer_type: TransferType, endpoint: usize) {
1075        match transfer_type {
1076            TransferType::Control => {
1077                self.registers
1078                    .rxenable_setup
1079                    .set(1 << endpoint | self.registers.rxenable_setup.get());
1080                self.registers
1081                    .rxenable_out
1082                    .set(1 << endpoint | self.registers.rxenable_out.get());
1083                self.descriptors[endpoint]
1084                    .state
1085                    .set(EndpointState::Ctrl(CtrlState::Init));
1086            }
1087            TransferType::Bulk => {
1088                self.registers
1089                    .rxenable_setup
1090                    .set(1 << endpoint | self.registers.rxenable_setup.get());
1091                self.registers
1092                    .rxenable_out
1093                    .set(1 << endpoint | self.registers.rxenable_out.get());
1094                self.descriptors[endpoint]
1095                    .state
1096                    .set(EndpointState::Bulk(None, Some(BulkOutState::Init)));
1097            }
1098            TransferType::Interrupt => {
1099                self.registers
1100                    .rxenable_out
1101                    .set(1 << endpoint | self.registers.rxenable_out.get());
1102                self.descriptors[endpoint]
1103                    .state
1104                    .set(EndpointState::Interrupt(64, InterruptState::Init));
1105            }
1106            TransferType::Isochronous => {
1107                self.registers
1108                    .rxenable_setup
1109                    .set(1 << endpoint | self.registers.rxenable_setup.get());
1110                self.registers
1111                    .rxenable_out
1112                    .set(1 << endpoint | self.registers.rxenable_out.get());
1113                self.registers.out_iso.set(1 << endpoint);
1114                self.descriptors[endpoint].state.set(EndpointState::Iso);
1115            }
1116        }
1117    }
1118
1119    fn endpoint_in_out_enable(&self, transfer_type: TransferType, endpoint: usize) {
1120        match transfer_type {
1121            TransferType::Bulk => {
1122                panic!("IN/OUT Bulk transfer is unsupported ");
1123            }
1124            _ => {}
1125        }
1126        self.endpoint_out_enable(transfer_type, endpoint)
1127    }
1128
1129    fn endpoint_resume_in(&self, endpoint: usize) {
1130        self.transmit_in(endpoint)
1131    }
1132
1133    fn endpoint_resume_out(&self, endpoint: usize) {
1134        // Renable the out endpoint
1135        self.registers
1136            .rxenable_out
1137            .set(1 << endpoint | self.registers.rxenable_out.get());
1138    }
1139}