diff --git a/src/lib.rs b/src/lib.rs index 0fdeaef..76e7dbe 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,7 +6,7 @@ mod errata; mod pac; mod usbd; -pub use usbd::Usbd; +pub use usbd::{disable_usb_interrupts, enable_usb_interrupts, Usbd}; /// A trait for device-specific USB peripherals. Implement this to add support for a new hardware /// platform. Peripherals that have this trait must have the same register block as NRF52 USBD diff --git a/src/usbd.rs b/src/usbd.rs index 24c324b..56ca2e4 100644 --- a/src/usbd.rs +++ b/src/usbd.rs @@ -742,3 +742,83 @@ impl UsbBus for Usbd { Ok(()) } } + +/// Enable USB event interrupts used by [Usbd] +/// +/// This must be done with a borrow of the USBD peripheral, prior to +/// calling the [Usbd::new()] constructor. +/// +/// This only enables the events of the USBD peripheral, you will +/// Also need to activate the USBD interrupt in the NVIC. This is +/// handled automatically if you are using RTIC with a hardware +/// bound task. +pub fn enable_usb_interrupts(_usbd: &T) { + let usbd = unsafe { &*(T::REGISTERS as *const RegisterBlock) }; + + usbd.intenset.write(|w| { + // rg -o "events_[a-z_0-9]+" ./usbd.rs | sort | uniq + w.endepin0().set_bit(); + w.endepin1().set_bit(); + w.endepin2().set_bit(); + w.endepin3().set_bit(); + w.endepin4().set_bit(); + w.endepin5().set_bit(); + w.endepin6().set_bit(); + w.endepin7().set_bit(); + + w.endepout0().set_bit(); + w.endepout1().set_bit(); + w.endepout2().set_bit(); + w.endepout3().set_bit(); + w.endepout4().set_bit(); + w.endepout5().set_bit(); + w.endepout6().set_bit(); + w.endepout7().set_bit(); + + w.ep0datadone().set_bit(); + w.ep0setup().set_bit(); + w.sof().set_bit(); + w.usbevent().set_bit(); + w.usbreset().set_bit(); + w + }); +} + +/// Disable USB event interrupts used by [Usbd] +/// +/// This must be done with a borrow of the USBD peripheral. This may +/// require unsafe code to obtain, after the creation of [Usbd] +/// +/// This only disables the events of the USBD peripheral, you will +/// also need to deactivate the USBD interrupt in the NVIC. +pub fn disable_usb_interrupts(_usbd: &T) { + let usbd = unsafe { &*(T::REGISTERS as *const RegisterBlock) }; + + usbd.intenclr.write(|w| { + // rg -o "events_[a-z_0-9]+" ./usbd.rs | sort | uniq + w.endepin0().set_bit(); + w.endepin1().set_bit(); + w.endepin2().set_bit(); + w.endepin3().set_bit(); + w.endepin4().set_bit(); + w.endepin5().set_bit(); + w.endepin6().set_bit(); + w.endepin7().set_bit(); + + w.endepout0().set_bit(); + w.endepout1().set_bit(); + w.endepout2().set_bit(); + w.endepout3().set_bit(); + w.endepout4().set_bit(); + w.endepout5().set_bit(); + w.endepout6().set_bit(); + w.endepout7().set_bit(); + + w.ep0datadone().set_bit(); + w.ep0setup().set_bit(); + w.sof().set_bit(); + w.usbevent().set_bit(); + w.usbreset().set_bit(); + w + }); +}