From b166ed6b78db0737005a65c1e444ce7563de7da3 Mon Sep 17 00:00:00 2001 From: pennae Date: Fri, 21 Jul 2023 21:31:44 +0200 Subject: rp: generalize adc inputs from pins to channels this lets us treat pins and the temperature sensor uniformly using the same interface. uniformity in turn lets us add more adc features without combinatorial explosion of methods and types needed to handle them all. --- tests/rp/src/bin/adc.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'tests') diff --git a/tests/rp/src/bin/adc.rs b/tests/rp/src/bin/adc.rs index e659844ae..9006ce8cc 100644 --- a/tests/rp/src/bin/adc.rs +++ b/tests/rp/src/bin/adc.rs @@ -6,7 +6,7 @@ mod common; use defmt::*; use embassy_executor::Spawner; -use embassy_rp::adc::{Adc, Config, InterruptHandler, Pin}; +use embassy_rp::adc::{Adc, Channel, Config, InterruptHandler}; use embassy_rp::bind_interrupts; use embassy_rp::gpio::Pull; use {defmt_rtt as _, panic_probe as _}; @@ -22,12 +22,12 @@ async fn main(_spawner: Spawner) { { { - let mut p = Pin::new(&mut p.PIN_26, Pull::Down); + let mut p = Channel::new_pin(&mut p.PIN_26, Pull::Down); defmt::assert!(adc.blocking_read(&mut p).unwrap() < 0b01_0000_0000); defmt::assert!(adc.read(&mut p).await.unwrap() < 0b01_0000_0000); } { - let mut p = Pin::new(&mut p.PIN_26, Pull::Up); + let mut p = Channel::new_pin(&mut p.PIN_26, Pull::Up); defmt::assert!(adc.blocking_read(&mut p).unwrap() > 0b11_0000_0000); defmt::assert!(adc.read(&mut p).await.unwrap() > 0b11_0000_0000); } @@ -35,21 +35,21 @@ async fn main(_spawner: Spawner) { // not bothering with async reads from now on { { - let mut p = Pin::new(&mut p.PIN_27, Pull::Down); + let mut p = Channel::new_pin(&mut p.PIN_27, Pull::Down); defmt::assert!(adc.blocking_read(&mut p).unwrap() < 0b01_0000_0000); } { - let mut p = Pin::new(&mut p.PIN_27, Pull::Up); + let mut p = Channel::new_pin(&mut p.PIN_27, Pull::Up); defmt::assert!(adc.blocking_read(&mut p).unwrap() > 0b11_0000_0000); } } { { - let mut p = Pin::new(&mut p.PIN_28, Pull::Down); + let mut p = Channel::new_pin(&mut p.PIN_28, Pull::Down); defmt::assert!(adc.blocking_read(&mut p).unwrap() < 0b01_0000_0000); } { - let mut p = Pin::new(&mut p.PIN_28, Pull::Up); + let mut p = Channel::new_pin(&mut p.PIN_28, Pull::Up); defmt::assert!(adc.blocking_read(&mut p).unwrap() > 0b11_0000_0000); } } @@ -57,22 +57,22 @@ async fn main(_spawner: Spawner) { // gp29 is connected to vsys through a 200k/100k divider, // adding pulls should change the value let low = { - let mut p = Pin::new(&mut p.PIN_29, Pull::Down); + let mut p = Channel::new_pin(&mut p.PIN_29, Pull::Down); adc.blocking_read(&mut p).unwrap() }; let none = { - let mut p = Pin::new(&mut p.PIN_29, Pull::None); + let mut p = Channel::new_pin(&mut p.PIN_29, Pull::None); adc.blocking_read(&mut p).unwrap() }; let up = { - let mut p = Pin::new(&mut p.PIN_29, Pull::Up); + let mut p = Channel::new_pin(&mut p.PIN_29, Pull::Up); adc.blocking_read(&mut p).unwrap() }; defmt::assert!(low < none); defmt::assert!(none < up); } - let temp = convert_to_celsius(adc.read_temperature().await.unwrap()); + let temp = convert_to_celsius(adc.read(&mut Channel::new_sensor(p.ADC_TEMP_SENSOR)).await.unwrap()); defmt::assert!(temp > 0.0); defmt::assert!(temp < 60.0); -- cgit From a6b8f3d99478266b4f110e9c150ce3add5c3ffc6 Mon Sep 17 00:00:00 2001 From: pennae Date: Fri, 21 Jul 2023 23:34:12 +0200 Subject: rp: add single-channel dma from adc with uniform treatment of adc inputs it's easy enough to add a new sampling method. dma sampling only supports one channel at the moment, though round-robin sampling would be a simple extension (probably a new trait that's implemented for Channel and &[Channel]). continuous dma as proposed in #1608 also isn't done here, we'd expect that to be a compound dma::Channel that internally splits a buffer in half and dispatches callbacks or something like that. --- tests/rp/src/bin/adc.rs | 55 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 4 deletions(-) (limited to 'tests') diff --git a/tests/rp/src/bin/adc.rs b/tests/rp/src/bin/adc.rs index 9006ce8cc..d6d58f0c0 100644 --- a/tests/rp/src/bin/adc.rs +++ b/tests/rp/src/bin/adc.rs @@ -6,7 +6,7 @@ mod common; use defmt::*; use embassy_executor::Spawner; -use embassy_rp::adc::{Adc, Channel, Config, InterruptHandler}; +use embassy_rp::adc::{Adc, Channel, Config, InterruptHandler, Sample}; use embassy_rp::bind_interrupts; use embassy_rp::gpio::Pull; use {defmt_rtt as _, panic_probe as _}; @@ -71,10 +71,57 @@ async fn main(_spawner: Spawner) { defmt::assert!(low < none); defmt::assert!(none < up); } + { + let temp = convert_to_celsius( + adc.read(&mut Channel::new_temp_sensor(&mut p.ADC_TEMP_SENSOR)) + .await + .unwrap(), + ); + defmt::assert!(temp > 0.0); + defmt::assert!(temp < 60.0); + } - let temp = convert_to_celsius(adc.read(&mut Channel::new_sensor(p.ADC_TEMP_SENSOR)).await.unwrap()); - defmt::assert!(temp > 0.0); - defmt::assert!(temp < 60.0); + // run a bunch of conversions. we'll only check gp29 and the temp + // sensor here for brevity, if those two work the rest will too. + { + // gp29 is connected to vsys through a 200k/100k divider, + // adding pulls should change the value + let mut low = [0u16; 16]; + let mut none = [0u8; 16]; + let mut up = [Sample::default(); 16]; + adc.read_many( + &mut Channel::new_pin(&mut p.PIN_29, Pull::Down), + &mut low, + &mut p.DMA_CH0, + ) + .await + .unwrap(); + adc.read_many( + &mut Channel::new_pin(&mut p.PIN_29, Pull::None), + &mut none, + &mut p.DMA_CH0, + ) + .await + .unwrap(); + adc.read_many_raw(&mut Channel::new_pin(&mut p.PIN_29, Pull::Up), &mut up, &mut p.DMA_CH0) + .await; + defmt::assert!(low.iter().zip(none.iter()).all(|(l, n)| *l >> 4 < *n as u16)); + defmt::assert!(up.iter().all(|s| s.good())); + defmt::assert!(none.iter().zip(up.iter()).all(|(n, u)| (*n as u16) < u.value())); + } + { + let mut temp = [0u16; 16]; + adc.read_many( + &mut Channel::new_temp_sensor(&mut p.ADC_TEMP_SENSOR), + &mut temp, + &mut p.DMA_CH0, + ) + .await + .unwrap(); + let temp = temp.map(convert_to_celsius); + defmt::assert!(temp.iter().all(|t| *t > 0.0)); + defmt::assert!(temp.iter().all(|t| *t < 60.0)); + } info!("Test OK"); cortex_m::asm::bkpt(); -- cgit