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();
+        }
+    }
+}