nrf52/
usbd.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//! Universal Serial Bus Device with EasyDMA (USBD)
6
7use core::cell::Cell;
8use cortexm4f::support::atomic;
9use kernel::hil;
10use kernel::hil::usb::TransferType;
11use kernel::utilities::cells::{OptionalCell, VolatileCell};
12use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable};
13use kernel::utilities::registers::{
14    register_bitfields, register_structs, Field, InMemoryRegister, LocalRegisterCopy, ReadOnly,
15    ReadWrite, WriteOnly,
16};
17use kernel::utilities::StaticRef;
18
19use crate::power;
20
21// The following macros provide some diagnostics and panics(!)
22// while this module is experimental and should eventually be removed or
23// replaced with better error handling.
24macro_rules! debug_events {
25    [ $( $arg:expr ),+ ] => {
26        {} // kernel::debug!($( $arg ),+)
27    };
28}
29
30macro_rules! debug_tasks {
31    [ $( $arg:expr ),+ ] => {
32        {} // kernel::debug!($( $arg ),+)
33    };
34}
35
36macro_rules! debug_packets {
37    [ $( $arg:expr ),+ ] => {
38        {} // kernel::debug!($( $arg ),+)
39    };
40}
41
42macro_rules! debug_info {
43    [ $( $arg:expr ),+ ] => {
44        {} // kernel::debug!($( $arg ),+)
45    };
46}
47
48macro_rules! internal_warn {
49    [ $( $arg:expr ),+ ] => {
50        {} // kernel::debug!($( $arg ),+)
51    };
52}
53
54macro_rules! internal_err {
55    [ $( $arg:expr ),+ ] => {
56        panic!($( $arg ),+)
57    };
58}
59
60const CHIPINFO_BASE: StaticRef<ChipInfoRegisters> =
61    unsafe { StaticRef::new(0x10000130 as *const ChipInfoRegisters) };
62
63const USBD_BASE: StaticRef<UsbdRegisters<'static>> =
64    unsafe { StaticRef::new(0x40027000 as *const UsbdRegisters<'static>) };
65
66const USBERRATA_BASE: StaticRef<UsbErrataRegisters> =
67    unsafe { StaticRef::new(0x4006E000 as *const UsbErrataRegisters) };
68
69const NUM_ENDPOINTS: usize = 8;
70
71register_structs! {
72    ChipInfoRegisters {
73        /// Undocumented register indicating the model of the chip
74        (0x000 => chip_model: ReadOnly<u32, ChipModel::Register>),
75        /// Undocumented register indicating the revision of the chip
76        /// - Address: 0x004 - 0x008
77        (0x004 => chip_revision: ReadOnly<u32, ChipRevision::Register>),
78        (0x008 => @END),
79    },
80
81    UsbErrataRegisters {
82        (0x000 => _reserved0),
83        /// Undocumented register - Errata 171
84        (0xC00 => reg_c00: ReadWrite<u32>),
85        (0xC04 => _reserved1),
86        /// Undocumented register - Errata 171
87        (0xC14 => reg_c14: WriteOnly<u32>),
88        (0xC18 => _reserved2),
89        /// Undocumented register - Errata 187
90        (0xD14 => reg_d14: WriteOnly<u32>),
91        (0xD18 => @END),
92    }
93}
94
95#[repr(C)]
96struct UsbdRegisters<'a> {
97    _reserved1: [u32; 1],
98    /// Captures the EPIN\[n\].PTR, EPIN\[n\].MAXCNT and EPIN\[n\].CONFIG
99    /// registers values and enables endpoint IN not respond to traffic
100    /// from host
101    /// - Address: 0x004 - 0x024
102    task_startepin: [WriteOnly<u32, Task::Register>; NUM_ENDPOINTS],
103    /// Captures the ISOIN.PTR, ISOIN.MAXCNT and ISOIN.CONFIG registers values
104    /// and enables sending data on iso endpoint
105    /// - Address: 0x024 - 0x028
106    task_startisoin: WriteOnly<u32, Task::Register>,
107    /// Captures the EPOUT\[n\].PTR, EPOUT\[n\].MAXCNT and EPOUT\[n\].CONFIG
108    /// registers values and enables endpoint IN n ot respond to traffic
109    ///  from host
110    /// - Address: 0x028 - 0x048
111    task_startepout: [WriteOnly<u32, Task::Register>; NUM_ENDPOINTS],
112    /// Captures the ISOOUT.PTR, ISOOUT.MAXCNT and ISOOUT.CONFIG registers
113    /// values and enables receiving data on iso endpoint
114    /// - Address: 0x048 - 0x04C
115    task_startisoout: WriteOnly<u32, Task::Register>,
116    /// Allows OUT data stage on control endpoint 0
117    /// - Address: 0x04C - 0x050
118    task_ep0rcvout: WriteOnly<u32, Task::Register>,
119    /// Allows status stage on control endpoint 0
120    /// - Address: 0x050 - 0x054
121    task_ep0status: WriteOnly<u32, Task::Register>,
122    /// STALLs data and status stage on control endpoint 0
123    /// - Address: 0x054 - 0x058
124    task_ep0stall: WriteOnly<u32, Task::Register>,
125    /// Forces D+ and D-lines to the state defined in the DPDMVALUE register
126    /// - Address: 0x058 - 0x05C
127    task_dpdmdrive: WriteOnly<u32, Task::Register>,
128    /// Stops forcing D+ and D- lines to any state (USB engine takes control)
129    /// - Address: 0x05C - 0x060
130    task_dpdmnodrive: WriteOnly<u32, Task::Register>,
131    _reserved2: [u32; 40],
132    /// Signals that a USB reset condition has been detected on the USB lines
133    /// - Address: 0x100 - 0x104
134    event_usbreset: ReadWrite<u32, Event::Register>,
135    /// Confirms that the EPIN\[n\].PTR, EPIN\[n\].MAXCNT, EPIN\[n\].CONFIG,
136    /// or EPOUT\[n\].PTR, EPOUT\[n\].MAXCNT and EPOUT\[n\].CONFIG
137    /// registers have been captured on all endpoints reported in
138    /// the EPSTATUS register
139    /// - Address: 0x104 - 0x108
140    event_started: ReadWrite<u32, Event::Register>,
141    /// The whole EPIN\[n\] buffer has been consumed.
142    /// The RAM buffer can be accessed safely by software.
143    /// - Address: 0x108 - 0x128
144    event_endepin: [ReadWrite<u32, Event::Register>; NUM_ENDPOINTS],
145    /// An acknowledged data transfer has taken place on the control endpoint
146    /// - Address: 0x128 - 0x12C
147    event_ep0datadone: ReadWrite<u32, Event::Register>,
148    /// The whole ISOIN buffer has been consumed.
149    /// The RAM buffer can be accessed safely by software.
150    /// - Address: 0x12C - 0x130
151    event_endisoin: ReadWrite<u32, Event::Register>,
152    /// The whole EPOUT\[n\] buffer has been consumed.
153    /// The RAM buffer can be accessed safely by software.
154    /// - Address: 0x130 - 0x150
155    event_endepout: [ReadWrite<u32, Event::Register>; NUM_ENDPOINTS],
156    /// The whole ISOOUT buffer has been consumed.
157    /// The RAM buffer can be accessed safely by software.
158    /// - Address: 0x150 - 0x154
159    event_endisoout: ReadWrite<u32, Event::Register>,
160    /// Signals that a SOF (start of frame) condition has been
161    /// detected on the USB lines
162    /// - Address: 0x154 - 0x158
163    event_sof: ReadWrite<u32, Event::Register>,
164    /// An event or an error not covered by specific events has occurred,
165    /// check EVENTCAUSE register to find the cause
166    /// - Address: 0x158 - 0x15C
167    event_usbevent: ReadWrite<u32, Event::Register>,
168    /// A valid SETUP token has been received (and acknowledged)
169    /// on the control endpoint
170    /// - Address: 0x15C - 0x160
171    event_ep0setup: ReadWrite<u32, Event::Register>,
172    /// A data transfer has occurred on a data endpoint,
173    /// indicated by the EPDATASTATUS register
174    /// - Address: 0x160 - 0x164
175    event_epdata: ReadWrite<u32, Event::Register>,
176    _reserved3: [u32; 39],
177    /// Shortcut register
178    /// - Address: 0x200 - 0x204
179    shorts: ReadWrite<u32, Shorts::Register>,
180    _reserved4: [u32; 63],
181    /// Enable or disable interrupt
182    /// - Address: 0x300 - 0x304
183    inten: ReadWrite<u32, Interrupt::Register>,
184    /// Enable interrupt
185    /// - Address: 0x304 - 0x308
186    intenset: ReadWrite<u32, Interrupt::Register>,
187    /// Disable interrupt
188    /// - Address: 0x308 - 0x30C
189    intenclr: ReadWrite<u32, Interrupt::Register>,
190    _reserved5: [u32; 61],
191    /// Details on event that caused the USBEVENT even
192    /// - Address: 0x400 - 0x404
193    eventcause: ReadWrite<u32, EventCause::Register>,
194    _reserved6: [u32; 7],
195    /// IN\[n\] endpoint halted status.
196    /// Can be used as is as response to a GetStatus() request to endpoint.
197    /// - Address: 0x420 - 0x440
198    halted_epin: [ReadOnly<u32, Halted::Register>; NUM_ENDPOINTS],
199    _reserved7: [u32; 1],
200    /// OUT\[n\] endpoint halted status.
201    /// Can be used as is as response to a GetStatus() request to endpoint.
202    /// - Address: 0x444 - 0x464
203    halted_epout: [ReadOnly<u32, Halted::Register>; NUM_ENDPOINTS],
204    _reserved8: [u32; 1],
205    /// Provides information on which endpoint's EasyDMA
206    /// registers have been captured
207    /// - Address: 0x468 - 0x46C
208    epstatus: ReadWrite<u32, EndpointStatus::Register>,
209    /// Provides information on which endpoint(s) an acknowledged data
210    /// transfer has occurred (EPDATA event)
211    /// - Address: 0x46C - 0x470
212    epdatastatus: ReadWrite<u32, EndpointStatus::Register>,
213    /// Device USB address
214    /// - Address: 0x470 - 0x474
215    usbaddr: ReadOnly<u32, UsbAddress::Register>,
216    _reserved9: [u32; 3],
217    /// SETUP data, byte 0, bmRequestType
218    /// - Address: 0x480 - 0x484
219    bmrequesttype: ReadOnly<u32, RequestType::Register>,
220    /// SETUP data, byte 1, bRequest
221    /// - Address: 0x484 - 0x488
222    brequest: ReadOnly<u32, Request::Register>,
223    /// SETUP data, byte 2, wValue LSB
224    /// - Address: 0x488 - 0x48C
225    wvaluel: ReadOnly<u32, Byte::Register>,
226    /// SETUP data, byte 3, wValue MSB
227    /// - Address: 0x48C - 0x490
228    wvalueh: ReadOnly<u32, Byte::Register>,
229    /// SETUP data, byte 4, wIndex LSB
230    /// - Address: 0x490 - 0x494
231    windexl: ReadOnly<u32, Byte::Register>,
232    /// SETUP data, byte 5, wIndex MSB
233    /// - Address: 0x494 - 0x498
234    windexh: ReadOnly<u32, Byte::Register>,
235    /// SETUP data, byte 6, wLength LSB
236    /// - Address: 0x498 - 0x49C
237    wlengthl: ReadOnly<u32, Byte::Register>,
238    /// SETUP data, byte 7, wLength MSB
239    /// - Address: 0x49C - 0x4A0
240    wlengthh: ReadOnly<u32, Byte::Register>,
241    /// Amount of bytes received last in the data stage of
242    /// this OUT\[n\] endpoint
243    /// - Address: 0x4A0 - 0x4C0
244    size_epout: [ReadWrite<u32, EndpointSize::Register>; NUM_ENDPOINTS],
245    /// Amount of bytes received last on this iso OUT data endpoint
246    /// - Address: 0x4C0 - 0x4C4
247    size_iosout: ReadOnly<u32, IsoEndpointSize::Register>,
248    _reserved10: [u32; 15],
249    /// Enable USB
250    /// - Address: 0x500 - 0x504
251    enable: ReadWrite<u32, Usb::Register>,
252    /// Control of the USB pull-up
253    /// - Address: 0x504 - 0x508
254    usbpullup: ReadWrite<u32, UsbPullup::Register>,
255    /// State at which the DPDMDRIVE task will force D+ and D-.
256    /// The DPDMNODRIVE task reverts the control of the lines
257    /// to MAC IP (no forcing).
258    /// - Address: 0x508 - 0x50C
259    dpdmvalue: ReadWrite<u32, DpDmValue::Register>,
260    /// Data toggle control and status
261    /// - Address: 0x50C - 0x510
262    dtoggle: ReadWrite<u32, Toggle::Register>,
263    /// Endpoint IN enable
264    /// - Address: 0x510 - 0x514
265    epinen: ReadWrite<u32, EndpointEnable::Register>,
266    /// Endpoint OUT enable
267    /// - Address: 0x514 - 0x518
268    epouten: ReadWrite<u32, EndpointEnable::Register>,
269    /// STALL endpoints
270    /// - Address: 0x518 - 0x51C
271    epstall: WriteOnly<u32, EndpointStall::Register>,
272    /// Controls the split of ISO buffers
273    /// - Address: 0x51C - 0x520
274    isosplit: ReadWrite<u32, IsoSplit::Register>,
275    /// Returns the current value of the start of frame counter
276    /// - Address: 0x520 - 0x524
277    framecntr: ReadOnly<u32, FrameCounter::Register>,
278    _reserved11: [u32; 2],
279    /// Controls USBD peripheral low power mode during USB suspend
280    /// - Address: 0x52C - 0x530
281    lowpower: ReadWrite<u32, LowPower::Register>,
282    /// Controls the response of the ISO IN endpoint to an IN token
283    /// when no data is ready to be sent
284    /// - Address: 0x530 - 0x534
285    isoinconfig: ReadWrite<u32, IsoInConfig::Register>,
286    _reserved12: [u32; 51],
287    /// - Address: 0x600 - 0x6A0
288    epin: [detail::EndpointRegisters<'a>; NUM_ENDPOINTS],
289    /// - Address: 0x6A0 - 0x6B4
290    isoin: detail::EndpointRegisters<'a>,
291    _reserved13: [u32; 19],
292    /// - Address: 0x700 - 0x7A0
293    epout: [detail::EndpointRegisters<'a>; NUM_ENDPOINTS],
294    /// - Address: 0x7A0 - 0x7B4
295    isoout: detail::EndpointRegisters<'a>,
296    _reserved14: [u32; 19],
297    /// Errata 166 related register (ISO double buffering not functional)
298    /// - Address: 0x800 - 0x804
299    errata166_1: WriteOnly<u32>,
300    /// Errata 166 related register (ISO double buffering not functional)
301    /// - Address: 0x804 - 0x808
302    errata166_2: WriteOnly<u32>,
303    _reserved15: [u32; 261],
304    /// Errata 199 related register (USBD cannot receive tasks during DMA)
305    /// - Address: 0xC1C - 0xC20
306    errata199: WriteOnly<u32>,
307}
308
309mod detail {
310    use super::{Amount, Count};
311    use core::marker::PhantomData;
312    use kernel::utilities::cells::VolatileCell;
313    use kernel::utilities::registers::interfaces::Writeable;
314    use kernel::utilities::registers::{ReadOnly, ReadWrite};
315
316    #[repr(C)]
317    pub struct EndpointRegisters<'a> {
318        ptr: VolatileCell<*const u8>,
319        maxcnt: ReadWrite<u32, Count::Register>,
320        amount: ReadOnly<u32, Amount::Register>,
321        // padding
322        _reserved: [u32; 2],
323        // Lifetime marker.
324        _phantom: PhantomData<&'a [u8]>,
325    }
326
327    impl<'a> EndpointRegisters<'a> {
328        pub fn set_buffer(&self, slice: &'a [VolatileCell<u8>]) {
329            self.ptr.set(slice.as_ptr().cast::<u8>());
330            self.maxcnt.write(Count::MAXCNT.val(slice.len() as u32));
331        }
332    }
333}
334
335register_bitfields! [u32,
336    /// Start task
337    Task [
338        ENABLE OFFSET(0) NUMBITS(1)
339    ],
340
341    /// Read event
342    Event [
343        READY OFFSET(0) NUMBITS(1)
344    ],
345
346    /// Shortcuts
347    Shorts [
348        // Shortcut between EP0DATADONE event and STARTEPIN[0] task
349        EP0DATADONE_STARTEPIN0 OFFSET(0) NUMBITS(1),
350        // Shortcut between EP0DATADONE event and STARTEPOUT[0] task
351        EP0DATADONE_STARTEPOUT0 OFFSET(1) NUMBITS(1),
352        // Shortcut between EP0DATADONE event and EP0STATUS task
353        EP0DATADONE_EP0STATUS OFFSET(2) NUMBITS(1),
354        // Shortcut between ENDEPOUT[0] event and EP0STATUS task
355        ENDEPOUT0_EP0STATUS OFFSET(3) NUMBITS(1),
356        // Shortcut between ENDEPOUT[0] event and EP0RCVOUT task
357        ENDEPOUT0_EP0RCVOUT OFFSET(4) NUMBITS(1)
358    ],
359
360    /// USB Interrupts
361    Interrupt [
362        USBRESET OFFSET(0) NUMBITS(1),
363        STARTED OFFSET(1) NUMBITS(1),
364        ENDEPIN0 OFFSET(2) NUMBITS(1),
365        ENDEPIN1 OFFSET(3) NUMBITS(1),
366        ENDEPIN2 OFFSET(4) NUMBITS(1),
367        ENDEPIN3 OFFSET(5) NUMBITS(1),
368        ENDEPIN4 OFFSET(6) NUMBITS(1),
369        ENDEPIN5 OFFSET(7) NUMBITS(1),
370        ENDEPIN6 OFFSET(8) NUMBITS(1),
371        ENDEPIN7 OFFSET(9) NUMBITS(1),
372        EP0DATADONE OFFSET(10) NUMBITS(1),
373        ENDISOIN OFFSET(11) NUMBITS(1),
374        ENDEPOUT0 OFFSET(12) NUMBITS(1),
375        ENDEPOUT1 OFFSET(13) NUMBITS(1),
376        ENDEPOUT2 OFFSET(14) NUMBITS(1),
377        ENDEPOUT3 OFFSET(15) NUMBITS(1),
378        ENDEPOUT4 OFFSET(16) NUMBITS(1),
379        ENDEPOUT5 OFFSET(17) NUMBITS(1),
380        ENDEPOUT6 OFFSET(18) NUMBITS(1),
381        ENDEPOUT7 OFFSET(19) NUMBITS(1),
382        ENDISOOUT OFFSET(20) NUMBITS(1),
383        SOF OFFSET(21) NUMBITS(1),
384        USBEVENT OFFSET(22) NUMBITS(1),
385        EP0SETUP OFFSET(23) NUMBITS(1),
386        EPDATA OFFSET(24) NUMBITS(1)
387    ],
388
389    /// Cause of a USBEVENT event
390    EventCause [
391        ISOOUTCRC OFFSET(0) NUMBITS(1),
392        SUSPEND OFFSET(8) NUMBITS(1),
393        RESUME OFFSET(9) NUMBITS(1),
394        USBWUALLOWED OFFSET(10) NUMBITS(1),
395        READY OFFSET(11) NUMBITS(1)
396    ],
397
398    Halted [
399        GETSTATUS OFFSET(0) NUMBITS(16) [
400            NotHalted = 0,
401            Halted = 1
402        ]
403    ],
404
405    EndpointStatus [
406        EPIN0 OFFSET(0) NUMBITS(1),
407        EPIN1 OFFSET(1) NUMBITS(1),
408        EPIN2 OFFSET(2) NUMBITS(1),
409        EPIN3 OFFSET(3) NUMBITS(1),
410        EPIN4 OFFSET(4) NUMBITS(1),
411        EPIN5 OFFSET(5) NUMBITS(1),
412        EPIN6 OFFSET(6) NUMBITS(1),
413        EPIN7 OFFSET(7) NUMBITS(1),
414        EPIN8 OFFSET(8) NUMBITS(1),
415        EPOUT0 OFFSET(16) NUMBITS(1),
416        EPOUT1 OFFSET(17) NUMBITS(1),
417        EPOUT2 OFFSET(18) NUMBITS(1),
418        EPOUT3 OFFSET(19) NUMBITS(1),
419        EPOUT4 OFFSET(20) NUMBITS(1),
420        EPOUT5 OFFSET(21) NUMBITS(1),
421        EPOUT6 OFFSET(22) NUMBITS(1),
422        EPOUT7 OFFSET(23) NUMBITS(1),
423        EPOUT8 OFFSET(24) NUMBITS(1)
424    ],
425
426    UsbAddress [
427        ADDR OFFSET(0) NUMBITS(7)
428    ],
429
430    RequestType [
431        RECIPIENT OFFSET(0) NUMBITS(5) [
432            Device = 0,
433            Interface = 1,
434            Endpoint = 2,
435            Other = 3
436        ],
437        TYPE OFFSET(5) NUMBITS(2) [
438            Standard = 0,
439            Class = 1,
440            Vendor = 2
441        ],
442        DIRECTION OFFSET(7) NUMBITS(1) [
443            HostToDevice = 0,
444            DeviceToHost = 1
445        ]
446    ],
447
448    Request [
449        BREQUEST OFFSET(0) NUMBITS(8) [
450            STD_GET_STATUS = 0,
451            STD_CLEAR_FEATURE = 1,
452            STD_SET_FEATURE = 3,
453            STD_SET_ADDRESS = 5,
454            STD_GET_DESCRIPTOR = 6,
455            STD_SET_DESCRIPTOR = 7,
456            STD_GET_CONFIGURATION = 8,
457            STD_SET_CONFIGURATION = 9,
458            STD_GET_INTERFACE = 10,
459            STD_SET_INTERFACE = 11,
460            STD_SYNCH_FRAME = 12
461        ]
462    ],
463
464    Byte [
465        VALUE OFFSET(0) NUMBITS(8)
466    ],
467
468    EndpointSize [
469        SIZE OFFSET(0) NUMBITS(7)
470    ],
471
472    IsoEndpointSize [
473        SIZE OFFSET(0) NUMBITS(10),
474        ZERO OFFSET(16) NUMBITS(1)
475    ],
476
477    /// Enable USB
478    Usb [
479        ENABLE OFFSET(0) NUMBITS(1) [
480            OFF = 0,
481            ON = 1
482        ]
483    ],
484
485    UsbPullup [
486        CONNECT OFFSET(0) NUMBITS(1) [
487            Disabled = 0,
488            Enabled = 1
489        ]
490    ],
491
492    DpDmValue [
493        STATE OFFSET(0) NUMBITS(5) [
494            Resume = 1,
495            J = 2,
496            K = 4
497        ]
498    ],
499
500    Toggle [
501        EP OFFSET(0) NUMBITS(3) [],
502        IO OFFSET(7) NUMBITS(1) [
503            Out = 0,
504            In = 1
505        ],
506        VALUE OFFSET(8) NUMBITS(2) [
507            Nop = 0,
508            Data0 = 1,
509            Data1 = 2
510        ]
511    ],
512
513    EndpointEnable [
514        EP0 OFFSET(0) NUMBITS(1) [
515            Disable = 0,
516            Enable = 1
517        ],
518        EP1 OFFSET(1) NUMBITS(1) [
519            Disable = 0,
520            Enable = 1
521        ],
522        EP2 OFFSET(2) NUMBITS(1) [
523            Disable = 0,
524            Enable = 1
525        ],
526        EP3 OFFSET(3) NUMBITS(1) [
527            Disable = 0,
528            Enable = 1
529        ],
530        EP4 OFFSET(4) NUMBITS(1) [
531            Disable = 0,
532            Enable = 1
533        ],
534        EP5 OFFSET(5) NUMBITS(1) [
535            Disable = 0,
536            Enable = 1
537        ],
538        EP6 OFFSET(6) NUMBITS(1) [
539            Disable = 0,
540            Enable = 1
541        ],
542        EP7 OFFSET(7) NUMBITS(1) [
543            Disable = 0,
544            Enable = 1
545        ],
546        ISO OFFSET(8) NUMBITS(1) [
547            Disable = 0,
548            Enable = 1
549        ]
550    ],
551
552    EndpointStall [
553        EP OFFSET(0) NUMBITS(3) [],
554        IO OFFSET(7) NUMBITS(1) [
555            Out = 0,
556            In = 1
557        ],
558        STALL OFFSET(8) NUMBITS(1) [
559            UnStall = 0,
560            Stall = 1
561        ]
562    ],
563
564    IsoSplit [
565        SPLIT OFFSET(0) NUMBITS(16) [
566            OneDir = 0x0000,
567            HalfIN = 0x0080
568        ]
569    ],
570
571    FrameCounter [
572        FRAMECNTR OFFSET(0) NUMBITS(11)
573    ],
574
575    LowPower [
576        LOWPOWER OFFSET(0) NUMBITS(1) [
577            ForceNormal = 0,
578            LowPower = 1
579        ]
580    ],
581
582    IsoInConfig [
583        RESPONSE OFFSET(0) NUMBITS(1) [
584            NoResp = 0,
585            ZeroData = 1
586        ]
587    ],
588
589    Count [
590        // 7 bits for a bulk endpoint but 10 bits for ISO EP
591        MAXCNT OFFSET(0) NUMBITS(10)
592    ],
593
594    Amount [
595        // 7 bits for a bulk endpoint but 10 bits for ISO EP
596        AMOUNT OFFSET(0) NUMBITS(10)
597    ],
598
599    ChipModel [
600        MODEL OFFSET(0) NUMBITS(32) [
601            NRF52840 = 8
602        ]
603    ],
604
605    ChipRevision [
606        REV OFFSET(0) NUMBITS(32) [
607            REVA = 0,
608            REVB = 1,
609            REVC = 2,
610            REVD = 3,
611            REVE = 4,
612            REVF = 5,
613        ]
614    ]
615];
616
617#[derive(Copy, Clone, Debug, PartialEq)]
618pub enum UsbState {
619    Disabled,
620    Started,
621    Initialized,
622    PoweredOn,
623    Attached,
624    Configured,
625}
626
627#[derive(Copy, Clone, Debug)]
628pub enum EndpointState {
629    Disabled,
630    Ctrl(CtrlState),
631    Bulk(TransferType, Option<BulkInState>, Option<BulkOutState>),
632}
633
634impl EndpointState {
635    fn ctrl_state(self) -> CtrlState {
636        match self {
637            EndpointState::Ctrl(state) => state,
638            _ => panic!("Expected EndpointState::Ctrl"),
639        }
640    }
641
642    fn bulk_state(self) -> (TransferType, Option<BulkInState>, Option<BulkOutState>) {
643        match self {
644            EndpointState::Bulk(transfer_type, in_state, out_state) => {
645                (transfer_type, in_state, out_state)
646            }
647            _ => panic!("Expected EndpointState::Bulk"),
648        }
649    }
650}
651
652/// State of the control endpoint (endpoint 0).
653#[derive(Copy, Clone, PartialEq, Debug)]
654pub enum CtrlState {
655    /// Control endpoint is idle, and waiting for a command from the host.
656    Init,
657    /// Control endpoint has started an IN transfer.
658    ReadIn,
659    /// Control endpoint has moved to the status phase.
660    ReadStatus,
661    /// Control endpoint is handling a control write (OUT) transfer.
662    WriteOut,
663}
664
665#[derive(Copy, Clone, PartialEq, Debug)]
666pub enum BulkInState {
667    // The endpoint is ready to perform transactions.
668    Init,
669    // There is a pending DMA transfer on this IN endpoint.
670    InDma,
671    // There is a pending IN packet transfer on this endpoint.
672    InData,
673}
674
675#[derive(Copy, Clone, PartialEq, Debug)]
676pub enum BulkOutState {
677    // The endpoint is ready to perform transactions.
678    Init,
679    // There is a pending OUT packet in this endpoint's buffer, to be read by
680    // the client application.
681    OutDelay,
682    // There is a pending EPDATA to reply to. Store the size right after the
683    // EPDATA event.
684    OutData { size: u32 },
685    // There is a pending DMA transfer on this OUT endpoint. Still need to keep
686    // track of the size of the transfer.
687    OutDma { size: u32 },
688}
689
690pub struct Endpoint<'a> {
691    slice_in: OptionalCell<&'a [VolatileCell<u8>]>,
692    slice_out: OptionalCell<&'a [VolatileCell<u8>]>,
693    state: Cell<EndpointState>,
694    // The USB controller can only process one DMA transfer at a time (over all endpoints). The
695    // request_transmit_* bits allow to queue transfers until the DMA becomes available again.
696    // Whether a DMA transfer is requested on this IN endpoint.
697    request_transmit_in: Cell<bool>,
698    // Whether a DMA transfer is requested on this OUT endpoint.
699    request_transmit_out: Cell<bool>,
700}
701
702impl Endpoint<'_> {
703    const fn new() -> Self {
704        Endpoint {
705            slice_in: OptionalCell::empty(),
706            slice_out: OptionalCell::empty(),
707            state: Cell::new(EndpointState::Disabled),
708            request_transmit_in: Cell::new(false),
709            request_transmit_out: Cell::new(false),
710        }
711    }
712}
713
714pub struct Usbd<'a> {
715    registers: StaticRef<UsbdRegisters<'a>>,
716    state: OptionalCell<UsbState>,
717    dma_pending: Cell<bool>,
718    client: OptionalCell<&'a dyn hil::usb::Client<'a>>,
719    descriptors: [Endpoint<'a>; NUM_ENDPOINTS],
720    power: OptionalCell<&'a power::Power<'a>>,
721}
722
723impl<'a> Usbd<'a> {
724    pub const fn new() -> Self {
725        Usbd {
726            registers: USBD_BASE,
727            client: OptionalCell::empty(),
728            state: OptionalCell::new(UsbState::Disabled),
729            dma_pending: Cell::new(false),
730            descriptors: [
731                Endpoint::new(),
732                Endpoint::new(),
733                Endpoint::new(),
734                Endpoint::new(),
735                Endpoint::new(),
736                Endpoint::new(),
737                Endpoint::new(),
738                Endpoint::new(),
739            ],
740            power: OptionalCell::empty(),
741        }
742    }
743
744    pub fn set_power_ref(&self, power: &'a power::Power<'a>) {
745        self.power.set(power);
746    }
747
748    // ERRATA
749    //
750    // There are known issues with nRF52840 USB hardware, and we check if
751    // specific errata apply given different versions of the chip.
752    //
753    // Reference
754    // https://github.com/NordicSemiconductor/nrfx/blob/master/mdk/nrf52_erratas.h
755    // for how the different errata apply.
756
757    fn has_errata_166(&self) -> bool {
758        true
759    }
760
761    fn has_errata_171(&self) -> bool {
762        true
763    }
764
765    fn has_errata_187(&self) -> bool {
766        CHIPINFO_BASE
767            .chip_model
768            .matches_all(ChipModel::MODEL::NRF52840)
769            && match CHIPINFO_BASE.chip_revision.read_as_enum(ChipRevision::REV) {
770                Some(ChipRevision::REV::Value::REVB)
771                | Some(ChipRevision::REV::Value::REVC)
772                | Some(ChipRevision::REV::Value::REVD)
773                | Some(ChipRevision::REV::Value::REVE)
774                | Some(ChipRevision::REV::Value::REVF) => true,
775                Some(ChipRevision::REV::Value::REVA) | None => false,
776            }
777    }
778
779    fn has_errata_199(&self) -> bool {
780        true
781    }
782
783    /// ISO double buffering not functional
784    fn apply_errata_166(&self) {
785        if self.has_errata_166() {
786            self.registers.errata166_1.set(0x7e3);
787            self.registers.errata166_2.set(0x40);
788        }
789    }
790
791    /// USBD might not reach its active state.
792    fn apply_errata_171(&self, val: u32) {
793        if self.has_errata_171() {
794            unsafe {
795                atomic(|| {
796                    if USBERRATA_BASE.reg_c00.get() == 0 {
797                        USBERRATA_BASE.reg_c00.set(0x9375);
798                        USBERRATA_BASE.reg_c14.set(val);
799                        USBERRATA_BASE.reg_c00.set(0x9375);
800                    } else {
801                        USBERRATA_BASE.reg_c14.set(val);
802                    }
803                });
804            }
805        }
806    }
807
808    /// USB cannot be enabled
809    fn apply_errata_187(&self, val: u32) {
810        if self.has_errata_187() {
811            unsafe {
812                atomic(|| {
813                    if USBERRATA_BASE.reg_c00.get() == 0 {
814                        USBERRATA_BASE.reg_c00.set(0x9375);
815                        USBERRATA_BASE.reg_d14.set(val);
816                        USBERRATA_BASE.reg_c00.set(0x9375);
817                    } else {
818                        USBERRATA_BASE.reg_d14.set(val);
819                    }
820                });
821            }
822        }
823    }
824
825    fn apply_errata_199(&self, val: u32) {
826        if self.has_errata_199() {
827            self.registers.errata199.set(val);
828        }
829    }
830
831    pub fn get_state(&self) -> UsbState {
832        self.state.unwrap_or_panic() // Unwrap fail = get_state: state value is in use
833    }
834
835    // Powers the USB PHY on
836    fn enable(&self) {
837        if self.get_state() != UsbState::Disabled {
838            internal_warn!("USBC is already enabled");
839            return;
840        }
841        self.registers.eventcause.modify(EventCause::READY::CLEAR);
842        self.apply_errata_187(3);
843        self.apply_errata_171(0xc0);
844        self.registers.enable.write(Usb::ENABLE::ON);
845        while !self.registers.eventcause.is_set(EventCause::READY) {}
846        self.registers.eventcause.modify(EventCause::READY::CLEAR);
847        self.apply_errata_171(0);
848        self.apply_errata_166();
849        self.clear_pending_dma();
850        self.state.set(UsbState::Initialized);
851        self.apply_errata_187(0);
852    }
853
854    // TODO: unused function
855    fn _suspend(&self) {
856        debug_info!("usbc::suspend()");
857        self.ep_abort_all();
858        if self.registers.eventcause.is_set(EventCause::RESUME) {
859            return;
860        }
861        self.enable_lowpower();
862        if self.registers.eventcause.is_set(EventCause::RESUME) {
863            self.disable_lowpower();
864        } else {
865            self.apply_errata_171(0);
866        }
867        internal_warn!("suspend() not fully implemented");
868    }
869
870    fn disable_all_interrupts(&self) {
871        self.registers.intenclr.set(0xffffffff);
872    }
873
874    fn enable_interrupts(&self, inter: u32) {
875        self.registers.inten.set(inter);
876    }
877
878    fn power_ready(&self) {
879        match self.get_state() {
880            UsbState::Disabled => {
881                self.enable();
882                self.state.set(UsbState::PoweredOn);
883            }
884            UsbState::Initialized => self.state.set(UsbState::PoweredOn),
885            _ => (),
886        }
887    }
888
889    fn enable_pullup(&self) {
890        debug_info!("enable_pullup() - State={:?}", self.get_state());
891        if self.get_state() == UsbState::Started {
892            debug_info!("Enabling USB pullups");
893            self.registers.usbpullup.write(UsbPullup::CONNECT::Enabled);
894        }
895        self.state.set(UsbState::Attached);
896        debug_info!("New state is {:?}", self.get_state());
897    }
898
899    fn disable_pullup(&self) {
900        debug_info!("Disabling USB pullup - State={:?}", self.get_state());
901        self.registers.usbpullup.write(UsbPullup::CONNECT::Disabled);
902        self.state.set(UsbState::Started);
903        debug_info!("New state is {:?}", self.get_state());
904    }
905
906    // Allows the peripheral to be enumerated by the USB master
907    fn start(&self) {
908        debug_info!("usbc::start() - State={:?}", self.get_state());
909
910        // Depending on the chip model, there are more or less errata to add to the code. To
911        // simplify things, this implementation only includes errata relevant to nRF52840 chips
912        // revisions >= C.
913        //
914        // If your chip isn't one of these, you will be alerted by these panics. You can disable
915        // them but will likely need to add the relevant errata to this implementation (errata 104,
916        // 154, 200).
917        let chip_model = CHIPINFO_BASE.chip_model.get();
918        if chip_model != u32::from(ChipModel::MODEL::NRF52840) {
919            panic!(
920                "USB was only tested on NRF52840. Your chip model is {}.",
921                chip_model
922            );
923        }
924        let chip_revision = CHIPINFO_BASE.chip_revision.extract();
925        match chip_revision.read_as_enum(ChipRevision::REV) {
926            Some(ChipRevision::REV::Value::REVA) | Some(ChipRevision::REV::Value::REVB) => {
927                panic!(
928                    "Errata for USB on NRF52840 chips revisions A and B are not implemented. Your chip revision is {}.",
929                    chip_revision.get()
930                );
931            }
932            Some(ChipRevision::REV::Value::REVC)
933            | Some(ChipRevision::REV::Value::REVD)
934            | Some(ChipRevision::REV::Value::REVE)
935            | Some(ChipRevision::REV::Value::REVF) => {
936                debug_info!(
937                    "Your chip is NRF52840 revision {}. The USB stack was tested on your chip :)",
938                    chip_revision.get()
939                );
940            }
941            None => {
942                internal_warn!(
943                    "Your chip is NRF52840 revision {} (unknown revision). Although this USB implementation should be compatible, your chip hasn't been tested.",
944                    chip_revision.get()
945                );
946            }
947        }
948        let power = self.power.unwrap_or_panic(); // Unwrap fail = failed to initialize power reference for USB
949        if !power.is_vbus_present() {
950            debug_info!("[!] VBUS power is not detected.");
951            return;
952        }
953        if self.get_state() == UsbState::Disabled {
954            self.enable();
955        }
956        if self.get_state() != UsbState::PoweredOn {
957            debug_info!("Waiting for power regulators...");
958            while power.is_vbus_present() && power.is_usb_power_ready() {}
959        }
960        debug_info!("usbc::start() - subscribing to interrupts.");
961        self.registers.intenset.write(
962            Interrupt::USBRESET::SET
963                + Interrupt::STARTED::SET
964                + Interrupt::ENDEPIN0::SET
965                + Interrupt::EP0DATADONE::SET
966                + Interrupt::ENDEPOUT0::SET
967                + Interrupt::USBEVENT::SET
968                + Interrupt::EP0SETUP::SET
969                + Interrupt::EPDATA::SET,
970        );
971        self.state.set(UsbState::Started);
972    }
973
974    fn stop(&self) {
975        debug_info!("usbc::stop() - State={:?}", self.get_state());
976        if self.get_state() != UsbState::Started {
977            return;
978        }
979        self.ep_abort_all();
980        self.disable_all_interrupts();
981        self.registers.usbpullup.write(UsbPullup::CONNECT::Disabled);
982        self.state.set(UsbState::PoweredOn);
983    }
984
985    fn disable(&self) {
986        debug_info!("usbc::disable() - State={:?}", self.get_state());
987        self.stop();
988        self.registers.enable.write(Usb::ENABLE::OFF);
989        self.state.set(UsbState::Initialized);
990        self.clear_pending_dma();
991    }
992
993    fn clear_pending_dma(&self) {
994        debug_packets!("clear_pending_dma()");
995        self.apply_errata_199(0);
996        self.dma_pending.set(false);
997    }
998
999    fn set_pending_dma(&self) {
1000        debug_packets!("set_pending_dma()");
1001        if self.dma_pending.get() {
1002            internal_err!("Pending DMA already in flight");
1003        }
1004        self.apply_errata_199(0x82);
1005        self.dma_pending.set(true);
1006    }
1007
1008    fn enable_in_endpoint_(&self, transfer_type: TransferType, endpoint: usize) {
1009        debug_info!(
1010            "enable_in_endpoint_({}), State={:?}",
1011            endpoint,
1012            self.get_state()
1013        );
1014        self.registers.intenset.write(match endpoint {
1015            0 => Interrupt::ENDEPIN0::SET,
1016            1 => Interrupt::ENDEPIN1::SET,
1017            2 => Interrupt::ENDEPIN2::SET,
1018            3 => Interrupt::ENDEPIN3::SET,
1019            4 => Interrupt::ENDEPIN4::SET,
1020            5 => Interrupt::ENDEPIN5::SET,
1021            6 => Interrupt::ENDEPIN6::SET,
1022            7 => Interrupt::ENDEPIN7::SET,
1023            8 => Interrupt::ENDISOIN::SET,
1024            _ => unreachable!("unexisting endpoint"),
1025        });
1026        self.registers.epinen.modify(match endpoint {
1027            0 => EndpointEnable::EP0::Enable,
1028            1 => EndpointEnable::EP1::Enable,
1029            2 => EndpointEnable::EP2::Enable,
1030            3 => EndpointEnable::EP3::Enable,
1031            4 => EndpointEnable::EP4::Enable,
1032            5 => EndpointEnable::EP5::Enable,
1033            6 => EndpointEnable::EP6::Enable,
1034            7 => EndpointEnable::EP7::Enable,
1035            8 => EndpointEnable::ISO::Enable,
1036            _ => unreachable!("unexisting endpoint"),
1037        });
1038        self.descriptors[endpoint].state.set(match endpoint {
1039            0 => EndpointState::Ctrl(CtrlState::Init),
1040            1..=7 => EndpointState::Bulk(transfer_type, Some(BulkInState::Init), None),
1041            8 => unimplemented!("isochronous endpoint"),
1042            _ => unreachable!("unexisting endpoint"),
1043        });
1044    }
1045
1046    fn enable_out_endpoint_(&self, transfer_type: TransferType, endpoint: usize) {
1047        debug_info!(
1048            "enable_out_endpoint_({}) - State={:?}",
1049            endpoint,
1050            self.get_state()
1051        );
1052        self.registers.intenset.write(match endpoint {
1053            0 => Interrupt::ENDEPOUT0::SET,
1054            1 => Interrupt::ENDEPOUT1::SET,
1055            2 => Interrupt::ENDEPOUT2::SET,
1056            3 => Interrupt::ENDEPOUT3::SET,
1057            4 => Interrupt::ENDEPOUT4::SET,
1058            5 => Interrupt::ENDEPOUT5::SET,
1059            6 => Interrupt::ENDEPOUT6::SET,
1060            7 => Interrupt::ENDEPOUT7::SET,
1061            8 => Interrupt::ENDISOOUT::SET,
1062            _ => unreachable!("unexisting endpoint"),
1063        });
1064        self.registers.epouten.modify(match endpoint {
1065            0 => EndpointEnable::EP0::Enable,
1066            1 => EndpointEnable::EP1::Enable,
1067            2 => EndpointEnable::EP2::Enable,
1068            3 => EndpointEnable::EP3::Enable,
1069            4 => EndpointEnable::EP4::Enable,
1070            5 => EndpointEnable::EP5::Enable,
1071            6 => EndpointEnable::EP6::Enable,
1072            7 => EndpointEnable::EP7::Enable,
1073            8 => EndpointEnable::ISO::Enable,
1074            _ => unreachable!("unexisting endpoint"),
1075        });
1076        self.descriptors[endpoint].state.set(match endpoint {
1077            0 => EndpointState::Ctrl(CtrlState::Init),
1078            1..=7 => EndpointState::Bulk(transfer_type, None, Some(BulkOutState::Init)),
1079            8 => unimplemented!("isochronous endpoint"),
1080            _ => unreachable!("unexisting endpoint"),
1081        });
1082    }
1083
1084    fn enable_in_out_endpoint_(&self, transfer_type: TransferType, endpoint: usize) {
1085        debug_info!(
1086            "enable_in_out_endpoint_({}) - State={:?}",
1087            endpoint,
1088            self.get_state()
1089        );
1090        self.registers.intenset.write(match endpoint {
1091            0 => Interrupt::ENDEPIN0::SET + Interrupt::ENDEPOUT0::SET,
1092            1 => Interrupt::ENDEPIN1::SET + Interrupt::ENDEPOUT1::SET,
1093            2 => Interrupt::ENDEPIN2::SET + Interrupt::ENDEPOUT2::SET,
1094            3 => Interrupt::ENDEPIN3::SET + Interrupt::ENDEPOUT3::SET,
1095            4 => Interrupt::ENDEPIN4::SET + Interrupt::ENDEPOUT4::SET,
1096            5 => Interrupt::ENDEPIN5::SET + Interrupt::ENDEPOUT5::SET,
1097            6 => Interrupt::ENDEPIN6::SET + Interrupt::ENDEPOUT6::SET,
1098            7 => Interrupt::ENDEPIN7::SET + Interrupt::ENDEPOUT7::SET,
1099            8 => Interrupt::ENDISOIN::SET + Interrupt::ENDISOOUT::SET,
1100            _ => unreachable!("unexisting endpoint"),
1101        });
1102        self.registers.epinen.modify(match endpoint {
1103            0 => EndpointEnable::EP0::Enable,
1104            1 => EndpointEnable::EP1::Enable,
1105            2 => EndpointEnable::EP2::Enable,
1106            3 => EndpointEnable::EP3::Enable,
1107            4 => EndpointEnable::EP4::Enable,
1108            5 => EndpointEnable::EP5::Enable,
1109            6 => EndpointEnable::EP6::Enable,
1110            7 => EndpointEnable::EP7::Enable,
1111            8 => EndpointEnable::ISO::Enable,
1112            _ => unreachable!("unexisting endpoint"),
1113        });
1114        self.registers.epouten.modify(match endpoint {
1115            0 => EndpointEnable::EP0::Enable,
1116            1 => EndpointEnable::EP1::Enable,
1117            2 => EndpointEnable::EP2::Enable,
1118            3 => EndpointEnable::EP3::Enable,
1119            4 => EndpointEnable::EP4::Enable,
1120            5 => EndpointEnable::EP5::Enable,
1121            6 => EndpointEnable::EP6::Enable,
1122            7 => EndpointEnable::EP7::Enable,
1123            8 => EndpointEnable::ISO::Enable,
1124            _ => unreachable!("unexisting endpoint"),
1125        });
1126        self.descriptors[endpoint].state.set(match endpoint {
1127            0 => EndpointState::Ctrl(CtrlState::Init),
1128            1..=7 => EndpointState::Bulk(
1129                transfer_type,
1130                Some(BulkInState::Init),
1131                Some(BulkOutState::Init),
1132            ),
1133            8 => unimplemented!("isochronous endpoint"),
1134            _ => unreachable!("unexisting endpoint"),
1135        });
1136    }
1137
1138    fn ep_abort_all(&self) {
1139        internal_warn!("ep_abort_all() not implemented");
1140    }
1141
1142    pub fn enable_lowpower(&self) {
1143        internal_warn!("enable_lowpower() not implemented");
1144    }
1145
1146    pub fn disable_lowpower(&self) {
1147        internal_warn!("disable_lowpower() not implemented");
1148    }
1149
1150    pub fn handle_interrupt(&self) {
1151        // Save then disable all interrupts.
1152        let saved_inter = self.registers.intenset.extract();
1153        self.disable_all_interrupts();
1154
1155        let active_events = self.active_events(&saved_inter);
1156        let events_to_process = saved_inter.bitand(active_events.get());
1157
1158        // The following order in which we test events is important.
1159        // Interrupts should be processed from bit 0 to bit 31 but EP0SETUP must be last.
1160        if events_to_process.is_set(Interrupt::USBRESET) {
1161            self.handle_usbreset();
1162        }
1163        if events_to_process.is_set(Interrupt::STARTED) {
1164            self.handle_started();
1165        }
1166        // Note: isochronous endpoint receives a dedicated ENDISOIN interrupt instead.
1167        for ep in 0..NUM_ENDPOINTS {
1168            if events_to_process.is_set(inter_endepin(ep)) {
1169                self.handle_endepin(ep);
1170            }
1171        }
1172        if events_to_process.is_set(Interrupt::EP0DATADONE) {
1173            self.handle_ep0datadone();
1174        }
1175        if events_to_process.is_set(Interrupt::ENDISOIN) {
1176            self.handle_endisoin();
1177        }
1178        // Note: isochronous endpoint receives a dedicated ENDISOOUT interrupt instead.
1179        for ep in 0..NUM_ENDPOINTS {
1180            if events_to_process.is_set(inter_endepout(ep)) {
1181                self.handle_endepout(ep);
1182            }
1183        }
1184        if events_to_process.is_set(Interrupt::ENDISOOUT) {
1185            self.handle_endisoout();
1186        }
1187        if events_to_process.is_set(Interrupt::SOF) {
1188            self.handle_sof();
1189        }
1190        if events_to_process.is_set(Interrupt::USBEVENT) {
1191            self.handle_usbevent();
1192        }
1193        if events_to_process.is_set(Interrupt::EPDATA) {
1194            self.handle_epdata();
1195        }
1196
1197        self.process_dma_requests();
1198
1199        // Setup packet received.
1200        // This event must be handled last, even though EPDATA is after.
1201        if events_to_process.is_set(Interrupt::EP0SETUP) {
1202            self.handle_ep0setup();
1203        }
1204
1205        // Restore interrupts
1206        self.enable_interrupts(saved_inter.get());
1207    }
1208
1209    fn active_events(
1210        &self,
1211        _saved_inter: &LocalRegisterCopy<u32, Interrupt::Register>,
1212    ) -> InMemoryRegister<u32, Interrupt::Register> {
1213        let result = InMemoryRegister::new(0);
1214        if Usbd::take_event(&self.registers.event_usbreset) {
1215            debug_events!(
1216                "- event: usbreset{}",
1217                ignored_str(_saved_inter, Interrupt::USBRESET)
1218            );
1219            result.modify(Interrupt::USBRESET::SET);
1220        }
1221        if Usbd::take_event(&self.registers.event_started) {
1222            debug_events!(
1223                "- event: started{}",
1224                ignored_str(_saved_inter, Interrupt::STARTED)
1225            );
1226            result.modify(Interrupt::STARTED::SET);
1227        }
1228        for ep in 0..8 {
1229            if Usbd::take_event(&self.registers.event_endepin[ep]) {
1230                debug_events!(
1231                    "- event: endepin[{}]{}",
1232                    ep,
1233                    ignored_str(_saved_inter, inter_endepin(ep))
1234                );
1235                result.modify(inter_endepin(ep).val(1));
1236            }
1237        }
1238        if Usbd::take_event(&self.registers.event_ep0datadone) {
1239            debug_events!(
1240                "- event: ep0datadone{}",
1241                ignored_str(_saved_inter, Interrupt::EP0DATADONE)
1242            );
1243            result.modify(Interrupt::EP0DATADONE::SET);
1244        }
1245        if Usbd::take_event(&self.registers.event_endisoin) {
1246            debug_events!(
1247                "- event: endisoin{}",
1248                ignored_str(_saved_inter, Interrupt::ENDISOIN)
1249            );
1250            result.modify(Interrupt::ENDISOIN::SET);
1251        }
1252        for ep in 0..8 {
1253            if Usbd::take_event(&self.registers.event_endepout[ep]) {
1254                debug_events!(
1255                    "- event: endepout[{}]{}",
1256                    ep,
1257                    ignored_str(_saved_inter, inter_endepout(ep))
1258                );
1259                result.modify(inter_endepout(ep).val(1));
1260            }
1261        }
1262        if Usbd::take_event(&self.registers.event_endisoout) {
1263            debug_events!(
1264                "- event: endisoout{}",
1265                ignored_str(_saved_inter, Interrupt::ENDISOOUT)
1266            );
1267            result.modify(Interrupt::ENDISOOUT::SET);
1268        }
1269        if Usbd::take_event(&self.registers.event_sof) {
1270            debug_events!("- event: sof{}", ignored_str(_saved_inter, Interrupt::SOF));
1271            result.modify(Interrupt::SOF::SET);
1272        }
1273        if Usbd::take_event(&self.registers.event_usbevent) {
1274            debug_events!(
1275                "- event: usbevent{}",
1276                ignored_str(_saved_inter, Interrupt::USBEVENT)
1277            );
1278            result.modify(Interrupt::USBEVENT::SET);
1279        }
1280        if Usbd::take_event(&self.registers.event_ep0setup) {
1281            debug_events!(
1282                "- event: ep0setup{}",
1283                ignored_str(_saved_inter, Interrupt::EP0SETUP)
1284            );
1285            result.modify(Interrupt::EP0SETUP::SET);
1286        }
1287        if Usbd::take_event(&self.registers.event_epdata) {
1288            debug_events!(
1289                "- event: epdata{}",
1290                ignored_str(_saved_inter, Interrupt::EPDATA)
1291            );
1292            result.modify(Interrupt::EPDATA::SET);
1293        }
1294        result
1295    }
1296
1297    // Reads the status of an Event register and clears the register.
1298    // Returns the READY status.
1299    fn take_event(event: &ReadWrite<u32, Event::Register>) -> bool {
1300        let result = event.is_set(Event::READY);
1301        if result {
1302            event.write(Event::READY::CLEAR);
1303        }
1304        result
1305    }
1306
1307    fn handle_usbreset(&self) {
1308        for (ep, desc) in self.descriptors.iter().enumerate() {
1309            match desc.state.get() {
1310                EndpointState::Disabled => {}
1311                EndpointState::Ctrl(_) => desc.state.set(EndpointState::Ctrl(CtrlState::Init)),
1312                EndpointState::Bulk(transfer_type, in_state, out_state) => {
1313                    desc.state.set(EndpointState::Bulk(
1314                        transfer_type,
1315                        in_state.map(|_| BulkInState::Init),
1316                        out_state.map(|_| BulkOutState::Init),
1317                    ));
1318                    if out_state.is_some() {
1319                        // Accept incoming OUT packets.
1320                        self.registers.size_epout[ep].set(0);
1321                    }
1322                }
1323            }
1324            // Clear the DMA status.
1325            desc.request_transmit_in.set(false);
1326            desc.request_transmit_out.set(false);
1327        }
1328
1329        self.dma_pending.set(false);
1330
1331        // Wait for at least T_RSTRCY for the hardware to be ready after the USB
1332        // RESET (ยง6.35.6). I measured the loop using GPIO pins from `0..800000`
1333        // as a 62.5 ms delay, and that was enough to allow the CDC layer to
1334        // work. I tried shorter time than that (`0..700000`, measured at 54.7
1335        // ms), but then the EPDATA event on the very first IN transfer
1336        // immediately after the `client.bus_reset()` call below never occurs.
1337        for _ in 0..800000 {
1338            cortexm4f::support::nop();
1339        }
1340
1341        // TODO: reset controller stack
1342        self.client.map(|client| {
1343            client.bus_reset();
1344        });
1345    }
1346
1347    fn handle_started(&self) {
1348        let epstatus = self.registers.epstatus.extract();
1349        // Acknowledge the status by writing ones to the acknowledged bits.
1350        self.registers.epstatus.set(epstatus.get());
1351        debug_events!("epstatus: {:08X}", epstatus.get());
1352
1353        // Nothing to do here, we just wait for the corresponding ENDEP* event.
1354    }
1355
1356    fn handle_endepin(&self, endpoint: usize) {
1357        // Make DMA available again for other endpoints.
1358        self.clear_pending_dma();
1359
1360        match endpoint {
1361            0 => {}
1362            1..=7 => {
1363                let (transfer_type, in_state, out_state) =
1364                    self.descriptors[endpoint].state.get().bulk_state();
1365                assert_eq!(in_state, Some(BulkInState::InDma));
1366                self.descriptors[endpoint].state.set(EndpointState::Bulk(
1367                    transfer_type,
1368                    Some(BulkInState::InData),
1369                    out_state,
1370                ));
1371            }
1372            8 => unimplemented!("isochronous endpoint"),
1373            _ => unreachable!("unexisting endpoint"),
1374        }
1375
1376        // Nothing else to do. Wait for the EPDATA event.
1377    }
1378
1379    /// Data has been sent over the USB bus, and the hardware has ACKed it.
1380    /// This is for the control endpoint only.
1381    fn handle_ep0datadone(&self) {
1382        let endpoint = 0;
1383        let state = self.descriptors[endpoint].state.get().ctrl_state();
1384        match state {
1385            CtrlState::ReadIn => {
1386                if self.dma_pending.get() {
1387                    self.descriptors[endpoint].request_transmit_in.set(true);
1388                } else {
1389                    self.transmit_in_ep0();
1390                }
1391            }
1392
1393            CtrlState::ReadStatus => {
1394                self.complete_ctrl_status();
1395            }
1396
1397            CtrlState::WriteOut => {
1398                // We just completed the Setup stage for a CTRL WRITE transfer,
1399                // and now we need to enable DMA so the USBD peripheral can copy
1400                // the received data. If the DMA is in use, queue our request.
1401                if self.dma_pending.get() {
1402                    self.descriptors[endpoint].request_transmit_out.set(true);
1403                } else {
1404                    self.transmit_out_ep0();
1405                }
1406            }
1407
1408            CtrlState::Init => {
1409                // We shouldn't be there. Let's STALL the endpoint.
1410                debug_tasks!("- task: ep0stall");
1411                self.registers.task_ep0stall.write(Task::ENABLE::SET);
1412            }
1413        }
1414    }
1415
1416    fn handle_endisoin(&self) {
1417        unimplemented!("handle_endisoin");
1418    }
1419
1420    fn handle_endepout(&self, endpoint: usize) {
1421        // Make DMA available again for other endpoints.
1422        self.clear_pending_dma();
1423
1424        match endpoint {
1425            0 => {
1426                // We got data on the control endpoint during a CTRL WRITE
1427                // transfer. Let the client handle the data, and then finish up
1428                // the control write by moving to the status stage.
1429
1430                // Now we can handle it and pass it to the client to see
1431                // what the client returns.
1432                self.client.map(|client| {
1433                    match client.ctrl_out(endpoint, self.registers.size_epout[endpoint].get()) {
1434                        hil::usb::CtrlOutResult::Ok => {
1435                            // We only handle the simple case where we have
1436                            // received all of the data we need to.
1437                            //
1438                            // TODO: Check if the CTRL WRITE is longer
1439                            // than the amount of data we have received,
1440                            // and receive more data before completing.
1441                            self.complete_ctrl_status();
1442                        }
1443                        hil::usb::CtrlOutResult::Delay => {}
1444                        _ => {
1445                            // Respond with STALL to any following transactions
1446                            // in this request
1447                            debug_tasks!("- task: ep0stall");
1448                            self.registers.task_ep0stall.write(Task::ENABLE::SET);
1449                            self.descriptors[endpoint]
1450                                .state
1451                                .set(EndpointState::Ctrl(CtrlState::Init));
1452                        }
1453                    }
1454                });
1455            }
1456            1..=7 => {
1457                // Notify the client about the new packet.
1458                let (transfer_type, in_state, out_state) =
1459                    self.descriptors[endpoint].state.get().bulk_state();
1460                assert!(matches!(out_state, Some(BulkOutState::OutDma { .. })));
1461
1462                let packet_bytes = if let Some(BulkOutState::OutDma { size }) = out_state {
1463                    size
1464                } else {
1465                    0
1466                };
1467
1468                self.debug_out_packet(packet_bytes as usize, endpoint);
1469
1470                self.client.map(|client| {
1471                    let result = client.packet_out(transfer_type, endpoint, packet_bytes);
1472                    debug_packets!("packet_out => {:?}", result);
1473                    let new_out_state = match result {
1474                        hil::usb::OutResult::Ok => {
1475                            // We do not need to do anything to tell the USB
1476                            // hardware this endpoint is ready to receive again.
1477                            // The DMA finishing is enough to signal the
1478                            // endpoint is ready.
1479                            BulkOutState::Init
1480                        }
1481
1482                        hil::usb::OutResult::Delay => {
1483                            // We can't send the packet now. Wait for a resume_out call from the client.
1484                            BulkOutState::OutDelay
1485                        }
1486
1487                        hil::usb::OutResult::Error => {
1488                            self.registers.epstall.write(
1489                                EndpointStall::EP.val(endpoint as u32)
1490                                    + EndpointStall::IO::Out
1491                                    + EndpointStall::STALL::Stall,
1492                            );
1493                            BulkOutState::Init
1494                        }
1495                    };
1496                    self.descriptors[endpoint].state.set(EndpointState::Bulk(
1497                        transfer_type,
1498                        in_state,
1499                        Some(new_out_state),
1500                    ));
1501                });
1502            }
1503            8 => unimplemented!("isochronous endpoint"),
1504            _ => unreachable!("unexisting endpoint"),
1505        }
1506    }
1507
1508    fn handle_endisoout(&self) {
1509        unimplemented!("handle_endisoout");
1510    }
1511
1512    fn handle_sof(&self) {
1513        unimplemented!("handle_sof");
1514    }
1515
1516    fn handle_usbevent(&self) {
1517        let eventcause = self.registers.eventcause.extract();
1518        // Acknowledge the cause by writing ones to the acknowledged bits.
1519        self.registers.eventcause.set(eventcause.get());
1520
1521        debug_events!("eventcause: {:08x}", eventcause.get());
1522        if eventcause.is_set(EventCause::ISOOUTCRC) {
1523            debug_events!("- usbevent: isooutcrc");
1524            internal_warn!("usbc::isooutcrc not implemented");
1525        }
1526        if eventcause.is_set(EventCause::SUSPEND) {
1527            debug_events!("- usbevent: suspend");
1528            internal_warn!("usbc::suspend not implemented");
1529        }
1530        if eventcause.is_set(EventCause::RESUME) {
1531            debug_events!("- usbevent: resume");
1532            internal_warn!("usbc::resume not implemented");
1533        }
1534        if eventcause.is_set(EventCause::USBWUALLOWED) {
1535            debug_events!("- usbevent: usbwuallowed");
1536            internal_warn!("usbc::usbwuallowed not implemented");
1537        }
1538        if eventcause.is_set(EventCause::READY) {
1539            debug_events!("- usbevent: ready");
1540            internal_warn!("usbc::ready not implemented");
1541        }
1542    }
1543
1544    fn handle_epdata(&self) {
1545        let epdatastatus = self.registers.epdatastatus.extract();
1546        // Acknowledge the status by writing ones to the acknowledged bits.
1547        self.registers.epdatastatus.set(epdatastatus.get());
1548        debug_events!("epdatastatus: {:08X}", epdatastatus.get());
1549
1550        // Endpoint 0 (control) receives an EP0DATADONE event instead.
1551        // Endpoint 8 (isochronous) doesn't receive any EPDATA event.
1552        for endpoint in 1..NUM_ENDPOINTS {
1553            if epdatastatus.is_set(status_epin(endpoint)) {
1554                let (transfer_type, in_state, out_state) =
1555                    self.descriptors[endpoint].state.get().bulk_state();
1556                assert!(in_state.is_some());
1557                match in_state.unwrap() {
1558                    BulkInState::InData => {
1559                        // Totally expected state. Nothing to do.
1560                    }
1561                    BulkInState::Init => {
1562                        internal_warn!(
1563                            "Received a stale epdata IN in an unexpected state: {:?}",
1564                            in_state
1565                        );
1566                    }
1567                    BulkInState::InDma => {
1568                        internal_err!("Unexpected state: {:?}", in_state);
1569                    }
1570                }
1571                self.descriptors[endpoint].state.set(EndpointState::Bulk(
1572                    transfer_type,
1573                    Some(BulkInState::Init),
1574                    out_state,
1575                ));
1576                self.client
1577                    .map(|client| client.packet_transmitted(endpoint));
1578            }
1579        }
1580
1581        // Endpoint 0 (control) receives an EP0DATADONE event instead.
1582        // Endpoint 8 (isochronous) doesn't receive any EPDATA event.
1583        for ep in 1..NUM_ENDPOINTS {
1584            if epdatastatus.is_set(status_epout(ep)) {
1585                let (transfer_type, in_state, out_state) =
1586                    self.descriptors[ep].state.get().bulk_state();
1587                assert!(out_state.is_some());
1588
1589                // We need to read the size at this point in the process (i.e.
1590                // immediately after getting the EPDATA event). At this point
1591                // the USB hardware has received the data, but we need DMA to
1592                // copy the data to memory. Later on the EPOUT.SIZE register can
1593                // be overwritten, particularly if the host is sending OUT
1594                // transactions quickly.
1595                let ep_size = self.registers.size_epout[ep].get();
1596
1597                match out_state.unwrap() {
1598                    BulkOutState::Init => {
1599                        // The endpoint is ready to receive data. Request a transmit_out.
1600                        self.descriptors[ep].request_transmit_out.set(true);
1601                    }
1602                    BulkOutState::OutDelay => {
1603                        // The endpoint will be resumed later by the client application with transmit_out().
1604                    }
1605                    BulkOutState::OutData { size: _ } | BulkOutState::OutDma { size: _ } => {
1606                        internal_err!("Unexpected state: {:?}", out_state);
1607                    }
1608                }
1609                // Indicate that the endpoint now has data available.
1610                self.descriptors[ep].state.set(EndpointState::Bulk(
1611                    transfer_type,
1612                    in_state,
1613                    Some(BulkOutState::OutData { size: ep_size }),
1614                ));
1615            }
1616        }
1617    }
1618
1619    /// Handle the first event of a control transfer, the setup stage.
1620    fn handle_ep0setup(&self) {
1621        let endpoint = 0;
1622        let state = self.descriptors[endpoint].state.get().ctrl_state();
1623        match state {
1624            CtrlState::Init => {
1625                // We are idle, and ready for any control transfer.
1626
1627                let ep_buf = &self.descriptors[endpoint].slice_out;
1628                let ep_buf = ep_buf.unwrap_or_panic(); // Unwrap fail = No OUT slice set for this descriptor
1629                if ep_buf.len() < 8 {
1630                    panic!("EP0 DMA buffer length < 8");
1631                }
1632
1633                // Re-construct the SETUP packet from various registers. The
1634                // client's ctrl_setup() will parse it as a SetupData
1635                // descriptor.
1636                ep_buf[0].set((self.registers.bmrequesttype.get() & 0xff) as u8);
1637                ep_buf[1].set((self.registers.brequest.get() & 0xff) as u8);
1638                ep_buf[2].set(self.registers.wvaluel.read(Byte::VALUE) as u8);
1639                ep_buf[3].set(self.registers.wvalueh.read(Byte::VALUE) as u8);
1640                ep_buf[4].set(self.registers.windexl.read(Byte::VALUE) as u8);
1641                ep_buf[5].set(self.registers.windexh.read(Byte::VALUE) as u8);
1642                ep_buf[6].set(self.registers.wlengthl.read(Byte::VALUE) as u8);
1643                ep_buf[7].set(self.registers.wlengthh.read(Byte::VALUE) as u8);
1644                let size = self.registers.wlengthl.read(Byte::VALUE)
1645                    + (self.registers.wlengthh.read(Byte::VALUE) << 8);
1646
1647                self.client.map(|client| {
1648                    // Notify the client that the ctrl setup event has occurred.
1649                    // Allow it to configure any data we need to send back.
1650                    match client.ctrl_setup(endpoint) {
1651                        hil::usb::CtrlSetupResult::OkSetAddress => {}
1652                        hil::usb::CtrlSetupResult::Ok => {
1653                            // Setup request is successful.
1654                            if size == 0 {
1655                                // Directly handle a 0 length setup request.
1656                                self.complete_ctrl_status();
1657                            } else {
1658                                match self
1659                                    .registers
1660                                    .bmrequesttype
1661                                    .read_as_enum(RequestType::DIRECTION)
1662                                {
1663                                    Some(RequestType::DIRECTION::Value::HostToDevice) => {
1664                                        // CTRL WRITE transfer with data to
1665                                        // receive.
1666                                        self.descriptors[endpoint]
1667                                            .state
1668                                            .set(EndpointState::Ctrl(CtrlState::WriteOut));
1669
1670                                        // Signal the ep0rcvout task to signal
1671                                        // instruct the hardware to ACK the
1672                                        // incoming CTRL WRITE. Note, this
1673                                        // doesn't match the datasheet where it
1674                                        // says (ยง6.35.9.2):
1675                                        //
1676                                        // > The software has to prepare EasyDMA
1677                                        // > by pointing to the buffer in Data
1678                                        // > RAM that shall contain the incoming
1679                                        // > data. If no other EasyDMA transfers
1680                                        // > are on-going with USBD, the
1681                                        // > software can then send the
1682                                        // > EP0RCVOUT task.
1683                                        //
1684                                        // But, since we are not using the
1685                                        // EP0DATADONE->STARTEPOUT[0] shortcut,
1686                                        // and DMA only needs to be setup to
1687                                        // copy the bytes from the USBD
1688                                        // peripheral, we can wait until we get
1689                                        // the EP0DATADONE event to enable DMA.
1690                                        debug_tasks!("- task: ep0rcvout");
1691                                        self.registers.task_ep0rcvout.write(Task::ENABLE::SET);
1692                                    }
1693                                    Some(RequestType::DIRECTION::Value::DeviceToHost) => {
1694                                        self.descriptors[endpoint]
1695                                            .state
1696                                            .set(EndpointState::Ctrl(CtrlState::ReadIn));
1697                                        // Transmit first packet if DMA is
1698                                        // available.
1699                                        if self.dma_pending.get() {
1700                                            self.descriptors[endpoint]
1701                                                .request_transmit_in
1702                                                .set(true);
1703                                        } else {
1704                                            self.transmit_in_ep0();
1705                                        }
1706                                    }
1707                                    None => unreachable!(),
1708                                }
1709                            }
1710                        }
1711                        _err => {
1712                            // An error occurred, we STALL
1713                            debug_tasks!("- task: ep0stall");
1714                            self.registers.task_ep0stall.write(Task::ENABLE::SET);
1715                        }
1716                    }
1717                });
1718            }
1719
1720            CtrlState::ReadIn | CtrlState::ReadStatus | CtrlState::WriteOut => {
1721                // Unexpected state to receive a SETUP packet. Let's STALL the endpoint.
1722                internal_warn!("handle_ep0setup - unexpected state = {:?}", state);
1723                debug_tasks!("- task: ep0stall");
1724                self.registers.task_ep0stall.write(Task::ENABLE::SET);
1725            }
1726        }
1727    }
1728
1729    fn complete_ctrl_status(&self) {
1730        let endpoint = 0;
1731
1732        self.client.map(|client| {
1733            client.ctrl_status(endpoint);
1734            debug_tasks!("- task: ep0status");
1735            self.registers.task_ep0status.write(Task::ENABLE::SET);
1736            client.ctrl_status_complete(endpoint);
1737            self.descriptors[endpoint]
1738                .state
1739                .set(EndpointState::Ctrl(CtrlState::Init));
1740        });
1741    }
1742
1743    fn process_dma_requests(&self) {
1744        if self.dma_pending.get() {
1745            return;
1746        }
1747
1748        for (endpoint, desc) in self.descriptors.iter().enumerate() {
1749            if desc.request_transmit_in.take() {
1750                if endpoint == 0 {
1751                    self.transmit_in_ep0();
1752                } else {
1753                    self.transmit_in(endpoint);
1754                }
1755                if self.dma_pending.get() {
1756                    break;
1757                }
1758            }
1759            if desc.request_transmit_out.take() {
1760                if endpoint == 0 {
1761                    self.transmit_out_ep0();
1762                } else {
1763                    self.transmit_out(endpoint);
1764                }
1765                if self.dma_pending.get() {
1766                    break;
1767                }
1768            }
1769        }
1770    }
1771
1772    fn transmit_in_ep0(&self) {
1773        let endpoint = 0;
1774
1775        self.client.map(|client| {
1776            match client.ctrl_in(endpoint) {
1777                hil::usb::CtrlInResult::Packet(size, last) => {
1778                    if size == 0 {
1779                        internal_err!("Empty ctrl packet?");
1780                    }
1781                    self.start_dma_in(endpoint, size);
1782                    if last {
1783                        self.descriptors[endpoint]
1784                            .state
1785                            .set(EndpointState::Ctrl(CtrlState::ReadStatus));
1786                    }
1787                }
1788
1789                hil::usb::CtrlInResult::Delay => {
1790                    internal_err!("Unexpected CtrlInResult::Delay");
1791                    // NAK is automatically sent by the modem.
1792                }
1793
1794                hil::usb::CtrlInResult::Error => {
1795                    // An error occurred, we STALL
1796                    debug_tasks!("- task: ep0stall");
1797                    self.registers.task_ep0stall.write(Task::ENABLE::SET);
1798                }
1799            }
1800        });
1801    }
1802
1803    /// Setup a reception for a CTRL WRITE transaction.
1804    ///
1805    /// We have received the EP0DATADONE event signaling that the host has sent
1806    /// us data. We now need to configure DMA so that the peripheral can copy us
1807    /// the data.
1808    fn transmit_out_ep0(&self) {
1809        let endpoint = 0;
1810        self.start_dma_out(endpoint);
1811    }
1812
1813    fn transmit_in(&self, endpoint: usize) {
1814        debug_events!("transmit_in({})", endpoint);
1815
1816        self.client.map(|client| {
1817            let (transfer_type, in_state, out_state) =
1818                self.descriptors[endpoint].state.get().bulk_state();
1819            assert_eq!(in_state, Some(BulkInState::Init));
1820
1821            let result = client.packet_in(transfer_type, endpoint);
1822            debug_packets!("packet_in => {:?}", result);
1823            let new_in_state = match result {
1824                hil::usb::InResult::Packet(size) => {
1825                    self.start_dma_in(endpoint, size);
1826                    BulkInState::InDma
1827                }
1828
1829                hil::usb::InResult::Delay => {
1830                    // No packet to send now. Wait for a resume call from the client.
1831                    BulkInState::Init
1832                }
1833
1834                hil::usb::InResult::Error => {
1835                    self.registers.epstall.write(
1836                        EndpointStall::EP.val(endpoint as u32)
1837                            + EndpointStall::IO::In
1838                            + EndpointStall::STALL::Stall,
1839                    );
1840                    BulkInState::Init
1841                }
1842            };
1843
1844            self.descriptors[endpoint].state.set(EndpointState::Bulk(
1845                transfer_type,
1846                Some(new_in_state),
1847                out_state,
1848            ));
1849        });
1850    }
1851
1852    fn transmit_out(&self, endpoint: usize) {
1853        debug_events!("transmit_out({})", endpoint);
1854
1855        let (transfer_type, in_state, out_state) =
1856            self.descriptors[endpoint].state.get().bulk_state();
1857        // Starting the DMA can only happen in the OutData state, i.e. after an EPDATA event.
1858        assert!(matches!(out_state, Some(BulkOutState::OutData { .. })));
1859        self.start_dma_out(endpoint);
1860
1861        let size = if let Some(BulkOutState::OutData { size }) = out_state {
1862            size
1863        } else {
1864            0
1865        };
1866
1867        self.descriptors[endpoint].state.set(EndpointState::Bulk(
1868            transfer_type,
1869            in_state,
1870            Some(BulkOutState::OutDma { size }),
1871        ));
1872    }
1873
1874    fn start_dma_in(&self, endpoint: usize, size: usize) {
1875        let slice = self.descriptors[endpoint].slice_in.unwrap_or_panic(); // Unwrap fail = No IN slice set for this descriptor
1876        self.debug_in_packet(size, endpoint);
1877
1878        // Start DMA transfer
1879        self.set_pending_dma();
1880        self.registers.epin[endpoint].set_buffer(&slice[..size]);
1881        debug_tasks!("- task: startepin[{}]", endpoint);
1882        self.registers.task_startepin[endpoint].write(Task::ENABLE::SET);
1883    }
1884
1885    fn start_dma_out(&self, endpoint: usize) {
1886        let slice = self.descriptors[endpoint].slice_out.unwrap_or_panic(); // Unwrap fail = No OUT slice set for this descriptor
1887
1888        // Start DMA transfer
1889        self.set_pending_dma();
1890        self.registers.epout[endpoint].set_buffer(slice);
1891        debug_tasks!("- task: startepout[{}]", endpoint);
1892        self.registers.task_startepout[endpoint].write(Task::ENABLE::SET);
1893    }
1894
1895    // Debug-only function
1896    fn debug_in_packet(&self, size: usize, endpoint: usize) {
1897        let slice = self.descriptors[endpoint].slice_in.unwrap_or_panic(); // Unwrap fail = No IN slice set for this descriptor
1898        if size > slice.len() {
1899            panic!("Packet is too large: {}", size);
1900        }
1901
1902        let mut packet_hex = [0; 128];
1903        packet_to_hex(slice, &mut packet_hex);
1904        debug_packets!(
1905            "in={}",
1906            core::str::from_utf8(&packet_hex[..(2 * size)]).unwrap()
1907        );
1908    }
1909
1910    // Debug-only function
1911    fn debug_out_packet(&self, size: usize, endpoint: usize) {
1912        let slice = self.descriptors[endpoint].slice_out.unwrap_or_panic(); // Unwrap fail = No OUT slice set for this descriptor
1913        if size > slice.len() {
1914            panic!("Packet is too large: {}", size);
1915        }
1916
1917        let mut packet_hex = [0; 128];
1918        packet_to_hex(slice, &mut packet_hex);
1919        debug_packets!(
1920            "out={}",
1921            core::str::from_utf8(&packet_hex[..(2 * size)]).unwrap()
1922        );
1923    }
1924}
1925
1926impl power::PowerClient for Usbd<'_> {
1927    fn handle_power_event(&self, event: power::PowerEvent) {
1928        match event {
1929            power::PowerEvent::UsbPluggedIn => self.enable(),
1930            power::PowerEvent::UsbPluggedOut => self.disable(),
1931            power::PowerEvent::UsbPowerReady => self.power_ready(),
1932            _ => internal_warn!("usbc::handle_power_event: unknown power event"),
1933        }
1934    }
1935}
1936
1937impl<'a> hil::usb::UsbController<'a> for Usbd<'a> {
1938    fn set_client(&self, client: &'a dyn hil::usb::Client<'a>) {
1939        self.client.set(client);
1940    }
1941
1942    fn endpoint_set_ctrl_buffer(&self, buf: &'a [VolatileCell<u8>]) {
1943        if buf.len() < 8 {
1944            panic!("Endpoint buffer must be at least 8 bytes");
1945        }
1946        if !buf.len().is_power_of_two() {
1947            panic!("Buffer size must be a power of 2");
1948        }
1949        self.descriptors[0].slice_in.set(buf);
1950        self.descriptors[0].slice_out.set(buf);
1951    }
1952
1953    fn endpoint_set_in_buffer(&self, endpoint: usize, buf: &'a [VolatileCell<u8>]) {
1954        if buf.len() < 8 {
1955            panic!("Endpoint buffer must be at least 8 bytes");
1956        }
1957        if !buf.len().is_power_of_two() {
1958            panic!("Buffer size must be a power of 2");
1959        }
1960        if endpoint == 0 || endpoint >= NUM_ENDPOINTS {
1961            panic!("Endpoint number is invalid");
1962        }
1963        self.descriptors[endpoint].slice_in.set(buf);
1964    }
1965
1966    fn endpoint_set_out_buffer(&self, endpoint: usize, buf: &'a [VolatileCell<u8>]) {
1967        if buf.len() < 8 {
1968            panic!("Endpoint buffer must be at least 8 bytes");
1969        }
1970        if !buf.len().is_power_of_two() {
1971            panic!("Buffer size must be a power of 2");
1972        }
1973        if endpoint == 0 || endpoint >= NUM_ENDPOINTS {
1974            panic!("Endpoint number is invalid");
1975        }
1976        self.descriptors[endpoint].slice_out.set(buf);
1977    }
1978
1979    fn enable_as_device(&self, speed: hil::usb::DeviceSpeed) {
1980        match speed {
1981            hil::usb::DeviceSpeed::Low => internal_err!("Low speed is not supported"),
1982            hil::usb::DeviceSpeed::Full => {}
1983        }
1984        self.start();
1985    }
1986
1987    fn attach(&self) {
1988        debug_info!("attach() - State={:?}", self.get_state());
1989        self.enable_pullup();
1990    }
1991
1992    fn detach(&self) {
1993        debug_info!("detach() - Disabling pull-ups");
1994        self.disable_pullup();
1995    }
1996
1997    fn set_address(&self, _addr: u16) {
1998        // Nothing to do, it's handled by PHY of nrf52 chip.
1999        debug_info!("Set Address = {}", _addr);
2000    }
2001
2002    fn enable_address(&self) {
2003        let _regs = &*self.registers;
2004        debug_info!("Enable Address = {}", _regs.usbaddr.read(UsbAddress::ADDR));
2005        // Nothing to do, it's handled by PHY of nrf52 chip.
2006    }
2007
2008    fn endpoint_in_enable(&self, transfer_type: TransferType, endpoint: usize) {
2009        match transfer_type {
2010            TransferType::Control => {
2011                panic!("There is no IN control endpoint");
2012            }
2013            TransferType::Bulk | TransferType::Interrupt => {
2014                if endpoint == 0 || endpoint >= NUM_ENDPOINTS {
2015                    panic!("Bulk/Interrupt endpoints are endpoints 1 to 7");
2016                }
2017                self.enable_in_endpoint_(transfer_type, endpoint);
2018            }
2019            TransferType::Isochronous => unimplemented!("isochronous endpoint"),
2020        }
2021    }
2022
2023    fn endpoint_out_enable(&self, transfer_type: TransferType, endpoint: usize) {
2024        match transfer_type {
2025            TransferType::Control => {
2026                if endpoint != 0 {
2027                    panic!("Only endpoint 0 can be a control endpoint");
2028                }
2029                self.enable_out_endpoint_(transfer_type, endpoint);
2030            }
2031            TransferType::Bulk | TransferType::Interrupt => {
2032                if endpoint == 0 || endpoint >= NUM_ENDPOINTS {
2033                    panic!("Bulk/Interrupt endpoints are endpoints 1 to 7");
2034                }
2035                self.enable_out_endpoint_(transfer_type, endpoint);
2036            }
2037            TransferType::Isochronous => unimplemented!("isochronous endpoint"),
2038        }
2039    }
2040
2041    fn endpoint_in_out_enable(&self, transfer_type: TransferType, endpoint: usize) {
2042        match transfer_type {
2043            TransferType::Control => {
2044                panic!("There is no IN control endpoint");
2045            }
2046            TransferType::Bulk | TransferType::Interrupt => {
2047                if endpoint == 0 || endpoint >= NUM_ENDPOINTS {
2048                    panic!("Bulk/Interrupt endpoints are endpoints 1 to 7");
2049                }
2050                self.enable_in_out_endpoint_(transfer_type, endpoint);
2051            }
2052            TransferType::Isochronous => unimplemented!("isochronous endpoint"),
2053        }
2054    }
2055
2056    fn endpoint_resume_in(&self, endpoint: usize) {
2057        debug_events!("endpoint_resume_in({})", endpoint);
2058
2059        // Get the state of the endpoint that the upper layer requested to start
2060        // an IN transfer with for our state machine.
2061        let (_, in_state, _) = self.descriptors[endpoint].state.get().bulk_state();
2062        // If the state is `None`, this endpoint is not configured and should
2063        // not have been used to call `endpoint_resume_in()`.
2064        assert!(in_state.is_some());
2065
2066        // If there is an active DMA request, or we are waiting on finishing up
2067        // a previous IN transfer, we queue this request and it will be serviced
2068        // after those complete.
2069        if self.dma_pending.get() || in_state != Some(BulkInState::Init) {
2070            debug_events!("requesting resume_in[{}]", endpoint);
2071            // A DMA is already pending. Schedule the resume for later.
2072            self.descriptors[endpoint].request_transmit_in.set(true);
2073        } else {
2074            // If we aren't waiting on anything, trigger the transaction now.
2075            //
2076            // NOTE! TODO! We can't actually do this. This leads to an upcall
2077            // (`client.packet_in()`) happening as a direct result of a downcall
2078            // (this `endpoint_resume_in()` call). Unfortunately, the nRF52
2079            // doesn't give us a great interrupt to use to check the
2080            // `request_transmit_in` flag if we were to queue unconditionally in
2081            // `endpoint_resume_in()`.
2082            self.transmit_in(endpoint);
2083        }
2084    }
2085
2086    fn endpoint_resume_out(&self, endpoint: usize) {
2087        debug_events!("endpoint_resume_out({})", endpoint);
2088
2089        let (transfer_type, in_state, out_state) =
2090            self.descriptors[endpoint].state.get().bulk_state();
2091        assert!(out_state.is_some());
2092
2093        match out_state.unwrap() {
2094            BulkOutState::OutDelay => {
2095                // The endpoint has now finished processing the last ENDEPOUT. No EPDATA event
2096                // happened in the meantime, so the state is now back to Init.
2097                self.descriptors[endpoint].state.set(EndpointState::Bulk(
2098                    transfer_type,
2099                    in_state,
2100                    Some(BulkOutState::Init),
2101                ));
2102            }
2103            BulkOutState::OutData { size: _ } => {
2104                // Although the client reported a delay before, an EPDATA event has
2105                // happened in the meantime. This pending transaction will now
2106                // continue in transmit_out().
2107                if self.dma_pending.get() {
2108                    debug_events!("requesting resume_out[{}]", endpoint);
2109                    // A DMA is already pending. Schedule the resume for later.
2110                    self.descriptors[endpoint].request_transmit_out.set(true);
2111                } else {
2112                    // Trigger the transaction now.
2113                    self.transmit_out(endpoint);
2114                }
2115            }
2116            BulkOutState::Init | BulkOutState::OutDma { size: _ } => {
2117                internal_err!("Unexpected state: {:?}", out_state);
2118            }
2119        }
2120    }
2121}
2122
2123fn status_epin(ep: usize) -> Field<u32, EndpointStatus::Register> {
2124    match ep {
2125        0 => EndpointStatus::EPIN0,
2126        1 => EndpointStatus::EPIN1,
2127        2 => EndpointStatus::EPIN2,
2128        3 => EndpointStatus::EPIN3,
2129        4 => EndpointStatus::EPIN4,
2130        5 => EndpointStatus::EPIN5,
2131        6 => EndpointStatus::EPIN6,
2132        7 => EndpointStatus::EPIN7,
2133        8 => EndpointStatus::EPIN8,
2134        _ => unreachable!(),
2135    }
2136}
2137
2138fn status_epout(ep: usize) -> Field<u32, EndpointStatus::Register> {
2139    match ep {
2140        0 => EndpointStatus::EPOUT0,
2141        1 => EndpointStatus::EPOUT1,
2142        2 => EndpointStatus::EPOUT2,
2143        3 => EndpointStatus::EPOUT3,
2144        4 => EndpointStatus::EPOUT4,
2145        5 => EndpointStatus::EPOUT5,
2146        6 => EndpointStatus::EPOUT6,
2147        7 => EndpointStatus::EPOUT7,
2148        8 => EndpointStatus::EPOUT8,
2149        _ => unreachable!(),
2150    }
2151}
2152
2153fn inter_endepin(ep: usize) -> Field<u32, Interrupt::Register> {
2154    match ep {
2155        0 => Interrupt::ENDEPIN0,
2156        1 => Interrupt::ENDEPIN1,
2157        2 => Interrupt::ENDEPIN2,
2158        3 => Interrupt::ENDEPIN3,
2159        4 => Interrupt::ENDEPIN4,
2160        5 => Interrupt::ENDEPIN5,
2161        6 => Interrupt::ENDEPIN6,
2162        7 => Interrupt::ENDEPIN7,
2163        _ => unreachable!(),
2164    }
2165}
2166
2167fn inter_endepout(ep: usize) -> Field<u32, Interrupt::Register> {
2168    match ep {
2169        0 => Interrupt::ENDEPOUT0,
2170        1 => Interrupt::ENDEPOUT1,
2171        2 => Interrupt::ENDEPOUT2,
2172        3 => Interrupt::ENDEPOUT3,
2173        4 => Interrupt::ENDEPOUT4,
2174        5 => Interrupt::ENDEPOUT5,
2175        6 => Interrupt::ENDEPOUT6,
2176        7 => Interrupt::ENDEPOUT7,
2177        _ => unreachable!(),
2178    }
2179}
2180
2181// Debugging functions.
2182fn packet_to_hex(packet: &[VolatileCell<u8>], packet_hex: &mut [u8]) {
2183    let hex_char = |x: u8| {
2184        if x < 10 {
2185            b'0' + x
2186        } else {
2187            b'a' + x - 10
2188        }
2189    };
2190
2191    for (i, x) in packet.iter().enumerate() {
2192        let x = x.get();
2193        packet_hex[2 * i] = hex_char(x >> 4);
2194        packet_hex[2 * i + 1] = hex_char(x & 0x0f);
2195    }
2196}
2197
2198#[allow(dead_code)]
2199fn ignored_str(
2200    saved_inter: &LocalRegisterCopy<u32, Interrupt::Register>,
2201    field: Field<u32, Interrupt::Register>,
2202) -> &'static str {
2203    if saved_inter.is_set(field) {
2204        ""
2205    } else {
2206        " (ignored)"
2207    }
2208}