diff --git a/Cargo.toml b/Cargo.toml
index 3ea912a947d2d15b1e079f11a097ea56f7683a16..79052f6ba80816e31251f591461f41f32881f039 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -33,6 +33,10 @@ 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 = "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 = { 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" }
diff --git a/examples/noise.rs b/examples/noise.rs
index 24e83a10d24c1cbba3fc9182456b08163a005c9c..c089326b61f22361bbc03c79ceb204e8b107b1c4 100644
--- a/examples/noise.rs
+++ b/examples/noise.rs
@@ -14,7 +14,8 @@ use defmt::{debug, info, warn, panic, error};
 #[cfg(feature = "defmt")]
 use {defmt_rtt as _, panic_probe as _};
 
-use embassy_rp::gpio::Flex;
+use embassy_rp::gpio::{Flex, AnyPin, Pin};
+use embassy_rp::Peripheral;
 use embassy_executor::Spawner;
 
 #[embassy_executor::main]
@@ -22,11 +23,102 @@ async fn main(_spawner: Spawner) {
     let p = embassy_rp::init(Default::default());
     let mut cp = cortex_m::peripheral::Peripherals::take().unwrap();
 
-    let mut gpio = (Flex::new(p.PIN_10), 10);
-    // let mut gpio = (Flex::new(p.PIN_22), 22);
-    caprand::noise(&mut gpio.0, gpio.1, &mut cp.SYST,
-        |v, overshoot| {
-            info!("{} {}", v, overshoot);
-            true
-    }).unwrap();
+    // 0.1uF
+    // let mut gpio = (Flex::new(p.PIN_6), 6);
+    // 0.01uF ?
+    // let mut gpio = (Flex::new(p.PIN_10), 10);
+    // nothing
+    // let mut gpio = Flex::new(p.PIN_22);
+    // nothing, adc pin
+    // let mut gpio = (Flex::new(p.PIN_28), 28);
+
+    // let mut gpio = (Flex::new(p.PIN_15), 15);
+
+    // // wifi sd_clk, or led for non-w
+    // let mut gpio = (Flex::new(p.PIN_29), 29);
+    // // check wifi is off.
+    // let mut gpio23 = Flex::new(p.PIN_23);
+    // assert!(gpio23.is_low());
+    // // wifi cs high
+    // let mut gpio25 = Flex::new(p.PIN_25);
+    // gpio25.set_low();
+    // gpio25.set_as_output();
+
+    // let mut gpio = Flex::new(p.PIN_15);
+    // let mut gpio = Flex::new(p.PIN_20);
+    // let mut gpio = p.PIN_20.into();
+
+    let mut hist = [0u32; 200];
+    let mut n = 0;
+
+    let PRINT = 50000;
+    // let PRINT = 50;
+
+    let mut gpios = [
+        p.PIN_6.degrade().into_ref(),
+        p.PIN_10.degrade().into_ref(),
+        p.PIN_13.degrade().into_ref(),
+        p.PIN_22.degrade().into_ref(),
+        // p.PIN_23.degrade().into_ref(),
+        // p.PIN_24.degrade().into_ref(),
+        p.PIN_25.degrade().into_ref(),
+    ];
+
+    // let mut gpios = [
+    //     p.PIN_0.degrade().into_ref(),
+    //     p.PIN_1.degrade().into_ref(),
+    //     p.PIN_2.degrade().into_ref(),
+    //     p.PIN_3.degrade().into_ref(),
+    //     p.PIN_4.degrade().into_ref(),
+    //     p.PIN_5.degrade().into_ref(),
+    //     p.PIN_6.degrade().into_ref(),
+    //     p.PIN_7.degrade().into_ref(),
+    //     p.PIN_8.degrade().into_ref(),
+    //     p.PIN_9.degrade().into_ref(),
+    //     p.PIN_10.degrade().into_ref(),
+    //     p.PIN_11.degrade().into_ref(),
+    //     p.PIN_12.degrade().into_ref(),
+    //     p.PIN_13.degrade().into_ref(),
+    //     p.PIN_14.degrade().into_ref(),
+    //     p.PIN_15.degrade().into_ref(),
+    //     p.PIN_16.degrade().into_ref(),
+    //     p.PIN_17.degrade().into_ref(),
+    //     p.PIN_18.degrade().into_ref(),
+    //     p.PIN_19.degrade().into_ref(),
+    //     p.PIN_20.degrade().into_ref(),
+    //     p.PIN_21.degrade().into_ref(),
+    //     p.PIN_22.degrade().into_ref(),
+    //     // p.PIN_23.degrade().into_ref(),
+    //     // p.PIN_24.degrade().into_ref(),
+    //     p.PIN_25.degrade().into_ref(),
+    //     p.PIN_26.degrade().into_ref(),
+    //     p.PIN_27.degrade().into_ref(),
+    //     p.PIN_28.degrade().into_ref(),
+    //     // p.PIN_29.degrade().into_ref(),
+    // ];
+
+    for gpio in gpios.iter_mut() {
+        let pin = gpio.pin();
+        caprand::noise(gpio.reborrow(), &mut cp.SYST,
+            |v, overshoot| {
+                // info!("{}", v);
+
+                let vu = v as usize;
+                hist[vu.min(hist.len()-1)] += 1;
+                n += 1;
+                if n % PRINT == 0 {
+                    info!("gpio {} iter {}", pin, n);
+                    for (p, h) in hist.iter_mut().enumerate() {
+                        if *h > 0 {
+                            info!("{}: {}", p, h);
+                            *h = 0;
+                        }
+                    }
+                    false
+                } else {
+                    true
+                }
+        }).unwrap();
+    }
+
 }
