diff --git a/examples/ch32v203/src/bin/adc.rs b/examples/ch32v203/src/bin/adc.rs index 0134b81..15ba5e2 100644 --- a/examples/ch32v203/src/bin/adc.rs +++ b/examples/ch32v203/src/bin/adc.rs @@ -6,7 +6,7 @@ use ch32_hal as hal; use embassy_executor::Spawner; use embassy_time::{Delay, Duration, Timer}; -use hal::adc::SampleTime; +use hal::adc::{SampleTime, Pga}; use hal::gpio::{Level, Output}; use hal::println; @@ -33,7 +33,7 @@ async fn main(spawner: Spawner) -> ! { Timer::after(Duration::from_millis(500)).await; println!("Starting conversion!"); - let val = adc.convert(&mut ch, SampleTime::CYCLES239_5); + let val = adc.convert(&mut ch, SampleTime::CYCLES239_5, Pga::X1); println!("val => {}", val); } diff --git a/examples/ch32v305/src/bin/adc.rs b/examples/ch32v305/src/bin/adc.rs index c452b1c..c62276f 100644 --- a/examples/ch32v305/src/bin/adc.rs +++ b/examples/ch32v305/src/bin/adc.rs @@ -6,7 +6,7 @@ use ch32_hal as hal; use embassy_executor::Spawner; use embassy_time::{Delay, Duration, Timer}; -use hal::adc::SampleTime; +use hal::adc::{SampleTime, Pga}; use hal::gpio::{Level, Output}; use hal::println; @@ -32,7 +32,7 @@ async fn main(spawner: Spawner) -> ! { Timer::after(Duration::from_millis(500)).await; println!("Starting conversion!"); - let val = adc.convert(&mut ch, SampleTime::CYCLES239_5); + let val = adc.convert(&mut ch, SampleTime::CYCLES239_5, Pga::X1); println!("val => {}", val); } diff --git a/examples/ch32v307/src/bin/adc.rs b/examples/ch32v307/src/bin/adc.rs index a1cf936..5879837 100644 --- a/examples/ch32v307/src/bin/adc.rs +++ b/examples/ch32v307/src/bin/adc.rs @@ -6,7 +6,7 @@ use ch32_hal as hal; use embassy_executor::Spawner; use embassy_time::{Delay, Duration, Timer}; -use hal::adc::SampleTime; +use hal::adc::{SampleTime, Pga}; use hal::gpio::{Level, Output}; use hal::println; @@ -33,7 +33,7 @@ async fn main(spawner: Spawner) -> ! { Timer::after(Duration::from_millis(500)).await; println!("Starting conversion!"); - let val = adc.convert(&mut ch, SampleTime::CYCLES239_5); + let val = adc.convert(&mut ch, SampleTime::CYCLES239_5, Pga::X1); println!("val => {}", val); } diff --git a/src/adc.rs b/src/adc.rs index 8cc5efe..d39d2a4 100644 --- a/src/adc.rs +++ b/src/adc.rs @@ -7,6 +7,8 @@ use core::marker::PhantomData; use embassy_sync::waitqueue::AtomicWaker; use crate::pac::adc::vals; +#[cfg(adc_v3)] +pub use crate::pac::adc::vals::Pga; pub use crate::pac::adc::vals::SampleTime; use crate::{into_ref, peripherals, Peripheral}; @@ -87,10 +89,60 @@ impl<'d, T: Instance> Adc<'d, T> { // ADC ON T::regs().ctlr2().modify(|w| w.set_adon(true)); + // start self-calibration + #[cfg(any(adc_v1, adc_v3))] + { + T::regs().ctlr2().modify(|w| w.set_rstcal(true)); // reset calibration + while T::regs().ctlr2().read().rstcal() {} + T::regs().ctlr2().modify(|w| w.set_cal(true)); // start calibration + while T::regs().ctlr2().read().cal() {} // wait for calibration to be done + } + Self { adc } } // regular conversion + #[cfg(adc_v3)] + pub fn configure_channel(&mut self, channel: &mut impl AdcChannel, rank: u8, sample_time: SampleTime, pga: Pga) { + channel.set_as_analog(); + + let channel = channel.channel(); + + // sample time config + if channel < 10 { + T::regs().samptr2().modify(|w| w.set_smp(channel as usize, sample_time)); + } else { + T::regs() + .samptr1() + .modify(|w| w.set_smp((channel - 10) as usize, sample_time)); + } + + // PGA config + T::regs().ctlr1().modify(|w| { + w.set_pga(pga); + if pga != Pga::X1 { + w.set_bufen(true); + } + }); + + // regular sequence config + assert!(rank < 17 || rank > 0); + if rank < 7 { + T::regs() + .rsqr3() + .modify(|w| w.set_sq((rank - 1) as usize, channel & 0b11111)); + } else if rank < 13 { + T::regs() + .rsqr2() + .modify(|w| w.set_sq((rank - 7) as usize, channel & 0b11111)); + } else { + T::regs() + .rsqr1() + .modify(|w| w.set_sq((rank - 13) as usize, channel & 0b11111)); + } + } + + #[cfg(not(adc_v3))] pub fn configure_channel(&mut self, channel: &mut impl AdcChannel, rank: u8, sample_time: SampleTime) { channel.set_as_analog(); @@ -123,6 +175,19 @@ impl<'d, T: Instance> Adc<'d, T> { } // Get_ADC_Val + #[cfg(adc_v3)] + pub fn convert(&mut self, channel: &mut impl AdcChannel, sample_time: SampleTime, pga: Pga) -> u16 { + self.configure_channel(channel, 1, sample_time, pga); + + T::regs().ctlr2().modify(|w| w.set_swstart(true)); + + // while not end of conversion + while !T::regs().statr().read().eoc() {} + + T::regs().rdatar().read().data() + } + + #[cfg(not(adc_v3))] pub fn convert(&mut self, channel: &mut impl AdcChannel, sample_time: SampleTime) -> u16 { self.configure_channel(channel, 1, sample_time);