Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
No results found
Show changes
Commits on Source (2)
......@@ -2,7 +2,7 @@
#![no_main]
#![feature(type_alias_impl_trait)]
use defmt::{info, panic};
use defmt::{info, debug, panic};
use embassy_executor::Spawner;
use embassy_time::{Timer, Duration};
use embassy_rp::pac as pac;
......@@ -110,67 +110,124 @@ async fn run<'d, P: Pin>(pin: &mut Flex<'d, P>, syst: &mut SYST) -> Result<(), D
while pin.is_high() {}
});
let mut up_x = 0u32;
let mut down_x = 0u32;
let mut up = 0u32;
let mut down = 0u32;
let mut up_x = 1u32;
let mut down_x = 1u32;
/*
|prev | |
|iter | |
| | |
. |
. . | .
. . | . .
. . | . .
.---------------.---------------.-----------.------ GPIO threshold. Probably isn't really flat.
. . .
. .
. .
.
*/
loop {
const LOOP: usize = 20;
const BUF: usize = 16;
const T: u32 = 8192;
let mut dels = [0u32; BUF];
// number of iterations per interrupt-free block
const LOOP: usize = 2000;
// Range of cycle counts for overshoot. Upper limit is the pullup/pulldown time
// from vcc/gnd to threshold.
// A large upper limit will also decrease the number of samples/second (but will
// perhaps have more entropy bits/sample?)
// Lower limit is necessary because we don't want to hit the threshold immediately
// on reading.
// Empirical values for a 1uF capacitor.
// TODO this could be determined from a calibration step?
// const UPRANGE: u32 = 50000;
// const LOWRANGE: u32 = 15000;
// nice integers
const LOW_OVER: u32 = 15000;
const HIGH_OVER: u32 = LOW_OVER + 8192;
// for debug printout
// BUF iterations from the start (or end?) will be printed. must be <LOOP
const BUF: usize = 64;
// for end of buffer
// const BUF_START: usize = LOOP - BUF;
// for start of buffer
const BUF_START: usize = 0;
let mut ups = [0u32; BUF];
let mut downs = [0u32; BUF];
let mut upx = [0u32; BUF];
let mut downx = [0u32; BUF];
// The main iteration function for experimentation.
// It calculates the next overshoot #cycles.
// `prev` is the #cycles returned from last step(), `meas` is the time
// taken for the return to centre value (which is targetting `T`).
// eg `up_x = step(up_x, down);`
let step = |prev: u32, meas: u32| {
if meas < T || prev < T {
prev * 2
// doubling step.
// x[n] = 2*x[n-1] + meas
let v = prev*2 + meas;
// modulo to sensible range
if v > UPRANGE {
LOWRANGE + (v % (UPRANGE - LOWRANGE))
} else {
prev.saturating_sub(T / 2)
}.max(1)
v
}
};
critical_section::with(|_cs| {
// We alternate between taking the measured down/up values as real output,
// and using it to compute the next overshoot.
// That prevents leaking "real output" values in the timing of subsequent overshoot
// delays.
for i in 0..LOOP {
cortex_m::asm::delay(down_x);
pin.set_pull(Pull::Up);
syst.clear_current();
let t1 = SYST::get_current();
while pin.is_low() {}
let t2 = SYST::get_current();
up = t1 - t2;
up_x = step(up_x, down);
let t_up = t1 - t2;
if i % 2 == 0 {
down_x = step(down_x, t_up);
} else {
// TODO: keep `up` as our random output
}
cortex_m::asm::delay(up_x);
pin.set_pull(Pull::Down);
syst.clear_current();
let t1 = SYST::get_current();
while pin.is_high() {}
let t2 = SYST::get_current();
down = t1 - t2;
down_x = step(down_x, up);
let t_down = t1 - t2;
if i % 2 == 0 {
up_x = step(up_x, t_down);
} else {
// TODO: keep `down` as our random output
}
cortex_m::asm::delay(down_x);
if i < BUF {
let n = i;
ups[n] = up;
if (BUF_START..BUF_START+BUF).contains(i) {
let n = i - BUF_START;
ups[n] = t_up;
upx[n] = up_x;
downs[n] = down;
downs[n] = t_down;
downx[n] = down_x;
dels[n] = up + down;
}
}
// put it in idle state so it'll be closer to threshold
// on the next critical_section iteration.
pin.set_pull(Pull::None);
});
for i in 0..BUF {
info!("{} U {} x {} D {} x {}", dels[i], ups[i], upx[i], downs[i], downx[i]);
for i in 0..BUF-1 {
if i % 2 == 1 {
info!("U {},{} x {} D {},{} x {} use", ups[i], ups[i+1], upx[i], downs[i], downs[i+1], downx[i]);
} else {
}
}
info!("===");
}
......