From f430c0e8c2e9703220978d9976b058ecf0117c45 Mon Sep 17 00:00:00 2001 From: Jacob Rosenthal Date: Sun, 12 Dec 2021 17:13:37 -0700 Subject: [PATCH 01/20] nrf-usbd --- embassy-nrf/Cargo.toml | 2 + embassy-nrf/src/lib.rs | 16 ++++++ examples/nrf/Cargo.toml | 5 ++ examples/nrf/src/bin/usb_uart.rs | 94 ++++++++++++++++++++++++++++++++ 4 files changed, 117 insertions(+) create mode 100644 examples/nrf/src/bin/usb_uart.rs diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml index dae9f26a..b04d44b0 100644 --- a/embassy-nrf/Cargo.toml +++ b/embassy-nrf/Cargo.toml @@ -59,6 +59,8 @@ rand_core = "0.6.3" fixed = "1.10.0" embedded-storage = "0.2.0" cfg-if = "1.0.0" +nrf-usbd = "0.1.0" +usb-device = "0.2.8" nrf52805-pac = { version = "0.10.1", optional = true, features = [ "rt" ] } nrf52810-pac = { version = "0.10.1", optional = true, features = [ "rt" ] } diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index 5a73b87e..95e3b3e7 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs @@ -73,6 +73,22 @@ pub(crate) use chip::pac; pub use chip::{peripherals, Peripherals}; +use nrf_usbd::{UsbPeripheral, Usbd}; +use usb_device::bus::UsbBusAllocator; + +pub struct UsbBus; +unsafe impl UsbPeripheral for UsbBus { + const REGISTERS: *const () = pac::USBD::ptr() as *const (); +} + +impl UsbBus { + pub fn new() -> UsbBusAllocator> { + Usbd::new(UsbBus) + } +} + +unsafe impl embassy_hal_common::usb::USBInterrupt for interrupt::USBD {} + pub mod interrupt { pub use crate::chip::irqs::*; pub use cortex_m::interrupt::{CriticalSection, Mutex}; diff --git a/examples/nrf/Cargo.toml b/examples/nrf/Cargo.toml index 5c58541a..646ba496 100644 --- a/examples/nrf/Cargo.toml +++ b/examples/nrf/Cargo.toml @@ -9,6 +9,7 @@ version = "0.1.0" embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] } embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] } embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote"] } +embassy-hal-common = { version = "0.1.0", path = "../../embassy-hal-common" } defmt = "0.3" defmt-rtt = "0.3" @@ -20,3 +21,7 @@ panic-probe = { version = "0.3", features = ["print-defmt"] } futures = { version = "0.3.17", default-features = false, features = ["async-await"] } rand = { version = "0.8.4", default-features = false } embedded-storage = "0.2.0" + +usb-device = "0.2" +usbd-serial = "0.1.1" +nrf-usbd = "0.1.0" diff --git a/examples/nrf/src/bin/usb_uart.rs b/examples/nrf/src/bin/usb_uart.rs new file mode 100644 index 00000000..b81fd5ee --- /dev/null +++ b/examples/nrf/src/bin/usb_uart.rs @@ -0,0 +1,94 @@ +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +#[path = "../example_common.rs"] +mod example_common; + +use defmt::{info, unwrap}; +use defmt_rtt as _; +use embassy::interrupt::InterruptExt; +use futures::future::{select, Either}; +use futures::pin_mut; +// global logger +use panic_probe as _; // print out panic messages + +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::UsbBus; +use embassy_nrf::{interrupt, Peripherals}; +use usb_device::device::{UsbDeviceBuilder, UsbVidPid}; + +#[embassy::main] +async fn main(_spawner: Spawner, _p: Peripherals) { + let mut tx_buffer = [0u8; 1024]; + let mut rx_buffer = [0u8; 640]; + + let usb_bus = UsbBus::new(); + + let serial = UsbSerial::new(&usb_bus, &mut rx_buffer, &mut tx_buffer); + + let device = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x27dd)) + .manufacturer("Fake company") + .product("Serial port") + .serial_number("TEST") + .device_class(0x02) + .build(); + + let irq = interrupt::take!(USBD); + irq.set_priority(interrupt::Priority::P3); + + let mut state = State::new(); + + let usb = unsafe { Usb::new(&mut state, device, serial, irq) }; + pin_mut!(usb); + // usb.start(); + + let (mut read_interface, mut write_interface) = usb.as_ref().take_serial_0(); + + unwrap!(write_interface.write_all(b"\r\nSend something\r\n").await); + + info!("usb initialized!"); + + let mut buf = [0u8; 64]; + loop { + let mut n = 0; + let left = { + let recv_fut = async { + loop { + let byte = unwrap!(read_interface.read_byte().await); + unwrap!(write_interface.write_byte(byte).await); + buf[n] = byte; + + n += 1; + if byte == b'\n' || byte == b'\r' || n == buf.len() { + break; + } + } + }; + pin_mut!(recv_fut); + + let timeout = Timer::after(Duration::from_ticks(32768 * 10)); + + match select(recv_fut, timeout).await { + Either::Left(_) => true, + Either::Right(_) => false, + } + }; + + if left { + for c in buf[..n].iter_mut() { + if 0x61 <= *c && *c <= 0x7a { + *c &= !0x20; + } + } + unwrap!(write_interface.write_byte(b'\n').await); + unwrap!(write_interface.write_all(&buf[..n]).await); + unwrap!(write_interface.write_byte(b'\n').await); + } else { + unwrap!(write_interface.write_all(b"\r\nSend something\r\n").await); + } + } +} From e5dc63e8e99d1d818ed7ab3b13ffff3ee2c40a3d Mon Sep 17 00:00:00 2001 From: Jacob Rosenthal Date: Sun, 12 Dec 2021 21:32:51 -0700 Subject: [PATCH 02/20] usb feature gate --- embassy-hal-common/src/usb/mod.rs | 2 +- embassy-nrf/src/lib.rs | 26 +++++++++++++++----------- examples/nrf/src/bin/usb_uart.rs | 2 +- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/embassy-hal-common/src/usb/mod.rs b/embassy-hal-common/src/usb/mod.rs index 70a74bd5..bab72d8b 100644 --- a/embassy-hal-common/src/usb/mod.rs +++ b/embassy-hal-common/src/usb/mod.rs @@ -11,7 +11,7 @@ pub mod usb_serial; use crate::peripheral::{PeripheralMutex, PeripheralState, StateStorage}; use embassy::interrupt::Interrupt; -use usb_serial::{ReadInterface, UsbSerial, WriteInterface}; +pub use usb_serial::{ReadInterface, UsbSerial, WriteInterface}; /// Marker trait to mark an interrupt to be used with the [`Usb`] abstraction. pub unsafe trait USBInterrupt: Interrupt + Send {} diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index 95e3b3e7..13e7803a 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs @@ -73,21 +73,25 @@ pub(crate) use chip::pac; pub use chip::{peripherals, Peripherals}; -use nrf_usbd::{UsbPeripheral, Usbd}; -use usb_device::bus::UsbBusAllocator; +#[cfg(any(feature = "nrf52820", feature = "nrf52833", feature = "nrf52840"))] +pub mod usb { -pub struct UsbBus; -unsafe impl UsbPeripheral for UsbBus { - const REGISTERS: *const () = pac::USBD::ptr() as *const (); -} + use nrf_usbd::{UsbPeripheral, Usbd}; + use usb_device::bus::UsbBusAllocator; -impl UsbBus { - pub fn new() -> UsbBusAllocator> { - Usbd::new(UsbBus) + pub struct UsbBus; + unsafe impl UsbPeripheral for UsbBus { + const REGISTERS: *const () = crate::pac::USBD::ptr() as *const (); } -} -unsafe impl embassy_hal_common::usb::USBInterrupt for interrupt::USBD {} + 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::*; diff --git a/examples/nrf/src/bin/usb_uart.rs b/examples/nrf/src/bin/usb_uart.rs index b81fd5ee..383edb34 100644 --- a/examples/nrf/src/bin/usb_uart.rs +++ b/examples/nrf/src/bin/usb_uart.rs @@ -17,7 +17,7 @@ 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::UsbBus; +use embassy_nrf::usb::UsbBus; use embassy_nrf::{interrupt, Peripherals}; use usb_device::device::{UsbDeviceBuilder, UsbVidPid}; From 83a1237ea3f8b164749cb895b7bdb7a5696107f6 Mon Sep 17 00:00:00 2001 From: Jacob Rosenthal Date: Mon, 13 Dec 2021 17:50:08 -0700 Subject: [PATCH 03/20] stub out the embassy registers for usbd --- embassy-nrf/src/chips/nrf52840.rs | 6 +++ embassy-nrf/src/lib.rs | 23 ++--------- embassy-nrf/src/usb.rs | 68 +++++++++++++++++++++++++++++++ examples/nrf/src/bin/usb_uart.rs | 6 ++- 4 files changed, 81 insertions(+), 22 deletions(-) create mode 100644 embassy-nrf/src/usb.rs 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); From 535d30335a7c4ae47e923c5e85851df80d2021a0 Mon Sep 17 00:00:00 2001 From: Jacob Rosenthal Date: Mon, 13 Dec 2021 18:13:38 -0700 Subject: [PATCH 04/20] make send, consolidate usb types --- embassy-nrf/src/usb.rs | 21 ++++++--------------- examples/nrf/src/bin/usb_uart.rs | 6 ++---- 2 files changed, 8 insertions(+), 19 deletions(-) diff --git a/embassy-nrf/src/usb.rs b/embassy-nrf/src/usb.rs index ca1d656a..4e3fcaaa 100644 --- a/embassy-nrf/src/usb.rs +++ b/embassy-nrf/src/usb.rs @@ -8,17 +8,8 @@ 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<'d, T: Instance> UsbPeripheral for Usb<'d, T> { + const REGISTERS: *const () = T::regs as *const (); } unsafe impl embassy_hal_common::usb::USBInterrupt for crate::interrupt::USBD {} @@ -29,12 +20,12 @@ pub struct Usb<'d, T: Instance> { impl<'d, T: Instance> Usb<'d, T> { #[allow(unused_unsafe)] - pub fn new(_usb: impl Unborrow + 'd) -> Self { + pub fn new(_usb: impl Unborrow + 'd) -> UsbBusAllocator> { let r = T::regs(); - Self { + Usbd::new(Self { phantom: PhantomData, - } + }) } fn on_interrupt(_: *mut ()) { @@ -50,7 +41,7 @@ pub(crate) mod sealed { } } -pub trait Instance: Unborrow + sealed::Instance + 'static { +pub trait Instance: Unborrow + sealed::Instance + 'static + Send { type Interrupt: Interrupt; } diff --git a/examples/nrf/src/bin/usb_uart.rs b/examples/nrf/src/bin/usb_uart.rs index 902075df..86ead84b 100644 --- a/examples/nrf/src/bin/usb_uart.rs +++ b/examples/nrf/src/bin/usb_uart.rs @@ -17,7 +17,7 @@ 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::{Usb as UsbDevice, UsbBus}; +use embassy_nrf::usb::Usb as UsbDevice; use embassy_nrf::{interrupt, Peripherals}; use usb_device::device::{UsbDeviceBuilder, UsbVidPid}; @@ -26,9 +26,7 @@ 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 usb_bus = UsbDevice::new(p.USBD); let serial = UsbSerial::new(&usb_bus, &mut rx_buffer, &mut tx_buffer); From f31140a70bbc7c14b07acf6305eb8a0a73560e5a Mon Sep 17 00:00:00 2001 From: Jacob Rosenthal Date: Tue, 14 Dec 2021 13:51:50 -0700 Subject: [PATCH 05/20] revert --- embassy-nrf/src/usb.rs | 21 +++++++++++++++------ examples/nrf/src/bin/usb_uart.rs | 6 ++++-- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/embassy-nrf/src/usb.rs b/embassy-nrf/src/usb.rs index 4e3fcaaa..ca1d656a 100644 --- a/embassy-nrf/src/usb.rs +++ b/embassy-nrf/src/usb.rs @@ -8,8 +8,17 @@ use crate::pac; use nrf_usbd::{UsbPeripheral, Usbd}; use usb_device::bus::UsbBusAllocator; -unsafe impl<'d, T: Instance> UsbPeripheral for Usb<'d, T> { - const REGISTERS: *const () = T::regs as *const (); +// 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 {} @@ -20,12 +29,12 @@ pub struct Usb<'d, T: Instance> { impl<'d, T: Instance> Usb<'d, T> { #[allow(unused_unsafe)] - pub fn new(_usb: impl Unborrow + 'd) -> UsbBusAllocator> { + pub fn new(_usb: impl Unborrow + 'd) -> Self { let r = T::regs(); - Usbd::new(Self { + Self { phantom: PhantomData, - }) + } } fn on_interrupt(_: *mut ()) { @@ -41,7 +50,7 @@ pub(crate) mod sealed { } } -pub trait Instance: Unborrow + sealed::Instance + 'static + Send { +pub trait Instance: Unborrow + sealed::Instance + 'static { type Interrupt: Interrupt; } diff --git a/examples/nrf/src/bin/usb_uart.rs b/examples/nrf/src/bin/usb_uart.rs index 86ead84b..902075df 100644 --- a/examples/nrf/src/bin/usb_uart.rs +++ b/examples/nrf/src/bin/usb_uart.rs @@ -17,7 +17,7 @@ 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::Usb as UsbDevice; +use embassy_nrf::usb::{Usb as UsbDevice, UsbBus}; use embassy_nrf::{interrupt, Peripherals}; use usb_device::device::{UsbDeviceBuilder, UsbVidPid}; @@ -26,7 +26,9 @@ async fn main(_spawner: Spawner, p: Peripherals) { let mut tx_buffer = [0u8; 1024]; let mut rx_buffer = [0u8; 640]; - let usb_bus = UsbDevice::new(p.USBD); + let _usb_dev = UsbDevice::new(p.USBD); + + let usb_bus = UsbBus::new(); let serial = UsbSerial::new(&usb_bus, &mut rx_buffer, &mut tx_buffer); From 07cbd41131a89ec0982f0ac6a3237d0544375f97 Mon Sep 17 00:00:00 2001 From: Jacob Rosenthal Date: Tue, 14 Dec 2021 15:47:54 -0700 Subject: [PATCH 06/20] dont expose embedded_hal_common::usb --- embassy-nrf/src/chips/nrf52840.rs | 5 --- embassy-nrf/src/usb.rs | 75 +++++++++++++------------------ examples/nrf/src/bin/usb_uart.rs | 8 +--- 3 files changed, 32 insertions(+), 56 deletions(-) diff --git a/embassy-nrf/src/chips/nrf52840.rs b/embassy-nrf/src/chips/nrf52840.rs index 5aea0652..6e5e8ed9 100644 --- a/embassy-nrf/src/chips/nrf52840.rs +++ b/embassy-nrf/src/chips/nrf52840.rs @@ -8,9 +8,6 @@ pub const FLASH_SIZE: usize = 1024 * 1024; embassy_hal_common::peripherals! { - // USB - USBD, - // RTC RTC0, RTC1, @@ -161,8 +158,6 @@ 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/usb.rs b/embassy-nrf/src/usb.rs index ca1d656a..6776d569 100644 --- a/embassy-nrf/src/usb.rs +++ b/embassy-nrf/src/usb.rs @@ -5,64 +5,49 @@ use embassy::util::Unborrow; use crate::interrupt::Interrupt; use crate::pac; +use embassy_hal_common::usb::{ClassSet, IntoClassSet, USBInterrupt}; +pub use embassy_hal_common::usb::{ReadInterface, State, UsbSerial, WriteInterface}; use nrf_usbd::{UsbPeripheral, Usbd}; -use usb_device::bus::UsbBusAllocator; +use usb_device::{bus::UsbBusAllocator, class_prelude::UsbBus, device::UsbDevice}; -// todo using different type than Usb because T isnt Send -pub struct UsbBus; -unsafe impl UsbPeripheral for UsbBus { +pub struct UsbThing; +unsafe impl UsbPeripheral for UsbThing { // todo hardcoding const REGISTERS: *const () = crate::pac::USBD::ptr() as *const (); } -impl UsbBus { - pub fn new() -> UsbBusAllocator> { - Usbd::new(UsbBus) +impl UsbThing { + pub fn new() -> UsbBusAllocator> { + Usbd::new(UsbThing) } } unsafe impl embassy_hal_common::usb::USBInterrupt for crate::interrupt::USBD {} -pub struct Usb<'d, T: Instance> { - phantom: PhantomData<&'d mut T>, +pub struct Usb<'bus, B, T, I> +where + B: UsbBus, + T: ClassSet, + I: USBInterrupt, +{ + // Don't you dare moving out `PeripheralMutex` + usb: embassy_hal_common::usb::Usb<'bus, B, T, I>, } -impl<'d, T: Instance> Usb<'d, T> { - #[allow(unused_unsafe)] - pub fn new(_usb: impl Unborrow + 'd) -> Self { - let r = T::regs(); +impl<'bus, B, T, I> Usb<'bus, B, T, I> +where + B: UsbBus, + T: ClassSet, + I: USBInterrupt, +{ + pub unsafe fn new>( + state: &'bus mut State<'bus, B, T, I>, + device: UsbDevice<'bus, B>, + class_set: S, + irq: I, + ) -> Self { + let usb = embassy_hal_common::usb::Usb::new(state, device, class_set, irq); - Self { - phantom: PhantomData, - } - } - - fn on_interrupt(_: *mut ()) { - let r = T::regs(); + Self { usb } } } - -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 902075df..9313fdb1 100644 --- a/examples/nrf/src/bin/usb_uart.rs +++ b/examples/nrf/src/bin/usb_uart.rs @@ -16,8 +16,7 @@ use panic_probe as _; // print out panic messages 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::{Usb as UsbDevice, UsbBus}; +use embassy_nrf::usb::{ReadInterface, State, Usb, UsbSerial, UsbThing, WriteInterface}; use embassy_nrf::{interrupt, Peripherals}; use usb_device::device::{UsbDeviceBuilder, UsbVidPid}; @@ -26,12 +25,9 @@ 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 usb_bus = UsbThing::new(); let serial = UsbSerial::new(&usb_bus, &mut rx_buffer, &mut tx_buffer); - let device = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x27dd)) .manufacturer("Fake company") .product("Serial port") From 3debe604fbff1789794b452e630c0186836c1756 Mon Sep 17 00:00:00 2001 From: Jacob Rosenthal Date: Tue, 14 Dec 2021 16:48:48 -0700 Subject: [PATCH 07/20] sorta works, too many interupts? --- embassy-nrf/src/usb.rs | 49 +++++++++----------------------- examples/nrf/Cargo.toml | 1 - examples/nrf/src/bin/usb_uart.rs | 6 ++-- 3 files changed, 16 insertions(+), 40 deletions(-) diff --git a/embassy-nrf/src/usb.rs b/embassy-nrf/src/usb.rs index 6776d569..5008b8e6 100644 --- a/embassy-nrf/src/usb.rs +++ b/embassy-nrf/src/usb.rs @@ -1,14 +1,8 @@ #![macro_use] -use core::marker::PhantomData; -use embassy::util::Unborrow; - -use crate::interrupt::Interrupt; -use crate::pac; -use embassy_hal_common::usb::{ClassSet, IntoClassSet, USBInterrupt}; -pub use embassy_hal_common::usb::{ReadInterface, State, UsbSerial, WriteInterface}; +pub use embassy_hal_common::usb::*; use nrf_usbd::{UsbPeripheral, Usbd}; -use usb_device::{bus::UsbBusAllocator, class_prelude::UsbBus, device::UsbDevice}; +use usb_device::bus::UsbBusAllocator; pub struct UsbThing; unsafe impl UsbPeripheral for UsbThing { @@ -17,37 +11,20 @@ unsafe impl UsbPeripheral for UsbThing { } impl UsbThing { + // todo should it consume a USBD peripheral? pub fn new() -> UsbBusAllocator> { + unsafe { + (*crate::pac::USBD::ptr()).intenset.write(|w| { + w.sof().set_bit(); + w.usbevent().set_bit(); + w.ep0datadone().set_bit(); + w.ep0setup().set_bit(); + w.usbreset().set_bit() + }) + }; + Usbd::new(UsbThing) } } unsafe impl embassy_hal_common::usb::USBInterrupt for crate::interrupt::USBD {} - -pub struct Usb<'bus, B, T, I> -where - B: UsbBus, - T: ClassSet, - I: USBInterrupt, -{ - // Don't you dare moving out `PeripheralMutex` - usb: embassy_hal_common::usb::Usb<'bus, B, T, I>, -} - -impl<'bus, B, T, I> Usb<'bus, B, T, I> -where - B: UsbBus, - T: ClassSet, - I: USBInterrupt, -{ - pub unsafe fn new>( - state: &'bus mut State<'bus, B, T, I>, - device: UsbDevice<'bus, B>, - class_set: S, - irq: I, - ) -> Self { - let usb = embassy_hal_common::usb::Usb::new(state, device, class_set, irq); - - Self { usb } - } -} diff --git a/examples/nrf/Cargo.toml b/examples/nrf/Cargo.toml index 646ba496..a144cb71 100644 --- a/examples/nrf/Cargo.toml +++ b/examples/nrf/Cargo.toml @@ -9,7 +9,6 @@ version = "0.1.0" embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] } embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] } embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote"] } -embassy-hal-common = { version = "0.1.0", path = "../../embassy-hal-common" } defmt = "0.3" defmt-rtt = "0.3" diff --git a/examples/nrf/src/bin/usb_uart.rs b/examples/nrf/src/bin/usb_uart.rs index 9313fdb1..84bce65e 100644 --- a/examples/nrf/src/bin/usb_uart.rs +++ b/examples/nrf/src/bin/usb_uart.rs @@ -16,18 +16,19 @@ use panic_probe as _; // print out panic messages use embassy::executor::Spawner; use embassy::io::{AsyncBufReadExt, AsyncWriteExt}; use embassy::time::{Duration, Timer}; -use embassy_nrf::usb::{ReadInterface, State, Usb, UsbSerial, UsbThing, WriteInterface}; +use embassy_nrf::usb::{State, Usb, UsbSerial, UsbThing}; 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_bus = UsbThing::new(); let serial = UsbSerial::new(&usb_bus, &mut rx_buffer, &mut tx_buffer); + let device = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x27dd)) .manufacturer("Fake company") .product("Serial port") @@ -42,7 +43,6 @@ async fn main(_spawner: Spawner, p: Peripherals) { let usb = unsafe { Usb::new(&mut state, device, serial, irq) }; pin_mut!(usb); - // usb.start(); let (mut read_interface, mut write_interface) = usb.as_ref().take_serial_0(); From 5f0fefbd25333d11b6e4feb6450228c78524acd1 Mon Sep 17 00:00:00 2001 From: Jacob Rosenthal Date: Tue, 14 Dec 2021 16:51:29 -0700 Subject: [PATCH 08/20] dont rely on nrf-usdb --- examples/nrf/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/nrf/Cargo.toml b/examples/nrf/Cargo.toml index a144cb71..ca013f8b 100644 --- a/examples/nrf/Cargo.toml +++ b/examples/nrf/Cargo.toml @@ -23,4 +23,3 @@ embedded-storage = "0.2.0" usb-device = "0.2" usbd-serial = "0.1.1" -nrf-usbd = "0.1.0" From 2a6d92d641672a7fd81cca23c1b54a611aeea2e3 Mon Sep 17 00:00:00 2001 From: Jacob Rosenthal Date: Tue, 14 Dec 2021 16:53:13 -0700 Subject: [PATCH 09/20] cleanup --- embassy-nrf/src/chips/nrf52840.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/embassy-nrf/src/chips/nrf52840.rs b/embassy-nrf/src/chips/nrf52840.rs index 6e5e8ed9..f5b90cd5 100644 --- a/embassy-nrf/src/chips/nrf52840.rs +++ b/embassy-nrf/src/chips/nrf52840.rs @@ -7,7 +7,6 @@ pub const FORCE_COPY_BUFFER_SIZE: usize = 512; pub const FLASH_SIZE: usize = 1024 * 1024; embassy_hal_common::peripherals! { - // RTC RTC0, RTC1, From 79502330def843562b4e3fc502d687c00b3b649f Mon Sep 17 00:00:00 2001 From: Jacob Rosenthal Date: Wed, 15 Dec 2021 09:59:56 -0700 Subject: [PATCH 10/20] rename to UsbBus --- embassy-nrf/src/usb.rs | 10 +++++----- examples/nrf/src/bin/usb_uart.rs | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/embassy-nrf/src/usb.rs b/embassy-nrf/src/usb.rs index 5008b8e6..39e53429 100644 --- a/embassy-nrf/src/usb.rs +++ b/embassy-nrf/src/usb.rs @@ -4,15 +4,15 @@ pub use embassy_hal_common::usb::*; use nrf_usbd::{UsbPeripheral, Usbd}; use usb_device::bus::UsbBusAllocator; -pub struct UsbThing; -unsafe impl UsbPeripheral for UsbThing { +pub struct UsbBus; +unsafe impl UsbPeripheral for UsbBus { // todo hardcoding const REGISTERS: *const () = crate::pac::USBD::ptr() as *const (); } -impl UsbThing { +impl UsbBus { // todo should it consume a USBD peripheral? - pub fn new() -> UsbBusAllocator> { + pub fn new() -> UsbBusAllocator> { unsafe { (*crate::pac::USBD::ptr()).intenset.write(|w| { w.sof().set_bit(); @@ -23,7 +23,7 @@ impl UsbThing { }) }; - Usbd::new(UsbThing) + Usbd::new(UsbBus) } } diff --git a/examples/nrf/src/bin/usb_uart.rs b/examples/nrf/src/bin/usb_uart.rs index 84bce65e..1df37d4b 100644 --- a/examples/nrf/src/bin/usb_uart.rs +++ b/examples/nrf/src/bin/usb_uart.rs @@ -16,7 +16,7 @@ use panic_probe as _; // print out panic messages use embassy::executor::Spawner; use embassy::io::{AsyncBufReadExt, AsyncWriteExt}; use embassy::time::{Duration, Timer}; -use embassy_nrf::usb::{State, Usb, UsbSerial, UsbThing}; +use embassy_nrf::usb::{State, Usb, UsbBus, UsbSerial}; use embassy_nrf::{interrupt, Peripherals}; use usb_device::device::{UsbDeviceBuilder, UsbVidPid}; @@ -25,7 +25,7 @@ async fn main(_spawner: Spawner, _p: Peripherals) { let mut tx_buffer = [0u8; 1024]; let mut rx_buffer = [0u8; 640]; - let usb_bus = UsbThing::new(); + let usb_bus = UsbBus::new(); let serial = UsbSerial::new(&usb_bus, &mut rx_buffer, &mut tx_buffer); From 1c0a3688a478cd05067c879751180097e3abf491 Mon Sep 17 00:00:00 2001 From: Jacob Rosenthal Date: Wed, 15 Dec 2021 10:00:17 -0700 Subject: [PATCH 11/20] use forked nrf-usbd --- embassy-nrf/Cargo.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml index b04d44b0..7e090344 100644 --- a/embassy-nrf/Cargo.toml +++ b/embassy-nrf/Cargo.toml @@ -59,7 +59,8 @@ rand_core = "0.6.3" fixed = "1.10.0" embedded-storage = "0.2.0" cfg-if = "1.0.0" -nrf-usbd = "0.1.0" +nrf-usbd = {version = "0.1.0", git="https://github.com/jacobrosenthal/nrf-usbd", branch="critical-section"} +# nrf-usbd = {version = "0.2.0"} usb-device = "0.2.8" nrf52805-pac = { version = "0.10.1", optional = true, features = [ "rt" ] } From 61f12324ff987cc1b8bbd8fe3e7096bd7285485d Mon Sep 17 00:00:00 2001 From: Jacob Rosenthal Date: Wed, 15 Dec 2021 10:11:00 -0700 Subject: [PATCH 12/20] enable USB peripheral for relevant chips --- embassy-nrf/src/chips/nrf52820.rs | 3 ++ embassy-nrf/src/chips/nrf52833.rs | 5 +++ embassy-nrf/src/chips/nrf52840.rs | 5 +++ embassy-nrf/src/chips/nrf5340_app.rs | 5 +++ embassy-nrf/src/lib.rs | 8 +++-- embassy-nrf/src/usb.rs | 54 ++++++++++++++++++++++------ examples/nrf/src/bin/usb_uart.rs | 4 +-- 7 files changed, 70 insertions(+), 14 deletions(-) diff --git a/embassy-nrf/src/chips/nrf52820.rs b/embassy-nrf/src/chips/nrf52820.rs index 128e1503..8aa07bb7 100644 --- a/embassy-nrf/src/chips/nrf52820.rs +++ b/embassy-nrf/src/chips/nrf52820.rs @@ -7,6 +7,9 @@ pub const FORCE_COPY_BUFFER_SIZE: usize = 512; pub const FLASH_SIZE: usize = 256 * 1024; embassy_hal_common::peripherals! { + // USB + USBD, + // RTC RTC0, RTC1, diff --git a/embassy-nrf/src/chips/nrf52833.rs b/embassy-nrf/src/chips/nrf52833.rs index 7c7198df..498a3c30 100644 --- a/embassy-nrf/src/chips/nrf52833.rs +++ b/embassy-nrf/src/chips/nrf52833.rs @@ -7,6 +7,9 @@ pub const FORCE_COPY_BUFFER_SIZE: usize = 512; pub const FLASH_SIZE: usize = 512 * 1024; embassy_hal_common::peripherals! { + // USB + USBD, + // RTC RTC0, RTC1, @@ -154,6 +157,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/chips/nrf52840.rs b/embassy-nrf/src/chips/nrf52840.rs index f5b90cd5..41176814 100644 --- a/embassy-nrf/src/chips/nrf52840.rs +++ b/embassy-nrf/src/chips/nrf52840.rs @@ -7,6 +7,9 @@ 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 +160,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/chips/nrf5340_app.rs b/embassy-nrf/src/chips/nrf5340_app.rs index ca761893..4fcb742e 100644 --- a/embassy-nrf/src/chips/nrf5340_app.rs +++ b/embassy-nrf/src/chips/nrf5340_app.rs @@ -211,6 +211,9 @@ pub const EASY_DMA_SIZE: usize = (1 << 16) - 1; pub const FORCE_COPY_BUFFER_SIZE: usize = 1024; embassy_hal_common::peripherals! { + // USB + USBD, + // RTC RTC0, RTC1, @@ -342,6 +345,8 @@ embassy_hal_common::peripherals! { P1_15, } +impl_usb!(USBD, USBD, USBD); + impl_uarte!(UARTETWISPI0, UARTE0, SERIAL0); impl_uarte!(UARTETWISPI1, UARTE1, SERIAL1); impl_uarte!(UARTETWISPI2, UARTE2, SERIAL2); diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index 7434905e..3cd1768c 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs @@ -48,8 +48,12 @@ pub mod temp; pub mod timer; pub mod twim; pub mod uarte; -//todo add nrf52833 nrf52840 -#[cfg(feature = "nrf52840")] +#[cfg(any( + feature = "_nrf5340-app", + feature = "nrf52820", + feature = "nrf52833", + feature = "nrf52840" +))] pub mod usb; #[cfg(not(feature = "_nrf5340"))] pub mod wdt; diff --git a/embassy-nrf/src/usb.rs b/embassy-nrf/src/usb.rs index 39e53429..d0944b7f 100644 --- a/embassy-nrf/src/usb.rs +++ b/embassy-nrf/src/usb.rs @@ -1,20 +1,27 @@ #![macro_use] -pub use embassy_hal_common::usb::*; +use crate::interrupt::Interrupt; +use crate::pac; + +use core::marker::PhantomData; +use embassy::util::Unborrow; use nrf_usbd::{UsbPeripheral, Usbd}; use usb_device::bus::UsbBusAllocator; -pub struct UsbBus; -unsafe impl UsbPeripheral for UsbBus { - // todo hardcoding - const REGISTERS: *const () = crate::pac::USBD::ptr() as *const (); +pub use embassy_hal_common::usb::*; + +pub struct UsbBus<'d, T: Instance> { + phantom: PhantomData<&'d mut T>, } -impl UsbBus { - // todo should it consume a USBD peripheral? - pub fn new() -> UsbBusAllocator> { +unsafe impl<'d, T: Instance> UsbPeripheral for UsbBus<'d, T> { + const REGISTERS: *const () = T::regs as *const (); +} + +impl<'d, T: Instance> UsbBus<'d, T> { + pub fn new(_usb: impl Unborrow + 'd) -> UsbBusAllocator>> { unsafe { - (*crate::pac::USBD::ptr()).intenset.write(|w| { + (*pac::USBD::ptr()).intenset.write(|w| { w.sof().set_bit(); w.usbevent().set_bit(); w.ep0datadone().set_bit(); @@ -23,8 +30,35 @@ impl UsbBus { }) }; - Usbd::new(UsbBus) + Usbd::new(UsbBus { + phantom: PhantomData, + }) } } unsafe impl embassy_hal_common::usb::USBInterrupt for crate::interrupt::USBD {} + +pub(crate) mod sealed { + use super::*; + + pub trait Instance { + fn regs() -> &'static pac::usbd::RegisterBlock; + } +} + +pub trait Instance: Unborrow + sealed::Instance + 'static + Send { + 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 1df37d4b..fc7ee03b 100644 --- a/examples/nrf/src/bin/usb_uart.rs +++ b/examples/nrf/src/bin/usb_uart.rs @@ -21,11 +21,11 @@ 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_bus = UsbBus::new(); + let usb_bus = UsbBus::new(p.USBD); let serial = UsbSerial::new(&usb_bus, &mut rx_buffer, &mut tx_buffer); From cd356896eeb000e16dec6590f82ac48891163ba0 Mon Sep 17 00:00:00 2001 From: Jacob Rosenthal Date: Wed, 15 Dec 2021 10:27:10 -0700 Subject: [PATCH 13/20] fix nrf52820 --- embassy-nrf/src/chips/nrf52820.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/embassy-nrf/src/chips/nrf52820.rs b/embassy-nrf/src/chips/nrf52820.rs index 8aa07bb7..aa2b2e61 100644 --- a/embassy-nrf/src/chips/nrf52820.rs +++ b/embassy-nrf/src/chips/nrf52820.rs @@ -125,6 +125,8 @@ embassy_hal_common::peripherals! { TEMP, } +impl_usb!(USBD, USBD, USBD); + impl_uarte!(UARTE0, UARTE0, UARTE0_UART0); impl_spim!(TWISPI0, SPIM0, SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); From 50f151e6bcf484735e2b8cd70196c72b038f3bc6 Mon Sep 17 00:00:00 2001 From: Jacob Rosenthal Date: Wed, 15 Dec 2021 10:29:19 -0700 Subject: [PATCH 14/20] use Instance regs --- embassy-nrf/src/usb.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/embassy-nrf/src/usb.rs b/embassy-nrf/src/usb.rs index d0944b7f..b110258c 100644 --- a/embassy-nrf/src/usb.rs +++ b/embassy-nrf/src/usb.rs @@ -20,15 +20,15 @@ unsafe impl<'d, T: Instance> UsbPeripheral for UsbBus<'d, T> { impl<'d, T: Instance> UsbBus<'d, T> { pub fn new(_usb: impl Unborrow + 'd) -> UsbBusAllocator>> { - unsafe { - (*pac::USBD::ptr()).intenset.write(|w| { - w.sof().set_bit(); - w.usbevent().set_bit(); - w.ep0datadone().set_bit(); - w.ep0setup().set_bit(); - w.usbreset().set_bit() - }) - }; + let r = T::regs(); + + r.intenset.write(|w| { + w.sof().set_bit(); + w.usbevent().set_bit(); + w.ep0datadone().set_bit(); + w.ep0setup().set_bit(); + w.usbreset().set_bit() + }); Usbd::new(UsbBus { phantom: PhantomData, From cfb5e8df57cdab5dd4c511494ce1326da2e88a61 Mon Sep 17 00:00:00 2001 From: Jacob Rosenthal Date: Wed, 15 Dec 2021 11:00:55 -0700 Subject: [PATCH 15/20] undo T:regs in impl UsbPeripheral --- embassy-nrf/src/usb.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/embassy-nrf/src/usb.rs b/embassy-nrf/src/usb.rs index b110258c..deab9454 100644 --- a/embassy-nrf/src/usb.rs +++ b/embassy-nrf/src/usb.rs @@ -15,7 +15,8 @@ pub struct UsbBus<'d, T: Instance> { } unsafe impl<'d, T: Instance> UsbPeripheral for UsbBus<'d, T> { - const REGISTERS: *const () = T::regs as *const (); + // todo how to use T::regs + const REGISTERS: *const () = pac::USBD::ptr() as *const (); } impl<'d, T: Instance> UsbBus<'d, T> { From 5d19f87acb32287d7a2034b3344a8aee5ed08fa3 Mon Sep 17 00:00:00 2001 From: Jacob Rosenthal Date: Wed, 15 Dec 2021 12:30:48 -0700 Subject: [PATCH 16/20] cleanup example --- examples/nrf/src/bin/usb_uart.rs | 48 +++++++++++++++++--------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/examples/nrf/src/bin/usb_uart.rs b/examples/nrf/src/bin/usb_uart.rs index fc7ee03b..56b45114 100644 --- a/examples/nrf/src/bin/usb_uart.rs +++ b/examples/nrf/src/bin/usb_uart.rs @@ -40,53 +40,55 @@ async fn main(_spawner: Spawner, p: Peripherals) { irq.set_priority(interrupt::Priority::P3); let mut state = State::new(); - let usb = unsafe { Usb::new(&mut state, device, serial, irq) }; pin_mut!(usb); - let (mut read_interface, mut write_interface) = usb.as_ref().take_serial_0(); + let (mut reader, mut writer) = usb.as_ref().take_serial_0(); - unwrap!(write_interface.write_all(b"\r\nSend something\r\n").await); + unwrap!(writer.write_all(b"\r\nSend something\r\n").await); info!("usb initialized!"); let mut buf = [0u8; 64]; loop { let mut n = 0; - let left = { - let recv_fut = async { + let timed_out = { + let newline_fut = async { loop { - let byte = unwrap!(read_interface.read_byte().await); - unwrap!(write_interface.write_byte(byte).await); - buf[n] = byte; + let char = unwrap!(reader.read_byte().await); + // echo input back to screen + unwrap!(writer.write_byte(char).await); + buf[n] = char; n += 1; - if byte == b'\n' || byte == b'\r' || n == buf.len() { + if char == b'\n' || char == b'\r' || n == buf.len() { break; } } }; - pin_mut!(recv_fut); + pin_mut!(newline_fut); - let timeout = Timer::after(Duration::from_ticks(32768 * 10)); + let timeout_fut = Timer::after(Duration::from_ticks(32768 * 10)); - match select(recv_fut, timeout).await { - Either::Left(_) => true, - Either::Right(_) => false, + // select chooses whichever returns first + match select(newline_fut, timeout_fut).await { + Either::Left(_) => false, + Either::Right(_) => true, } }; - if left { - for c in buf[..n].iter_mut() { - if 0x61 <= *c && *c <= 0x7a { - *c &= !0x20; + if timed_out { + unwrap!(writer.write_all(b"\r\nTimed out\r\n").await); + } else { + for char in buf[..n].iter_mut() { + // upper case + if 0x61 <= *char && *char <= 0x7a { + *char &= !0x20; } } - unwrap!(write_interface.write_byte(b'\n').await); - unwrap!(write_interface.write_all(&buf[..n]).await); - unwrap!(write_interface.write_byte(b'\n').await); - } else { - unwrap!(write_interface.write_all(b"\r\nSend something\r\n").await); + unwrap!(writer.write_byte(b'\n').await); + unwrap!(writer.write_all(&buf[..n]).await); + unwrap!(writer.write_byte(b'\n').await); } } } From 1f2bbe3e4a65f652edc0c2381405ea58df199130 Mon Sep 17 00:00:00 2001 From: Jacob Rosenthal Date: Thu, 16 Dec 2021 14:59:08 -0700 Subject: [PATCH 17/20] simplify usb_uart example --- examples/nrf/src/bin/usb_uart.rs | 58 ++++++++++++++++---------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/examples/nrf/src/bin/usb_uart.rs b/examples/nrf/src/bin/usb_uart.rs index 56b45114..8c386daa 100644 --- a/examples/nrf/src/bin/usb_uart.rs +++ b/examples/nrf/src/bin/usb_uart.rs @@ -15,15 +15,15 @@ use panic_probe as _; // print out panic messages use embassy::executor::Spawner; use embassy::io::{AsyncBufReadExt, AsyncWriteExt}; -use embassy::time::{Duration, Timer}; use embassy_nrf::usb::{State, Usb, UsbBus, UsbSerial}; use embassy_nrf::{interrupt, Peripherals}; use usb_device::device::{UsbDeviceBuilder, UsbVidPid}; #[embassy::main] async fn main(_spawner: Spawner, p: Peripherals) { - let mut tx_buffer = [0u8; 1024]; - let mut rx_buffer = [0u8; 640]; + let mut rx_buffer = [0u8; 64]; + // we send back input + cr + lf + let mut tx_buffer = [0u8; 66]; let usb_bus = UsbBus::new(p.USBD); @@ -45,50 +45,50 @@ async fn main(_spawner: Spawner, p: Peripherals) { let (mut reader, mut writer) = usb.as_ref().take_serial_0(); - unwrap!(writer.write_all(b"\r\nSend something\r\n").await); - info!("usb initialized!"); + unwrap!( + writer + .write_all(b"\r\nInput returned upper cased on CR+LF\r\n") + .await + ); + let mut buf = [0u8; 64]; loop { let mut n = 0; - let timed_out = { - let newline_fut = async { - loop { - let char = unwrap!(reader.read_byte().await); - // echo input back to screen - unwrap!(writer.write_byte(char).await); - buf[n] = char; - n += 1; - if char == b'\n' || char == b'\r' || n == buf.len() { - break; - } + async { + loop { + let char = unwrap!(reader.read_byte().await); + + // throw away, read more on cr, exit on lf + if char == b'\r' { + continue; + } else if char == b'\n' { + break; } - }; - pin_mut!(newline_fut); - let timeout_fut = Timer::after(Duration::from_ticks(32768 * 10)); + buf[n] = char; + n += 1; - // select chooses whichever returns first - match select(newline_fut, timeout_fut).await { - Either::Left(_) => false, - Either::Right(_) => true, + // stop if we're out of room + if n == buf.len() { + break; + } } - }; + } + .await; - if timed_out { - unwrap!(writer.write_all(b"\r\nTimed out\r\n").await); - } else { + if n > 0 { for char in buf[..n].iter_mut() { // upper case if 0x61 <= *char && *char <= 0x7a { *char &= !0x20; } } - unwrap!(writer.write_byte(b'\n').await); unwrap!(writer.write_all(&buf[..n]).await); - unwrap!(writer.write_byte(b'\n').await); + unwrap!(writer.write_all(b"\r\n").await); + unwrap!(writer.flush().await); } } } From 1d51f91368c4ba6b497cdfb5bca5b764d13074f9 Mon Sep 17 00:00:00 2001 From: Jacob Rosenthal Date: Thu, 16 Dec 2021 14:59:35 -0700 Subject: [PATCH 18/20] usb_uart_io example equivilent to usb_uart --- examples/nrf/src/bin/usb_uart_io.rs | 70 +++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 examples/nrf/src/bin/usb_uart_io.rs diff --git a/examples/nrf/src/bin/usb_uart_io.rs b/examples/nrf/src/bin/usb_uart_io.rs new file mode 100644 index 00000000..f07ed891 --- /dev/null +++ b/examples/nrf/src/bin/usb_uart_io.rs @@ -0,0 +1,70 @@ +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +#[path = "../example_common.rs"] +mod example_common; + +use defmt::{info, unwrap}; +use defmt_rtt as _; +// global logger +use panic_probe as _; // print out panic messages + +use embassy::executor::Spawner; +use embassy::interrupt::InterruptExt; +use embassy::io::{read_line, AsyncWriteExt}; +use embassy_nrf::usb::{State, Usb, UsbBus, UsbSerial}; +use embassy_nrf::{interrupt, Peripherals}; +use futures::pin_mut; +use usb_device::device::{UsbDeviceBuilder, UsbVidPid}; + +#[embassy::main] +async fn main(_spawner: Spawner, p: Peripherals) { + let mut rx_buffer = [0u8; 64]; + // we send back input + cr + lf + let mut tx_buffer = [0u8; 66]; + + let usb_bus = UsbBus::new(p.USBD); + + let serial = UsbSerial::new(&usb_bus, &mut rx_buffer, &mut tx_buffer); + + let device = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x27dd)) + .manufacturer("Fake company") + .product("Serial port") + .serial_number("TEST") + .device_class(0x02) + .build(); + + let irq = interrupt::take!(USBD); + irq.set_priority(interrupt::Priority::P3); + + let mut state = State::new(); + let usb = unsafe { Usb::new(&mut state, device, serial, irq) }; + pin_mut!(usb); + + let (mut reader, mut writer) = usb.as_ref().take_serial_0(); + + info!("usb initialized!"); + + unwrap!( + writer + .write_all(b"\r\nInput returned upper cased on CR+LF\r\n") + .await + ); + + let mut buf = [0u8; 64]; + loop { + let n = unwrap!(read_line(&mut reader, &mut buf).await); + + for char in buf[..n].iter_mut() { + // upper case + if 0x61 <= *char && *char <= 0x7a { + *char &= !0x20; + } + } + + unwrap!(writer.write_all(&buf[..n]).await); + unwrap!(writer.write_all(b"\r\n").await); + unwrap!(writer.flush().await); + } +} From e7d2c52680fb894ca44913c3b62c2ba6980f398a Mon Sep 17 00:00:00 2001 From: Jacob Rosenthal Date: Thu, 16 Dec 2021 15:20:56 -0700 Subject: [PATCH 19/20] example cleanup --- examples/nrf/src/bin/usb_uart.rs | 4 +--- examples/nrf/src/bin/usb_uart_io.rs | 3 +-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/examples/nrf/src/bin/usb_uart.rs b/examples/nrf/src/bin/usb_uart.rs index 8c386daa..c345df9e 100644 --- a/examples/nrf/src/bin/usb_uart.rs +++ b/examples/nrf/src/bin/usb_uart.rs @@ -6,11 +6,9 @@ mod example_common; use defmt::{info, unwrap}; -use defmt_rtt as _; +use defmt_rtt as _; // global logger use embassy::interrupt::InterruptExt; -use futures::future::{select, Either}; use futures::pin_mut; -// global logger use panic_probe as _; // print out panic messages use embassy::executor::Spawner; diff --git a/examples/nrf/src/bin/usb_uart_io.rs b/examples/nrf/src/bin/usb_uart_io.rs index f07ed891..8fc61526 100644 --- a/examples/nrf/src/bin/usb_uart_io.rs +++ b/examples/nrf/src/bin/usb_uart_io.rs @@ -6,8 +6,7 @@ mod example_common; use defmt::{info, unwrap}; -use defmt_rtt as _; -// global logger +use defmt_rtt as _; // global logger use panic_probe as _; // print out panic messages use embassy::executor::Spawner; From 7be34aa22fe735850c61a5a1c3b7304cce6ef102 Mon Sep 17 00:00:00 2001 From: Jacob Rosenthal Date: Mon, 3 Jan 2022 11:52:36 -0700 Subject: [PATCH 20/20] use upstream nrf-usdb --- embassy-nrf/Cargo.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml index 7e090344..3d0c171f 100644 --- a/embassy-nrf/Cargo.toml +++ b/embassy-nrf/Cargo.toml @@ -59,8 +59,7 @@ rand_core = "0.6.3" fixed = "1.10.0" embedded-storage = "0.2.0" cfg-if = "1.0.0" -nrf-usbd = {version = "0.1.0", git="https://github.com/jacobrosenthal/nrf-usbd", branch="critical-section"} -# nrf-usbd = {version = "0.2.0"} +nrf-usbd = {version = "0.1.1"} usb-device = "0.2.8" nrf52805-pac = { version = "0.10.1", optional = true, features = [ "rt" ] }