Merge pull request #433 from esp-rs/legacy-drivers

Hide the legacy ADC driver behind a feature flag
This commit is contained in:
Frederick Vollbrecht 2024-06-16 12:23:16 +02:00 committed by GitHub
commit c6afacb151
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 381 additions and 342 deletions

View File

@ -22,7 +22,11 @@ alloc = []
nightly = []
wake-from-isr = [] # Only enable if you plan to use the `edge-executor` crate
embassy-sync = [] # For now, the dependecy on the `embassy-sync` crate is non-optional, but this might change in future
# Temporary, until (https://github.com/espressif/esp-idf/issues/13938) is addressed
# - When enabled, the code for the legacy ADC oneshot driver will be compiled;
# - When not enabled (default) the code for the new ADC oneshot driver will be compiled;
# - Since we don't wrap the legacy _continuous_ ADC driver, the new _continuous_ ADC driver is always compiled.
adc-oneshot-legacy = []
# Propagated esp-idf-sys features
native = ["esp-idf-sys/native"]
pio = ["esp-idf-sys/pio"]

View File

@ -6,11 +6,12 @@ use esp_idf_sys::{self as _}; // If using the `binstart` feature of `esp-idf-sys
use std::thread;
use std::time::Duration;
#[cfg(any(feature = "adc-oneshot-legacy", esp_idf_version_major = "4"))]
fn main() -> anyhow::Result<()> {
use esp_idf_hal::adc::config::Config;
use esp_idf_hal::adc::*;
use esp_idf_hal::peripherals::Peripherals;
fn main() -> anyhow::Result<()> {
let peripherals = Peripherals::take()?;
#[cfg(not(esp32))]
@ -35,3 +36,12 @@ fn main() -> anyhow::Result<()> {
println!("ADC value: {}", adc.read(&mut adc_pin)?);
}
}
#[cfg(not(any(feature = "adc-oneshot-legacy", esp_idf_version_major = "4")))]
fn main() -> anyhow::Result<()> {
println!("This example requires feature `adc-oneshot-legacy` enabled or using ESP-IDF v4.4.X");
loop {
thread::sleep(Duration::from_millis(1000));
}
}

View File

@ -4,7 +4,7 @@
use std::thread;
use std::time::Duration;
#[cfg(not(esp_idf_version_major = "4"))]
#[cfg(not(any(feature = "adc-oneshot-legacy", esp_idf_version_major = "4")))]
fn main() -> anyhow::Result<()> {
use esp_idf_hal::adc::attenuation::DB_11;
use esp_idf_hal::adc::oneshot::config::AdcChannelConfig;
@ -40,9 +40,11 @@ fn main() -> anyhow::Result<()> {
}
}
#[cfg(esp_idf_version_major = "4")]
#[cfg(any(feature = "adc-oneshot-legacy", esp_idf_version_major = "4"))]
fn main() -> anyhow::Result<()> {
println!("This example requires ESP-IDF v5.0 or newer");
println!(
"This example requires ESP-IDF v5.X or newer and feature `adc-oneshot-legacy` disabled"
);
loop {
thread::sleep(Duration::from_millis(1000));

View File

@ -1,11 +1,5 @@
use esp_idf_sys::*;
use crate::gpio::ADCPin;
use crate::peripheral::{Peripheral, PeripheralRef};
pub type AdcConfig = config::Config;
#[cfg(all(
not(esp_idf_version_major = "4"),
not(esp32c2),
@ -17,6 +11,9 @@ pub use continuous::{
Attenuated, ChainedAdcChannels, EmptyAdcChannels,
};
#[cfg(any(feature = "adc-oneshot-legacy", esp_idf_version_major = "4"))]
pub use oneshot_legacy::*;
pub trait Adc: Send {
fn unit() -> adc_unit_t;
}
@ -34,10 +31,6 @@ pub mod attenuation {
pub const DB_11: adc_atten_t = adc_atten_t_ADC_ATTEN_DB_11;
}
/// ADC configuration
pub mod config {
use esp_idf_sys::*;
/// The sampling/readout resolution of the ADC
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum Resolution {
@ -82,6 +75,22 @@ pub mod config {
}
}
#[cfg(any(feature = "adc-oneshot-legacy", esp_idf_version_major = "4"))]
mod oneshot_legacy {
use esp_idf_sys::*;
use crate::gpio::ADCPin;
use crate::peripheral::{Peripheral, PeripheralRef};
use super::{to_nb_err, Adc};
pub type AdcConfig = config::Config;
/// ADC configuration
pub mod config {
pub use crate::adc::Resolution;
#[derive(Debug, Copy, Clone, Default)]
pub struct Config {
pub resolution: Resolution,
@ -157,8 +166,9 @@ pub struct AdcDriver<'d, ADC: Adc> {
any(esp32, esp32s2, esp32s3, esp32c3),
any(esp_idf_comp_esp_adc_cal_enabled, esp_idf_comp_esp_adc_enabled)
))]
cal_characteristics:
Option<[Option<esp_adc_cal_characteristics_t>; adc_atten_t_ADC_ATTEN_DB_11 as usize + 1]>,
cal_characteristics: Option<
[Option<esp_adc_cal_characteristics_t>; adc_atten_t_ADC_ATTEN_DB_11 as usize + 1],
>,
}
unsafe impl<'d, ADC: Adc> Send for AdcDriver<'d, ADC> {}
@ -168,13 +178,15 @@ impl<'d, ADC: Adc> AdcDriver<'d, ADC> {
esp32,
any(esp_idf_comp_esp_adc_cal_enabled, esp_idf_comp_esp_adc_enabled)
))]
const CALIBRATION_SCHEME: esp_adc_cal_value_t = esp_adc_cal_value_t_ESP_ADC_CAL_VAL_EFUSE_VREF;
const CALIBRATION_SCHEME: esp_adc_cal_value_t =
esp_adc_cal_value_t_ESP_ADC_CAL_VAL_EFUSE_VREF;
#[cfg(all(
any(esp32c3, esp32s2),
any(esp_idf_comp_esp_adc_cal_enabled, esp_idf_comp_esp_adc_enabled)
))]
const CALIBRATION_SCHEME: esp_adc_cal_value_t = esp_adc_cal_value_t_ESP_ADC_CAL_VAL_EFUSE_TP;
const CALIBRATION_SCHEME: esp_adc_cal_value_t =
esp_adc_cal_value_t_ESP_ADC_CAL_VAL_EFUSE_TP;
#[cfg(all(
esp32s3,
@ -284,7 +296,9 @@ impl<'d, ADC: Adc> AdcDriver<'d, ADC> {
#[cfg(not(any(esp32c2, esp32h2, esp32c5, esp32c6, esp32p4)))]
{
let mut measurement = 0;
esp!(unsafe { adc2_get_raw(channel, self.resolution.into(), &mut measurement) })?;
esp!(unsafe {
adc2_get_raw(channel, self.resolution.into(), &mut measurement)
})?;
Ok(measurement as _)
}
@ -314,7 +328,8 @@ impl<'d, ADC: Adc> AdcDriver<'d, ADC> {
any(esp32, esp32s2, esp32s3, esp32c3),
any(esp_idf_comp_esp_adc_cal_enabled, esp_idf_comp_esp_adc_enabled)
)))]
let mv = (measurement as u32 * Self::get_max_mv(attenuation) / Self::MAX_READING) as u16;
let mv =
(measurement as u32 * Self::get_max_mv(attenuation) / Self::MAX_READING) as u16;
Ok(mv)
}
@ -402,15 +417,19 @@ where
}
#[cfg(all(esp32, esp_idf_version_major = "4"))]
impl<'d> embedded_hal_0_2::adc::OneShot<ADC1, u16, crate::hall::HallSensor>
for AdcDriver<'d, ADC1>
impl<'d> embedded_hal_0_2::adc::OneShot<super::ADC1, u16, crate::hall::HallSensor>
for AdcDriver<'d, super::ADC1>
{
type Error = EspError;
fn read(&mut self, hall_sensor: &mut crate::hall::HallSensor) -> nb::Result<u16, Self::Error> {
fn read(
&mut self,
hall_sensor: &mut crate::hall::HallSensor,
) -> nb::Result<u16, Self::Error> {
AdcDriver::read_hall(self, hall_sensor).map_err(to_nb_err)
}
}
}
fn to_nb_err(err: EspError) -> nb::Error<EspError> {
if err.code() == ESP_ERR_INVALID_STATE {
@ -437,7 +456,11 @@ impl_adc!(ADC1: adc_unit_t_ADC_UNIT_1);
#[cfg(not(any(esp32c2, esp32h2, esp32c5, esp32c6, esp32p4)))] // TODO: Check for esp32c5 and esp32p4
impl_adc!(ADC2: adc_unit_t_ADC_UNIT_2);
#[cfg(all(not(esp_idf_version_major = "4"), esp_idf_comp_esp_adc_enabled))]
#[cfg(all(
not(feature = "adc-oneshot-legacy"),
not(esp_idf_version_major = "4"),
esp_idf_comp_esp_adc_enabled
))]
pub mod oneshot {
use core::borrow::Borrow;
@ -448,13 +471,13 @@ pub mod oneshot {
use crate::peripheral::PeripheralRef;
use super::attenuation::adc_atten_t;
use super::config::Resolution;
use super::to_nb_err;
use super::Adc;
pub mod config {
use super::adc_atten_t;
use super::Resolution;
pub use crate::adc::Resolution;
#[derive(Debug, Copy, Clone, Default)]
pub struct AdcChannelConfig {