Skip to main content

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::with_interrupts_disabled;
9use kernel::hil;
10use kernel::hil::usb::TransferType;
11use kernel::utilities::StaticRef;
12use kernel::utilities::cells::OptionalCell;
13use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable};
14use kernel::utilities::registers::{
15    Field, InMemoryRegister, LocalRegisterCopy, ReadOnly, ReadWrite, WriteOnly, register_bitfields,
16    register_structs,
17};
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::registers::InMemoryRegister;
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: ReadWrite<u32>,
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 [InMemoryRegister<u8>]) {
329            self.ptr.set(slice.as_ptr().cast::<u8>() as u32);
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 [InMemoryRegister<u8>]>,
692    slice_out: OptionalCell<&'a [InMemoryRegister<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            with_interrupts_disabled(|| {
795                if USBERRATA_BASE.reg_c00.get() == 0 {
796                    USBERRATA_BASE.reg_c00.set(0x9375);
797                    USBERRATA_BASE.reg_c14.set(val);
798                    USBERRATA_BASE.reg_c00.set(0x9375);
799                } else {
800                    USBERRATA_BASE.reg_c14.set(val);
801                }
802            });
803        }
804    }
805
806    /// USB cannot be enabled
807    fn apply_errata_187(&self, val: u32) {
808        if self.has_errata_187() {
809            with_interrupts_disabled(|| {
810                if USBERRATA_BASE.reg_c00.get() == 0 {
811                    USBERRATA_BASE.reg_c00.set(0x9375);
812                    USBERRATA_BASE.reg_d14.set(val);
813                    USBERRATA_BASE.reg_c00.set(0x9375);
814                } else {
815                    USBERRATA_BASE.reg_d14.set(val);
816                }
817            });
818        }
819    }
820
821    fn apply_errata_199(&self, val: u32) {
822        if self.has_errata_199() {
823            self.registers.errata199.set(val);
824        }
825    }
826
827    pub fn get_state(&self) -> UsbState {
828        self.state.unwrap_or_panic() // Unwrap fail = get_state: state value is in use
829    }
830
831    // Powers the USB PHY on
832    fn enable(&self) {
833        if self.get_state() != UsbState::Disabled {
834            internal_warn!("USBC is already enabled");
835            return;
836        }
837        self.registers.eventcause.modify(EventCause::READY::CLEAR);
838        self.apply_errata_187(3);
839        self.apply_errata_171(0xc0);
840        self.registers.enable.write(Usb::ENABLE::ON);
841        while !self.registers.eventcause.is_set(EventCause::READY) {}
842        self.registers.eventcause.modify(EventCause::READY::CLEAR);
843        self.apply_errata_171(0);
844        self.apply_errata_166();
845        self.clear_pending_dma();
846        self.state.set(UsbState::Initialized);
847        self.apply_errata_187(0);
848    }
849
850    // TODO: unused function
851    fn _suspend(&self) {
852        debug_info!("usbc::suspend()");
853        self.ep_abort_all();
854        if self.registers.eventcause.is_set(EventCause::RESUME) {
855            return;
856        }
857        self.enable_lowpower();
858        if self.registers.eventcause.is_set(EventCause::RESUME) {
859            self.disable_lowpower();
860        } else {
861            self.apply_errata_171(0);
862        }
863        internal_warn!("suspend() not fully implemented");
864    }
865
866    fn disable_all_interrupts(&self) {
867        self.registers.intenclr.set(0xffffffff);
868    }
869
870    fn enable_interrupts(&self, inter: u32) {
871        self.registers.inten.set(inter);
872    }
873
874    fn power_ready(&self) {
875        match self.get_state() {
876            UsbState::Disabled => {
877                self.enable();
878                self.state.set(UsbState::PoweredOn);
879            }
880            UsbState::Initialized => self.state.set(UsbState::PoweredOn),
881            _ => (),
882        }
883    }
884
885    fn enable_pullup(&self) {
886        debug_info!("enable_pullup() - State={:?}", self.get_state());
887        if self.get_state() == UsbState::Started {
888            debug_info!("Enabling USB pullups");
889            self.registers.usbpullup.write(UsbPullup::CONNECT::Enabled);
890        }
891        self.state.set(UsbState::Attached);
892        debug_info!("New state is {:?}", self.get_state());
893    }
894
895    fn disable_pullup(&self) {
896        debug_info!("Disabling USB pullup - State={:?}", self.get_state());
897        self.registers.usbpullup.write(UsbPullup::CONNECT::Disabled);
898        self.state.set(UsbState::Started);
899        debug_info!("New state is {:?}", self.get_state());
900    }
901
902    // Allows the peripheral to be enumerated by the USB master
903    fn start(&self) {
904        debug_info!("usbc::start() - State={:?}", self.get_state());
905
906        // Depending on the chip model, there are more or less errata to add to the code. To
907        // simplify things, this implementation only includes errata relevant to nRF52840 chips
908        // revisions >= C.
909        //
910        // If your chip isn't one of these, you will be alerted by these panics. You can disable
911        // them but will likely need to add the relevant errata to this implementation (errata 104,
912        // 154, 200).
913        let chip_model = CHIPINFO_BASE.chip_model.get();
914        if chip_model != u32::from(ChipModel::MODEL::NRF52840) {
915            panic!(
916                "USB was only tested on NRF52840. Your chip model is {}.",
917                chip_model
918            );
919        }
920        let chip_revision = CHIPINFO_BASE.chip_revision.extract();
921        match chip_revision.read_as_enum(ChipRevision::REV) {
922            Some(ChipRevision::REV::Value::REVA) | Some(ChipRevision::REV::Value::REVB) => {
923                panic!(
924                    "Errata for USB on NRF52840 chips revisions A and B are not implemented. Your chip revision is {}.",
925                    chip_revision.get()
926                );
927            }
928            Some(ChipRevision::REV::Value::REVC)
929            | Some(ChipRevision::REV::Value::REVD)
930            | Some(ChipRevision::REV::Value::REVE)
931            | Some(ChipRevision::REV::Value::REVF) => {
932                debug_info!(
933                    "Your chip is NRF52840 revision {}. The USB stack was tested on your chip :)",
934                    chip_revision.get()
935                );
936            }
937            None => {
938                internal_warn!(
939                    "Your chip is NRF52840 revision {} (unknown revision). Although this USB implementation should be compatible, your chip hasn't been tested.",
940                    chip_revision.get()
941                );
942            }
943        }
944        let power = self.power.unwrap_or_panic(); // Unwrap fail = failed to initialize power reference for USB
945        if !power.is_vbus_present() {
946            debug_info!("[!] VBUS power is not detected.");
947            return;
948        }
949        if self.get_state() == UsbState::Disabled {
950            self.enable();
951        }
952        if self.get_state() != UsbState::PoweredOn {
953            debug_info!("Waiting for power regulators...");
954            while power.is_vbus_present() && power.is_usb_power_ready() {}
955        }
956        debug_info!("usbc::start() - subscribing to interrupts.");
957        self.registers.intenset.write(
958            Interrupt::USBRESET::SET
959                + Interrupt::STARTED::SET
960                + Interrupt::ENDEPIN0::SET
961                + Interrupt::EP0DATADONE::SET
962                + Interrupt::ENDEPOUT0::SET
963                + Interrupt::USBEVENT::SET
964                + Interrupt::EP0SETUP::SET
965                + Interrupt::EPDATA::SET,
966        );
967        self.state.set(UsbState::Started);
968    }
969
970    fn stop(&self) {
971        debug_info!("usbc::stop() - State={:?}", self.get_state());
972        if self.get_state() != UsbState::Started {
973            return;
974        }
975        self.ep_abort_all();
976        self.disable_all_interrupts();
977        self.registers.usbpullup.write(UsbPullup::CONNECT::Disabled);
978        self.state.set(UsbState::PoweredOn);
979    }
980
981    fn disable(&self) {
982        debug_info!("usbc::disable() - State={:?}", self.get_state());
983        self.stop();
984        self.registers.enable.write(Usb::ENABLE::OFF);
985        self.state.set(UsbState::Initialized);
986        self.clear_pending_dma();
987    }
988
989    fn clear_pending_dma(&self) {
990        debug_packets!("clear_pending_dma()");
991        self.apply_errata_199(0);
992        self.dma_pending.set(false);
993    }
994
995    fn set_pending_dma(&self) {
996        debug_packets!("set_pending_dma()");
997        if self.dma_pending.get() {
998            internal_err!("Pending DMA already in flight");
999        }
1000        self.apply_errata_199(0x82);
1001        self.dma_pending.set(true);
1002    }
1003
1004    fn enable_in_endpoint_(&self, transfer_type: TransferType, endpoint: usize) {
1005        debug_info!(
1006            "enable_in_endpoint_({}), State={:?}",
1007            endpoint,
1008            self.get_state()
1009        );
1010        self.registers.intenset.write(match endpoint {
1011            0 => Interrupt::ENDEPIN0::SET,
1012            1 => Interrupt::ENDEPIN1::SET,
1013            2 => Interrupt::ENDEPIN2::SET,
1014            3 => Interrupt::ENDEPIN3::SET,
1015            4 => Interrupt::ENDEPIN4::SET,
1016            5 => Interrupt::ENDEPIN5::SET,
1017            6 => Interrupt::ENDEPIN6::SET,
1018            7 => Interrupt::ENDEPIN7::SET,
1019            8 => Interrupt::ENDISOIN::SET,
1020            _ => unreachable!("unexisting endpoint"),
1021        });
1022        self.registers.epinen.modify(match endpoint {
1023            0 => EndpointEnable::EP0::Enable,
1024            1 => EndpointEnable::EP1::Enable,
1025            2 => EndpointEnable::EP2::Enable,
1026            3 => EndpointEnable::EP3::Enable,
1027            4 => EndpointEnable::EP4::Enable,
1028            5 => EndpointEnable::EP5::Enable,
1029            6 => EndpointEnable::EP6::Enable,
1030            7 => EndpointEnable::EP7::Enable,
1031            8 => EndpointEnable::ISO::Enable,
1032            _ => unreachable!("unexisting endpoint"),
1033        });
1034        self.descriptors[endpoint].state.set(match endpoint {
1035            0 => EndpointState::Ctrl(CtrlState::Init),
1036            1..=7 => EndpointState::Bulk(transfer_type, Some(BulkInState::Init), None),
1037            8 => unimplemented!("isochronous endpoint"),
1038            _ => unreachable!("unexisting endpoint"),
1039        });
1040    }
1041
1042    fn enable_out_endpoint_(&self, transfer_type: TransferType, endpoint: usize) {
1043        debug_info!(
1044            "enable_out_endpoint_({}) - State={:?}",
1045            endpoint,
1046            self.get_state()
1047        );
1048        self.registers.intenset.write(match endpoint {
1049            0 => Interrupt::ENDEPOUT0::SET,
1050            1 => Interrupt::ENDEPOUT1::SET,
1051            2 => Interrupt::ENDEPOUT2::SET,
1052            3 => Interrupt::ENDEPOUT3::SET,
1053            4 => Interrupt::ENDEPOUT4::SET,
1054            5 => Interrupt::ENDEPOUT5::SET,
1055            6 => Interrupt::ENDEPOUT6::SET,
1056            7 => Interrupt::ENDEPOUT7::SET,
1057            8 => Interrupt::ENDISOOUT::SET,
1058            _ => unreachable!("unexisting endpoint"),
1059        });
1060        self.registers.epouten.modify(match endpoint {
1061            0 => EndpointEnable::EP0::Enable,
1062            1 => EndpointEnable::EP1::Enable,
1063            2 => EndpointEnable::EP2::Enable,
1064            3 => EndpointEnable::EP3::Enable,
1065            4 => EndpointEnable::EP4::Enable,
1066            5 => EndpointEnable::EP5::Enable,
1067            6 => EndpointEnable::EP6::Enable,
1068            7 => EndpointEnable::EP7::Enable,
1069            8 => EndpointEnable::ISO::Enable,
1070            _ => unreachable!("unexisting endpoint"),
1071        });
1072        self.descriptors[endpoint].state.set(match endpoint {
1073            0 => EndpointState::Ctrl(CtrlState::Init),
1074            1..=7 => EndpointState::Bulk(transfer_type, None, Some(BulkOutState::Init)),
1075            8 => unimplemented!("isochronous endpoint"),
1076            _ => unreachable!("unexisting endpoint"),
1077        });
1078    }
1079
1080    fn enable_in_out_endpoint_(&self, transfer_type: TransferType, endpoint: usize) {
1081        debug_info!(
1082            "enable_in_out_endpoint_({}) - State={:?}",
1083            endpoint,
1084            self.get_state()
1085        );
1086        self.registers.intenset.write(match endpoint {
1087            0 => Interrupt::ENDEPIN0::SET + Interrupt::ENDEPOUT0::SET,
1088            1 => Interrupt::ENDEPIN1::SET + Interrupt::ENDEPOUT1::SET,
1089            2 => Interrupt::ENDEPIN2::SET + Interrupt::ENDEPOUT2::SET,
1090            3 => Interrupt::ENDEPIN3::SET + Interrupt::ENDEPOUT3::SET,
1091            4 => Interrupt::ENDEPIN4::SET + Interrupt::ENDEPOUT4::SET,
1092            5 => Interrupt::ENDEPIN5::SET + Interrupt::ENDEPOUT5::SET,
1093            6 => Interrupt::ENDEPIN6::SET + Interrupt::ENDEPOUT6::SET,
1094            7 => Interrupt::ENDEPIN7::SET + Interrupt::ENDEPOUT7::SET,
1095            8 => Interrupt::ENDISOIN::SET + Interrupt::ENDISOOUT::SET,
1096            _ => unreachable!("unexisting endpoint"),
1097        });
1098        self.registers.epinen.modify(match endpoint {
1099            0 => EndpointEnable::EP0::Enable,
1100            1 => EndpointEnable::EP1::Enable,
1101            2 => EndpointEnable::EP2::Enable,
1102            3 => EndpointEnable::EP3::Enable,
1103            4 => EndpointEnable::EP4::Enable,
1104            5 => EndpointEnable::EP5::Enable,
1105            6 => EndpointEnable::EP6::Enable,
1106            7 => EndpointEnable::EP7::Enable,
1107            8 => EndpointEnable::ISO::Enable,
1108            _ => unreachable!("unexisting endpoint"),
1109        });
1110        self.registers.epouten.modify(match endpoint {
1111            0 => EndpointEnable::EP0::Enable,
1112            1 => EndpointEnable::EP1::Enable,
1113            2 => EndpointEnable::EP2::Enable,
1114            3 => EndpointEnable::EP3::Enable,
1115            4 => EndpointEnable::EP4::Enable,
1116            5 => EndpointEnable::EP5::Enable,
1117            6 => EndpointEnable::EP6::Enable,
1118            7 => EndpointEnable::EP7::Enable,
1119            8 => EndpointEnable::ISO::Enable,
1120            _ => unreachable!("unexisting endpoint"),
1121        });
1122        self.descriptors[endpoint].state.set(match endpoint {
1123            0 => EndpointState::Ctrl(CtrlState::Init),
1124            1..=7 => EndpointState::Bulk(
1125                transfer_type,
1126                Some(BulkInState::Init),
1127                Some(BulkOutState::Init),
1128            ),
1129            8 => unimplemented!("isochronous endpoint"),
1130            _ => unreachable!("unexisting endpoint"),
1131        });
1132    }
1133
1134    fn ep_abort_all(&self) {
1135        internal_warn!("ep_abort_all() not implemented");
1136    }
1137
1138    pub fn enable_lowpower(&self) {
1139        internal_warn!("enable_lowpower() not implemented");
1140    }
1141
1142    pub fn disable_lowpower(&self) {
1143        internal_warn!("disable_lowpower() not implemented");
1144    }
1145
1146    pub fn handle_interrupt(&self) {
1147        // Save then disable all interrupts.
1148        let saved_inter = self.registers.intenset.extract();
1149        self.disable_all_interrupts();
1150
1151        let active_events = self.active_events(&saved_inter);
1152        let events_to_process = saved_inter.bitand(active_events.get());
1153
1154        // The following order in which we test events is important.
1155        // Interrupts should be processed from bit 0 to bit 31 but EP0SETUP must be last.
1156        if events_to_process.is_set(Interrupt::USBRESET) {
1157            self.handle_usbreset();
1158        }
1159        if events_to_process.is_set(Interrupt::STARTED) {
1160            self.handle_started();
1161        }
1162        // Note: isochronous endpoint receives a dedicated ENDISOIN interrupt instead.
1163        for ep in 0..NUM_ENDPOINTS {
1164            if events_to_process.is_set(inter_endepin(ep)) {
1165                self.handle_endepin(ep);
1166            }
1167        }
1168        if events_to_process.is_set(Interrupt::EP0DATADONE) {
1169            self.handle_ep0datadone();
1170        }
1171        if events_to_process.is_set(Interrupt::ENDISOIN) {
1172            self.handle_endisoin();
1173        }
1174        // Note: isochronous endpoint receives a dedicated ENDISOOUT interrupt instead.
1175        for ep in 0..NUM_ENDPOINTS {
1176            if events_to_process.is_set(inter_endepout(ep)) {
1177                self.handle_endepout(ep);
1178            }
1179        }
1180        if events_to_process.is_set(Interrupt::ENDISOOUT) {
1181            self.handle_endisoout();
1182        }
1183        if events_to_process.is_set(Interrupt::SOF) {
1184            self.handle_sof();
1185        }
1186        if events_to_process.is_set(Interrupt::USBEVENT) {
1187            self.handle_usbevent();
1188        }
1189        if events_to_process.is_set(Interrupt::EPDATA) {
1190            self.handle_epdata();
1191        }
1192
1193        self.process_dma_requests();
1194
1195        // Setup packet received.
1196        // This event must be handled last, even though EPDATA is after.
1197        if events_to_process.is_set(Interrupt::EP0SETUP) {
1198            self.handle_ep0setup();
1199        }
1200
1201        // Restore interrupts
1202        self.enable_interrupts(saved_inter.get());
1203    }
1204
1205    fn active_events(
1206        &self,
1207        _saved_inter: &LocalRegisterCopy<u32, Interrupt::Register>,
1208    ) -> InMemoryRegister<u32, Interrupt::Register> {
1209        let result = InMemoryRegister::new(0);
1210        if Usbd::take_event(&self.registers.event_usbreset) {
1211            debug_events!(
1212                "- event: usbreset{}",
1213                ignored_str(_saved_inter, Interrupt::USBRESET)
1214            );
1215            result.modify(Interrupt::USBRESET::SET);
1216        }
1217        if Usbd::take_event(&self.registers.event_started) {
1218            debug_events!(
1219                "- event: started{}",
1220                ignored_str(_saved_inter, Interrupt::STARTED)
1221            );
1222            result.modify(Interrupt::STARTED::SET);
1223        }
1224        for ep in 0..8 {
1225            if Usbd::take_event(&self.registers.event_endepin[ep]) {
1226                debug_events!(
1227                    "- event: endepin[{}]{}",
1228                    ep,
1229                    ignored_str(_saved_inter, inter_endepin(ep))
1230                );
1231                result.modify(inter_endepin(ep).val(1));
1232            }
1233        }
1234        if Usbd::take_event(&self.registers.event_ep0datadone) {
1235            debug_events!(
1236                "- event: ep0datadone{}",
1237                ignored_str(_saved_inter, Interrupt::EP0DATADONE)
1238            );
1239            result.modify(Interrupt::EP0DATADONE::SET);
1240        }
1241        if Usbd::take_event(&self.registers.event_endisoin) {
1242            debug_events!(
1243                "- event: endisoin{}",
1244                ignored_str(_saved_inter, Interrupt::ENDISOIN)
1245            );
1246            result.modify(Interrupt::ENDISOIN::SET);
1247        }
1248        for ep in 0..8 {
1249            if Usbd::take_event(&self.registers.event_endepout[ep]) {
1250                debug_events!(
1251                    "- event: endepout[{}]{}",
1252                    ep,
1253                    ignored_str(_saved_inter, inter_endepout(ep))
1254                );
1255                result.modify(inter_endepout(ep).val(1));
1256            }
1257        }
1258        if Usbd::take_event(&self.registers.event_endisoout) {
1259            debug_events!(
1260                "- event: endisoout{}",
1261                ignored_str(_saved_inter, Interrupt::ENDISOOUT)
1262            );
1263            result.modify(Interrupt::ENDISOOUT::SET);
1264        }
1265        if Usbd::take_event(&self.registers.event_sof) {
1266            debug_events!("- event: sof{}", ignored_str(_saved_inter, Interrupt::SOF));
1267            result.modify(Interrupt::SOF::SET);
1268        }
1269        if Usbd::take_event(&self.registers.event_usbevent) {
1270            debug_events!(
1271                "- event: usbevent{}",
1272                ignored_str(_saved_inter, Interrupt::USBEVENT)
1273            );
1274            result.modify(Interrupt::USBEVENT::SET);
1275        }
1276        if Usbd::take_event(&self.registers.event_ep0setup) {
1277            debug_events!(
1278                "- event: ep0setup{}",
1279                ignored_str(_saved_inter, Interrupt::EP0SETUP)
1280            );
1281            result.modify(Interrupt::EP0SETUP::SET);
1282        }
1283        if Usbd::take_event(&self.registers.event_epdata) {
1284            debug_events!(
1285                "- event: epdata{}",
1286                ignored_str(_saved_inter, Interrupt::EPDATA)
1287            );
1288            result.modify(Interrupt::EPDATA::SET);
1289        }
1290        result
1291    }
1292
1293    // Reads the status of an Event register and clears the register.
1294    // Returns the READY status.
1295    fn take_event(event: &ReadWrite<u32, Event::Register>) -> bool {
1296        let result = event.is_set(Event::READY);
1297        if result {
1298            event.write(Event::READY::CLEAR);
1299        }
1300        result
1301    }
1302
1303    fn handle_usbreset(&self) {
1304        for (ep, desc) in self.descriptors.iter().enumerate() {
1305            match desc.state.get() {
1306                EndpointState::Disabled => {}
1307                EndpointState::Ctrl(_) => desc.state.set(EndpointState::Ctrl(CtrlState::Init)),
1308                EndpointState::Bulk(transfer_type, in_state, out_state) => {
1309                    desc.state.set(EndpointState::Bulk(
1310                        transfer_type,
1311                        in_state.map(|_| BulkInState::Init),
1312                        out_state.map(|_| BulkOutState::Init),
1313                    ));
1314                    if out_state.is_some() {
1315                        // Accept incoming OUT packets.
1316                        self.registers.size_epout[ep].set(0);
1317                    }
1318                }
1319            }
1320            // Clear the DMA status.
1321            desc.request_transmit_in.set(false);
1322            desc.request_transmit_out.set(false);
1323        }
1324
1325        self.dma_pending.set(false);
1326
1327        // Wait for at least T_RSTRCY for the hardware to be ready after the USB
1328        // RESET (ยง6.35.6). I measured the loop using GPIO pins from `0..800000`
1329        // as a 62.5 ms delay, and that was enough to allow the CDC layer to
1330        // work. I tried shorter time than that (`0..700000`, measured at 54.7
1331        // ms), but then the EPDATA event on the very first IN transfer
1332        // immediately after the `client.bus_reset()` call below never occurs.
1333        for _ in 0..800000 {
1334            cortexm4f::support::nop();
1335        }
1336
1337        // TODO: reset controller stack
1338        self.client.map(|client| {
1339            client.bus_reset();
1340        });
1341    }
1342
1343    fn handle_started(&self) {
1344        let epstatus = self.registers.epstatus.extract();
1345        // Acknowledge the status by writing ones to the acknowledged bits.
1346        self.registers.epstatus.set(epstatus.get());
1347        debug_events!("epstatus: {:08X}", epstatus.get());
1348
1349        // Nothing to do here, we just wait for the corresponding ENDEP* event.
1350    }
1351
1352    fn handle_endepin(&self, endpoint: usize) {
1353        // Make DMA available again for other endpoints.
1354        self.clear_pending_dma();
1355
1356        match endpoint {
1357            0 => {}
1358            1..=7 => {
1359                let (transfer_type, in_state, out_state) =
1360                    self.descriptors[endpoint].state.get().bulk_state();
1361                assert_eq!(in_state, Some(BulkInState::InDma));
1362                self.descriptors[endpoint].state.set(EndpointState::Bulk(
1363                    transfer_type,
1364                    Some(BulkInState::InData),
1365                    out_state,
1366                ));
1367            }
1368            8 => unimplemented!("isochronous endpoint"),
1369            _ => unreachable!("unexisting endpoint"),
1370        }
1371
1372        // Nothing else to do. Wait for the EPDATA event.
1373    }
1374
1375    /// Data has been sent over the USB bus, and the hardware has ACKed it.
1376    /// This is for the control endpoint only.
1377    fn handle_ep0datadone(&self) {
1378        let endpoint = 0;
1379        let state = self.descriptors[endpoint].state.get().ctrl_state();
1380        match state {
1381            CtrlState::ReadIn => {
1382                if self.dma_pending.get() {
1383                    self.descriptors[endpoint].request_transmit_in.set(true);
1384                } else {
1385                    self.transmit_in_ep0();
1386                }
1387            }
1388
1389            CtrlState::ReadStatus => {
1390                self.complete_ctrl_status();
1391            }
1392
1393            CtrlState::WriteOut => {
1394                // We just completed the Setup stage for a CTRL WRITE transfer,
1395                // and now we need to enable DMA so the USBD peripheral can copy
1396                // the received data. If the DMA is in use, queue our request.
1397                if self.dma_pending.get() {
1398                    self.descriptors[endpoint].request_transmit_out.set(true);
1399                } else {
1400                    self.transmit_out_ep0();
1401                }
1402            }
1403
1404            CtrlState::Init => {
1405                // We shouldn't be there. Let's STALL the endpoint.
1406                debug_tasks!("- task: ep0stall");
1407                self.registers.task_ep0stall.write(Task::ENABLE::SET);
1408            }
1409        }
1410    }
1411
1412    fn handle_endisoin(&self) {
1413        unimplemented!("handle_endisoin");
1414    }
1415
1416    fn handle_endepout(&self, endpoint: usize) {
1417        // Make DMA available again for other endpoints.
1418        self.clear_pending_dma();
1419
1420        match endpoint {
1421            0 => {
1422                // We got data on the control endpoint during a CTRL WRITE
1423                // transfer. Let the client handle the data, and then finish up
1424                // the control write by moving to the status stage.
1425
1426                // Now we can handle it and pass it to the client to see
1427                // what the client returns.
1428                self.client.map(|client| {
1429                    match client.ctrl_out(endpoint, self.registers.size_epout[endpoint].get()) {
1430                        hil::usb::CtrlOutResult::Ok => {
1431                            // We only handle the simple case where we have
1432                            // received all of the data we need to.
1433                            //
1434                            // TODO: Check if the CTRL WRITE is longer
1435                            // than the amount of data we have received,
1436                            // and receive more data before completing.
1437                            self.complete_ctrl_status();
1438                        }
1439                        hil::usb::CtrlOutResult::Delay => {}
1440                        _ => {
1441                            // Respond with STALL to any following transactions
1442                            // in this request
1443                            debug_tasks!("- task: ep0stall");
1444                            self.registers.task_ep0stall.write(Task::ENABLE::SET);
1445                            self.descriptors[endpoint]
1446                                .state
1447                                .set(EndpointState::Ctrl(CtrlState::Init));
1448                        }
1449                    }
1450                });
1451            }
1452            1..=7 => {
1453                // Notify the client about the new packet.
1454                let (transfer_type, in_state, out_state) =
1455                    self.descriptors[endpoint].state.get().bulk_state();
1456                assert!(matches!(out_state, Some(BulkOutState::OutDma { .. })));
1457
1458                let packet_bytes = if let Some(BulkOutState::OutDma { size }) = out_state {
1459                    size
1460                } else {
1461                    0
1462                };
1463
1464                self.debug_out_packet(packet_bytes as usize, endpoint);
1465
1466                self.client.map(|client| {
1467                    let result = client.packet_out(transfer_type, endpoint, packet_bytes);
1468                    debug_packets!("packet_out => {:?}", result);
1469                    let new_out_state = match result {
1470                        hil::usb::OutResult::Ok => {
1471                            // We do not need to do anything to tell the USB
1472                            // hardware this endpoint is ready to receive again.
1473                            // The DMA finishing is enough to signal the
1474                            // endpoint is ready.
1475                            BulkOutState::Init
1476                        }
1477
1478                        hil::usb::OutResult::Delay => {
1479                            // We can't send the packet now. Wait for a resume_out call from the client.
1480                            BulkOutState::OutDelay
1481                        }
1482
1483                        hil::usb::OutResult::Error => {
1484                            self.registers.epstall.write(
1485                                EndpointStall::EP.val(endpoint as u32)
1486                                    + EndpointStall::IO::Out
1487                                    + EndpointStall::STALL::Stall,
1488                            );
1489                            BulkOutState::Init
1490                        }
1491                    };
1492                    self.descriptors[endpoint].state.set(EndpointState::Bulk(
1493                        transfer_type,
1494                        in_state,
1495                        Some(new_out_state),
1496                    ));
1497                });
1498            }
1499            8 => unimplemented!("isochronous endpoint"),
1500            _ => unreachable!("unexisting endpoint"),
1501        }
1502    }
1503
1504    fn handle_endisoout(&self) {
1505        unimplemented!("handle_endisoout");
1506    }
1507
1508    fn handle_sof(&self) {
1509        unimplemented!("handle_sof");
1510    }
1511
1512    fn handle_usbevent(&self) {
1513        let eventcause = self.registers.eventcause.extract();
1514        // Acknowledge the cause by writing ones to the acknowledged bits.
1515        self.registers.eventcause.set(eventcause.get());
1516
1517        debug_events!("eventcause: {:08x}", eventcause.get());
1518        if eventcause.is_set(EventCause::ISOOUTCRC) {
1519            debug_events!("- usbevent: isooutcrc");
1520            internal_warn!("usbc::isooutcrc not implemented");
1521        }
1522        if eventcause.is_set(EventCause::SUSPEND) {
1523            debug_events!("- usbevent: suspend");
1524            internal_warn!("usbc::suspend not implemented");
1525        }
1526        if eventcause.is_set(EventCause::RESUME) {
1527            debug_events!("- usbevent: resume");
1528            internal_warn!("usbc::resume not implemented");
1529        }
1530        if eventcause.is_set(EventCause::USBWUALLOWED) {
1531            debug_events!("- usbevent: usbwuallowed");
1532            internal_warn!("usbc::usbwuallowed not implemented");
1533        }
1534        if eventcause.is_set(EventCause::READY) {
1535            debug_events!("- usbevent: ready");
1536            internal_warn!("usbc::ready not implemented");
1537        }
1538    }
1539
1540    fn handle_epdata(&self) {
1541        let epdatastatus = self.registers.epdatastatus.extract();
1542        // Acknowledge the status by writing ones to the acknowledged bits.
1543        self.registers.epdatastatus.set(epdatastatus.get());
1544        debug_events!("epdatastatus: {:08X}", epdatastatus.get());
1545
1546        // Endpoint 0 (control) receives an EP0DATADONE event instead.
1547        // Endpoint 8 (isochronous) doesn't receive any EPDATA event.
1548        for endpoint in 1..NUM_ENDPOINTS {
1549            if epdatastatus.is_set(status_epin(endpoint)) {
1550                let (transfer_type, in_state, out_state) =
1551                    self.descriptors[endpoint].state.get().bulk_state();
1552                assert!(in_state.is_some());
1553                match in_state.unwrap() {
1554                    BulkInState::InData => {
1555                        // Totally expected state. Nothing to do.
1556                    }
1557                    BulkInState::Init => {
1558                        internal_warn!(
1559                            "Received a stale epdata IN in an unexpected state: {:?}",
1560                            in_state
1561                        );
1562                    }
1563                    BulkInState::InDma => {
1564                        internal_err!("Unexpected state: {:?}", in_state);
1565                    }
1566                }
1567                self.descriptors[endpoint].state.set(EndpointState::Bulk(
1568                    transfer_type,
1569                    Some(BulkInState::Init),
1570                    out_state,
1571                ));
1572                self.client
1573                    .map(|client| client.packet_transmitted(endpoint));
1574            }
1575        }
1576
1577        // Endpoint 0 (control) receives an EP0DATADONE event instead.
1578        // Endpoint 8 (isochronous) doesn't receive any EPDATA event.
1579        for ep in 1..NUM_ENDPOINTS {
1580            if epdatastatus.is_set(status_epout(ep)) {
1581                let (transfer_type, in_state, out_state) =
1582                    self.descriptors[ep].state.get().bulk_state();
1583                assert!(out_state.is_some());
1584
1585                // We need to read the size at this point in the process (i.e.
1586                // immediately after getting the EPDATA event). At this point
1587                // the USB hardware has received the data, but we need DMA to
1588                // copy the data to memory. Later on the EPOUT.SIZE register can
1589                // be overwritten, particularly if the host is sending OUT
1590                // transactions quickly.
1591                let ep_size = self.registers.size_epout[ep].get();
1592
1593                match out_state.unwrap() {
1594                    BulkOutState::Init => {
1595                        // The endpoint is ready to receive data. Request a transmit_out.
1596                        self.descriptors[ep].request_transmit_out.set(true);
1597                    }
1598                    BulkOutState::OutDelay => {
1599                        // The endpoint will be resumed later by the client application with transmit_out().
1600                    }
1601                    BulkOutState::OutData { size: _ } | BulkOutState::OutDma { size: _ } => {
1602                        internal_err!("Unexpected state: {:?}", out_state);
1603                    }
1604                }
1605                // Indicate that the endpoint now has data available.
1606                self.descriptors[ep].state.set(EndpointState::Bulk(
1607                    transfer_type,
1608                    in_state,
1609                    Some(BulkOutState::OutData { size: ep_size }),
1610                ));
1611            }
1612        }
1613    }
1614
1615    /// Handle the first event of a control transfer, the setup stage.
1616    fn handle_ep0setup(&self) {
1617        let endpoint = 0;
1618        let state = self.descriptors[endpoint].state.get().ctrl_state();
1619        match state {
1620            CtrlState::Init => {
1621                // We are idle, and ready for any control transfer.
1622
1623                let ep_buf = &self.descriptors[endpoint].slice_out;
1624                let ep_buf = ep_buf.unwrap_or_panic(); // Unwrap fail = No OUT slice set for this descriptor
1625                if ep_buf.len() < 8 {
1626                    panic!("EP0 DMA buffer length < 8");
1627                }
1628
1629                // Re-construct the SETUP packet from various registers. The
1630                // client's ctrl_setup() will parse it as a SetupData
1631                // descriptor.
1632                ep_buf[0].set((self.registers.bmrequesttype.get() & 0xff) as u8);
1633                ep_buf[1].set((self.registers.brequest.get() & 0xff) as u8);
1634                ep_buf[2].set(self.registers.wvaluel.read(Byte::VALUE) as u8);
1635                ep_buf[3].set(self.registers.wvalueh.read(Byte::VALUE) as u8);
1636                ep_buf[4].set(self.registers.windexl.read(Byte::VALUE) as u8);
1637                ep_buf[5].set(self.registers.windexh.read(Byte::VALUE) as u8);
1638                ep_buf[6].set(self.registers.wlengthl.read(Byte::VALUE) as u8);
1639                ep_buf[7].set(self.registers.wlengthh.read(Byte::VALUE) as u8);
1640                let size = self.registers.wlengthl.read(Byte::VALUE)
1641                    + (self.registers.wlengthh.read(Byte::VALUE) << 8);
1642
1643                self.client.map(|client| {
1644                    // Notify the client that the ctrl setup event has occurred.
1645                    // Allow it to configure any data we need to send back.
1646                    match client.ctrl_setup(endpoint) {
1647                        hil::usb::CtrlSetupResult::OkSetAddress => {}
1648                        hil::usb::CtrlSetupResult::Ok => {
1649                            // Setup request is successful.
1650                            if size == 0 {
1651                                // Directly handle a 0 length setup request.
1652                                self.complete_ctrl_status();
1653                            } else {
1654                                match self
1655                                    .registers
1656                                    .bmrequesttype
1657                                    .read_as_enum(RequestType::DIRECTION)
1658                                {
1659                                    Some(RequestType::DIRECTION::Value::HostToDevice) => {
1660                                        // CTRL WRITE transfer with data to
1661                                        // receive.
1662                                        self.descriptors[endpoint]
1663                                            .state
1664                                            .set(EndpointState::Ctrl(CtrlState::WriteOut));
1665
1666                                        // Signal the ep0rcvout task to signal
1667                                        // instruct the hardware to ACK the
1668                                        // incoming CTRL WRITE. Note, this
1669                                        // doesn't match the datasheet where it
1670                                        // says (ยง6.35.9.2):
1671                                        //
1672                                        // > The software has to prepare EasyDMA
1673                                        // > by pointing to the buffer in Data
1674                                        // > RAM that shall contain the incoming
1675                                        // > data. If no other EasyDMA transfers
1676                                        // > are on-going with USBD, the
1677                                        // > software can then send the
1678                                        // > EP0RCVOUT task.
1679                                        //
1680                                        // But, since we are not using the
1681                                        // EP0DATADONE->STARTEPOUT[0] shortcut,
1682                                        // and DMA only needs to be setup to
1683                                        // copy the bytes from the USBD
1684                                        // peripheral, we can wait until we get
1685                                        // the EP0DATADONE event to enable DMA.
1686                                        debug_tasks!("- task: ep0rcvout");
1687                                        self.registers.task_ep0rcvout.write(Task::ENABLE::SET);
1688                                    }
1689                                    Some(RequestType::DIRECTION::Value::DeviceToHost) => {
1690                                        self.descriptors[endpoint]
1691                                            .state
1692                                            .set(EndpointState::Ctrl(CtrlState::ReadIn));
1693                                        // Transmit first packet if DMA is
1694                                        // available.
1695                                        if self.dma_pending.get() {
1696                                            self.descriptors[endpoint]
1697                                                .request_transmit_in
1698                                                .set(true);
1699                                        } else {
1700                                            self.transmit_in_ep0();
1701                                        }
1702                                    }
1703                                    None => unreachable!(),
1704                                }
1705                            }
1706                        }
1707                        _err => {
1708                            // An error occurred, we STALL
1709                            debug_tasks!("- task: ep0stall");
1710                            self.registers.task_ep0stall.write(Task::ENABLE::SET);
1711                        }
1712                    }
1713                });
1714            }
1715
1716            CtrlState::ReadIn | CtrlState::ReadStatus | CtrlState::WriteOut => {
1717                // Unexpected state to receive a SETUP packet. Let's STALL the endpoint.
1718                internal_warn!("handle_ep0setup - unexpected state = {:?}", state);
1719                debug_tasks!("- task: ep0stall");
1720                self.registers.task_ep0stall.write(Task::ENABLE::SET);
1721            }
1722        }
1723    }
1724
1725    fn complete_ctrl_status(&self) {
1726        let endpoint = 0;
1727
1728        self.client.map(|client| {
1729            client.ctrl_status(endpoint);
1730            debug_tasks!("- task: ep0status");
1731            self.registers.task_ep0status.write(Task::ENABLE::SET);
1732            client.ctrl_status_complete(endpoint);
1733            self.descriptors[endpoint]
1734                .state
1735                .set(EndpointState::Ctrl(CtrlState::Init));
1736        });
1737    }
1738
1739    fn process_dma_requests(&self) {
1740        if self.dma_pending.get() {
1741            return;
1742        }
1743
1744        for (endpoint, desc) in self.descriptors.iter().enumerate() {
1745            if desc.request_transmit_in.take() {
1746                if endpoint == 0 {
1747                    self.transmit_in_ep0();
1748                } else {
1749                    self.transmit_in(endpoint);
1750                }
1751                if self.dma_pending.get() {
1752                    break;
1753                }
1754            }
1755            if desc.request_transmit_out.take() {
1756                if endpoint == 0 {
1757                    self.transmit_out_ep0();
1758                } else {
1759                    self.transmit_out(endpoint);
1760                }
1761                if self.dma_pending.get() {
1762                    break;
1763                }
1764            }
1765        }
1766    }
1767
1768    fn transmit_in_ep0(&self) {
1769        let endpoint = 0;
1770
1771        self.client.map(|client| {
1772            match client.ctrl_in(endpoint) {
1773                hil::usb::CtrlInResult::Packet(size, last) => {
1774                    if size == 0 {
1775                        internal_err!("Empty ctrl packet?");
1776                    }
1777                    self.start_dma_in(endpoint, size);
1778                    if last {
1779                        self.descriptors[endpoint]
1780                            .state
1781                            .set(EndpointState::Ctrl(CtrlState::ReadStatus));
1782                    }
1783                }
1784
1785                hil::usb::CtrlInResult::Delay => {
1786                    internal_err!("Unexpected CtrlInResult::Delay");
1787                    // NAK is automatically sent by the modem.
1788                }
1789
1790                hil::usb::CtrlInResult::Error => {
1791                    // An error occurred, we STALL
1792                    debug_tasks!("- task: ep0stall");
1793                    self.registers.task_ep0stall.write(Task::ENABLE::SET);
1794                }
1795            }
1796        });
1797    }
1798
1799    /// Setup a reception for a CTRL WRITE transaction.
1800    ///
1801    /// We have received the EP0DATADONE event signaling that the host has sent
1802    /// us data. We now need to configure DMA so that the peripheral can copy us
1803    /// the data.
1804    fn transmit_out_ep0(&self) {
1805        let endpoint = 0;
1806        self.start_dma_out(endpoint);
1807    }
1808
1809    fn transmit_in(&self, endpoint: usize) {
1810        debug_events!("transmit_in({})", endpoint);
1811
1812        self.client.map(|client| {
1813            let (transfer_type, in_state, out_state) =
1814                self.descriptors[endpoint].state.get().bulk_state();
1815            assert_eq!(in_state, Some(BulkInState::Init));
1816
1817            let result = client.packet_in(transfer_type, endpoint);
1818            debug_packets!("packet_in => {:?}", result);
1819            let new_in_state = match result {
1820                hil::usb::InResult::Packet(size) => {
1821                    self.start_dma_in(endpoint, size);
1822                    BulkInState::InDma
1823                }
1824
1825                hil::usb::InResult::Delay => {
1826                    // No packet to send now. Wait for a resume call from the client.
1827                    BulkInState::Init
1828                }
1829
1830                hil::usb::InResult::Error => {
1831                    self.registers.epstall.write(
1832                        EndpointStall::EP.val(endpoint as u32)
1833                            + EndpointStall::IO::In
1834                            + EndpointStall::STALL::Stall,
1835                    );
1836                    BulkInState::Init
1837                }
1838            };
1839
1840            self.descriptors[endpoint].state.set(EndpointState::Bulk(
1841                transfer_type,
1842                Some(new_in_state),
1843                out_state,
1844            ));
1845        });
1846    }
1847
1848    fn transmit_out(&self, endpoint: usize) {
1849        debug_events!("transmit_out({})", endpoint);
1850
1851        let (transfer_type, in_state, out_state) =
1852            self.descriptors[endpoint].state.get().bulk_state();
1853        // Starting the DMA can only happen in the OutData state, i.e. after an EPDATA event.
1854        assert!(matches!(out_state, Some(BulkOutState::OutData { .. })));
1855        self.start_dma_out(endpoint);
1856
1857        let size = if let Some(BulkOutState::OutData { size }) = out_state {
1858            size
1859        } else {
1860            0
1861        };
1862
1863        self.descriptors[endpoint].state.set(EndpointState::Bulk(
1864            transfer_type,
1865            in_state,
1866            Some(BulkOutState::OutDma { size }),
1867        ));
1868    }
1869
1870    fn start_dma_in(&self, endpoint: usize, size: usize) {
1871        let slice = self.descriptors[endpoint].slice_in.unwrap_or_panic(); // Unwrap fail = No IN slice set for this descriptor
1872        self.debug_in_packet(size, endpoint);
1873
1874        // Start DMA transfer
1875        self.set_pending_dma();
1876        self.registers.epin[endpoint].set_buffer(&slice[..size]);
1877        debug_tasks!("- task: startepin[{}]", endpoint);
1878        self.registers.task_startepin[endpoint].write(Task::ENABLE::SET);
1879    }
1880
1881    fn start_dma_out(&self, endpoint: usize) {
1882        let slice = self.descriptors[endpoint].slice_out.unwrap_or_panic(); // Unwrap fail = No OUT slice set for this descriptor
1883
1884        // Start DMA transfer
1885        self.set_pending_dma();
1886        self.registers.epout[endpoint].set_buffer(slice);
1887        debug_tasks!("- task: startepout[{}]", endpoint);
1888        self.registers.task_startepout[endpoint].write(Task::ENABLE::SET);
1889    }
1890
1891    // Debug-only function
1892    fn debug_in_packet(&self, size: usize, endpoint: usize) {
1893        let slice = self.descriptors[endpoint].slice_in.unwrap_or_panic(); // Unwrap fail = No IN slice set for this descriptor
1894        if size > slice.len() {
1895            panic!("Packet is too large: {}", size);
1896        }
1897
1898        let mut packet_hex = [0; 128];
1899        packet_to_hex(slice, &mut packet_hex);
1900        debug_packets!(
1901            "in={}",
1902            core::str::from_utf8(&packet_hex[..(2 * size)]).unwrap()
1903        );
1904    }
1905
1906    // Debug-only function
1907    fn debug_out_packet(&self, size: usize, endpoint: usize) {
1908        let slice = self.descriptors[endpoint].slice_out.unwrap_or_panic(); // Unwrap fail = No OUT slice set for this descriptor
1909        if size > slice.len() {
1910            panic!("Packet is too large: {}", size);
1911        }
1912
1913        let mut packet_hex = [0; 128];
1914        packet_to_hex(slice, &mut packet_hex);
1915        debug_packets!(
1916            "out={}",
1917            core::str::from_utf8(&packet_hex[..(2 * size)]).unwrap()
1918        );
1919    }
1920}
1921
1922impl power::PowerClient for Usbd<'_> {
1923    fn handle_power_event(&self, event: power::PowerEvent) {
1924        match event {
1925            power::PowerEvent::UsbPluggedIn => self.enable(),
1926            power::PowerEvent::UsbPluggedOut => self.disable(),
1927            power::PowerEvent::UsbPowerReady => self.power_ready(),
1928            _ => internal_warn!("usbc::handle_power_event: unknown power event"),
1929        }
1930    }
1931}
1932
1933impl<'a> hil::usb::UsbController<'a> for Usbd<'a> {
1934    fn set_client(&self, client: &'a dyn hil::usb::Client<'a>) {
1935        self.client.set(client);
1936    }
1937
1938    fn endpoint_set_ctrl_buffer(&self, buf: &'a [InMemoryRegister<u8>]) {
1939        if buf.len() < 8 {
1940            panic!("Endpoint buffer must be at least 8 bytes");
1941        }
1942        if !buf.len().is_power_of_two() {
1943            panic!("Buffer size must be a power of 2");
1944        }
1945        self.descriptors[0].slice_in.set(buf);
1946        self.descriptors[0].slice_out.set(buf);
1947    }
1948
1949    fn endpoint_set_in_buffer(&self, endpoint: usize, buf: &'a [InMemoryRegister<u8>]) {
1950        if buf.len() < 8 {
1951            panic!("Endpoint buffer must be at least 8 bytes");
1952        }
1953        if !buf.len().is_power_of_two() {
1954            panic!("Buffer size must be a power of 2");
1955        }
1956        if endpoint == 0 || endpoint >= NUM_ENDPOINTS {
1957            panic!("Endpoint number is invalid");
1958        }
1959        self.descriptors[endpoint].slice_in.set(buf);
1960    }
1961
1962    fn endpoint_set_out_buffer(&self, endpoint: usize, buf: &'a [InMemoryRegister<u8>]) {
1963        if buf.len() < 8 {
1964            panic!("Endpoint buffer must be at least 8 bytes");
1965        }
1966        if !buf.len().is_power_of_two() {
1967            panic!("Buffer size must be a power of 2");
1968        }
1969        if endpoint == 0 || endpoint >= NUM_ENDPOINTS {
1970            panic!("Endpoint number is invalid");
1971        }
1972        self.descriptors[endpoint].slice_out.set(buf);
1973    }
1974
1975    fn enable_as_device(&self, speed: hil::usb::DeviceSpeed) {
1976        match speed {
1977            hil::usb::DeviceSpeed::Low => internal_err!("Low speed is not supported"),
1978            hil::usb::DeviceSpeed::Full => {}
1979        }
1980        self.start();
1981    }
1982
1983    fn attach(&self) {
1984        debug_info!("attach() - State={:?}", self.get_state());
1985        self.enable_pullup();
1986    }
1987
1988    fn detach(&self) {
1989        debug_info!("detach() - Disabling pull-ups");
1990        self.disable_pullup();
1991    }
1992
1993    fn set_address(&self, _addr: u16) {
1994        // Nothing to do, it's handled by PHY of nrf52 chip.
1995        debug_info!("Set Address = {}", _addr);
1996    }
1997
1998    fn enable_address(&self) {
1999        let _regs = &*self.registers;
2000        debug_info!("Enable Address = {}", _regs.usbaddr.read(UsbAddress::ADDR));
2001        // Nothing to do, it's handled by PHY of nrf52 chip.
2002    }
2003
2004    fn endpoint_in_enable(&self, transfer_type: TransferType, endpoint: usize) {
2005        match transfer_type {
2006            TransferType::Control => {
2007                panic!("There is no IN control endpoint");
2008            }
2009            TransferType::Bulk | TransferType::Interrupt => {
2010                if endpoint == 0 || endpoint >= NUM_ENDPOINTS {
2011                    panic!("Bulk/Interrupt endpoints are endpoints 1 to 7");
2012                }
2013                self.enable_in_endpoint_(transfer_type, endpoint);
2014            }
2015            TransferType::Isochronous => unimplemented!("isochronous endpoint"),
2016        }
2017    }
2018
2019    fn endpoint_out_enable(&self, transfer_type: TransferType, endpoint: usize) {
2020        match transfer_type {
2021            TransferType::Control => {
2022                if endpoint != 0 {
2023                    panic!("Only endpoint 0 can be a control endpoint");
2024                }
2025                self.enable_out_endpoint_(transfer_type, endpoint);
2026            }
2027            TransferType::Bulk | TransferType::Interrupt => {
2028                if endpoint == 0 || endpoint >= NUM_ENDPOINTS {
2029                    panic!("Bulk/Interrupt endpoints are endpoints 1 to 7");
2030                }
2031                self.enable_out_endpoint_(transfer_type, endpoint);
2032            }
2033            TransferType::Isochronous => unimplemented!("isochronous endpoint"),
2034        }
2035    }
2036
2037    fn endpoint_in_out_enable(&self, transfer_type: TransferType, endpoint: usize) {
2038        match transfer_type {
2039            TransferType::Control => {
2040                panic!("There is no IN control endpoint");
2041            }
2042            TransferType::Bulk | TransferType::Interrupt => {
2043                if endpoint == 0 || endpoint >= NUM_ENDPOINTS {
2044                    panic!("Bulk/Interrupt endpoints are endpoints 1 to 7");
2045                }
2046                self.enable_in_out_endpoint_(transfer_type, endpoint);
2047            }
2048            TransferType::Isochronous => unimplemented!("isochronous endpoint"),
2049        }
2050    }
2051
2052    fn endpoint_resume_in(&self, endpoint: usize) {
2053        debug_events!("endpoint_resume_in({})", endpoint);
2054
2055        // Get the state of the endpoint that the upper layer requested to start
2056        // an IN transfer with for our state machine.
2057        let (_, in_state, _) = self.descriptors[endpoint].state.get().bulk_state();
2058        // If the state is `None`, this endpoint is not configured and should
2059        // not have been used to call `endpoint_resume_in()`.
2060        assert!(in_state.is_some());
2061
2062        // If there is an active DMA request, or we are waiting on finishing up
2063        // a previous IN transfer, we queue this request and it will be serviced
2064        // after those complete.
2065        if self.dma_pending.get() || in_state != Some(BulkInState::Init) {
2066            debug_events!("requesting resume_in[{}]", endpoint);
2067            // A DMA is already pending. Schedule the resume for later.
2068            self.descriptors[endpoint].request_transmit_in.set(true);
2069        } else {
2070            // If we aren't waiting on anything, trigger the transaction now.
2071            //
2072            // NOTE! TODO! We can't actually do this. This leads to an upcall
2073            // (`client.packet_in()`) happening as a direct result of a downcall
2074            // (this `endpoint_resume_in()` call). Unfortunately, the nRF52
2075            // doesn't give us a great interrupt to use to check the
2076            // `request_transmit_in` flag if we were to queue unconditionally in
2077            // `endpoint_resume_in()`.
2078            self.transmit_in(endpoint);
2079        }
2080    }
2081
2082    fn endpoint_resume_out(&self, endpoint: usize) {
2083        debug_events!("endpoint_resume_out({})", endpoint);
2084
2085        let (transfer_type, in_state, out_state) =
2086            self.descriptors[endpoint].state.get().bulk_state();
2087        assert!(out_state.is_some());
2088
2089        match out_state.unwrap() {
2090            BulkOutState::OutDelay => {
2091                // The endpoint has now finished processing the last ENDEPOUT. No EPDATA event
2092                // happened in the meantime, so the state is now back to Init.
2093                self.descriptors[endpoint].state.set(EndpointState::Bulk(
2094                    transfer_type,
2095                    in_state,
2096                    Some(BulkOutState::Init),
2097                ));
2098            }
2099            BulkOutState::OutData { size: _ } => {
2100                // Although the client reported a delay before, an EPDATA event has
2101                // happened in the meantime. This pending transaction will now
2102                // continue in transmit_out().
2103                if self.dma_pending.get() {
2104                    debug_events!("requesting resume_out[{}]", endpoint);
2105                    // A DMA is already pending. Schedule the resume for later.
2106                    self.descriptors[endpoint].request_transmit_out.set(true);
2107                } else {
2108                    // Trigger the transaction now.
2109                    self.transmit_out(endpoint);
2110                }
2111            }
2112            BulkOutState::Init | BulkOutState::OutDma { size: _ } => {
2113                internal_err!("Unexpected state: {:?}", out_state);
2114            }
2115        }
2116    }
2117}
2118
2119fn status_epin(ep: usize) -> Field<u32, EndpointStatus::Register> {
2120    match ep {
2121        0 => EndpointStatus::EPIN0,
2122        1 => EndpointStatus::EPIN1,
2123        2 => EndpointStatus::EPIN2,
2124        3 => EndpointStatus::EPIN3,
2125        4 => EndpointStatus::EPIN4,
2126        5 => EndpointStatus::EPIN5,
2127        6 => EndpointStatus::EPIN6,
2128        7 => EndpointStatus::EPIN7,
2129        8 => EndpointStatus::EPIN8,
2130        _ => unreachable!(),
2131    }
2132}
2133
2134fn status_epout(ep: usize) -> Field<u32, EndpointStatus::Register> {
2135    match ep {
2136        0 => EndpointStatus::EPOUT0,
2137        1 => EndpointStatus::EPOUT1,
2138        2 => EndpointStatus::EPOUT2,
2139        3 => EndpointStatus::EPOUT3,
2140        4 => EndpointStatus::EPOUT4,
2141        5 => EndpointStatus::EPOUT5,
2142        6 => EndpointStatus::EPOUT6,
2143        7 => EndpointStatus::EPOUT7,
2144        8 => EndpointStatus::EPOUT8,
2145        _ => unreachable!(),
2146    }
2147}
2148
2149fn inter_endepin(ep: usize) -> Field<u32, Interrupt::Register> {
2150    match ep {
2151        0 => Interrupt::ENDEPIN0,
2152        1 => Interrupt::ENDEPIN1,
2153        2 => Interrupt::ENDEPIN2,
2154        3 => Interrupt::ENDEPIN3,
2155        4 => Interrupt::ENDEPIN4,
2156        5 => Interrupt::ENDEPIN5,
2157        6 => Interrupt::ENDEPIN6,
2158        7 => Interrupt::ENDEPIN7,
2159        _ => unreachable!(),
2160    }
2161}
2162
2163fn inter_endepout(ep: usize) -> Field<u32, Interrupt::Register> {
2164    match ep {
2165        0 => Interrupt::ENDEPOUT0,
2166        1 => Interrupt::ENDEPOUT1,
2167        2 => Interrupt::ENDEPOUT2,
2168        3 => Interrupt::ENDEPOUT3,
2169        4 => Interrupt::ENDEPOUT4,
2170        5 => Interrupt::ENDEPOUT5,
2171        6 => Interrupt::ENDEPOUT6,
2172        7 => Interrupt::ENDEPOUT7,
2173        _ => unreachable!(),
2174    }
2175}
2176
2177// Debugging functions.
2178fn packet_to_hex(packet: &[InMemoryRegister<u8>], packet_hex: &mut [u8]) {
2179    let hex_char = |x: u8| {
2180        if x < 10 { b'0' + x } else { b'a' + x - 10 }
2181    };
2182
2183    for (i, x) in packet.iter().enumerate() {
2184        let x = x.get();
2185        packet_hex[2 * i] = hex_char(x >> 4);
2186        packet_hex[2 * i + 1] = hex_char(x & 0x0f);
2187    }
2188}
2189
2190#[allow(dead_code)]
2191fn ignored_str(
2192    saved_inter: &LocalRegisterCopy<u32, Interrupt::Register>,
2193    field: Field<u32, Interrupt::Register>,
2194) -> &'static str {
2195    if saved_inter.is_set(field) {
2196        ""
2197    } else {
2198        " (ignored)"
2199    }
2200}