From 36b8ff74f77f22ec6f290e7918a8e421002bb863 Mon Sep 17 00:00:00 2001 From: Matt Johnston <matt@ucc.asn.au> Date: Fri, 30 Sep 2022 18:25:41 +0800 Subject: [PATCH] Demo of capacitor randomness --- examples/rp/Cargo.toml | 3 ++ examples/rp/src/bin/usb_serial.rs | 82 +++++++++++++++++++++++++++---- 2 files changed, 76 insertions(+), 9 deletions(-) diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml index 3c8f923e..07aaa0ad 100644 --- a/examples/rp/Cargo.toml +++ b/examples/rp/Cargo.toml @@ -16,6 +16,9 @@ embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } defmt = "0.3" defmt-rtt = "0.3" +heapless = "0.7" +critical-section = "1.1" + cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } cortex-m-rt = "0.7.0" panic-probe = { version = "0.3", features = ["print-defmt"] } diff --git a/examples/rp/src/bin/usb_serial.rs b/examples/rp/src/bin/usb_serial.rs index b7d6493b..714fb2ce 100644 --- a/examples/rp/src/bin/usb_serial.rs +++ b/examples/rp/src/bin/usb_serial.rs @@ -4,20 +4,30 @@ use defmt::{info, panic}; use embassy_executor::Spawner; +use embassy_time::{Timer, Duration}; +use embassy_rp::pac as pac; use embassy_futures::join::join; use embassy_rp::interrupt; +use embassy_rp::gpio::{Flex, Pull, Pin}; use embassy_rp::usb::{Driver, Instance}; use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; use embassy_usb::driver::EndpointError; use embassy_usb::{Builder, Config}; use {defmt_rtt as _, panic_probe as _}; +use cortex_m::peripheral::SYST; +use core::fmt::Write; + +const MAX_CDC_PACKET: u8 = 64; + #[embassy_executor::main] async fn main(_spawner: Spawner) { info!("Hello there!"); let p = embassy_rp::init(Default::default()); + let mut cp = cortex_m::peripheral::Peripherals::take().unwrap(); + // Create the driver, from the HAL. let irq = interrupt::take!(USBCTRL_IRQ); let driver = Driver::new(p.USB, irq); @@ -28,7 +38,7 @@ async fn main(_spawner: Spawner) { config.product = Some("USB-serial example"); config.serial_number = Some("12345678"); config.max_power = 100; - config.max_packet_size_0 = 64; + config.max_packet_size_0 = MAX_CDC_PACKET; // Required for windows compatiblity. // https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.9.1/kconfig/CONFIG_CDC_ACM_IAD.html#help @@ -57,20 +67,23 @@ async fn main(_spawner: Spawner) { ); // Create classes on the builder. - let mut class = CdcAcmClass::new(&mut builder, &mut state, 64); + let mut class = CdcAcmClass::new(&mut builder, &mut state, MAX_CDC_PACKET as u16); // Build the builder. let mut usb = builder.build(); // Run the USB device. let usb_fut = usb.run(); + let _ = class.write_packet(b"top\r\n").await; + + let mut gpio6 = Flex::new(p.PIN_6); // Do stuff with the class! let echo_fut = async { loop { class.wait_connection().await; info!("Connected"); - let _ = echo(&mut class).await; + let _ = echo(&mut class, &mut gpio6, &mut cp.SYST).await; info!("Disconnected"); } }; @@ -91,12 +104,63 @@ impl From<EndpointError> for Disconnected { } } -async fn echo<'d, T: Instance + 'd>(class: &mut CdcAcmClass<'d, Driver<'d, T>>) -> Result<(), Disconnected> { - let mut buf = [0; 64]; +#[derive(Default)] +struct FmtBuf { + s: heapless::String<1024>, +} + +impl FmtBuf { + fn str(&self) -> &str { + self.s.as_str() + } + async fn write<'d, T: Instance+'d>(cdc: &mut CdcAcmClass<'d, Driver<'d, T>>, args: core::fmt::Arguments<'_>) -> Result<(), core::fmt::Error> { + let mut f = Self::default(); + f.write_fmt(args)?; + + let b = f.str().as_bytes(); + for c in b.chunks(MAX_CDC_PACKET as usize) { + cdc.write_packet(c).await.map_err(|_| core::fmt::Error)? + } + Ok(()) + } +} + +impl core::fmt::Write for FmtBuf { + fn write_str(&mut self, s: &str) -> Result<(), core::fmt::Error> { + self.s.push_str(s).map_err(|_| core::fmt::Error) + } +} + +async fn echo<'d, P: Pin, T: Instance + 'd>(class: &mut CdcAcmClass<'d, Driver<'d, T>>, + pin: &mut Flex<'d, P>, syst: &mut SYST) -> Result<(), Disconnected> { + class.write_packet(b"hello\r\n").await?; + + syst.set_reload(10_000_000-1); + syst.clear_current(); + syst.set_clock_source(cortex_m::peripheral::syst::SystClkSource::Core); + syst.enable_counter(); + + unsafe{ pac::ROSC.ctrl().modify(|s| s.set_enable(pac::rosc::vals::Enable::DISABLE))}; + loop { - let n = class.read_packet(&mut buf).await?; - let data = &buf[..n]; - info!("data: {:x}", data); - class.write_packet(data).await?; + let (t1, t2) = critical_section::with(|_cs| { + syst.clear_current(); + + pin.set_pull(Pull::Down); + pin.set_as_output(); + pin.set_high(); + // // approx 1ms + // cortex_m::asm::delay(125_000); + cortex_m::asm::delay(600); + let t1 = SYST::get_current(); + pin.set_as_input(); + while pin.is_high() {} + + let t2 = SYST::get_current(); + (t1, t2) + }); + let del = t1 - t2; + FmtBuf::write(class, format_args!("{del}\n")).await.map_err(|_| Disconnected{})?; + } } -- GitLab