mirror of
https://github.com/esp-rs/esp-idf-hal.git
synced 2025-09-30 13:50:53 +00:00
ADC
This commit is contained in:
parent
46fe944d0d
commit
b8657d8d4a
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "esp-idf-hal"
|
||||
version = "0.29.5"
|
||||
version = "0.30.0"
|
||||
authors = ["sapir <yasapir@gmail.com>", "Ivan Markov <ivan.markov@gmail.com>"]
|
||||
edition = "2018"
|
||||
resolver = "2"
|
||||
|
342
src/adc.rs
Normal file
342
src/adc.rs
Normal file
@ -0,0 +1,342 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
#[cfg(not(feature = "ulp"))]
|
||||
use esp_idf_sys::*;
|
||||
|
||||
#[cfg(feature = "ulp")]
|
||||
use crate::ulp::sys::*;
|
||||
|
||||
#[cfg(all(esp32, not(feature = "ulp")))]
|
||||
use crate::hall;
|
||||
|
||||
pub trait Adc: Send {
|
||||
fn unit() -> adc_unit_t;
|
||||
}
|
||||
|
||||
pub trait Analog<ADC: Adc>: Send {
|
||||
fn attenuation() -> adc_atten_t;
|
||||
}
|
||||
|
||||
pub struct Atten0dB<ADC: Adc> {
|
||||
_adc: PhantomData<ADC>,
|
||||
}
|
||||
|
||||
pub struct Atten2p5dB<ADC: Adc> {
|
||||
_adc: PhantomData<ADC>,
|
||||
}
|
||||
|
||||
pub struct Atten6dB<ADC: Adc> {
|
||||
_adc: PhantomData<ADC>,
|
||||
}
|
||||
|
||||
pub struct Atten11dB<ADC: Adc> {
|
||||
_adc: PhantomData<ADC>,
|
||||
}
|
||||
|
||||
impl<ADC: Adc> Analog<ADC> for Atten0dB<ADC> {
|
||||
fn attenuation() -> adc_atten_t {
|
||||
adc_atten_t_ADC_ATTEN_DB_0
|
||||
}
|
||||
}
|
||||
|
||||
impl<ADC: Adc> Analog<ADC> for Atten2p5dB<ADC> {
|
||||
fn attenuation() -> adc_atten_t {
|
||||
adc_atten_t_ADC_ATTEN_DB_2_5
|
||||
}
|
||||
}
|
||||
|
||||
impl<ADC: Adc> Analog<ADC> for Atten6dB<ADC> {
|
||||
fn attenuation() -> adc_atten_t {
|
||||
adc_atten_t_ADC_ATTEN_DB_6
|
||||
}
|
||||
}
|
||||
|
||||
impl<ADC: Adc> Analog<ADC> for Atten11dB<ADC> {
|
||||
fn attenuation() -> adc_atten_t {
|
||||
adc_atten_t_ADC_ATTEN_DB_11
|
||||
}
|
||||
}
|
||||
|
||||
/// ADC configuration
|
||||
#[cfg(not(feature = "ulp"))]
|
||||
pub mod config {
|
||||
use esp_idf_sys::*;
|
||||
|
||||
/// The sampling/readout resolution of the ADC
|
||||
#[derive(PartialEq, Eq, Clone, Copy)]
|
||||
pub enum Resolution {
|
||||
#[cfg(esp32)]
|
||||
Resolution9Bit,
|
||||
#[cfg(esp32)]
|
||||
Resolution10Bit,
|
||||
#[cfg(esp32)]
|
||||
Resolution11Bit,
|
||||
#[cfg(any(esp32, esp32c3, esp32s3))]
|
||||
Resolution12Bit,
|
||||
#[cfg(esp32s2)]
|
||||
Resolution13Bit,
|
||||
}
|
||||
|
||||
impl Default for Resolution {
|
||||
#[cfg(any(esp32, esp32c3, esp32s3))]
|
||||
fn default() -> Self {
|
||||
Self::Resolution12Bit
|
||||
}
|
||||
|
||||
#[cfg(esp32s2)]
|
||||
fn default() -> Self {
|
||||
Self::Resolution13Bit
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Resolution> for adc_bits_width_t {
|
||||
fn from(resolution: Resolution) -> Self {
|
||||
match resolution {
|
||||
#[cfg(esp32)]
|
||||
Resolution::Resolution9Bit => adc_bits_width_t_ADC_WIDTH_BIT_9,
|
||||
#[cfg(esp32)]
|
||||
Resolution::Resolution10Bit => adc_bits_width_t_ADC_WIDTH_BIT_10,
|
||||
#[cfg(esp32)]
|
||||
Resolution::Resolution11Bit => adc_bits_width_t_ADC_WIDTH_BIT_11,
|
||||
#[cfg(any(esp32, esp32s3, esp32c3))]
|
||||
Resolution::Resolution12Bit => adc_bits_width_t_ADC_WIDTH_BIT_12,
|
||||
#[cfg(esp32s2)]
|
||||
Resolution::Resolution13Bit => adc_bits_width_t_ADC_WIDTH_BIT_13,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Config {
|
||||
pub resolution: Resolution,
|
||||
pub calibration: bool,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn new() -> Self {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn resolution(mut self, resolution: Resolution) -> Self {
|
||||
self.resolution = resolution;
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn calibration(mut self, calibration: bool) -> Self {
|
||||
self.calibration = calibration;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
resolution: Default::default(),
|
||||
calibration: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "ulp"))]
|
||||
pub struct PoweredAdc<ADC: Adc> {
|
||||
adc: ADC,
|
||||
resolution: config::Resolution,
|
||||
cal_characteristics:
|
||||
Option<[Option<esp_adc_cal_characteristics_t>; adc_atten_t_ADC_ATTEN_MAX as usize + 1]>,
|
||||
}
|
||||
|
||||
unsafe impl<ADC: Adc> Send for PoweredAdc<ADC> {}
|
||||
|
||||
#[cfg(not(feature = "ulp"))]
|
||||
impl<ADC: Adc> PoweredAdc<ADC> {
|
||||
#[cfg(esp32)]
|
||||
const CALIBRATION_SCHEME: esp_adc_cal_value_t = esp_adc_cal_value_t_ESP_ADC_CAL_VAL_EFUSE_VREF;
|
||||
|
||||
#[cfg(any(esp32c3, esp32s2))]
|
||||
const CALIBRATION_SCHEME: esp_adc_cal_value_t = esp_adc_cal_value_t_ESP_ADC_CAL_VAL_EFUSE_TP;
|
||||
|
||||
#[cfg(esp32s3)]
|
||||
const CALIBRATION_SCHEME: esp_adc_cal_value_t =
|
||||
esp_adc_cal_value_t_ESP_ADC_CAL_VAL_EFUSE_TP_FIT;
|
||||
|
||||
#[cfg(not(esp32s2))]
|
||||
const MAX_READING: u32 = 4095;
|
||||
|
||||
#[cfg(esp32s2)]
|
||||
const MAX_READING: u32 = 8191;
|
||||
|
||||
pub fn new(adc: ADC, config: config::Config) -> Result<Self, EspError> {
|
||||
if config.calibration {
|
||||
esp!(unsafe { esp_adc_cal_check_efuse(Self::CALIBRATION_SCHEME) })?;
|
||||
}
|
||||
|
||||
if ADC::unit() == adc_unit_t_ADC_UNIT_1 {
|
||||
esp!(unsafe { adc1_config_width(config.resolution.into()) })?;
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
adc,
|
||||
resolution: config.resolution,
|
||||
cal_characteristics: if config.calibration {
|
||||
Some(Default::default())
|
||||
} else {
|
||||
None
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
pub fn release(self) -> ADC {
|
||||
self.adc
|
||||
}
|
||||
|
||||
fn raw_to_voltage(
|
||||
&mut self,
|
||||
measurement: c_types::c_int,
|
||||
attenuation: adc_atten_t,
|
||||
) -> Result<u16, EspError> {
|
||||
let mv = if let Some(cal) = self.get_cal_characteristics(attenuation)? {
|
||||
unsafe { esp_adc_cal_raw_to_voltage(measurement as u32, &cal as *const _) as u16 }
|
||||
} else {
|
||||
(measurement as u32 * Self::get_max_mv(attenuation) / Self::MAX_READING) as u16
|
||||
};
|
||||
|
||||
Ok(mv)
|
||||
}
|
||||
|
||||
#[allow(non_upper_case_globals)]
|
||||
fn get_max_mv(attenuation: adc_atten_t) -> u32 {
|
||||
#[cfg(esp32)]
|
||||
let mv = match attenuation {
|
||||
adc_atten_t_ADC_ATTEN_DB_0 => 950,
|
||||
adc_atten_t_ADC_ATTEN_DB_2_5 => 1250,
|
||||
adc_atten_t_ADC_ATTEN_DB_6 => 1750,
|
||||
adc_atten_t_ADC_ATTEN_DB_11 => 2450,
|
||||
other => panic!("Unknown attenuation: {}", other),
|
||||
};
|
||||
|
||||
#[cfg(any(esp32c3, esp32s2))]
|
||||
let mv = match attenuation {
|
||||
adc_atten_t_ADC_ATTEN_DB_0 => 750,
|
||||
adc_atten_t_ADC_ATTEN_DB_2_5 => 1050,
|
||||
adc_atten_t_ADC_ATTEN_DB_6 => 1300,
|
||||
adc_atten_t_ADC_ATTEN_DB_11 => 2500,
|
||||
other => panic!("Unknown attenuation: {}", other),
|
||||
};
|
||||
|
||||
#[cfg(esp32s3)]
|
||||
let mv = match attenuation {
|
||||
adc_atten_t_ADC_ATTEN_DB_0 => 950,
|
||||
adc_atten_t_ADC_ATTEN_DB_2_5 => 1250,
|
||||
adc_atten_t_ADC_ATTEN_DB_6 => 1750,
|
||||
adc_atten_t_ADC_ATTEN_DB_11 => 3100,
|
||||
other => panic!("Unknown attenuation: {}", other),
|
||||
};
|
||||
|
||||
mv
|
||||
}
|
||||
|
||||
fn get_cal_characteristics(
|
||||
&mut self,
|
||||
attenuation: adc_atten_t,
|
||||
) -> Result<Option<esp_adc_cal_characteristics_t>, EspError> {
|
||||
if let Some(characteristics) = &mut self.cal_characteristics {
|
||||
if let Some(cal) = characteristics[attenuation as usize] {
|
||||
Ok(Some(cal))
|
||||
} else {
|
||||
esp!(unsafe { esp_adc_cal_check_efuse(Self::CALIBRATION_SCHEME) })?;
|
||||
|
||||
let mut cal: esp_adc_cal_characteristics_t = Default::default();
|
||||
unsafe {
|
||||
esp_adc_cal_characterize(
|
||||
ADC::unit(),
|
||||
attenuation,
|
||||
self.resolution.into(),
|
||||
0,
|
||||
&mut cal as *mut _,
|
||||
)
|
||||
};
|
||||
|
||||
characteristics[attenuation as usize] = Some(cal);
|
||||
|
||||
Ok(Some(cal))
|
||||
}
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "ulp"))]
|
||||
impl<ADC, AN, PIN> embedded_hal::adc::OneShot<AN, u16, PIN> for PoweredAdc<ADC>
|
||||
where
|
||||
ADC: Adc,
|
||||
AN: Analog<ADC>,
|
||||
PIN: embedded_hal::adc::Channel<AN, ID = u8>,
|
||||
{
|
||||
type Error = EspError;
|
||||
|
||||
fn read(&mut self, _pin: &mut PIN) -> nb::Result<u16, Self::Error> {
|
||||
let mut measurement = 0 as c_types::c_int;
|
||||
|
||||
if ADC::unit() == adc_unit_t_ADC_UNIT_1 {
|
||||
measurement = unsafe { adc1_get_raw(PIN::channel() as adc_channel_t) };
|
||||
} else {
|
||||
let res = unsafe {
|
||||
adc2_get_raw(
|
||||
PIN::channel() as adc_channel_t,
|
||||
self.resolution.into(),
|
||||
&mut measurement as *mut _,
|
||||
)
|
||||
};
|
||||
|
||||
if res == ESP_ERR_INVALID_STATE as i32 {
|
||||
return Err(nb::Error::WouldBlock);
|
||||
} else if res < 0 {
|
||||
return Err(nb::Error::Other(EspError::from(res).unwrap()));
|
||||
}
|
||||
};
|
||||
|
||||
Ok(self.raw_to_voltage(measurement, AN::attenuation())?)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(esp32, not(feature = "ulp")))]
|
||||
impl embedded_hal::adc::OneShot<ADC1, u16, hall::HallSensor> for PoweredAdc<ADC1> {
|
||||
type Error = EspError;
|
||||
|
||||
fn read(&mut self, _hall_sensor: &mut hall::HallSensor) -> nb::Result<u16, Self::Error> {
|
||||
let measurement = unsafe { hall_sensor_read() };
|
||||
|
||||
Ok(self.raw_to_voltage(measurement, adc_atten_t_ADC_ATTEN_DB_0)?)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_adc {
|
||||
($adc:ident: $unit:expr) => {
|
||||
pub struct $adc(::core::marker::PhantomData<*const ()>);
|
||||
|
||||
impl $adc {
|
||||
/// # Safety
|
||||
///
|
||||
/// Care should be taken not to instnatiate this ADC instance, if it is already instantiated and used elsewhere
|
||||
pub unsafe fn new() -> Self {
|
||||
$adc(::core::marker::PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Send for $adc {}
|
||||
|
||||
impl Adc for $adc {
|
||||
#[inline(always)]
|
||||
fn unit() -> adc_unit_t {
|
||||
$unit
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_adc!(ADC1: adc_unit_t_ADC_UNIT_1);
|
||||
impl_adc!(ADC2: adc_unit_t_ADC_UNIT_2);
|
163
src/gpio.rs
163
src/gpio.rs
@ -18,6 +18,8 @@ use esp_idf_sys::*;
|
||||
#[cfg(feature = "ulp")]
|
||||
use crate::ulp::sys::*;
|
||||
|
||||
use crate::adc;
|
||||
|
||||
pub use chip::*;
|
||||
|
||||
/// Extension trait to split a GPIO peripheral into independent pins and registers
|
||||
@ -62,22 +64,22 @@ pub trait InputPin: Pin {}
|
||||
pub trait OutputPin: Pin {}
|
||||
|
||||
pub trait RTCPin: Pin {
|
||||
fn rtc_pin() -> i32;
|
||||
fn rtc_pin(&self) -> i32;
|
||||
}
|
||||
|
||||
pub trait ADCPin: Pin {
|
||||
fn adc_unit() -> adc_unit_t;
|
||||
fn adc_channel() -> adc_channel_t;
|
||||
fn adc_unit(&self) -> adc_unit_t;
|
||||
fn adc_channel(&self) -> adc_channel_t;
|
||||
}
|
||||
|
||||
#[cfg(all(not(esp32c3), not(esp32s3)))]
|
||||
pub trait DACPin: Pin {
|
||||
fn dac_channel() -> dac_channel_t;
|
||||
fn dac_channel(&self) -> dac_channel_t;
|
||||
}
|
||||
|
||||
#[cfg(not(esp32c3))]
|
||||
pub trait TouchPin: Pin {
|
||||
fn touch_channel() -> touch_pad_t;
|
||||
fn touch_channel(&self) -> touch_pad_t;
|
||||
}
|
||||
|
||||
pub struct Input;
|
||||
@ -258,6 +260,16 @@ impl embedded_hal::digital::v2::StatefulOutputPin for GpioPin<InputOutput> {
|
||||
|
||||
impl embedded_hal::digital::v2::toggleable::Default for GpioPin<InputOutput> {}
|
||||
|
||||
// Not possible with embedded-hal V0.2 (possible with V1.0)
|
||||
// because in V0.2, channel() does not take &self
|
||||
// impl<AN: Analog<ADC>, ADC: Adc> embedded_hal::adc::Channel for GpioPin<AN> {
|
||||
// type ID = u8;
|
||||
|
||||
// fn channel() -> Self::ID {
|
||||
// todo!()
|
||||
// }
|
||||
// }
|
||||
|
||||
/// Interrupt events
|
||||
///
|
||||
/// *Note: ESP32 has a bug (3.14), which prevents correct triggering of interrupts when
|
||||
@ -286,18 +298,6 @@ pub struct RTCInput<MODE> {
|
||||
_mode: PhantomData<MODE>,
|
||||
}
|
||||
|
||||
/// Floating input (type state)
|
||||
pub struct Floating;
|
||||
|
||||
/// Pulled down input (type state)
|
||||
pub struct PullDown;
|
||||
|
||||
/// Pulled up input (type state)
|
||||
pub struct PullUp;
|
||||
|
||||
/// Pulled up + pulled down input (type state)
|
||||
pub struct PullUpDown;
|
||||
|
||||
/// Output mode via RTC (type state)
|
||||
pub struct RTCOutput<MODE> {
|
||||
_mode: PhantomData<MODE>,
|
||||
@ -308,15 +308,6 @@ pub struct RTCInputOutput<MODE> {
|
||||
_mode: PhantomData<MODE>,
|
||||
}
|
||||
|
||||
/// Open drain input or output (type state)
|
||||
pub struct OpenDrain;
|
||||
|
||||
/// Push pull output (type state)
|
||||
pub struct PushPull;
|
||||
|
||||
/// Analog mode (type state)
|
||||
pub struct Analog;
|
||||
|
||||
/// Drive strength (values are approximates)
|
||||
#[cfg(not(feature = "ulp"))]
|
||||
pub enum DriveStrength {
|
||||
@ -727,7 +718,7 @@ macro_rules! impl_rtc {
|
||||
where
|
||||
MODE: Send,
|
||||
{
|
||||
fn rtc_pin() -> i32 {
|
||||
fn rtc_pin(&self) -> i32 {
|
||||
$rtc
|
||||
}
|
||||
}
|
||||
@ -738,33 +729,139 @@ macro_rules! impl_rtc {
|
||||
|
||||
macro_rules! impl_adc {
|
||||
($pxi:ident: $pin:expr, ADC1: $adc:expr) => {
|
||||
#[cfg(not(feature = "ulp"))]
|
||||
impl<MODE> $pxi<MODE>
|
||||
where
|
||||
MODE: Send,
|
||||
{
|
||||
pub fn into_analog_atten_0db(
|
||||
mut self,
|
||||
) -> Result<$pxi<adc::Atten0dB<adc::ADC1>>, EspError> {
|
||||
self.reset()?;
|
||||
esp!(unsafe { adc1_config_channel_atten($adc, adc_atten_t_ADC_ATTEN_DB_0) })?;
|
||||
|
||||
Ok($pxi { _mode: PhantomData })
|
||||
}
|
||||
|
||||
pub fn into_analog_atten_2p5db(
|
||||
mut self,
|
||||
) -> Result<$pxi<adc::Atten2p5dB<adc::ADC1>>, EspError> {
|
||||
self.reset()?;
|
||||
esp!(unsafe { adc1_config_channel_atten($adc, adc_atten_t_ADC_ATTEN_DB_2_5) })?;
|
||||
|
||||
Ok($pxi { _mode: PhantomData })
|
||||
}
|
||||
|
||||
pub fn into_analog_atten_6db(
|
||||
mut self,
|
||||
) -> Result<$pxi<adc::Atten6dB<adc::ADC1>>, EspError> {
|
||||
self.reset()?;
|
||||
esp!(unsafe { adc1_config_channel_atten($adc, adc_atten_t_ADC_ATTEN_DB_6) })?;
|
||||
|
||||
Ok($pxi { _mode: PhantomData })
|
||||
}
|
||||
|
||||
pub fn into_analog_atten_11db(
|
||||
mut self,
|
||||
) -> Result<$pxi<adc::Atten11dB<adc::ADC1>>, EspError> {
|
||||
self.reset()?;
|
||||
esp!(unsafe { adc1_config_channel_atten($adc, adc_atten_t_ADC_ATTEN_DB_11) })?;
|
||||
|
||||
Ok($pxi { _mode: PhantomData })
|
||||
}
|
||||
}
|
||||
|
||||
impl<MODE> ADCPin for $pxi<MODE>
|
||||
where
|
||||
MODE: Send,
|
||||
{
|
||||
fn adc_unit() -> adc_unit_t {
|
||||
fn adc_unit(&self) -> adc_unit_t {
|
||||
adc_unit_t_ADC_UNIT_1
|
||||
}
|
||||
|
||||
fn adc_channel() -> adc_channel_t {
|
||||
fn adc_channel(&self) -> adc_channel_t {
|
||||
$adc
|
||||
}
|
||||
}
|
||||
|
||||
impl<AN> embedded_hal::adc::Channel<AN> for $pxi<AN>
|
||||
where
|
||||
AN: adc::Analog<adc::ADC1> + Send,
|
||||
{
|
||||
type ID = u8;
|
||||
|
||||
fn channel() -> Self::ID {
|
||||
$adc as u8
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
($pxi:ident: $pin:expr, ADC2: $adc:expr) => {
|
||||
#[cfg(not(feature = "ulp"))]
|
||||
impl<MODE> $pxi<MODE>
|
||||
where
|
||||
MODE: Send,
|
||||
{
|
||||
pub fn into_analog_atten_0db(
|
||||
mut self,
|
||||
) -> Result<$pxi<adc::Atten0dB<adc::ADC2>>, EspError> {
|
||||
self.reset()?;
|
||||
esp!(unsafe { adc2_config_channel_atten($adc, adc_atten_t_ADC_ATTEN_DB_0) })?;
|
||||
|
||||
Ok($pxi { _mode: PhantomData })
|
||||
}
|
||||
|
||||
pub fn into_analog_atten_2p5db(
|
||||
mut self,
|
||||
) -> Result<$pxi<adc::Atten2p5dB<adc::ADC2>>, EspError> {
|
||||
self.reset()?;
|
||||
esp!(unsafe { adc2_config_channel_atten($adc, adc_atten_t_ADC_ATTEN_DB_2_5) })?;
|
||||
|
||||
Ok($pxi { _mode: PhantomData })
|
||||
}
|
||||
|
||||
pub fn into_analog_atten_6db(
|
||||
mut self,
|
||||
) -> Result<$pxi<adc::Atten6dB<adc::ADC2>>, EspError> {
|
||||
self.reset()?;
|
||||
esp!(unsafe { adc2_config_channel_atten($adc, adc_atten_t_ADC_ATTEN_DB_6) })?;
|
||||
|
||||
Ok($pxi { _mode: PhantomData })
|
||||
}
|
||||
|
||||
pub fn into_analog_atten_11db(
|
||||
mut self,
|
||||
) -> Result<$pxi<adc::Atten11dB<adc::ADC2>>, EspError> {
|
||||
self.reset()?;
|
||||
esp!(unsafe { adc2_config_channel_atten($adc, adc_atten_t_ADC_ATTEN_DB_11) })?;
|
||||
|
||||
Ok($pxi { _mode: PhantomData })
|
||||
}
|
||||
}
|
||||
|
||||
impl<MODE> ADCPin for $pxi<MODE>
|
||||
where
|
||||
MODE: Send,
|
||||
{
|
||||
fn adc_unit() -> adc_unit_t {
|
||||
fn adc_unit(&self) -> adc_unit_t {
|
||||
adc_unit_t_ADC_UNIT_2
|
||||
}
|
||||
|
||||
fn adc_channel() -> adc_channel_t {
|
||||
fn adc_channel(&self) -> adc_channel_t {
|
||||
$adc
|
||||
}
|
||||
}
|
||||
|
||||
impl<AN> embedded_hal::adc::Channel<AN> for $pxi<AN>
|
||||
where
|
||||
AN: adc::Analog<adc::ADC2> + Send,
|
||||
{
|
||||
type ID = u8;
|
||||
|
||||
fn channel() -> Self::ID {
|
||||
$adc as u8
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
($pxi:ident: $pin:expr, NOADC: $adc:expr) => {};
|
||||
@ -777,7 +874,7 @@ macro_rules! impl_dac {
|
||||
where
|
||||
MODE: Send,
|
||||
{
|
||||
fn dac_channel() -> dac_channel_t {
|
||||
fn dac_channel(&self) -> dac_channel_t {
|
||||
$dac
|
||||
}
|
||||
}
|
||||
@ -793,7 +890,7 @@ macro_rules! impl_touch {
|
||||
where
|
||||
MODE: Send,
|
||||
{
|
||||
fn touch_channel() -> touch_pad_t {
|
||||
fn touch_channel(&self) -> touch_pad_t {
|
||||
$touch
|
||||
}
|
||||
}
|
||||
|
24
src/hall.rs
Normal file
24
src/hall.rs
Normal file
@ -0,0 +1,24 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use crate::adc;
|
||||
|
||||
pub struct HallSensor(PhantomData<*const ()>);
|
||||
|
||||
impl HallSensor {
|
||||
/// # Safety
|
||||
///
|
||||
/// Care should be taken not to instnatiate this Hall Sensor instance, if it is already instantiated and used elsewhere
|
||||
pub unsafe fn new() -> Self {
|
||||
HallSensor(PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Send for HallSensor {}
|
||||
|
||||
impl embedded_hal::adc::Channel<adc::ADC1> for HallSensor {
|
||||
type ID = ();
|
||||
|
||||
fn channel() -> Self::ID {
|
||||
()
|
||||
}
|
||||
}
|
@ -27,6 +27,10 @@ pub mod config {
|
||||
}
|
||||
|
||||
impl MasterConfig {
|
||||
pub fn new() -> Self {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn baudrate(mut self, baudrate: Hertz) -> Self {
|
||||
self.baudrate = baudrate;
|
||||
@ -74,6 +78,10 @@ pub mod config {
|
||||
}
|
||||
|
||||
impl SlaveConfig {
|
||||
pub fn new() -> Self {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn timeout(mut self, timeout: Option<Duration>) -> Self {
|
||||
self.timeout = timeout;
|
||||
|
@ -9,9 +9,12 @@ compile_error!("Feature `ulp` is currently only supported on esp32s2");
|
||||
|
||||
#[macro_use]
|
||||
pub mod ulp;
|
||||
pub mod adc;
|
||||
#[cfg(not(feature = "ulp"))]
|
||||
pub mod delay;
|
||||
pub mod gpio;
|
||||
#[cfg(esp32)]
|
||||
pub mod hall;
|
||||
#[cfg(not(feature = "ulp"))]
|
||||
pub mod i2c;
|
||||
pub mod peripherals;
|
||||
|
@ -6,7 +6,10 @@ use esp_idf_sys::EspMutex;
|
||||
#[cfg(feature = "ulp")]
|
||||
use crate::ulp::sys::EspMutex;
|
||||
|
||||
use crate::adc;
|
||||
use crate::gpio;
|
||||
#[cfg(esp32)]
|
||||
use crate::hall;
|
||||
#[cfg(not(feature = "ulp"))]
|
||||
use crate::i2c;
|
||||
#[cfg(not(feature = "ulp"))]
|
||||
@ -32,6 +35,10 @@ pub struct Peripherals {
|
||||
pub spi2: spi::SPI2,
|
||||
#[cfg(all(not(esp32c3), not(feature = "ulp")))]
|
||||
pub spi3: spi::SPI3,
|
||||
pub adc1: adc::ADC1,
|
||||
pub adc2: adc::ADC2,
|
||||
#[cfg(esp32)]
|
||||
pub hall_sensor: hall::HallSensor,
|
||||
}
|
||||
|
||||
static mut TAKEN: EspMutex<bool> = EspMutex::new(false);
|
||||
@ -72,6 +79,10 @@ impl Peripherals {
|
||||
spi2: spi::SPI2::new(),
|
||||
#[cfg(all(not(esp32c3), not(feature = "ulp")))]
|
||||
spi3: spi::SPI3::new(),
|
||||
adc1: adc::ADC1::new(),
|
||||
adc2: adc::ADC2::new(),
|
||||
#[cfg(esp32)]
|
||||
hall_sensor: hall::HallSensor::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -211,6 +211,10 @@ pub mod config {
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn new() -> Self {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn baudrate(mut self, baudrate: Hertz) -> Self {
|
||||
self.baudrate = baudrate;
|
||||
|
@ -69,6 +69,10 @@ pub mod config {
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn new() -> Self {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn baudrate(mut self, baudrate: Hertz) -> Self {
|
||||
self.baudrate = baudrate;
|
||||
|
Loading…
x
Reference in New Issue
Block a user