diff --git a/Cargo.toml b/Cargo.toml index dd68c1ca0036b0f388d136865b9d7e5d1b395b51..1c40bfa40f4a8616da3ce609e2e8e602297e7f2e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,8 +6,8 @@ edition = "2021" [dependencies] cortex-m = "0.7" -embassy-rp = { version = "0.1.0", features = ["defmt", "unstable-traits", "nightly", "unstable-pac", "time-driver"] } -embassy-time = { version = "0.1.0", features = ["defmt", "defmt-timestamp-uptime"] } +embassy-rp = { version = "0.1.0", features = ["unstable-traits", "nightly", "unstable-pac", "time-driver"] } +embassy-time = { version = "0.1.0" } defmt = { version = "0.3", optional = true } # rtt-target = { version = "0.3", optional = true } @@ -21,8 +21,10 @@ log = { version = "0.4", default-features = false } [dev-dependencies] cortex-m-rt = "0.7.0" cortex-m = { version = "0.7", features = ["critical-section-single-core"]} -embassy-executor = { version = "0.1.0", features = ["defmt", "integrated-timers"] } -panic-probe = { version = "0.3", features = ["print-defmt"] } +embassy-executor = { version = "0.1.0", features = ["integrated-timers"] } +embassy-usb = { version = "0.1.0", features = ["defmt"] } +embassy-futures = { version = "0.1.0" } +panic-probe = { version = "0.3" } defmt-rtt = { version = "0.3" } getrandom = { version = "0.2", default-features = false, features = ["custom"]} @@ -34,10 +36,14 @@ debug = 2 [patch.crates-io] # embassy isn't released to crates.io yet -# embassy-rp = { git = "https://github.com/embassy-rs/embassy", rev = "1d6f5493e7764767eb592e0b90d6b07d46b100ca" } -# embassy-executor = { git = "https://github.com/embassy-rs/embassy", rev = "1d6f5493e7764767eb592e0b90d6b07d46b100ca" } -# embassy-time = { git = "https://github.com/embassy-rs/embassy", rev = "1d6f5493e7764767eb592e0b90d6b07d46b100ca" } +# embassy-rp = { git = "https://github.com/embassy-rs/embassy", rev = "8c42b26fc623f556c865a0f27c7f956b06bedff9" } +# embassy-executor = { git = "https://github.com/embassy-rs/embassy", rev = "8c42b26fc623f556c865a0f27c7f956b06bedff9" } +# embassy-time = { git = "https://github.com/embassy-rs/embassy", rev = "8c42b26fc623f556c865a0f27c7f956b06bedff9" } +# embassy-usb = { git = "https://github.com/embassy-rs/embassy", rev = "8c42b26fc623f556c865a0f27c7f956b06bedff9" } +# embassy-futures = { git = "https://github.com/embassy-rs/embassy", rev = "8c42b26fc623f556c865a0f27c7f956b06bedff9" } embassy-rp = { path = "/home/matt/3rd/rs/embassy/embassy-rp" } embassy-executor = { path = "/home/matt/3rd/rs/embassy/embassy-executor" } embassy-time = { path = "/home/matt/3rd/rs/embassy/embassy-time" } +embassy-usb = { path = "/home/matt/3rd/rs/embassy/embassy-usb" } +embassy-futures = { path = "/home/matt/3rd/rs/embassy/embassy-futures" } diff --git a/examples/noise.rs b/examples/noise.rs index ca96531dec33063e0e4dc469fd65fc8aa99978ef..72f88488102bf6e8e10d4d87a142c0f0fa428581 100644 --- a/examples/noise.rs +++ b/examples/noise.rs @@ -105,7 +105,7 @@ async fn main(_spawner: Spawner) { // for low_delay in 0..1{ let pin = gpio.pin(); let mut n = 0; - caprand::noise(gpio, low_delay, + caprand::cap::noise(gpio, low_delay, |v| { info!("{},{},{}", pin, low_delay, v); n += 1; diff --git a/examples/rand.rs b/examples/rand.rs index 4cd3358a5b0471cf29ccbe2550953aab1bc7ab82..5afc0fe2446fa63c61a18dbb67527d61fc27d773 100644 --- a/examples/rand.rs +++ b/examples/rand.rs @@ -21,9 +21,9 @@ use getrandom::register_custom_getrandom; async fn main(_spawner: Spawner) { let p = embassy_rp::init(Default::default()); - let gpio = p.PIN_25.degrade().into_ref(); + let mut gpio = p.PIN_25.degrade(); - caprand::setup(gpio).unwrap(); + caprand::setup(&mut gpio).unwrap(); register_custom_getrandom!(caprand::random); diff --git a/examples/usbnoise.rs b/examples/usbnoise.rs new file mode 100644 index 0000000000000000000000000000000000000000..8e6eeaece71a9bb81979ba771a4bd76ed2b17d90 --- /dev/null +++ b/examples/usbnoise.rs @@ -0,0 +1,193 @@ +//! Prints raw samples from the capacitor random number generator. +//! These would not usually be used directly, instead use `CapRng`. +//! Raw samples are useful to analyse the entropy. + +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +#[cfg(not(feature = "defmt"))] +use log::{debug, info, warn, error}; +#[cfg(not(feature = "defmt"))] +use panic_abort as _; + +#[cfg(feature = "defmt")] +use defmt::{debug, info, warn, panic, error, trace}; +#[cfg(feature = "defmt")] +use {defmt_rtt as _, panic_probe as _}; + +use embassy_rp::gpio::{Flex, AnyPin, Pin}; +use embassy_rp::Peripheral; +use embassy_executor::Spawner; +use embassy_futures::join::join; +use embassy_time::{Timer, Duration, Instant}; +use embassy_rp::interrupt; +use embassy_rp::usb::{Driver, Instance}; +use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; +use embassy_usb::{Builder, Config}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + info!("top"); + let mut p = embassy_rp::init(Default::default()); + + // Create the driver, from the HAL. + let irq = interrupt::take!(USBCTRL_IRQ); + let driver = Driver::new(p.USB, irq); + + // Create embassy-usb Config + let mut config = Config::new(0xc0de, 0xcafe); + config.manufacturer = Some("Embassy"); + config.product = Some("USB noise"); + config.serial_number = Some("12345678"); + // let mut config = Config::new(0x6666, 0x628d); + // config.manufacturer = Some("Matt"); + // config.product = Some("Noise"); + // config.serial_number = Some("12345"); + config.max_power = 100; + config.max_packet_size_0 = 64; + + // Required for windows compatiblity. + // https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.9.1/kconfig/CONFIG_CDC_ACM_IAD.html#help + config.device_class = 0xEF; + config.device_sub_class = 0x02; + config.device_protocol = 0x01; + config.composite_with_iads = true; + + // Create embassy-usb DeviceBuilder using the driver and config. + // It needs some buffers for building the descriptors. + let mut device_descriptor = [0; 256]; + let mut config_descriptor = [0; 256]; + let mut bos_descriptor = [0; 256]; + let mut control_buf = [0; 64]; + + let mut state = State::new(); + + let mut builder = Builder::new( + driver, + config, + &mut device_descriptor, + &mut config_descriptor, + &mut bos_descriptor, + &mut control_buf, + None, + ); + + // Create classes on the builder. + let mut class = CdcAcmClass::new(&mut builder, &mut state, 64); + + // Build the builder. + let mut usb = builder.build(); + + // Run the USB device. + let usb_fut = usb.run(); + + // Do stuff with the class! + let echo_fut = async { + loop { + class.wait_connection().await; + info!("Connected"); + let _ = run(&mut p.PIN_25, &mut class).await; + info!("Disconnected"); + } + }; + + join(usb_fut, echo_fut).await; +} + + +fn nibble_hex(c: u8) -> u8 { + debug_assert!(c <= 0xf); + if c < 10 { + b'0' + c + } else { + b'a' - 0xa + c + } +} + +// struct Extractor { +// acc: u8, +// bit: u8, +// deci_pos: u8, +// prev: u8 +// } + +// impl Extractor { +// const DECIM: u8 = 32; +// fn new() -> Self { +// acc: 0, +// bit: 0, +// deci_pos: 0, +// prev: u8, +// } + +// fn feed(&mut self, v: u8) -> Option<u8> { +// self.deci_pos += 1; +// if self.deci_pos % DECIM != 0 { +// return None +// } + +// jk +// } +// } + +async fn run<'d, T: Instance + 'd>(pin: &mut impl Pin, class: &mut CdcAcmClass<'d, Driver<'d, T>>) -> Result<(), ()> { + + // max packet is 64 bytes. we hex encode and add newline, 31*2+1 + const CHUNK: usize = 31; + + let mut buf = [false; CHUNK * 8 * 10]; + + let mut a = None; + let mut pos = 0u32; + let deci = 40u32; + loop { + let mut b = buf.iter_mut(); + let low_delay = 30; + // XXX should discard first iter or something. + caprand::cap::noise(pin, low_delay, + |v| { + pos = pos.wrapping_add(1); + if pos % deci == 0 { + let v = v as u8; + if a.is_none() { + a = Some(v); + true + } else { + let aa = a.take().unwrap(); + if aa != v { + if let Some(i) = b.next() { + *i = aa > v; + true + } else { + false + } + } else { + true + } + } + + } else { + // discard + true + } + }).unwrap(); + + for chunk in buf.chunks(CHUNK*8) { + // write!(&mut buf, "{:?}", chunk); + let mut hex = ['B' as u8; CHUNK*2+1]; + let mut c = chunk.iter(); + let mut m = hex.iter_mut(); + for _ in 0..CHUNK { + let mut x = 0u8; + for b in 0..8 { + x |= (*c.next().unwrap() as u8) << b; + } + *m.next().unwrap() = nibble_hex(x >> 4); + *m.next().unwrap() = nibble_hex(x & 0xf); + } + *m.next().unwrap() = b'\n'; + class.write_packet(&hex).await.unwrap(); + } + } +}