diff --git a/embassy-nrf/src/chips/nrf52840.rs b/embassy-nrf/src/chips/nrf52840.rs index f5b90cd5..5aea0652 100644 --- a/embassy-nrf/src/chips/nrf52840.rs +++ b/embassy-nrf/src/chips/nrf52840.rs @@ -7,6 +7,10 @@ pub const FORCE_COPY_BUFFER_SIZE: usize = 512; pub const FLASH_SIZE: usize = 1024 * 1024; embassy_hal_common::peripherals! { + + // USB + USBD, + // RTC RTC0, RTC1, @@ -157,6 +161,8 @@ embassy_hal_common::peripherals! { TEMP, } +impl_usb!(USBD, USBD, USBD); + impl_uarte!(UARTE0, UARTE0, UARTE0_UART0); impl_uarte!(UARTE1, UARTE1, UARTE1); diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index 13e7803a..7434905e 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs @@ -48,6 +48,9 @@ pub mod temp; pub mod timer; pub mod twim; pub mod uarte; +//todo add nrf52833 nrf52840 +#[cfg(feature = "nrf52840")] +pub mod usb; #[cfg(not(feature = "_nrf5340"))] pub mod wdt; @@ -73,26 +76,6 @@ pub(crate) use chip::pac; pub use chip::{peripherals, Peripherals}; -#[cfg(any(feature = "nrf52820", feature = "nrf52833", feature = "nrf52840"))] -pub mod usb { - - use nrf_usbd::{UsbPeripheral, Usbd}; - use usb_device::bus::UsbBusAllocator; - - pub struct UsbBus; - unsafe impl UsbPeripheral for UsbBus { - const REGISTERS: *const () = crate::pac::USBD::ptr() as *const (); - } - - impl UsbBus { - pub fn new() -> UsbBusAllocator> { - Usbd::new(UsbBus) - } - } - - unsafe impl embassy_hal_common::usb::USBInterrupt for crate::interrupt::USBD {} -} - pub mod interrupt { pub use crate::chip::irqs::*; pub use cortex_m::interrupt::{CriticalSection, Mutex}; diff --git a/embassy-nrf/src/usb.rs b/embassy-nrf/src/usb.rs new file mode 100644 index 00000000..ca1d656a --- /dev/null +++ b/embassy-nrf/src/usb.rs @@ -0,0 +1,68 @@ +#![macro_use] + +use core::marker::PhantomData; +use embassy::util::Unborrow; + +use crate::interrupt::Interrupt; +use crate::pac; +use nrf_usbd::{UsbPeripheral, Usbd}; +use usb_device::bus::UsbBusAllocator; + +// todo using different type than Usb because T isnt Send +pub struct UsbBus; +unsafe impl UsbPeripheral for UsbBus { + // todo hardcoding + const REGISTERS: *const () = crate::pac::USBD::ptr() as *const (); +} + +impl UsbBus { + pub fn new() -> UsbBusAllocator> { + Usbd::new(UsbBus) + } +} + +unsafe impl embassy_hal_common::usb::USBInterrupt for crate::interrupt::USBD {} + +pub struct Usb<'d, T: Instance> { + phantom: PhantomData<&'d mut T>, +} + +impl<'d, T: Instance> Usb<'d, T> { + #[allow(unused_unsafe)] + pub fn new(_usb: impl Unborrow + 'd) -> Self { + let r = T::regs(); + + Self { + phantom: PhantomData, + } + } + + fn on_interrupt(_: *mut ()) { + let r = T::regs(); + } +} + +pub(crate) mod sealed { + use super::*; + + pub trait Instance { + fn regs() -> &'static pac::usbd::RegisterBlock; + } +} + +pub trait Instance: Unborrow + sealed::Instance + 'static { + type Interrupt: Interrupt; +} + +macro_rules! impl_usb { + ($type:ident, $pac_type:ident, $irq:ident) => { + impl crate::usb::sealed::Instance for peripherals::$type { + fn regs() -> &'static pac::usbd::RegisterBlock { + unsafe { &*pac::$pac_type::ptr() } + } + } + impl crate::usb::Instance for peripherals::$type { + type Interrupt = crate::interrupt::$irq; + } + }; +} diff --git a/examples/nrf/src/bin/usb_uart.rs b/examples/nrf/src/bin/usb_uart.rs index 383edb34..902075df 100644 --- a/examples/nrf/src/bin/usb_uart.rs +++ b/examples/nrf/src/bin/usb_uart.rs @@ -17,15 +17,17 @@ use embassy::executor::Spawner; use embassy::io::{AsyncBufReadExt, AsyncWriteExt}; use embassy::time::{Duration, Timer}; use embassy_hal_common::usb::{State, Usb, UsbSerial}; -use embassy_nrf::usb::UsbBus; +use embassy_nrf::usb::{Usb as UsbDevice, UsbBus}; use embassy_nrf::{interrupt, Peripherals}; use usb_device::device::{UsbDeviceBuilder, UsbVidPid}; #[embassy::main] -async fn main(_spawner: Spawner, _p: Peripherals) { +async fn main(_spawner: Spawner, p: Peripherals) { let mut tx_buffer = [0u8; 1024]; let mut rx_buffer = [0u8; 640]; + let _usb_dev = UsbDevice::new(p.USBD); + let usb_bus = UsbBus::new(); let serial = UsbSerial::new(&usb_bus, &mut rx_buffer, &mut tx_buffer);