diff --git a/src/cap.rs b/src/cap.rs
index a5be1ca513f5ab4aee5335ef475ac552588ec2b1..07cfcb103b408f84a04ca5fc930fbb76050ef952 100644
--- a/src/cap.rs
+++ b/src/cap.rs
@@ -7,8 +7,8 @@ use defmt::{error, debug, info, panic};
 use core::arch::asm;
 
 use cortex_m::peripheral::SYST;
-use embassy_rp::gpio::{Flex, Pin, Pull};
-use embassy_rp::pac;
+use embassy_rp::gpio::{Flex, Pin, Pull, AnyPin};
+use embassy_rp::{pac, Peripheral, PeripheralRef};
 
 ///                                         _ still pullup, =up_x
 ///         t3      t4       t1      t2    /
@@ -64,8 +64,8 @@ GPIO13
 // const LOW_OVER: u32 = 1000;
 // // Power of two for faster modulo
 // const HIGH_OVER: u32 = LOW_OVER + 1023;
-const LOW_OVER: u32 = 0;
-const HIGH_OVER: u32 = 0;
+const LOW_OVER: u32 = 100;
+const HIGH_OVER: u32 = 100;
 
 // Assume worst case from rp2040 datasheet.
 // 3.3v vdd, 2v logical high voltage, 50kohm pullup, 0.01uF capacitor, 125Mhz clock.
@@ -103,56 +103,40 @@ impl<'t> SyTi<'t> {
         Ok(self.t1 - t2)
     }
 }
