Skip to content
Snippets Groups Projects
Commit 1353b3da authored by Matt Johnston's avatar Matt Johnston
Browse files

starting ascii art

parent b66c05bf
No related merge requests found
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#![no_main] #![no_main]
#![feature(type_alias_impl_trait)] #![feature(type_alias_impl_trait)]
use defmt::{info, panic}; use defmt::{info, debug, panic};
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embassy_time::{Timer, Duration}; use embassy_time::{Timer, Duration};
use embassy_rp::pac as pac; use embassy_rp::pac as pac;
...@@ -112,18 +112,47 @@ async fn run<'d, P: Pin>(pin: &mut Flex<'d, P>, syst: &mut SYST) -> Result<(), D ...@@ -112,18 +112,47 @@ async fn run<'d, P: Pin>(pin: &mut Flex<'d, P>, syst: &mut SYST) -> Result<(), D
let mut up_x = 1u32; let mut up_x = 1u32;
let mut down_x = 1u32; let mut down_x = 1u32;
let mut up = 0u32;
let mut down = 0u32; /*
|prev | |
|iter | |
| | |
. |
. . | .
. . | . .
. . | . .
.---------------.---------------.-----------.------ GPIO threshold. Probably isn't really flat.
. . .
. .
. .
.
*/
loop { loop {
// number of loops per interrupt-free block // number of iterations per interrupt-free block
const LOOP: usize = 2000; const LOOP: usize = 2000;
// count of cycles to target // Range of cycle counts for overshoot. Upper limit is the pullup/pulldown time
const T: u32 = 256; // from vcc/gnd to threshold.
// A large upper limit will also decrease the number of samples/second (but will
// BUF iterations from the start (or end?) will be printed // perhaps have more entropy bits/sample?)
const BUF: usize = 16; // 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 ups = [0u32; BUF];
let mut downs = [0u32; BUF]; let mut downs = [0u32; BUF];
let mut upx = [0u32; BUF]; let mut upx = [0u32; BUF];
...@@ -135,24 +164,35 @@ async fn run<'d, P: Pin>(pin: &mut Flex<'d, P>, syst: &mut SYST) -> Result<(), D ...@@ -135,24 +164,35 @@ async fn run<'d, P: Pin>(pin: &mut Flex<'d, P>, syst: &mut SYST) -> Result<(), D
// taken for the return to centre value (which is targetting `T`). // taken for the return to centre value (which is targetting `T`).
// eg `up_x = step(up_x, down);` // eg `up_x = step(up_x, down);`
let step = |prev: u32, meas: u32| { let step = |prev: u32, meas: u32| {
if meas < T { // doubling step.
(prev + meas)*2 // x[n] = 2*x[n-1] + meas
let v = prev*2 + meas;
// modulo to sensible range
if v > UPRANGE {
LOWRANGE + (v % (UPRANGE - LOWRANGE))
} else { } else {
prev - prev/4 + meas % T v
}.max(1) }
}; };
critical_section::with(|_cs| { 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 { for i in 0..LOOP {
pin.set_pull(Pull::Up); pin.set_pull(Pull::Up);
syst.clear_current(); syst.clear_current();
let t1 = SYST::get_current(); let t1 = SYST::get_current();
while pin.is_low() {} while pin.is_low() {}
let t2 = SYST::get_current(); let t2 = SYST::get_current();
up = t1 - t2; let t_up = t1 - t2;
if i % 2 == 0 { if i % 2 == 0 {
down_x = step(down_x, up); down_x = step(down_x, t_up);
} else {
// TODO: keep `up` as our random output
} }
cortex_m::asm::delay(up_x); cortex_m::asm::delay(up_x);
...@@ -161,21 +201,25 @@ async fn run<'d, P: Pin>(pin: &mut Flex<'d, P>, syst: &mut SYST) -> Result<(), D ...@@ -161,21 +201,25 @@ async fn run<'d, P: Pin>(pin: &mut Flex<'d, P>, syst: &mut SYST) -> Result<(), D
let t1 = SYST::get_current(); let t1 = SYST::get_current();
while pin.is_high() {} while pin.is_high() {}
let t2 = SYST::get_current(); let t2 = SYST::get_current();
down = t1 - t2; let t_down = t1 - t2;
if i % 2 == 0 { if i % 2 == 0 {
up_x = step(up_x, down); up_x = step(up_x, t_down);
} else {
// TODO: keep `down` as our random output
} }
cortex_m::asm::delay(down_x); cortex_m::asm::delay(down_x);
if i >= LOOP-BUF { if (BUF_START..BUF_START+BUF).contains(i) {
let n = i - (LOOP-BUF); let n = i - BUF_START;
ups[n] = up; ups[n] = t_up;
upx[n] = up_x; upx[n] = up_x;
downs[n] = down; downs[n] = t_down;
downx[n] = down_x; downx[n] = down_x;
} }
} }
// put it in idle state so it'll be closer to threshold
// on the next critical_section iteration.
pin.set_pull(Pull::None); pin.set_pull(Pull::None);
}); });
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment