Much better logging, graphing html tool
This commit is contained in:
@@ -33,3 +33,7 @@ rustflags = [
|
|||||||
# This runner will find a supported SWD debug probe and flash your RP2040 over
|
# This runner will find a supported SWD debug probe and flash your RP2040 over
|
||||||
# SWD:
|
# SWD:
|
||||||
runner = "probe-rs run --chip RP2040 --protocol swd"
|
runner = "probe-rs run --chip RP2040 --protocol swd"
|
||||||
|
|
||||||
|
[env]
|
||||||
|
DEFMT_RTT_BUFFER_SIZE = { value = "4096", force = true }
|
||||||
|
DEFMT_LOG = { value = "info", force = true }
|
||||||
211
src/main.rs
211
src/main.rs
@@ -1,11 +1,15 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use defmt::println;
|
use cortex_m::singleton;
|
||||||
|
use defmt::info;
|
||||||
|
use defmt::{println, write};
|
||||||
|
|
||||||
use defmt_rtt as _;
|
use defmt_rtt as _;
|
||||||
use panic_probe as _;
|
use panic_probe as _;
|
||||||
|
|
||||||
|
use rp2040_hal::dma::DMAExt;
|
||||||
|
use rp2040_hal::dma::single_buffer;
|
||||||
use rp2040_hal::gpio::DynFunction;
|
use rp2040_hal::gpio::DynFunction;
|
||||||
use rp2040_hal::gpio::DynPinId;
|
use rp2040_hal::gpio::DynPinId;
|
||||||
use rp2040_hal::gpio::DynPullType;
|
use rp2040_hal::gpio::DynPullType;
|
||||||
@@ -39,6 +43,8 @@ pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER_GENERIC_03H;
|
|||||||
/// if your board has a different frequency
|
/// if your board has a different frequency
|
||||||
const XTAL_FREQ_HZ: u32 = 12_000_000u32;
|
const XTAL_FREQ_HZ: u32 = 12_000_000u32;
|
||||||
|
|
||||||
|
const NUM_ADC_SAMPLES: usize = 1024;
|
||||||
|
|
||||||
/// Entry point to our bare-metal application.
|
/// Entry point to our bare-metal application.
|
||||||
///
|
///
|
||||||
/// The `#[rp2040_hal::entry]` macro ensures the Cortex-M start-up code calls this function
|
/// The `#[rp2040_hal::entry]` macro ensures the Cortex-M start-up code calls this function
|
||||||
@@ -89,9 +95,19 @@ fn main() -> ! {
|
|||||||
MyPin::new(MyPinMode::Input, pins.gpio13.into_dyn_pin()),
|
MyPin::new(MyPinMode::Input, pins.gpio13.into_dyn_pin()),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
let dma = pac.DMA.split(&mut pac.RESETS);
|
||||||
|
|
||||||
let mut adc = hal::Adc::new(pac.ADC, &mut pac.RESETS);
|
let mut adc = hal::Adc::new(pac.ADC, &mut pac.RESETS);
|
||||||
let mut adc_pin = hal::adc::AdcPin::new(pins.gpio26.into_floating_input()).unwrap();
|
let mut adc_pin = hal::adc::AdcPin::new(pins.gpio26.into_floating_input()).unwrap();
|
||||||
let mut adc_fifo = adc.build_fifo().set_channel(&mut adc_pin).start_paused();
|
let mut adc_fifo = adc
|
||||||
|
.build_fifo()
|
||||||
|
.clock_divider(24000, 0)
|
||||||
|
.set_channel(&mut adc_pin)
|
||||||
|
.enable_dma()
|
||||||
|
.start_paused();
|
||||||
|
let buf_for_samples = singleton!(: [u16; NUM_ADC_SAMPLES] = [0; NUM_ADC_SAMPLES]).unwrap();
|
||||||
|
let mut dma_transfer =
|
||||||
|
single_buffer::Config::new(dma.ch0, adc_fifo.dma_read_target(), buf_for_samples).start();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let pushed = input_btn_pin.is_high().unwrap();
|
let pushed = input_btn_pin.is_high().unwrap();
|
||||||
@@ -111,81 +127,112 @@ fn main() -> ! {
|
|||||||
println!("Running test.");
|
println!("Running test.");
|
||||||
delay.delay_ms(500);
|
delay.delay_ms(500);
|
||||||
|
|
||||||
if test_pins.iter_mut().any(|tp| tp.is_high()) {
|
if test_pins.iter_mut().any(|tp| {
|
||||||
|
tp.switch_to_input();
|
||||||
|
tp.is_high()
|
||||||
|
}) {
|
||||||
println!("Uh oh, voltage on test pins? Aborting test");
|
println!("Uh oh, voltage on test pins? Aborting test");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TEST 1
|
// TEST 1
|
||||||
delay.delay_ms(10);
|
delay.delay_ms(100);
|
||||||
println!("Testing at 0v");
|
println!("Testing at 0v");
|
||||||
|
|
||||||
test_pins[0].switch_into_output();
|
test_pins[0].switch_into_output();
|
||||||
test_pins[0].set_low();
|
test_pins[0].set_low();
|
||||||
adc_fifo.clear();
|
|
||||||
adc_fifo.resume();
|
adc_fifo.resume();
|
||||||
|
let (ch, adc_read_target, buf_for_samples) = dma_transfer.wait();
|
||||||
while adc_fifo.len() < 8 {
|
let avg = avg_fifo(buf_for_samples, false);
|
||||||
println!("waiting for ADC... {} / 8", adc_fifo.len());
|
|
||||||
}
|
|
||||||
adc_fifo.pause();
|
|
||||||
|
|
||||||
let avg = avg_fifo(&mut adc_fifo);
|
|
||||||
println!("Avg: {}", avg);
|
println!("Avg: {}", avg);
|
||||||
|
|
||||||
|
adc_fifo.pause();
|
||||||
|
adc_fifo.clear();
|
||||||
|
dma_transfer = single_buffer::Config::new(ch, adc_read_target, buf_for_samples).start();
|
||||||
|
|
||||||
// TEST 2
|
// TEST 2
|
||||||
delay.delay_ms(10);
|
delay.delay_ms(1000);
|
||||||
println!("Testing at 3.3v");
|
println!("Testing at 3.3v");
|
||||||
test_pins[0].set_high();
|
test_pins[0].set_high();
|
||||||
adc_fifo.clear();
|
delay.delay_ms(100);
|
||||||
adc_fifo.resume();
|
adc_fifo.resume();
|
||||||
|
let (ch, adc_read_target, buf_for_samples) = dma_transfer.wait();
|
||||||
while adc_fifo.len() < 8 {
|
let avg = avg_fifo(buf_for_samples, false);
|
||||||
println!("waiting for ADC... {} / 8", adc_fifo.len());
|
|
||||||
}
|
|
||||||
adc_fifo.pause();
|
|
||||||
|
|
||||||
let avg = avg_fifo(&mut adc_fifo);
|
|
||||||
println!("Avg: {}", avg);
|
println!("Avg: {}", avg);
|
||||||
|
|
||||||
|
adc_fifo.pause();
|
||||||
|
adc_fifo.clear();
|
||||||
|
dma_transfer = single_buffer::Config::new(ch, adc_read_target, buf_for_samples).start();
|
||||||
|
|
||||||
// TEST 3
|
// TEST 3
|
||||||
|
delay.delay_ms(1000);
|
||||||
println!("Testing floating");
|
println!("Testing floating");
|
||||||
adc_fifo.clear();
|
test_pins[2].switch_into_output();
|
||||||
|
test_pins[2].set_low();
|
||||||
test_pins[0].switch_to_input();
|
delay.delay_ms(200);
|
||||||
adc_fifo.resume();
|
adc_fifo.resume();
|
||||||
|
test_pins[0].switch_to_floating();
|
||||||
while adc_fifo.len() < 8 {
|
let (ch, adc_read_target, buf_for_samples) = dma_transfer.wait();
|
||||||
println!("waiting for ADC... {} / 8", adc_fifo.len());
|
let avg = avg_fifo(buf_for_samples, true);
|
||||||
}
|
delay.delay_ms(10);
|
||||||
|
println!("Avg: {}", avg);
|
||||||
|
|
||||||
adc_fifo.pause();
|
adc_fifo.pause();
|
||||||
let avg = avg_fifo(&mut adc_fifo);
|
adc_fifo.clear();
|
||||||
|
dma_transfer = single_buffer::Config::new(ch, adc_read_target, buf_for_samples).start();
|
||||||
|
|
||||||
|
// TEST 4
|
||||||
|
delay.delay_ms(1000);
|
||||||
|
println!("Testing resistance");
|
||||||
|
test_pins[0].switch_into_output();
|
||||||
|
test_pins[2].switch_into_output();
|
||||||
|
test_pins[0].set_high();
|
||||||
|
test_pins[2].set_low();
|
||||||
|
delay.delay_ms(100);
|
||||||
|
adc_fifo.resume();
|
||||||
|
let (ch, adc_read_target, buf_for_samples) = dma_transfer.wait();
|
||||||
|
delay.delay_ms(10);
|
||||||
|
let avg = avg_fifo(buf_for_samples, false);
|
||||||
|
delay.delay_ms(10);
|
||||||
println!("Avg: {}", avg);
|
println!("Avg: {}", avg);
|
||||||
|
|
||||||
|
adc_fifo.pause();
|
||||||
|
adc_fifo.clear();
|
||||||
|
dma_transfer = single_buffer::Config::new(ch, adc_read_target, buf_for_samples).start();
|
||||||
|
|
||||||
|
// CLEAN UP
|
||||||
|
delay.delay_ms(1000);
|
||||||
|
println!("Draining outputs");
|
||||||
|
|
||||||
|
test_pins.iter_mut().for_each(|tp| {
|
||||||
|
tp.switch_into_output();
|
||||||
|
tp.set_low();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn avg_fifo(adc_fifo: &mut rp2040_hal::adc::AdcFifo<u16>) -> u32 {
|
fn avg_fifo(samps: &[u16; NUM_ADC_SAMPLES], log_all: bool) -> u32 {
|
||||||
let mut avg = 0u32;
|
let mut avg = 0u32;
|
||||||
for i in 0..8 {
|
if log_all {
|
||||||
let samp = adc_fifo.read();
|
info!("{}", samps[0..NUM_ADC_SAMPLES]);
|
||||||
println!("Value {}, {}", i, samp);
|
|
||||||
avg += samp as u32;
|
|
||||||
}
|
}
|
||||||
|
samps.iter().for_each(|n| {
|
||||||
avg /= 8;
|
avg += *n as u32;
|
||||||
avg
|
});
|
||||||
|
avg / (NUM_ADC_SAMPLES as u32)
|
||||||
}
|
}
|
||||||
|
|
||||||
enum MyPinMode {
|
enum MyPinMode {
|
||||||
Input,
|
Input,
|
||||||
Output,
|
Output,
|
||||||
|
Floating,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MyPin {
|
struct MyPin {
|
||||||
mode: MyPinMode,
|
mode: MyPinMode,
|
||||||
i_pin: Option<Pin<DynPinId, FunctionSioInput, PullNone>>,
|
i_pin: Option<Pin<DynPinId, FunctionSioInput, PullNone>>,
|
||||||
o_pin: Option<Pin<DynPinId, FunctionSioOutput, PullDown>>,
|
o_pin: Option<Pin<DynPinId, FunctionSioOutput, PullDown>>,
|
||||||
|
d_pin: Option<Pin<DynPinId, FunctionNull, PullNone>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MyPin {
|
impl MyPin {
|
||||||
@@ -200,6 +247,7 @@ impl MyPin {
|
|||||||
.into_pull_type::<PullNone>(),
|
.into_pull_type::<PullNone>(),
|
||||||
),
|
),
|
||||||
o_pin: None,
|
o_pin: None,
|
||||||
|
d_pin: None,
|
||||||
},
|
},
|
||||||
MyPinMode::Output => MyPin {
|
MyPinMode::Output => MyPin {
|
||||||
mode,
|
mode,
|
||||||
@@ -209,59 +257,108 @@ impl MyPin {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.into_pull_type::<PullDown>(),
|
.into_pull_type::<PullDown>(),
|
||||||
),
|
),
|
||||||
|
d_pin: None,
|
||||||
|
},
|
||||||
|
MyPinMode::Floating => MyPin {
|
||||||
|
mode,
|
||||||
|
i_pin: None,
|
||||||
|
o_pin: None,
|
||||||
|
d_pin: Some(pin.into_pull_type::<PullNone>()),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn switch_to_input(&mut self) {
|
fn switch_to_floating(&mut self) {
|
||||||
match self.mode {
|
self.d_pin = match self.mode {
|
||||||
MyPinMode::Input => (),
|
MyPinMode::Floating => return,
|
||||||
|
MyPinMode::Input => {
|
||||||
|
let pin = self.i_pin.take().unwrap();
|
||||||
|
Some(
|
||||||
|
pin.into_pull_type::<PullNone>()
|
||||||
|
.try_into_function::<FunctionNull>()
|
||||||
|
.unwrap()
|
||||||
|
.into_pull_type::<PullNone>(),
|
||||||
|
)
|
||||||
|
}
|
||||||
MyPinMode::Output => {
|
MyPinMode::Output => {
|
||||||
let pin = self.o_pin.take().unwrap();
|
let pin = self.o_pin.take().unwrap();
|
||||||
self.i_pin = Some(
|
Some(
|
||||||
|
pin.into_pull_type::<PullNone>()
|
||||||
|
.try_into_function::<FunctionNull>()
|
||||||
|
.unwrap()
|
||||||
|
.into_pull_type::<PullNone>(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
self.mode = MyPinMode::Floating;
|
||||||
|
}
|
||||||
|
fn switch_to_input(&mut self) {
|
||||||
|
self.i_pin = match self.mode {
|
||||||
|
MyPinMode::Input => return,
|
||||||
|
MyPinMode::Output => {
|
||||||
|
let pin = self.o_pin.take().unwrap();
|
||||||
|
Some(
|
||||||
pin.into_pull_type::<PullNone>()
|
pin.into_pull_type::<PullNone>()
|
||||||
.try_into_function::<FunctionSioInput>()
|
.try_into_function::<FunctionSioInput>()
|
||||||
.unwrap(),
|
.unwrap()
|
||||||
);
|
.into_pull_type::<PullNone>(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
MyPinMode::Floating => {
|
||||||
|
let pin = self.d_pin.take().unwrap();
|
||||||
|
Some(
|
||||||
|
pin.into_pull_type::<PullNone>()
|
||||||
|
.try_into_function::<FunctionSioInput>()
|
||||||
|
.unwrap()
|
||||||
|
.into_pull_type::<PullNone>(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
};
|
||||||
self.mode = MyPinMode::Input;
|
self.mode = MyPinMode::Input;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn switch_into_output(&mut self) {
|
fn switch_into_output(&mut self) {
|
||||||
match self.mode {
|
self.o_pin = match self.mode {
|
||||||
|
MyPinMode::Output => return,
|
||||||
MyPinMode::Input => {
|
MyPinMode::Input => {
|
||||||
let pin = self.i_pin.take().unwrap();
|
let pin = self.i_pin.take().unwrap();
|
||||||
self.o_pin = Some(
|
Some(
|
||||||
pin.into_pull_type::<PullDown>()
|
pin.into_pull_type::<PullDown>()
|
||||||
.try_into_function::<FunctionSioOutput>()
|
.try_into_function::<FunctionSioOutput>()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
);
|
)
|
||||||
|
}
|
||||||
|
MyPinMode::Floating => {
|
||||||
|
let pin = self.d_pin.take().unwrap();
|
||||||
|
Some(
|
||||||
|
pin.into_pull_type::<PullDown>()
|
||||||
|
.try_into_function::<FunctionSioOutput>()
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
};
|
||||||
self.mode = MyPinMode::Output;
|
self.mode = MyPinMode::Output;
|
||||||
}
|
}
|
||||||
MyPinMode::Output => (),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_low(&mut self) {
|
fn set_low(&mut self) {
|
||||||
match self.mode {
|
match self.mode {
|
||||||
MyPinMode::Input => println!("Ignoring set_low for input pin"),
|
|
||||||
MyPinMode::Output => self.o_pin.as_mut().unwrap().set_low().unwrap(),
|
MyPinMode::Output => self.o_pin.as_mut().unwrap().set_low().unwrap(),
|
||||||
|
_ => println!("Ignoring set_low for input or floating pin"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_high(&mut self) {
|
fn set_high(&mut self) {
|
||||||
match self.mode {
|
match self.mode {
|
||||||
MyPinMode::Input => println!("Ignoring set_high for input pin"),
|
|
||||||
MyPinMode::Output => self.o_pin.as_mut().unwrap().set_high().unwrap(),
|
MyPinMode::Output => self.o_pin.as_mut().unwrap().set_high().unwrap(),
|
||||||
|
_ => println!("Ignoring set_high for input or floating pin"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_high(&mut self) -> bool {
|
fn is_high(&mut self) -> bool {
|
||||||
match self.mode {
|
match self.mode {
|
||||||
MyPinMode::Input => self.i_pin.as_mut().unwrap().is_high().unwrap(),
|
MyPinMode::Input => self.i_pin.as_mut().unwrap().is_high().unwrap(),
|
||||||
MyPinMode::Output => {
|
_ => {
|
||||||
println!("Warning: read of output pin.");
|
println!("Warning: read of output or floating pin.");
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -270,8 +367,8 @@ impl MyPin {
|
|||||||
fn is_low(&mut self) -> bool {
|
fn is_low(&mut self) -> bool {
|
||||||
match self.mode {
|
match self.mode {
|
||||||
MyPinMode::Input => self.i_pin.as_mut().unwrap().is_low().unwrap(),
|
MyPinMode::Input => self.i_pin.as_mut().unwrap().is_low().unwrap(),
|
||||||
MyPinMode::Output => {
|
_ => {
|
||||||
println!("Warning: read of output pin.");
|
println!("Warning: read of output or floating pin.");
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
143
tests/draw.html
Normal file
143
tests/draw.html
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user