+// Returns (ticks: u32, precise: bool)
+fn time_rise(pin: PeripheralRef<AnyPin>, wait: &mut u32, rpos: &mut u32, syst: &mut SYST) -> Result<(u32, bool), ()> {
 
-
-/// Equivalent to
-/// `while gpioN.is_high() {}`
-/// but with known 4 cycle loop time (vs 26 cycles for the `while` loop at
-/// at time of writing)
-fn time_fall(pin_num: usize, syst: &mut SYST) -> Result<u32, ()> {
+    let pin_num = pin.pin();
     // bank 0 single cycle IO in
     let gpio_in = pac::SIO.gpio_in(0).ptr();
     let mask = 1u32 << pin_num;
-    let t = SyTi::new(syst);
+
+    let so = pac::SIO.gpio_out(0);
+    let soe = pac::SIO.gpio_oe(0);
     unsafe {
-        asm!(
-            "222:",
-            // read gpio_in register, 1 cycle
-            "ldr {tmp}, [{gpio_in}]",
-            // AND with the desired pin bit, 1 cycle
-            "ands {tmp}, {mask}",
-            // loop if bit set, 2 cycles
-            "bne 222b",
-            tmp = out(reg) _,
-            mask = in(reg) mask,
-            gpio_in = in(reg) gpio_in,
-            options(nostack, readonly),
-        );
+        so.value_clr().write_value(1<<pin_num);
+        soe.value_set().write_value(1<<pin_num);
     }
-    t.done()
-}
-
-// Returns (ticks: u32, precise: bool)
-fn time_fall_unroll(pin_num: usize, syst: &mut SYST) -> Result<(u32, bool), ()> {
-    // bank 0 single cycle IO in
-    let gpio_in = pac::SIO.gpio_in(0).ptr();
-    let mask = 1u32 << pin_num;
-
-    // let so = pac::SIO.gpio_out(0);
-    // let soe = pac::SIO.gpio_out(0);
-    // unsafe {
-    //     so.value_set().write_value(1<<pin_num);
-    //     soe.value_set().write_value(1<<pin_num);
-    // }
-    // cortex_m::asm::delay(10000);
     // unsafe {
-    //     soe.value_clr().write_value(1<<pin_num);
+    //     asm!(
+    //         "nop",
+    //     )
     // }
+    // cortex_m::asm::delay(200);
+    cortex_m::asm::delay(1000);
+    unsafe {
+        soe.value_clr().write_value(1<<pin_num);
+    }
+
     // for testing with logic analyzer
     // let mut out = Flex::new(unsafe { embassy_rp::peripherals::PIN_16::steal() });
     // out.set_as_output();
     // so.value_clr().write_value(1<<16);
 
+    // pin.set_pull(Pull::Down);
+    // cortex_m::asm::delay(900);
+    // pin.set_pull(Pull::None);
+
     let t = SyTi::new(syst);
 
     let x0: u32;
@@ -161,6 +145,8 @@ fn time_fall_unroll(pin_num: usize, syst: &mut SYST) -> Result<(u32, bool), ()>
     let x3: u32;
     let x4: u32;
     let x5: u32;
+    let mut gpio = Flex::<AnyPin>::new(pin);
+    gpio.set_pull(Pull::Up);
     unsafe {
         asm!(
             // save
@@ -177,7 +163,7 @@ fn time_fall_unroll(pin_num: usize, syst: &mut SYST) -> Result<(u32, bool), ()>
             // only test the most recent sample. 1 cycle
             "ands r7, {mask}",
             // Loop if bit set, 2 cycles
-            "bne 222b",
+            "beq 222b",
 
             // return last sample in x5
             "mov {mask}, r7",
@@ -198,38 +184,45 @@ fn time_fall_unroll(pin_num: usize, syst: &mut SYST) -> Result<(u32, bool), ()>
 
     let tick = t.done()?;
 
-    let pos = if x0 & mask == 0 {
+    let pos = if x0 & mask != 0 {
         0
-    } else if x1 & mask == 0 {
+    } else if x1 & mask != 0 {
         1
-    } else if x2 & mask == 0 {
+    } else if x2 & mask != 0 {
         2
-    } else if x3 & mask == 0 {
+    } else if x3 & mask != 0 {
         3
-    } else if x4 & mask == 0 {
+    } else if x4 & mask != 0 {
         4
-    } else if x5 & mask == 0 {
+    } else if x5 & mask != 0 {
         5
     } else {
         6
     };
     let tick = tick + pos;
-    // let precise = pos != 0;
-    let precise = true;
+    // first measurement is less precise.
+    let precise = pos != 0;
+
+    if tick > 600 {
+        *wait = wait.saturating_sub(1);
+    } else if tick > 600 {
+        *wait = (*wait+1).max(10000);
+    }
 
+    *rpos = pos;
     Ok((tick, precise))
 }
 
 // `f()` is called on each output `u32`.
-pub fn noise<'d, P: Pin, F>(
-    pin: &mut Flex<'d, P>,
-    pin_num: usize,
+pub fn noise<'d, F>(
+    mut pin: PeripheralRef<AnyPin>,
     syst: &mut SYST,
     mut f: F,
 ) -> Result<(), ()>
 where
     F: FnMut(u32, u32) -> bool,
 {
+    let pin_num = pin.pin() as usize;
     syst.set_clock_source(cortex_m::peripheral::syst::SystClkSource::Core);
     // prescribed sequence for setup
     syst.set_reload(10_000_000 - 1);
@@ -248,20 +241,22 @@ where
             .modify(|s| s.set_schmitt(false))
     };
 
-    // Measure pulldown time from vcc as a sanity check
-    pin.set_as_output();
-    pin.set_high();
-    // Long enough to drive the capacitor high
+    let mut gpio = Flex::<AnyPin>::new(pin.reborrow());
+    // Measure pullup time from 0 as a sanity check
+    gpio.set_as_output();
+    gpio.set_low();
+    // Long enough to drive the capacitor low
     cortex_m::asm::delay(10000);
-    pin.set_as_input();
+    gpio.set_as_input();
     let del = critical_section::with(|_cs| {
-        pin.set_pull(Pull::Down);
+        gpio.set_pull(Pull::Up);
         let t = SyTi::new(syst);
         // Get it near the threshold to begin.
-        while pin.is_high() {}
+        while gpio.is_low() {}
         t.done()
     })?;
-    info!("Initial pulldown del is {}", del);
+    drop(gpio);
+    // info!("Initial pullup del is {}", del);
 
     if del < MIN_CAPACITOR_DEL {
         error!("Capacitor seems small or missing?");
@@ -272,6 +267,8 @@ where
     let mut overshoot = 1u32;
 
     let mut warming = WARMUP;
+    let mut wait = 0;
+    let mut pos = 0;
 
     // After warmup we sample twice at each "overshoot" value.
     // One sample is returned as random output, the other is mixed
@@ -279,28 +276,37 @@ where
     for (i, _) in core::iter::repeat(()).enumerate() {
 
         let (meas, precise) = critical_section::with(|_cs| {
-            pin.set_pull(Pull::Up);
-            while pin.is_low() {}
-            // Keep pulling up for `overshoot` cycles
-            cortex_m::asm::delay(overshoot);
+            // pin.set_pull(Pull::Down);
+            // // let t = SyTi::new(syst);
+            // while pin.is_high() {}
+            // // let ticks = t.done()?;
+            // // Keep pulling down for `overshoot` cycles
+            // cortex_m::asm::delay(overshoot);
 
-            // Pull down, time how long to reach threshold
-            pin.set_pull(Pull::Down);
+            // // Pull up, time how long to reach threshold
+            // pin.set_pull(Pull::None);
+            // debug!("pulldown {}", ticks);
 
             // let t = SyTi::new(syst);
             // while pin.is_high() {}
             // let r = t.done().map(|t| (t, true));
 
-            let r = time_fall_unroll(pin_num, syst);
+            let (r, precise) = time_rise(pin.reborrow(), &mut wait, &mut pos, syst)?;
+
+            let mut gpio = Flex::<AnyPin>::new(pin.reborrow());
+            gpio.set_pull(Pull::None);
+
+            // if (r > )
+
 
-            pin.set_pull(Pull::None);
-            r
+            Ok((r, precise))
         })?;
 
         if i % 2 == 0 {
             // real output
-            if precise && warming == 0 {
-                if !f(meas, overshoot) {
+            // if precise && warming == 0 {
+            if warming == 0 {
+                if !f(meas, pos) {
                     // no more output wanted
                     break
                 }
diff --git a/src/lib.rs b/src/lib.rs
index 0a53d3a6ac126ac0941a38c431aa4289de475b9d..f57abc60af347f87518199fe8f6f210e7fd3911c 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -5,6 +5,7 @@ use log::error;
 
 mod rng;
 mod cap;
+// mod numpin;
 
 pub use rng::{setup, random};
 pub use cap::noise;
diff --git a/src/rng.rs b/src/rng.rs
index cc5377a531efe066384602af1a95f2b2c22b4181..8120373badaff260b49cb9ef5dc3e21dfe108bab 100644
--- a/src/rng.rs
+++ b/src/rng.rs
@@ -13,10 +13,12 @@ use rand_chacha::ChaCha20Rng;
 use sha2::{Digest, Sha256};
 
 use cortex_m::peripheral::SYST;
-use embassy_rp::gpio::{Flex, Pin};
+use embassy_rp::gpio::{Flex, Pin, Pull, AnyPin};
+use embassy_rp::{pac, Peripheral, PeripheralRef};
 
 use rand_chacha::rand_core::{RngCore, SeedableRng};
 
+
 // arbitrary constant
 pub const CAPRAND_ERR: u32 = getrandom::Error::CUSTOM_START + 510132368;
 
@@ -45,12 +47,11 @@ pub fn random(buf: &mut [u8]) -> Result<(), getrandom::Error> {
 /// Call this at early startup. If noisy interrupts or time slicing is happening the caller
 /// should disable interrupts.
 /// `syst` will be modified.
-pub fn setup<P: Pin>(
-    pin: &mut Flex<P>,
-    pin_num: usize,
+pub fn setup(
+    pin: PeripheralRef<AnyPin>,
     syst: &mut SYST,
 ) -> Result<(), getrandom::Error> {
-    let r = CapRng::new(pin, pin_num, syst)?;
+    let r = CapRng::new(pin, syst)?;
 
     critical_section::with(|cs| {
         let mut rng = RNG.borrow_ref_mut(cs);
@@ -64,19 +65,18 @@ pub fn setup<P: Pin>(
 struct CapRng(ChaCha20Rng);
 
 impl CapRng {
-    const SEED_SAMPLES: usize = 1024;
+    // const SEED_SAMPLES: usize = 1024;
+    const SEED_SAMPLES: usize = 50000;
 
     /// Call this at early startup. If noisy interrupts or time slicing is happening the caller
     /// should disable interrupts.
     /// `syst` will be modified.
-    fn new<P: Pin>(
-        pin: &mut Flex<P>,
-        pin_num: usize,
+    fn new(pin: PeripheralRef<AnyPin>,
         syst: &mut SYST,
     ) -> Result<Self, getrandom::Error> {
         let mut h = Sha256::new();
         let mut count = 0;
-        crate::cap::noise(pin, pin_num, syst, |v, _over| {
+        crate::cap::noise(pin, syst, |v, _over| {
             h.update(v.to_be_bytes());
             count += 1;
             count < Self::SEED_SAMPLES