diff --git a/examples/noise.rs b/examples/noise.rs
index f3d2eb8e8a049a403de54b64d597480ab11c91ea..1dca3b7b16c696c91b07153a4da148723d5ad03c 100644
--- a/examples/noise.rs
+++ b/examples/noise.rs
@@ -50,7 +50,7 @@ async fn main(_spawner: Spawner) {
 
     let mut hist = [0u32; 200];
 
-    let PRINT = 1000;
+    let PRINT = 10000;
     // let PRINT = 50;
 
     // let mut gpios = [
@@ -67,17 +67,18 @@ async fn main(_spawner: Spawner) {
         // serial
         // 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_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_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_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(),
@@ -90,34 +91,37 @@ async fn main(_spawner: Spawner) {
         p.PIN_22.degrade().into_ref(),
         // p.PIN_23.degrade().into_ref(),
         // p.PIN_24.degrade().into_ref(),
+        // wl_cs, gate of vsys adc mosfet
         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_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();
-        let mut n = 0;
-        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;
+        for low_delay in 0..1{
+            let pin = gpio.pin();
+            let mut n = 0;
+            caprand::noise(gpio.reborrow(), low_delay,
+                &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 {} delay {} iter {}", pin, low_delay, n);
+                        for (p, h) in hist.iter_mut().enumerate() {
+                            if *h > 0 {
+                                info!("{}: {}", p, h);
+                                *h = 0;
+                            }
                         }
                     }
-                }
-                n < PRINT
-        }).unwrap();
+                    n < PRINT
+            }).unwrap();
+        }
     }
-
 }
diff --git a/src/cap.rs b/src/cap.rs
index 823ae68690ab605ebf46ed9a86ab172440045b4d..feb736e4e9beb5df0589904e084eefc8df3e2ec5 100644
--- a/src/cap.rs
+++ b/src/cap.rs
@@ -92,6 +92,10 @@ impl<'t> SyTi<'t> {
         }
     }
 
+    fn reset(&mut self) {
+        self.syst.clear_current();
+    }
+
     /// returns the duration, or failure on overflow
     fn done(self) -> Result<u32, ()> {
         let t2 = SYST::get_current();
@@ -103,39 +107,150 @@ 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), ()> {
-
+// Returns (ticks: u32, pos: u8)
+// `pos == 0` are less precise than other results
+fn time_rise(pin: PeripheralRef<AnyPin>, low_delay: u32, syst: &mut SYST) -> Result<(u32, u8), ()> {
     let pin_num = pin.pin() as usize;
     let mask = 1u32 << pin_num;
 
+    unsafe {
+        pac::PADS_BANK0
+            .gpio(pin_num)
+            .modify(|s| {
+                // Pullup
+                s.set_pue(true);
+            });
+    };
+
     // bank 0 single cycle IO in
     let gpio_in = pac::SIO.gpio_in(0).ptr();
     let so = pac::SIO.gpio_out(0);
     let soe = pac::SIO.gpio_oe(0);
     unsafe {
         so.value_clr().write_value(1 << pin_num);
-        soe.value_set().write_value(1 << pin_num);
     }
-    // // unsafe {
-    // //     asm!(
-    // //         "nop",
-    // //     )
-    // // }
-    // cortex_m::asm::delay(20);
-    // cortex_m::asm::delay(1000);
-    unsafe {
-        soe.value_clr().write_value(1 << pin_num);
+
+    let soe_set = soe.value_set().ptr();
+    let soe_clr = soe.value_clr().ptr();
+    let mut t = SyTi::new(syst);
+
+    // actual low time is low_delay+1 cycles
+    match (low_delay, low_delay % 3) {
+        (0, _) => unsafe {
+            asm!(
+                "str {mask}, [{soe_set}]",
+                // low for 1 cycle
+                "str {mask}, [{soe_clr}]",
+
+                mask = in(reg) mask,
+                soe_set = in(reg) soe_set,
+                soe_clr = in(reg) soe_clr,
+                options(nostack, readonly),
+                )
+        },
+        (1, _) => unsafe {
+            asm!(
+                "str {mask}, [{soe_set}]",
+                // low for 2 cycles
+                "nop",
+                "str {mask}, [{soe_clr}]",
+
+                mask = in(reg) mask,
+                soe_set = in(reg) soe_set,
+                soe_clr = in(reg) soe_clr,
+                options(nostack, readonly),
+                )
+        },
+        (_, 2) => unsafe {
+            // min delay of 2
+            let mut d = low_delay + 1;
+            assert!(d % 3 == 0);
+            asm!(
+                "str {mask}, [{soe_set}]",
+                "000:",
+                // one cycle
+                "subs {d}, 3",
+                // two cycles bne taken
+                "bne 000b",
+                // one cycle for bne not taken
+                "str {mask}, [{soe_clr}]",
+
+                mask = in(reg) mask,
+                soe_set = in(reg) soe_set,
+                soe_clr = in(reg) soe_clr,
+                d = inout(reg) d,
+                options(nostack, readonly),
+                );
+            assert_eq!(d, 0);
+        },
+        (_, 0) => unsafe {
+            // min delay of 3
+            let mut d = low_delay + 1;
+            assert!(d % 3 == 1);
+            asm!(
+                "str {mask}, [{soe_set}]",
+                // one cycle
+                "subs {d}, 1",
+                "000:",
+                // one cycle
+                "subs {d}, 3",
+                // two cycles bne taken
+                "bne 000b",
+                // one cycle for bne not taken
+                "str {mask}, [{soe_clr}]",
+
+                mask = in(reg) mask,
+                soe_set = in(reg) soe_set,
+                soe_clr = in(reg) soe_clr,
+                d = inout(reg) d,
+                options(nostack, readonly),
+                );
+            assert_eq!(d, 0);
+        },
+        (_, 1) => unsafe {
+            // min delay of 4
+            let mut d = low_delay + 1;
+            assert!(d % 3 == 2);
+            asm!(
+                "str {mask}, [{soe_set}]",
+                // one cycle
+                "subs {d}, 1",
+                // one cycle
+                "subs {d}, 1",
+                "000:",
+                // one cycle
+                "subs {d}, 3",
+                // two cycles bne taken
+                "bne 000b",
+                // one cycle for bne not taken
+                "str {mask}, [{soe_clr}]",
+
+                mask = in(reg) mask,
+                soe_set = in(reg) soe_set,
+                soe_clr = in(reg) soe_clr,
+                d = inout(reg) d,
+                options(nostack, readonly),
+                );
+            assert_eq!(d, 0);
+        },
+        // `match` doesn't understand modulo
+        _ => unreachable!()
     }
 
-    unsafe {
-        pac::PADS_BANK0
-            .gpio(pin_num)
-            .modify(|s| {
-                // Pullup
-                s.set_pue(true);
-            });
-    };
+    t.reset();
+    // unsafe {
+    //     soe.value_set().write_value(1 << pin_num);
+    // }
+    // // // unsafe {
+    // // //     asm!(
+    // // //         "nop",
+    // // //     )
+    // // // }
+    // // cortex_m::asm::delay(20);
+    // // 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() });
@@ -146,7 +261,6 @@ fn time_rise(pin: PeripheralRef<AnyPin>, wait: &mut u32, rpos: &mut u32, syst: &
     // cortex_m::asm::delay(900);
     // pin.set_pull(Pull::None);
 
-    let t = SyTi::new(syst);
 
     let x0: u32;
     let x1: u32;
@@ -211,12 +325,6 @@ fn time_rise(pin: PeripheralRef<AnyPin>, wait: &mut u32, rpos: &mut u32, syst: &
     // 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);
-    }
-
     unsafe {
         pac::PADS_BANK0
             .gpio(pin_num)
@@ -226,13 +334,13 @@ fn time_rise(pin: PeripheralRef<AnyPin>, wait: &mut u32, rpos: &mut u32, syst: &
             });
     };
 
-    *rpos = pos;
-    Ok((tick, precise))
+    Ok((tick, pos as u8))
 }
 
 // `f()` is called on each output `u32`.
 pub fn noise<'d, F>(
     mut pin: PeripheralRef<AnyPin>,
+    low_delay: u32,
     syst: &mut SYST,
     mut f: F,
 ) -> Result<(), ()>
@@ -258,40 +366,46 @@ where
     // Long enough to drive the capacitor low
     cortex_m::asm::delay(10000);
     gpio.set_as_input();
-    let del = critical_section::with(|_cs| {
-        gpio.set_pull(Pull::Up);
-        let t = SyTi::new(syst);
-        // Get it near the threshold to begin.
-        while gpio.is_low() {}
-        t.done()
-    })?;
+    // let del = critical_section::with(|_cs| {
+    //     gpio.set_pull(Pull::Up);
+    //     let t = SyTi::new(syst);
+    //     // Get it near the threshold to begin.
+    //     while gpio.is_low() {}
+    //     t.done()
+    // })?;
     drop(gpio);
-    info!("Initial pullup del is {}", del);
+    // info!("Initial pullup del is {}", del);
 
-    if del < MIN_CAPACITOR_DEL {
-        error!("Capacitor seems small or missing?");
-        return Err(())
-    }
+    // if del < MIN_CAPACITOR_DEL {
+    //     error!("Capacitor seems small or missing?");
+    //     return Err(())
+    // }
 
 
     // The main loop
     let mut overshoot = 1u32;
 
     let mut warming = WARMUP;
-    let mut wait = 0;
     let mut pos = 0;
 
     unsafe {
         pac::PADS_BANK0
             .gpio(pin_num)
             .modify(|s| {
-                // Disabling the Schmitt Trigger gives a clearer correlation between "overshoot"
-                // and measured values.
-                s.set_schmitt(false);
+                // // Disabling the Schmitt Trigger gives a clearer correlation between "overshoot"
+                // // and measured values.
+                // s.set_schmitt(false);
                 // Input enable
                 s.set_ie(true);
             });
 
+        pac::SYSCFG
+            .proc_in_sync_bypass()
+            .modify(|s| {
+                let val = s.proc_in_sync_bypass();
+                s.set_proc_in_sync_bypass(val | 1 << pin_num);
+            });
+
         // Use SIO
         pac::IO_BANK0
             .gpio(pin_num)
@@ -322,7 +436,8 @@ where
             // while pin.is_high() {}
             // let r = t.done().map(|t| (t, true));
 
-            let (r, precise) = time_rise(pin.reborrow(), &mut wait, &mut pos, syst)?;
+            let (r, pos) = time_rise(pin.reborrow(), 0, syst)?;
+            let precise = pos == 0;
 
             // let mut gpio = Flex::<AnyPin>::new(pin.reborrow());
             // gpio.set_pull(Pull::None);
diff --git a/src/rng.rs b/src/rng.rs
index 8120373badaff260b49cb9ef5dc3e21dfe108bab..00085373a9810792b1cd3a95cc7a58dbe0856a92 100644
--- a/src/rng.rs
+++ b/src/rng.rs
@@ -76,7 +76,7 @@ impl CapRng {
     ) -> Result<Self, getrandom::Error> {
         let mut h = Sha256::new();
         let mut count = 0;
-        crate::cap::noise(pin, syst, |v, _over| {
+        crate::cap::noise(pin, 0, syst, |v, _over| {
             h.update(v.to_be_bytes());
             count += 1;
             count < Self::SEED_SAMPLES