1use 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
21macro_rules! debug_events {
25 [ $( $arg:expr ),+ ] => {
26 {} };
28}
29
30macro_rules! debug_tasks {
31 [ $( $arg:expr ),+ ] => {
32 {} };
34}
35
36macro_rules! debug_packets {
37 [ $( $arg:expr ),+ ] => {
38 {} };
40}
41
42macro_rules! debug_info {
43 [ $( $arg:expr ),+ ] => {
44 {} };
46}
47
48macro_rules! internal_warn {
49 [ $( $arg:expr ),+ ] => {
50 {} };
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 (0x000 => chip_model: ReadOnly<u32, ChipModel::Register>),
75 (0x004 => chip_revision: ReadOnly<u32, ChipRevision::Register>),
78 (0x008 => @END),
79 },
80
81 UsbErrataRegisters {
82 (0x000 => _reserved0),
83 (0xC00 => reg_c00: ReadWrite<u32>),
85 (0xC04 => _reserved1),
86 (0xC14 => reg_c14: WriteOnly<u32>),
88 (0xC18 => _reserved2),
89 (0xD14 => reg_d14: WriteOnly<u32>),
91 (0xD18 => @END),
92 }
93}
94
95#[repr(C)]
96struct UsbdRegisters<'a> {
97 _reserved1: [u32; 1],
98 task_startepin: [WriteOnly<u32, Task::Register>; NUM_ENDPOINTS],
103 task_startisoin: WriteOnly<u32, Task::Register>,
107 task_startepout: [WriteOnly<u32, Task::Register>; NUM_ENDPOINTS],
112 task_startisoout: WriteOnly<u32, Task::Register>,
116 task_ep0rcvout: WriteOnly<u32, Task::Register>,
119 task_ep0status: WriteOnly<u32, Task::Register>,
122 task_ep0stall: WriteOnly<u32, Task::Register>,
125 task_dpdmdrive: WriteOnly<u32, Task::Register>,
128 task_dpdmnodrive: WriteOnly<u32, Task::Register>,
131 _reserved2: [u32; 40],
132 event_usbreset: ReadWrite<u32, Event::Register>,
135 event_started: ReadWrite<u32, Event::Register>,
141 event_endepin: [ReadWrite<u32, Event::Register>; NUM_ENDPOINTS],
145 event_ep0datadone: ReadWrite<u32, Event::Register>,
148 event_endisoin: ReadWrite<u32, Event::Register>,
152 event_endepout: [ReadWrite<u32, Event::Register>; NUM_ENDPOINTS],
156 event_endisoout: ReadWrite<u32, Event::Register>,
160 event_sof: ReadWrite<u32, Event::Register>,
164 event_usbevent: ReadWrite<u32, Event::Register>,
168 event_ep0setup: ReadWrite<u32, Event::Register>,
172 event_epdata: ReadWrite<u32, Event::Register>,
176 _reserved3: [u32; 39],
177 shorts: ReadWrite<u32, Shorts::Register>,
180 _reserved4: [u32; 63],
181 inten: ReadWrite<u32, Interrupt::Register>,
184 intenset: ReadWrite<u32, Interrupt::Register>,
187 intenclr: ReadWrite<u32, Interrupt::Register>,
190 _reserved5: [u32; 61],
191 eventcause: ReadWrite<u32, EventCause::Register>,
194 _reserved6: [u32; 7],
195 halted_epin: [ReadOnly<u32, Halted::Register>; NUM_ENDPOINTS],
199 _reserved7: [u32; 1],
200 halted_epout: [ReadOnly<u32, Halted::Register>; NUM_ENDPOINTS],
204 _reserved8: [u32; 1],
205 epstatus: ReadWrite<u32, EndpointStatus::Register>,
209 epdatastatus: ReadWrite<u32, EndpointStatus::Register>,
213 usbaddr: ReadOnly<u32, UsbAddress::Register>,
216 _reserved9: [u32; 3],
217 bmrequesttype: ReadOnly<u32, RequestType::Register>,
220 brequest: ReadOnly<u32, Request::Register>,
223 wvaluel: ReadOnly<u32, Byte::Register>,
226 wvalueh: ReadOnly<u32, Byte::Register>,
229 windexl: ReadOnly<u32, Byte::Register>,
232 windexh: ReadOnly<u32, Byte::Register>,
235 wlengthl: ReadOnly<u32, Byte::Register>,
238 wlengthh: ReadOnly<u32, Byte::Register>,
241 size_epout: [ReadWrite<u32, EndpointSize::Register>; NUM_ENDPOINTS],
245 size_iosout: ReadOnly<u32, IsoEndpointSize::Register>,
248 _reserved10: [u32; 15],
249 enable: ReadWrite<u32, Usb::Register>,
252 usbpullup: ReadWrite<u32, UsbPullup::Register>,
255 dpdmvalue: ReadWrite<u32, DpDmValue::Register>,
260 dtoggle: ReadWrite<u32, Toggle::Register>,
263 epinen: ReadWrite<u32, EndpointEnable::Register>,
266 epouten: ReadWrite<u32, EndpointEnable::Register>,
269 epstall: WriteOnly<u32, EndpointStall::Register>,
272 isosplit: ReadWrite<u32, IsoSplit::Register>,
275 framecntr: ReadOnly<u32, FrameCounter::Register>,
278 _reserved11: [u32; 2],
279 lowpower: ReadWrite<u32, LowPower::Register>,
282 isoinconfig: ReadWrite<u32, IsoInConfig::Register>,
286 _reserved12: [u32; 51],
287 epin: [detail::EndpointRegisters<'a>; NUM_ENDPOINTS],
289 isoin: detail::EndpointRegisters<'a>,
291 _reserved13: [u32; 19],
292 epout: [detail::EndpointRegisters<'a>; NUM_ENDPOINTS],
294 isoout: detail::EndpointRegisters<'a>,
296 _reserved14: [u32; 19],
297 errata166_1: WriteOnly<u32>,
300 errata166_2: WriteOnly<u32>,
303 _reserved15: [u32; 261],
304 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 _reserved: [u32; 2],
323 _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 Task [
338 ENABLE OFFSET(0) NUMBITS(1)
339 ],
340
341 Event [
343 READY OFFSET(0) NUMBITS(1)
344 ],
345
346 Shorts [
348 EP0DATADONE_STARTEPIN0 OFFSET(0) NUMBITS(1),
350 EP0DATADONE_STARTEPOUT0 OFFSET(1) NUMBITS(1),
352 EP0DATADONE_EP0STATUS OFFSET(2) NUMBITS(1),
354 ENDEPOUT0_EP0STATUS OFFSET(3) NUMBITS(1),
356 ENDEPOUT0_EP0RCVOUT OFFSET(4) NUMBITS(1)
358 ],
359
360 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 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 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 MAXCNT OFFSET(0) NUMBITS(10)
592 ],
593
594 Amount [
595 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#[derive(Copy, Clone, PartialEq, Debug)]
654pub enum CtrlState {
655 Init,
657 ReadIn,
659 ReadStatus,
661 WriteOut,
663}
664
665#[derive(Copy, Clone, PartialEq, Debug)]
666pub enum BulkInState {
667 Init,
669 InDma,
671 InData,
673}
674
675#[derive(Copy, Clone, PartialEq, Debug)]
676pub enum BulkOutState {
677 Init,
679 OutDelay,
682 OutData { size: u32 },
685 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 request_transmit_in: Cell<bool>,
698 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 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 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 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 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() }
830
831 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 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 fn start(&self) {
904 debug_info!("usbc::start() - State={:?}", self.get_state());
905
906 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(); 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 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 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 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 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 if events_to_process.is_set(Interrupt::EP0SETUP) {
1198 self.handle_ep0setup();
1199 }
1200
1201 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 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 self.registers.size_epout[ep].set(0);
1317 }
1318 }
1319 }
1320 desc.request_transmit_in.set(false);
1322 desc.request_transmit_out.set(false);
1323 }
1324
1325 self.dma_pending.set(false);
1326
1327 for _ in 0..800000 {
1334 cortexm4f::support::nop();
1335 }
1336
1337 self.client.map(|client| {
1339 client.bus_reset();
1340 });
1341 }
1342
1343 fn handle_started(&self) {
1344 let epstatus = self.registers.epstatus.extract();
1345 self.registers.epstatus.set(epstatus.get());
1347 debug_events!("epstatus: {:08X}", epstatus.get());
1348
1349 }
1351
1352 fn handle_endepin(&self, endpoint: usize) {
1353 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 }
1374
1375 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 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 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 self.clear_pending_dma();
1419
1420 match endpoint {
1421 0 => {
1422 self.client.map(|client| {
1429 match client.ctrl_out(endpoint, self.registers.size_epout[endpoint].get()) {
1430 hil::usb::CtrlOutResult::Ok => {
1431 self.complete_ctrl_status();
1438 }
1439 hil::usb::CtrlOutResult::Delay => {}
1440 _ => {
1441 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 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 BulkOutState::Init
1476 }
1477
1478 hil::usb::OutResult::Delay => {
1479 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 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 self.registers.epdatastatus.set(epdatastatus.get());
1544 debug_events!("epdatastatus: {:08X}", epdatastatus.get());
1545
1546 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 }
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 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 let ep_size = self.registers.size_epout[ep].get();
1592
1593 match out_state.unwrap() {
1594 BulkOutState::Init => {
1595 self.descriptors[ep].request_transmit_out.set(true);
1597 }
1598 BulkOutState::OutDelay => {
1599 }
1601 BulkOutState::OutData { size: _ } | BulkOutState::OutDma { size: _ } => {
1602 internal_err!("Unexpected state: {:?}", out_state);
1603 }
1604 }
1605 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 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 let ep_buf = &self.descriptors[endpoint].slice_out;
1624 let ep_buf = ep_buf.unwrap_or_panic(); if ep_buf.len() < 8 {
1626 panic!("EP0 DMA buffer length < 8");
1627 }
1628
1629 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 match client.ctrl_setup(endpoint) {
1647 hil::usb::CtrlSetupResult::OkSetAddress => {}
1648 hil::usb::CtrlSetupResult::Ok => {
1649 if size == 0 {
1651 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 self.descriptors[endpoint]
1663 .state
1664 .set(EndpointState::Ctrl(CtrlState::WriteOut));
1665
1666 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 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 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 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 }
1789
1790 hil::usb::CtrlInResult::Error => {
1791 debug_tasks!("- task: ep0stall");
1793 self.registers.task_ep0stall.write(Task::ENABLE::SET);
1794 }
1795 }
1796 });
1797 }
1798
1799 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 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 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(); self.debug_in_packet(size, endpoint);
1873
1874 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(); 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 fn debug_in_packet(&self, size: usize, endpoint: usize) {
1893 let slice = self.descriptors[endpoint].slice_in.unwrap_or_panic(); 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 fn debug_out_packet(&self, size: usize, endpoint: usize) {
1908 let slice = self.descriptors[endpoint].slice_out.unwrap_or_panic(); 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 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 }
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 let (_, in_state, _) = self.descriptors[endpoint].state.get().bulk_state();
2058 assert!(in_state.is_some());
2061
2062 if self.dma_pending.get() || in_state != Some(BulkInState::Init) {
2066 debug_events!("requesting resume_in[{}]", endpoint);
2067 self.descriptors[endpoint].request_transmit_in.set(true);
2069 } else {
2070 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 self.descriptors[endpoint].state.set(EndpointState::Bulk(
2094 transfer_type,
2095 in_state,
2096 Some(BulkOutState::Init),
2097 ));
2098 }
2099 BulkOutState::OutData { size: _ } => {
2100 if self.dma_pending.get() {
2104 debug_events!("requesting resume_out[{}]", endpoint);
2105 self.descriptors[endpoint].request_transmit_out.set(true);
2107 } else {
2108 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
2177fn 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}