mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-09-28 04:40:52 +00:00
Reading raw ADC data on ESP32 and ESP32-S2
This commit is contained in:
parent
1655e36c31
commit
568e37c166
6
esp-hal-common/.vscode/settings.json
vendored
6
esp-hal-common/.vscode/settings.json
vendored
@ -1,6 +1,6 @@
|
||||
{
|
||||
"rust-analyzer.cargo.features": [
|
||||
"esp32s3"
|
||||
"esp32s2"
|
||||
],
|
||||
"rust-analyzer.cargo.allFeatures": false,
|
||||
"editor.formatOnSave": true,
|
||||
@ -10,12 +10,12 @@
|
||||
"cargo",
|
||||
"check",
|
||||
"--features",
|
||||
"esp32s3",
|
||||
"esp32s2",
|
||||
"--message-format=json",
|
||||
"-Z",
|
||||
"build-std=core",
|
||||
"--target",
|
||||
"xtensa-esp32s3-none-elf",
|
||||
"xtensa-esp32s2-none-elf",
|
||||
"--examples",
|
||||
"--lib",
|
||||
],
|
||||
|
394
esp-hal-common/src/analog/adc/esp32.rs
Normal file
394
esp-hal-common/src/analog/adc/esp32.rs
Normal file
@ -0,0 +1,394 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use embedded_hal::adc::{Channel, OneShot};
|
||||
|
||||
use crate::{
|
||||
analog::{ADC1, ADC2},
|
||||
pac::{RTCIO, SENS},
|
||||
};
|
||||
|
||||
/// The sampling/readout resolution of the ADC
|
||||
#[derive(PartialEq, Eq, Clone, Copy)]
|
||||
pub enum Resolution {
|
||||
Resolution9Bit = 0b00,
|
||||
Resolution10Bit = 0b01,
|
||||
Resolution11Bit = 0b10,
|
||||
Resolution12Bit = 0b11,
|
||||
}
|
||||
|
||||
/// The attenuation of the ADC pin
|
||||
#[derive(PartialEq, Eq, Clone, Copy)]
|
||||
pub enum Attenuation {
|
||||
Attenuation0dB = 0b00,
|
||||
Attenuation2p5dB = 0b01,
|
||||
Attenuation6dB = 0b10,
|
||||
Attenuation11dB = 0b11,
|
||||
}
|
||||
|
||||
pub struct AdcConfig<ADCI> {
|
||||
pub resolution: Resolution,
|
||||
pub attenuations: [Option<Attenuation>; 10],
|
||||
_phantom: PhantomData<ADCI>,
|
||||
}
|
||||
|
||||
impl<ADCI> AdcConfig<ADCI>
|
||||
where
|
||||
ADCI: RegisterAccess,
|
||||
{
|
||||
pub fn new() -> AdcConfig<ADCI> {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
pub fn enable_pin<PIN: Channel<ADCI, ID = u8>>(
|
||||
&mut self,
|
||||
_pin: &PIN,
|
||||
attenuation: Attenuation,
|
||||
) {
|
||||
self.attenuations[PIN::channel() as usize] = Some(attenuation);
|
||||
}
|
||||
}
|
||||
|
||||
impl<ADCI> Default for AdcConfig<ADCI> {
|
||||
fn default() -> Self {
|
||||
AdcConfig {
|
||||
resolution: Resolution::Resolution12Bit,
|
||||
attenuations: [None; 10],
|
||||
_phantom: PhantomData::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait RegisterAccess {
|
||||
fn set_bit_width(resolution: u8);
|
||||
|
||||
fn set_sample_bit(resolution: u8);
|
||||
|
||||
fn set_attenuation(channel: usize, attenuation: u8);
|
||||
|
||||
fn clear_dig_force();
|
||||
|
||||
fn set_start_force();
|
||||
|
||||
fn set_en_pad_force();
|
||||
|
||||
fn set_en_pad(channel: u8);
|
||||
|
||||
fn clear_start_sar();
|
||||
|
||||
fn set_start_sar();
|
||||
|
||||
fn read_done_sar() -> bool;
|
||||
|
||||
fn read_data_sar() -> u16;
|
||||
}
|
||||
|
||||
impl RegisterAccess for ADC1 {
|
||||
fn set_bit_width(resolution: u8) {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors
|
||||
.sar_start_force
|
||||
.modify(|_, w| unsafe { w.sar1_bit_width().bits(resolution) });
|
||||
}
|
||||
|
||||
fn set_sample_bit(resolution: u8) {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors
|
||||
.sar_read_ctrl
|
||||
.modify(|_, w| unsafe { w.sar1_sample_bit().bits(resolution) });
|
||||
}
|
||||
|
||||
fn set_attenuation(channel: usize, attenuation: u8) {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors.sar_atten1.modify(|r, w| {
|
||||
let new_value = (r.bits() & !(0b11 << (channel * 2)))
|
||||
| (((attenuation as u8 & 0b11) as u32) << (channel * 2));
|
||||
|
||||
unsafe { w.sar1_atten().bits(new_value) }
|
||||
});
|
||||
}
|
||||
|
||||
fn clear_dig_force() {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors
|
||||
.sar_read_ctrl
|
||||
.modify(|_, w| w.sar1_dig_force().clear_bit());
|
||||
}
|
||||
|
||||
fn set_start_force() {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors
|
||||
.sar_meas_start1
|
||||
.modify(|_, w| w.meas1_start_force().set_bit());
|
||||
}
|
||||
|
||||
fn set_en_pad_force() {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors
|
||||
.sar_meas_start1
|
||||
.modify(|_, w| w.sar1_en_pad_force().set_bit());
|
||||
}
|
||||
|
||||
fn set_en_pad(channel: u8) {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors
|
||||
.sar_meas_start1
|
||||
.modify(|_, w| unsafe { w.sar1_en_pad().bits(1 << channel) });
|
||||
}
|
||||
|
||||
fn clear_start_sar() {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors
|
||||
.sar_meas_start1
|
||||
.modify(|_, w| w.meas1_start_sar().clear_bit());
|
||||
}
|
||||
|
||||
fn set_start_sar() {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors
|
||||
.sar_meas_start1
|
||||
.modify(|_, w| w.meas1_start_sar().set_bit());
|
||||
}
|
||||
|
||||
fn read_done_sar() -> bool {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors.sar_meas_start1.read().meas1_done_sar().bit_is_set()
|
||||
}
|
||||
|
||||
fn read_data_sar() -> u16 {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors.sar_meas_start1.read().meas1_data_sar().bits() as u16
|
||||
}
|
||||
}
|
||||
|
||||
impl RegisterAccess for ADC2 {
|
||||
fn set_bit_width(resolution: u8) {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors
|
||||
.sar_start_force
|
||||
.modify(|_, w| unsafe { w.sar2_bit_width().bits(resolution) });
|
||||
}
|
||||
|
||||
fn set_sample_bit(resolution: u8) {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors
|
||||
.sar_read_ctrl2
|
||||
.modify(|_, w| unsafe { w.sar2_sample_bit().bits(resolution) });
|
||||
}
|
||||
|
||||
fn set_attenuation(channel: usize, attenuation: u8) {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors.sar_atten2.modify(|r, w| {
|
||||
let new_value = (r.bits() & !(0b11 << (channel * 2)))
|
||||
| (((attenuation as u8 & 0b11) as u32) << (channel * 2));
|
||||
|
||||
unsafe { w.sar2_atten().bits(new_value) }
|
||||
});
|
||||
}
|
||||
|
||||
fn clear_dig_force() {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors
|
||||
.sar_read_ctrl2
|
||||
.modify(|_, w| w.sar2_dig_force().clear_bit());
|
||||
}
|
||||
|
||||
fn set_start_force() {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors
|
||||
.sar_meas_start2
|
||||
.modify(|_, w| w.meas2_start_force().set_bit());
|
||||
}
|
||||
|
||||
fn set_en_pad_force() {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors
|
||||
.sar_meas_start2
|
||||
.modify(|_, w| w.sar2_en_pad_force().set_bit());
|
||||
}
|
||||
|
||||
fn set_en_pad(channel: u8) {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors
|
||||
.sar_meas_start2
|
||||
.modify(|_, w| unsafe { w.sar2_en_pad().bits(1 << channel) });
|
||||
}
|
||||
|
||||
fn clear_start_sar() {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors
|
||||
.sar_meas_start2
|
||||
.modify(|_, w| w.meas2_start_sar().clear_bit());
|
||||
}
|
||||
|
||||
fn set_start_sar() {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors
|
||||
.sar_meas_start2
|
||||
.modify(|_, w| w.meas2_start_sar().set_bit());
|
||||
}
|
||||
|
||||
fn read_done_sar() -> bool {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors.sar_meas_start2.read().meas2_done_sar().bit_is_set()
|
||||
}
|
||||
|
||||
fn read_data_sar() -> u16 {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors.sar_meas_start2.read().meas2_data_sar().bits() as u16
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ADC<ADC> {
|
||||
adc: PhantomData<ADC>,
|
||||
attenuations: [Option<Attenuation>; 10],
|
||||
active_channel: Option<u8>,
|
||||
}
|
||||
|
||||
impl<ADCI> ADC<ADCI>
|
||||
where
|
||||
ADCI: RegisterAccess,
|
||||
{
|
||||
pub fn adc(_adc_instance: ADCI, config: AdcConfig<ADCI>) -> Result<Self, ()> {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
|
||||
// Set reading and sampling resolution
|
||||
let resolution: u8 = config.resolution as u8;
|
||||
|
||||
ADCI::set_bit_width(resolution);
|
||||
ADCI::set_sample_bit(resolution);
|
||||
|
||||
// Set attenuation for pins
|
||||
let attenuations = config.attenuations;
|
||||
|
||||
for channel in 0..attenuations.len() {
|
||||
if let Some(attenuation) = attenuations[channel] {
|
||||
ADC1::set_attenuation(channel, attenuation as u8);
|
||||
}
|
||||
}
|
||||
|
||||
// Set controller to RTC
|
||||
ADCI::clear_dig_force();
|
||||
ADCI::set_start_force();
|
||||
ADCI::set_en_pad_force();
|
||||
sensors
|
||||
.sar_touch_ctrl1
|
||||
.modify(|_, w| w.xpd_hall_force().set_bit());
|
||||
sensors
|
||||
.sar_touch_ctrl1
|
||||
.modify(|_, w| w.hall_phase_force().set_bit());
|
||||
|
||||
// Set power to SW power on
|
||||
sensors
|
||||
.sar_meas_wait2
|
||||
.modify(|_, w| unsafe { w.force_xpd_sar().bits(0b11) });
|
||||
|
||||
// disable AMP
|
||||
sensors
|
||||
.sar_meas_wait2
|
||||
.modify(|_, w| unsafe { w.force_xpd_amp().bits(0b10) });
|
||||
sensors
|
||||
.sar_meas_ctrl
|
||||
.modify(|_, w| unsafe { w.amp_rst_fb_fsm().bits(0) });
|
||||
sensors
|
||||
.sar_meas_ctrl
|
||||
.modify(|_, w| unsafe { w.amp_short_ref_fsm().bits(0) });
|
||||
sensors
|
||||
.sar_meas_ctrl
|
||||
.modify(|_, w| unsafe { w.amp_short_ref_gnd_fsm().bits(0) });
|
||||
sensors
|
||||
.sar_meas_wait1
|
||||
.modify(|_, w| unsafe { w.sar_amp_wait1().bits(1) });
|
||||
sensors
|
||||
.sar_meas_wait1
|
||||
.modify(|_, w| unsafe { w.sar_amp_wait2().bits(1) });
|
||||
sensors
|
||||
.sar_meas_wait2
|
||||
.modify(|_, w| unsafe { w.sar_amp_wait3().bits(1) });
|
||||
|
||||
let adc = ADC {
|
||||
adc: PhantomData,
|
||||
attenuations: config.attenuations,
|
||||
active_channel: None,
|
||||
};
|
||||
|
||||
Ok(adc)
|
||||
}
|
||||
}
|
||||
|
||||
impl<ADC1> ADC<ADC1> {
|
||||
pub fn enable_hall_sensor() {
|
||||
// Connect hall sensor
|
||||
let rtcio = unsafe { &*RTCIO::ptr() };
|
||||
rtcio.hall_sens.modify(|_, w| w.xpd_hall().set_bit());
|
||||
}
|
||||
|
||||
pub fn disable_hall_sensor() {
|
||||
// Disconnect hall sensor
|
||||
let rtcio = unsafe { &*RTCIO::ptr() };
|
||||
rtcio.hall_sens.modify(|_, w| w.xpd_hall().clear_bit());
|
||||
}
|
||||
}
|
||||
|
||||
impl<ADCI, WORD, PIN> OneShot<ADCI, WORD, PIN> for ADC<ADCI>
|
||||
where
|
||||
WORD: From<u16>,
|
||||
PIN: Channel<ADCI, ID = u8>,
|
||||
ADCI: RegisterAccess,
|
||||
{
|
||||
type Error = ();
|
||||
|
||||
fn read(&mut self, _pin: &mut PIN) -> nb::Result<WORD, Self::Error> {
|
||||
if self.attenuations[PIN::channel() as usize] == None {
|
||||
panic!("Channel {} is not configured reading!", PIN::channel());
|
||||
}
|
||||
|
||||
if let Some(active_channel) = self.active_channel {
|
||||
// There is conversion in progress:
|
||||
// - if it's for a different channel try again later
|
||||
// - if it's for the given channel, go ahaid and check progress
|
||||
if active_channel != PIN::channel() {
|
||||
return Err(nb::Error::WouldBlock);
|
||||
}
|
||||
} else {
|
||||
// If no conversions are in progress, start a new one for given channel
|
||||
self.active_channel = Some(PIN::channel());
|
||||
|
||||
ADCI::set_en_pad(PIN::channel() as u8);
|
||||
|
||||
ADCI::clear_start_sar();
|
||||
ADCI::set_start_sar();
|
||||
}
|
||||
|
||||
// Wait for ADC to finish conversion
|
||||
let conversion_finished = ADCI::read_done_sar();
|
||||
if !conversion_finished {
|
||||
return Err(nb::Error::WouldBlock);
|
||||
}
|
||||
|
||||
// Get converted value
|
||||
let converted_value = ADCI::read_data_sar();
|
||||
|
||||
// Mark that no conversions are currently in progress
|
||||
self.active_channel = None;
|
||||
|
||||
Ok(converted_value.into())
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! impl_adc_interface {
|
||||
($adc:ident [
|
||||
$( ($pin:ident, $channel:expr) ,)+
|
||||
]) => {
|
||||
|
||||
$(
|
||||
impl Channel<$adc> for $pin<Analog> {
|
||||
type ID = u8;
|
||||
|
||||
fn channel() -> u8 { $channel }
|
||||
}
|
||||
)+
|
||||
}
|
||||
}
|
||||
|
||||
pub use impl_adc_interface;
|
1
esp-hal-common/src/analog/adc/esp32c3.rs
Normal file
1
esp-hal-common/src/analog/adc/esp32c3.rs
Normal file
@ -0,0 +1 @@
|
||||
// Currently we are missing the SENS peripheral from the SVD
|
379
esp-hal-common/src/analog/adc/esp32s2.rs
Normal file
379
esp-hal-common/src/analog/adc/esp32s2.rs
Normal file
@ -0,0 +1,379 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use embedded_hal::adc::{Channel, OneShot};
|
||||
use esp32s2_pac::APB_SARADC;
|
||||
|
||||
use crate::{
|
||||
analog::{ADC1, ADC2},
|
||||
pac::SENS,
|
||||
};
|
||||
|
||||
/// The sampling/readout resolution of the ADC
|
||||
#[derive(PartialEq, Eq, Clone, Copy)]
|
||||
pub enum Resolution {
|
||||
Resolution13Bit,
|
||||
}
|
||||
|
||||
/// The attenuation of the ADC pin
|
||||
#[derive(PartialEq, Eq, Clone, Copy)]
|
||||
pub enum Attenuation {
|
||||
Attenuation0dB = 0b00,
|
||||
Attenuation2p5dB = 0b01,
|
||||
Attenuation6dB = 0b10,
|
||||
Attenuation11dB = 0b11,
|
||||
}
|
||||
|
||||
pub struct AdcConfig<ADCI> {
|
||||
pub resolution: Resolution,
|
||||
pub attenuations: [Option<Attenuation>; 10],
|
||||
_phantom: PhantomData<ADCI>,
|
||||
}
|
||||
|
||||
impl<ADCI> AdcConfig<ADCI>
|
||||
where
|
||||
ADCI: RegisterAccess,
|
||||
{
|
||||
pub fn new() -> AdcConfig<ADCI> {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
pub fn enable_pin<PIN: Channel<ADCI, ID = u8>>(
|
||||
&mut self,
|
||||
_pin: &PIN,
|
||||
attenuation: Attenuation,
|
||||
) {
|
||||
self.attenuations[PIN::channel() as usize] = Some(attenuation);
|
||||
}
|
||||
}
|
||||
|
||||
impl<ADCI> Default for AdcConfig<ADCI> {
|
||||
fn default() -> Self {
|
||||
AdcConfig {
|
||||
resolution: Resolution::Resolution13Bit,
|
||||
attenuations: [None; 10],
|
||||
_phantom: PhantomData::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait RegisterAccess {
|
||||
fn set_bit_width(resolution: u8);
|
||||
|
||||
fn set_sample_bit(resolution: u8);
|
||||
|
||||
fn set_attenuation(channel: usize, attenuation: u8);
|
||||
|
||||
fn clear_dig_force();
|
||||
|
||||
fn set_start_force();
|
||||
|
||||
fn set_en_pad_force();
|
||||
|
||||
fn set_en_pad(channel: u8);
|
||||
|
||||
fn clear_start_sar();
|
||||
|
||||
fn set_start_sar();
|
||||
|
||||
fn read_done_sar() -> bool;
|
||||
|
||||
fn read_data_sar() -> u16;
|
||||
}
|
||||
|
||||
impl RegisterAccess for ADC1 {
|
||||
fn set_bit_width(_resolution: u8) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
fn set_sample_bit(_resolution: u8) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
fn set_attenuation(channel: usize, attenuation: u8) {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors.sar_atten1.modify(|r, w| {
|
||||
let new_value = (r.bits() & !(0b11 << (channel * 2)))
|
||||
| (((attenuation as u8 & 0b11) as u32) << (channel * 2));
|
||||
|
||||
unsafe { w.sar1_atten().bits(new_value) }
|
||||
});
|
||||
}
|
||||
|
||||
fn clear_dig_force() {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors
|
||||
.sar_meas1_mux
|
||||
.modify(|_, w| w.sar1_dig_force().clear_bit());
|
||||
}
|
||||
|
||||
fn set_start_force() {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors
|
||||
.sar_meas1_ctrl2
|
||||
.modify(|_, w| w.meas1_start_force().set_bit());
|
||||
}
|
||||
|
||||
fn set_en_pad_force() {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors
|
||||
.sar_meas1_ctrl2
|
||||
.modify(|_, w| w.sar1_en_pad_force().set_bit());
|
||||
}
|
||||
|
||||
fn set_en_pad(channel: u8) {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors
|
||||
.sar_meas1_ctrl2
|
||||
.modify(|_, w| unsafe { w.sar1_en_pad().bits(1 << channel) });
|
||||
}
|
||||
|
||||
fn clear_start_sar() {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors
|
||||
.sar_meas1_ctrl2
|
||||
.modify(|_, w| w.meas1_start_sar().clear_bit());
|
||||
}
|
||||
|
||||
fn set_start_sar() {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors
|
||||
.sar_meas1_ctrl2
|
||||
.modify(|_, w| w.meas1_start_sar().set_bit());
|
||||
}
|
||||
|
||||
fn read_done_sar() -> bool {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors.sar_meas1_ctrl2.read().meas1_done_sar().bit_is_set()
|
||||
}
|
||||
|
||||
fn read_data_sar() -> u16 {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors.sar_meas1_ctrl2.read().meas1_data_sar().bits() as u16
|
||||
}
|
||||
}
|
||||
|
||||
impl RegisterAccess for ADC2 {
|
||||
fn set_bit_width(_resolution: u8) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
fn set_sample_bit(_resolution: u8) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
fn set_attenuation(channel: usize, attenuation: u8) {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors.sar_atten2.modify(|r, w| {
|
||||
let new_value = (r.bits() & !(0b11 << (channel * 2)))
|
||||
| (((attenuation as u8 & 0b11) as u32) << (channel * 2));
|
||||
|
||||
unsafe { w.sar2_atten().bits(new_value) }
|
||||
});
|
||||
}
|
||||
|
||||
fn clear_dig_force() {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors
|
||||
.sar_meas2_mux
|
||||
.modify(|_, w| w.sar2_rtc_force().set_bit());
|
||||
|
||||
let sar_apb = unsafe { &*APB_SARADC::ptr() };
|
||||
sar_apb
|
||||
.arb_ctrl
|
||||
.modify(|_, w| w.adc_arb_rtc_force().set_bit());
|
||||
}
|
||||
|
||||
fn set_start_force() {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors
|
||||
.sar_meas2_ctrl2
|
||||
.modify(|_, w| w.meas2_start_force().set_bit());
|
||||
}
|
||||
|
||||
fn set_en_pad_force() {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors
|
||||
.sar_meas2_ctrl2
|
||||
.modify(|_, w| w.sar2_en_pad_force().set_bit());
|
||||
}
|
||||
|
||||
fn set_en_pad(channel: u8) {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors
|
||||
.sar_meas2_ctrl2
|
||||
.modify(|_, w| unsafe { w.sar2_en_pad().bits(1 << channel) });
|
||||
}
|
||||
|
||||
fn clear_start_sar() {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors
|
||||
.sar_meas2_ctrl2
|
||||
.modify(|_, w| w.meas2_start_sar().clear_bit());
|
||||
}
|
||||
|
||||
fn set_start_sar() {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors
|
||||
.sar_meas2_ctrl2
|
||||
.modify(|_, w| w.meas2_start_sar().set_bit());
|
||||
}
|
||||
|
||||
fn read_done_sar() -> bool {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors.sar_meas2_ctrl2.read().meas2_done_sar().bit_is_set()
|
||||
}
|
||||
|
||||
fn read_data_sar() -> u16 {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
sensors.sar_meas2_ctrl2.read().meas2_data_sar().bits() as u16
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ADC<ADC> {
|
||||
adc: PhantomData<ADC>,
|
||||
attenuations: [Option<Attenuation>; 10],
|
||||
active_channel: Option<u8>,
|
||||
}
|
||||
|
||||
impl<ADCI> ADC<ADCI>
|
||||
where
|
||||
ADCI: RegisterAccess,
|
||||
{
|
||||
pub fn adc(_adc_instance: ADCI, config: AdcConfig<ADCI>) -> Result<Self, ()> {
|
||||
let sensors = unsafe { &*SENS::ptr() };
|
||||
|
||||
// Set reading and sampling resolution
|
||||
let resolution: u8 = config.resolution as u8;
|
||||
|
||||
ADCI::set_bit_width(resolution);
|
||||
ADCI::set_sample_bit(resolution);
|
||||
|
||||
// Set attenuation for pins
|
||||
let attenuations = config.attenuations;
|
||||
|
||||
for channel in 0..attenuations.len() {
|
||||
if let Some(attenuation) = attenuations[channel] {
|
||||
ADC1::set_attenuation(channel, attenuation as u8);
|
||||
}
|
||||
}
|
||||
|
||||
// Set controller to RTC
|
||||
ADCI::clear_dig_force();
|
||||
ADCI::set_start_force();
|
||||
ADCI::set_en_pad_force();
|
||||
sensors
|
||||
.sar_hall_ctrl
|
||||
.modify(|_, w| w.xpd_hall_force().set_bit());
|
||||
sensors
|
||||
.sar_hall_ctrl
|
||||
.modify(|_, w| w.hall_phase_force().set_bit());
|
||||
|
||||
// Set power to SW power on
|
||||
sensors
|
||||
.sar_meas1_ctrl1
|
||||
.modify(|_, w| w.rtc_saradc_clkgate_en().set_bit());
|
||||
|
||||
sensors
|
||||
.sar_power_xpd_sar
|
||||
.modify(|_, w| w.sarclk_en().set_bit());
|
||||
|
||||
sensors
|
||||
.sar_power_xpd_sar
|
||||
.modify(|_, w| unsafe { w.force_xpd_sar().bits(0b11) });
|
||||
|
||||
// disable AMP
|
||||
sensors
|
||||
.sar_meas1_ctrl1
|
||||
.modify(|_, w| unsafe { w.force_xpd_amp().bits(0b11) });
|
||||
sensors
|
||||
.sar_amp_ctrl3
|
||||
.modify(|_, w| unsafe { w.amp_rst_fb_fsm().bits(0) });
|
||||
sensors
|
||||
.sar_amp_ctrl3
|
||||
.modify(|_, w| unsafe { w.amp_short_ref_fsm().bits(0) });
|
||||
sensors
|
||||
.sar_amp_ctrl3
|
||||
.modify(|_, w| unsafe { w.amp_short_ref_gnd_fsm().bits(0) });
|
||||
sensors
|
||||
.sar_amp_ctrl1
|
||||
.modify(|_, w| unsafe { w.sar_amp_wait1().bits(1) });
|
||||
sensors
|
||||
.sar_amp_ctrl1
|
||||
.modify(|_, w| unsafe { w.sar_amp_wait2().bits(1) });
|
||||
sensors
|
||||
.sar_amp_ctrl2
|
||||
.modify(|_, w| unsafe { w.sar_amp_wait3().bits(1) });
|
||||
|
||||
let adc = ADC {
|
||||
adc: PhantomData,
|
||||
attenuations: config.attenuations,
|
||||
active_channel: None,
|
||||
};
|
||||
|
||||
Ok(adc)
|
||||
}
|
||||
}
|
||||
|
||||
impl<ADCI, WORD, PIN> OneShot<ADCI, WORD, PIN> for ADC<ADCI>
|
||||
where
|
||||
WORD: From<u16>,
|
||||
PIN: Channel<ADCI, ID = u8>,
|
||||
ADCI: RegisterAccess,
|
||||
{
|
||||
type Error = ();
|
||||
|
||||
fn read(&mut self, _pin: &mut PIN) -> nb::Result<WORD, Self::Error> {
|
||||
if self.attenuations[PIN::channel() as usize] == None {
|
||||
panic!("Channel {} is not configured reading!", PIN::channel());
|
||||
}
|
||||
|
||||
if let Some(active_channel) = self.active_channel {
|
||||
// There is conversion in progress:
|
||||
// - if it's for a different channel try again later
|
||||
// - if it's for the given channel, go ahaid and check progress
|
||||
if active_channel != PIN::channel() {
|
||||
return Err(nb::Error::WouldBlock);
|
||||
}
|
||||
} else {
|
||||
// If no conversions are in progress, start a new one for given channel
|
||||
self.active_channel = Some(PIN::channel());
|
||||
|
||||
ADCI::set_en_pad(PIN::channel() as u8);
|
||||
|
||||
ADCI::clear_start_sar();
|
||||
ADCI::set_start_sar();
|
||||
}
|
||||
|
||||
// Wait for ADC to finish conversion
|
||||
let conversion_finished = ADCI::read_done_sar();
|
||||
if !conversion_finished {
|
||||
return Err(nb::Error::WouldBlock);
|
||||
}
|
||||
|
||||
// Get converted value
|
||||
let converted_value = ADCI::read_data_sar();
|
||||
|
||||
// Mark that no conversions are currently in progress
|
||||
self.active_channel = None;
|
||||
|
||||
Ok(converted_value.into())
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! impl_adc_interface {
|
||||
($adc:ident [
|
||||
$( ($pin:ident, $channel:expr) ,)+
|
||||
]) => {
|
||||
|
||||
$(
|
||||
impl Channel<$adc> for $pin<Analog> {
|
||||
type ID = u8;
|
||||
|
||||
fn channel() -> u8 { $channel }
|
||||
}
|
||||
)+
|
||||
}
|
||||
}
|
||||
|
||||
pub use impl_adc_interface;
|
1
esp-hal-common/src/analog/adc/esp32s3.rs
Normal file
1
esp-hal-common/src/analog/adc/esp32s3.rs
Normal file
@ -0,0 +1 @@
|
||||
|
@ -1,3 +1,8 @@
|
||||
#[cfg_attr(feature = "esp32", path = "adc/esp32.rs")]
|
||||
#[cfg_attr(feature = "esp32s2", path = "adc/esp32s2.rs")]
|
||||
#[cfg_attr(feature = "esp32s3", path = "adc/esp32s3.rs")]
|
||||
#[cfg_attr(feature = "esp32c3", path = "adc/esp32c3.rs")]
|
||||
pub mod adc;
|
||||
#[cfg(not(any(feature = "esp32c3", feature = "esp32s3")))]
|
||||
pub mod dac;
|
||||
|
||||
|
@ -1159,11 +1159,11 @@ pub fn enable_iomux_clk_gate() {
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
macro_rules! analog {
|
||||
([
|
||||
$($pxi:ident: ($pin_num:expr, $pin_reg:ident, $hold: ident, $mux_sel:ident,
|
||||
(
|
||||
$($pxi:ident: ($pin_num:expr, $pin_reg:expr, $hold: ident, $mux_sel:ident,
|
||||
$fun_sel:ident, $fun_ie:ident, $slp_ie:ident, $slp_sel:ident
|
||||
$(, $rue:ident, $rde:ident, $drv:ident, $slp_oe:ident)?),)+
|
||||
]) => {
|
||||
) => {
|
||||
$(
|
||||
impl<MODE> $pxi<MODE> {
|
||||
pub fn into_analog(mut self) -> $pxi<Analog> {
|
||||
@ -1174,33 +1174,36 @@ macro_rules! analog {
|
||||
$crate::gpio::enable_iomux_clk_gate();
|
||||
|
||||
// disable input
|
||||
rtcio.$pin_reg.modify(|_,w| w.$fun_ie().bit(false));
|
||||
paste! {
|
||||
rtcio.$pin_reg.modify(|_,w| w.$fun_ie().bit(false));
|
||||
}
|
||||
|
||||
// disable output
|
||||
rtcio.enable_w1tc.write(|w| unsafe { w.enable_w1tc().bits(1 << $pin_num) });
|
||||
// ESP32-S2 rtcio.rtc_gpio_enable_w1tc.write(|w| unsafe { w.reg_rtcio_reg_gpio_enable_w1tc().bits(1 << $pin_num) });
|
||||
//rtcio.rtc_gpio_enable_w1tc.write(|w| unsafe { w.rtc_gpio_enable_w1tc().bits(1 << $pin_num) });
|
||||
|
||||
// disable open drain
|
||||
rtcio.pin[$pin_num].modify(|_,w| w.pin_pad_driver().bit(false));
|
||||
//rtcio.rtc_gpio_pin[$pin_num].modify(|_,w| w.gpio_pin0_pad_driver().bit(false));
|
||||
|
||||
rtcio.$pin_reg.modify(|_,w| {
|
||||
w.$fun_ie().clear_bit();
|
||||
paste! {
|
||||
rtcio.$pin_reg.modify(|_,w| {
|
||||
w.$fun_ie().clear_bit();
|
||||
|
||||
// Connect pin to analog / RTC module instead of standard GPIO
|
||||
w.$mux_sel().set_bit();
|
||||
// Connect pin to analog / RTC module instead of standard GPIO
|
||||
w.$mux_sel().set_bit();
|
||||
|
||||
// Select function "RTC function 1" (GPIO) for analog use
|
||||
unsafe { w.$fun_sel().bits(0b00) }
|
||||
});
|
||||
// Select function "RTC function 1" (GPIO) for analog use
|
||||
unsafe { w.$fun_sel().bits(0b00) }
|
||||
});
|
||||
}
|
||||
|
||||
// Disable pull-up and pull-down resistors on the pin, if it has them
|
||||
rtcio.$pin_reg.modify(|_,w| {
|
||||
w
|
||||
.$rue().bit(false)
|
||||
.$rde().bit(false)
|
||||
});
|
||||
paste! {
|
||||
rtcio.$pin_reg.modify(|_,w| {
|
||||
w
|
||||
.$rue().bit(false)
|
||||
.$rde().bit(false)
|
||||
});
|
||||
}
|
||||
)?
|
||||
|
||||
$pxi { _mode: PhantomData }
|
||||
|
2
esp32-hal/.vscode/settings.json
vendored
2
esp32-hal/.vscode/settings.json
vendored
@ -1,7 +1,7 @@
|
||||
{
|
||||
"rust-analyzer.cargo.features": [],
|
||||
"rust-analyzer.cargo.allFeatures": false,
|
||||
"editor.formatOnSave": true,
|
||||
"editor.formatOnSave": false,
|
||||
"rust-analyzer.checkOnSave.allTargets": false,
|
||||
"rust-analyzer.checkOnSave.allFeatures": false,
|
||||
"rust-analyzer.checkOnSave.overrideCommand": [
|
||||
|
@ -29,6 +29,7 @@ embedded-hal = { version = "0.2", features = ["unproven"] }
|
||||
embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.8" }
|
||||
xtensa-lx = { version = "0.7", features = ["esp32"] }
|
||||
xtensa-lx-rt = { version = "0.12", features = ["esp32"], optional = true }
|
||||
nb = "1.0.0"
|
||||
|
||||
[dependencies.esp-hal-common]
|
||||
path = "../esp-hal-common"
|
||||
|
55
esp32-hal/examples/adc.rs
Normal file
55
esp32-hal/examples/adc.rs
Normal file
@ -0,0 +1,55 @@
|
||||
//! Connect a potentiometer to PIN25 and see the read values change when
|
||||
//! rotating the shaft. If could also connect the PIN to GND or 3V3 to see the
|
||||
//! maximum and minimum raw values read.
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use esp32_hal::{
|
||||
clock::ClockControl,
|
||||
gpio::IO,
|
||||
pac::Peripherals,
|
||||
prelude::*,
|
||||
AdcConfig,
|
||||
Attenuation,
|
||||
Delay,
|
||||
RtcCntl,
|
||||
Timer,
|
||||
ADC,
|
||||
ADC2,
|
||||
};
|
||||
use esp_println::println;
|
||||
use panic_halt as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
let peripherals = Peripherals::take().unwrap();
|
||||
let system = peripherals.DPORT.split();
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
|
||||
let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock);
|
||||
let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL);
|
||||
|
||||
// Disable MWDT and RWDT (Watchdog) flash boot protection
|
||||
timer0.disable();
|
||||
rtc_cntl.set_wdt_global_enable(false);
|
||||
|
||||
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
let mut pin25 = io.pins.gpio25.into_analog();
|
||||
|
||||
// Create ADC instances
|
||||
let analog = peripherals.SENS.split();
|
||||
|
||||
let mut adc2_config = AdcConfig::new();
|
||||
adc2_config.enable_pin(&pin25, Attenuation::Attenuation11dB);
|
||||
let mut adc2 = ADC::<ADC2>::adc(analog.adc2, adc2_config).unwrap();
|
||||
|
||||
let mut delay = Delay::new(&clocks);
|
||||
|
||||
loop {
|
||||
let pin25_value: u16 = nb::block!(adc2.read(&mut pin25)).unwrap();
|
||||
println!("PIN25 ADC reading = {}", pin25_value);
|
||||
delay.delay_ms(1500u32);
|
||||
}
|
||||
}
|
52
esp32-hal/src/adc.rs
Normal file
52
esp32-hal/src/adc.rs
Normal file
@ -0,0 +1,52 @@
|
||||
//! Analog to digital (ADC) conversion support.
|
||||
//!
|
||||
//! This module provides functions for reading analog values from two
|
||||
//! analog to digital converters available on the ESP32: `ADC1` and `ADC2`.
|
||||
//!
|
||||
//! The following pins can be configured for analog readout:
|
||||
//!
|
||||
//! | Channel | ADC1 | ADC2 |
|
||||
//! |---------|----------------------|---------------|
|
||||
//! | 0 | GPIO36 (SENSOR_VP) | GPIO4 |
|
||||
//! | 1 | GPIO37 (SENSOR_CAPP) | GPIO0 |
|
||||
//! | 2 | GPIO38 (SENSOR_CAPN) | GPIO2 |
|
||||
//! | 3 | GPIO39 (SENSOR_VN) | GPIO15 (MTDO) |
|
||||
//! | 4 | GPIO33 (32K_XP) | GPIO13 (MTCK) |
|
||||
//! | 5 | GPIO32 (32K_XN) | GPIO12 (MTDI) |
|
||||
//! | 6 | GPIO34 (VDET_1) | GPIO14 (MTMS) |
|
||||
//! | 7 | GPIO35 (VDET_2) | GPIO27 |
|
||||
//! | 8 | | GPIO25 |
|
||||
//! | 9 | | GPIO26 |
|
||||
|
||||
use embedded_hal::adc::Channel;
|
||||
use esp_hal_common::analog::{adc::impl_adc_interface, ADC1, ADC2};
|
||||
|
||||
use crate::{gpio::*, gpio_types::Analog};
|
||||
|
||||
impl_adc_interface! {
|
||||
ADC1 [
|
||||
(Gpio36, 0), // Alt. name: SENSOR_VP
|
||||
(Gpio37, 1), // Alt. name: SENSOR_CAPP
|
||||
(Gpio38, 2), // Alt. name: SENSOR_CAPN
|
||||
(Gpio39, 3), // Alt. name: SENSOR_VN
|
||||
(Gpio33, 4), // Alt. name: 32K_XP
|
||||
(Gpio32, 5), // Alt. name: 32K_XN
|
||||
(Gpio34, 6), // Alt. name: VDET_1
|
||||
(Gpio35, 7), // Alt. name: VDET_2
|
||||
]
|
||||
}
|
||||
|
||||
impl_adc_interface! {
|
||||
ADC2 [
|
||||
(Gpio4, 0),
|
||||
(Gpio0, 1),
|
||||
(Gpio2, 2),
|
||||
(Gpio15, 3), // Alt. name: MTDO
|
||||
(Gpio13, 4), // Alt. name: MTCK
|
||||
(Gpio12, 5), // Alt. name: MTDI
|
||||
(Gpio14, 6), // Alt. name: MTMS
|
||||
(Gpio27, 7),
|
||||
(Gpio25, 8),
|
||||
(Gpio26, 9),
|
||||
]
|
||||
}
|
@ -54,7 +54,7 @@ gpio! {
|
||||
Gpio39: (gpio39, 39, gpio39, Input, 0, Bank1, None),
|
||||
}
|
||||
|
||||
analog! {[
|
||||
analog! {
|
||||
Gpio36: (0, sensor_pads, sense1_hold, sense1_mux_sel, sense1_fun_sel, sense1_fun_ie, sense1_slp_ie, sense1_slp_sel ),
|
||||
Gpio37: (1, sensor_pads, sense2_hold, sense2_mux_sel, sense2_fun_sel, sense2_fun_ie, sense2_slp_ie, sense2_slp_sel ),
|
||||
Gpio38: (2, sensor_pads, sense3_hold, sense3_mux_sel, sense3_fun_sel, sense3_fun_ie, sense3_slp_ie, sense3_slp_sel ),
|
||||
@ -73,4 +73,4 @@ analog! {[
|
||||
Gpio12: (15, touch_pad5, hold, mux_sel, fun_sel, fun_ie, slp_ie, slp_sel, rue, rde, drv, slp_oe),
|
||||
Gpio14: (16, touch_pad6, hold, mux_sel, fun_sel, fun_ie, slp_ie, slp_sel, rue, rde, drv, slp_oe),
|
||||
Gpio27: (17, touch_pad7, hold, mux_sel, fun_sel, fun_ie, slp_ie, slp_sel, rue, rde, drv, slp_oe),
|
||||
]}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
pub use embedded_hal as ehal;
|
||||
pub use esp_hal_common::{
|
||||
analog::{adc::*, *},
|
||||
clock,
|
||||
cpu_control::CpuControl,
|
||||
efuse,
|
||||
@ -25,6 +26,7 @@ pub use esp_hal_common::{
|
||||
|
||||
pub use self::gpio::IO;
|
||||
|
||||
pub mod adc;
|
||||
pub mod dac;
|
||||
pub mod gpio;
|
||||
|
||||
|
@ -39,6 +39,7 @@ embedded-graphics = "0.7"
|
||||
panic-halt = "0.2"
|
||||
ssd1306 = "0.7"
|
||||
smart-leds = "0.3"
|
||||
esp-println = { version = "0.1.0", features = ["esp32s2"] }
|
||||
|
||||
[features]
|
||||
default = ["rt"]
|
||||
|
58
esp32s2-hal/examples/adc.rs
Normal file
58
esp32s2-hal/examples/adc.rs
Normal file
@ -0,0 +1,58 @@
|
||||
//! Connect a potentiometer to PIN3 and see the read values change when
|
||||
//! rotating the shaft. If could also connect the PIN to GND or 3V3 to see the
|
||||
//! maximum and minimum raw values read.
|
||||
//!
|
||||
//! THIS CURRENTLY DOESN'T WORK IN DEBUG BUILDS! THIS NEEDS TO GET FIGURED OUT!
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use esp32s2_hal::{
|
||||
clock::ClockControl,
|
||||
gpio::IO,
|
||||
pac::Peripherals,
|
||||
prelude::*,
|
||||
AdcConfig,
|
||||
Attenuation,
|
||||
Delay,
|
||||
RtcCntl,
|
||||
Timer,
|
||||
ADC,
|
||||
ADC1,
|
||||
};
|
||||
use esp_println::println;
|
||||
use panic_halt as _;
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
let peripherals = Peripherals::take().unwrap();
|
||||
let system = peripherals.SYSTEM.split();
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
|
||||
let mut timer0 = Timer::new(peripherals.TIMG0, clocks.apb_clock);
|
||||
let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL);
|
||||
|
||||
// Disable MWDT and RWDT (Watchdog) flash boot protection
|
||||
timer0.disable();
|
||||
rtc_cntl.set_wdt_global_enable(false);
|
||||
|
||||
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
let mut pin3 = io.pins.gpio3.into_analog();
|
||||
|
||||
// Create ADC instances
|
||||
let analog = peripherals.SENS.split();
|
||||
|
||||
let mut adc1_config = AdcConfig::new();
|
||||
adc1_config.enable_pin(&pin3, Attenuation::Attenuation11dB);
|
||||
let mut adc1 = ADC::<ADC1>::adc(analog.adc1, adc1_config).unwrap();
|
||||
|
||||
let mut delay = Delay::new(&clocks);
|
||||
|
||||
loop {
|
||||
println!("About to read from ADC");
|
||||
let pin3_value: u16 = nb::block!(adc1.read(&mut pin3)).unwrap();
|
||||
println!("PIN3 ADC reading = {}", pin3_value);
|
||||
delay.delay_ms(1500u32);
|
||||
}
|
||||
}
|
34
esp32s2-hal/src/adc.rs
Normal file
34
esp32s2-hal/src/adc.rs
Normal file
@ -0,0 +1,34 @@
|
||||
use embedded_hal::adc::Channel;
|
||||
use esp_hal_common::analog::{adc::impl_adc_interface, ADC1, ADC2};
|
||||
|
||||
use crate::{gpio::*, gpio_types::Analog};
|
||||
|
||||
impl_adc_interface! {
|
||||
ADC1 [
|
||||
(Gpio1, 0),
|
||||
(Gpio2, 1),
|
||||
(Gpio3, 2),
|
||||
(Gpio4, 3),
|
||||
(Gpio5, 4),
|
||||
(Gpio6, 5),
|
||||
(Gpio7, 6),
|
||||
(Gpio8, 7),
|
||||
(Gpio9, 8),
|
||||
(Gpio10,9),
|
||||
]
|
||||
}
|
||||
|
||||
impl_adc_interface! {
|
||||
ADC2 [
|
||||
(Gpio11, 0),
|
||||
(Gpio12, 1),
|
||||
(Gpio13, 2),
|
||||
(Gpio14, 3),
|
||||
(Gpio15, 4),
|
||||
(Gpio16, 5),
|
||||
(Gpio17, 6),
|
||||
(Gpio18, 7),
|
||||
(Gpio19, 8),
|
||||
(Gpio20, 9),
|
||||
]
|
||||
}
|
@ -59,8 +59,27 @@ gpio! {
|
||||
Gpio46: (gpio46, 46, gpio46, IO,Input, Bank1, None),
|
||||
}
|
||||
|
||||
// TODO other analog capable gpios - see https://github.com/espressif/esp-idf/blob/master/components/soc/esp32s2/rtc_io_periph.c
|
||||
analog! {[
|
||||
Gpio17: (17, pad_dac1, pdac1_hold, pdac1_mux_sel, pdac1_fun_sel, pdac1_fun_ie, pdac1_slp_ie, pdac1_slp_sel, pdac1_rue, pdac1_rde, pdac1_drv, pdac1_slp_oe),
|
||||
Gpio18: (18, pad_dac2, pdac2_hold, pdac2_mux_sel, pdac2_fun_sel, pdac2_fun_ie, pdac2_slp_ie, pdac2_slp_sel, pdac2_rue, pdac2_rde, pdac2_drv, pdac2_slp_oe),
|
||||
]}
|
||||
analog! {
|
||||
Gpio0: ( 0, touch_pad[0], touch_pad0_hold, touch_pad0_mux_sel, touch_pad0_fun_sel, touch_pad0_fun_ie, touch_pad0_slp_ie, touch_pad0_slp_sel, touch_pad0_rue, touch_pad0_rde, touch_pad0_drv, touch_pad0_slp_oe),
|
||||
Gpio1: ( 1, touch_pad[1], touch_pad1_hold, touch_pad0_mux_sel, touch_pad0_fun_sel, touch_pad0_fun_ie, touch_pad0_slp_ie, touch_pad0_slp_sel, touch_pad0_rue, touch_pad0_rde, touch_pad0_drv, touch_pad0_slp_oe),
|
||||
Gpio2: ( 2, touch_pad[2], touch_pad2_hold, touch_pad0_mux_sel, touch_pad0_fun_sel, touch_pad0_fun_ie, touch_pad0_slp_ie, touch_pad0_slp_sel, touch_pad0_rue, touch_pad0_rde, touch_pad0_drv, touch_pad0_slp_oe),
|
||||
Gpio3: ( 3, touch_pad[3], touch_pad3_hold, touch_pad0_mux_sel, touch_pad0_fun_sel, touch_pad0_fun_ie, touch_pad0_slp_ie, touch_pad0_slp_sel, touch_pad0_rue, touch_pad0_rde, touch_pad0_drv, touch_pad0_slp_oe),
|
||||
Gpio4: ( 4, touch_pad[4], touch_pad4_hold, touch_pad0_mux_sel, touch_pad0_fun_sel, touch_pad0_fun_ie, touch_pad0_slp_ie, touch_pad0_slp_sel, touch_pad0_rue, touch_pad0_rde, touch_pad0_drv, touch_pad0_slp_oe),
|
||||
Gpio5: ( 5, touch_pad[5], touch_pad5_hold, touch_pad0_mux_sel, touch_pad0_fun_sel, touch_pad0_fun_ie, touch_pad0_slp_ie, touch_pad0_slp_sel, touch_pad0_rue, touch_pad0_rde, touch_pad0_drv, touch_pad0_slp_oe),
|
||||
Gpio6: ( 6, touch_pad[6], touch_pad6_hold, touch_pad0_mux_sel, touch_pad0_fun_sel, touch_pad0_fun_ie, touch_pad0_slp_ie, touch_pad0_slp_sel, touch_pad0_rue, touch_pad0_rde, touch_pad0_drv, touch_pad0_slp_oe),
|
||||
Gpio7: ( 7, touch_pad[7], touch_pad7_hold, touch_pad0_mux_sel, touch_pad0_fun_sel, touch_pad0_fun_ie, touch_pad0_slp_ie, touch_pad0_slp_sel, touch_pad0_rue, touch_pad0_rde, touch_pad0_drv, touch_pad0_slp_oe),
|
||||
Gpio8: ( 8, touch_pad[8], touch_pad8_hold, touch_pad0_mux_sel, touch_pad0_fun_sel, touch_pad0_fun_ie, touch_pad0_slp_ie, touch_pad0_slp_sel, touch_pad0_rue, touch_pad0_rde, touch_pad0_drv, touch_pad0_slp_oe),
|
||||
Gpio9: ( 9, touch_pad[9], touch_pad9_hold, touch_pad0_mux_sel, touch_pad0_fun_sel, touch_pad0_fun_ie, touch_pad0_slp_ie, touch_pad0_slp_sel, touch_pad0_rue, touch_pad0_rde, touch_pad0_drv, touch_pad0_slp_oe),
|
||||
Gpio10: (10, touch_pad[10], touch_pad10_hold, touch_pad0_mux_sel, touch_pad0_fun_sel, touch_pad0_fun_ie, touch_pad0_slp_ie, touch_pad0_slp_sel, touch_pad0_rue, touch_pad0_rde, touch_pad0_drv, touch_pad0_slp_oe),
|
||||
Gpio11: (11, touch_pad[11], touch_pad11_hold, touch_pad0_mux_sel, touch_pad0_fun_sel, touch_pad0_fun_ie, touch_pad0_slp_ie, touch_pad0_slp_sel, touch_pad0_rue, touch_pad0_rde, touch_pad0_drv, touch_pad0_slp_oe),
|
||||
Gpio12: (12, touch_pad[12], touch_pad12_hold, touch_pad0_mux_sel, touch_pad0_fun_sel, touch_pad0_fun_ie, touch_pad0_slp_ie, touch_pad0_slp_sel, touch_pad0_rue, touch_pad0_rde, touch_pad0_drv, touch_pad0_slp_oe),
|
||||
Gpio13: (13, touch_pad[13], touch_pad13_hold, touch_pad0_mux_sel, touch_pad0_fun_sel, touch_pad0_fun_ie, touch_pad0_slp_ie, touch_pad0_slp_sel, touch_pad0_rue, touch_pad0_rde, touch_pad0_drv, touch_pad0_slp_oe),
|
||||
Gpio14: (14, touch_pad[14], touch_pad14_hold, touch_pad0_mux_sel, touch_pad0_fun_sel, touch_pad0_fun_ie, touch_pad0_slp_ie, touch_pad0_slp_sel, touch_pad0_rue, touch_pad0_rde, touch_pad0_drv, touch_pad0_slp_oe),
|
||||
Gpio15: (15, xtal_32p_pad, x32p_hold, x32p_mux_sel, x32p_fun_sel, x32p_fun_ie, x32p_slp_ie, x32p_slp_sel, x32p_rue, x32p_rde, x32p_drv, x32p_slp_oe),
|
||||
Gpio16: (16, xtal_32n_pad, x32n_hold, x32n_mux_sel, x32n_fun_sel, x32n_fun_ie, x32n_slp_ie, x32n_slp_sel, x32n_rue, x32n_rde, x32n_drv, x32pn_slp_oe),
|
||||
Gpio17: (17, pad_dac1, pdac1_hold, pdac1_mux_sel, pdac1_fun_sel, pdac1_fun_ie, pdac1_slp_ie, pdac1_slp_sel, pdac1_rue, pdac1_rde, pdac1_drv, pdac1_slp_oe),
|
||||
Gpio18: (18, pad_dac2, pdac2_hold, pdac2_mux_sel, pdac2_fun_sel, pdac2_fun_ie, pdac2_slp_ie, pdac2_slp_sel, pdac2_rue, pdac2_rde, pdac2_drv, pdac2_slp_oe),
|
||||
Gpio19: (19, rtc_pad19, rtc_pad19_hold, mux_sel, fun_sel, fun_ie, slp_ie, slp_sel, rue, rde, drv, slp_oe),
|
||||
Gpio20: (20, rtc_pad20, rtc_pad20_hold, mux_sel, fun_sel, fun_ie, slp_ie, slp_sel, rue, rde, drv, slp_oe),
|
||||
Gpio21: (21, rtc_pad21, rtc_pad21_hold, mux_sel, fun_sel, fun_ie, slp_ie, slp_sel, rue, rde, drv, slp_oe),
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
pub use embedded_hal as ehal;
|
||||
pub use esp_hal_common::{
|
||||
analog::{adc::*, *},
|
||||
clock,
|
||||
efuse,
|
||||
gpio as gpio_types,
|
||||
@ -25,6 +26,7 @@ pub use esp_hal_common::{
|
||||
|
||||
pub use self::gpio::IO;
|
||||
|
||||
pub mod adc;
|
||||
pub mod dac;
|
||||
pub mod gpio;
|
||||
|
||||
|
@ -64,4 +64,27 @@ gpio! {
|
||||
Gpio48: (gpio48, 48, gpio[48], IO, 0, Bank1, None),
|
||||
}
|
||||
|
||||
// TODO add analog capable gpios - see https://github.com/espressif/esp-idf/blob/master/components/soc/esp32s3/rtc_io_periph.c
|
||||
analog! {
|
||||
Gpio0: ( 0, touch_pad0, touch_pad0_hold, mux_sel, fun_sel, fun_ie, slp_ie, slp_sel, rue, rde, drv, slp_oe),
|
||||
Gpio1: ( 1, touch_pad1, touch_pad1_hold, mux_sel, fun_sel, fun_ie, slp_ie, slp_sel, rue, rde, drv, slp_oe),
|
||||
Gpio2: ( 2, touch_pad2, touch_pad2_hold, mux_sel, fun_sel, fun_ie, slp_ie, slp_sel, rue, rde, drv, slp_oe),
|
||||
Gpio3: ( 3, touch_pad3, touch_pad3_hold, mux_sel, fun_sel, fun_ie, slp_ie, slp_sel, rue, rde, drv, slp_oe),
|
||||
Gpio4: ( 4, touch_pad4, touch_pad4_hold, mux_sel, fun_sel, fun_ie, slp_ie, slp_sel, rue, rde, drv, slp_oe),
|
||||
Gpio5: ( 5, touch_pad5, touch_pad5_hold, mux_sel, fun_sel, fun_ie, slp_ie, slp_sel, rue, rde, drv, slp_oe),
|
||||
Gpio6: ( 6, touch_pad6, touch_pad6_hold, mux_sel, fun_sel, fun_ie, slp_ie, slp_sel, rue, rde, drv, slp_oe),
|
||||
Gpio7: ( 7, touch_pad7, touch_pad7_hold, mux_sel, fun_sel, fun_ie, slp_ie, slp_sel, rue, rde, drv, slp_oe),
|
||||
Gpio8: ( 8, touch_pad8, touch_pad8_hold, mux_sel, fun_sel, fun_ie, slp_ie, slp_sel, rue, rde, drv, slp_oe),
|
||||
Gpio9: ( 9, touch_pad9, touch_pad9_hold, mux_sel, fun_sel, fun_ie, slp_ie, slp_sel, rue, rde, drv, slp_oe),
|
||||
Gpio10: (10, touch_pad10, touch_pad10_hold, mux_sel, fun_sel, fun_ie, slp_ie, slp_sel, rue, rde, drv, slp_oe),
|
||||
Gpio11: (11, touch_pad11, touch_pad11_hold, mux_sel, fun_sel, fun_ie, slp_ie, slp_sel, rue, rde, drv, slp_oe),
|
||||
Gpio12: (12, touch_pad12, touch_pad12_hold, mux_sel, fun_sel, fun_ie, slp_ie, slp_sel, rue, rde, drv, slp_oe),
|
||||
Gpio13: (13, touch_pad13, touch_pad13_hold, mux_sel, fun_sel, fun_ie, slp_ie, slp_sel, rue, rde, drv, slp_oe),
|
||||
Gpio14: (14, touch_pad14, touch_pad14_hold, mux_sel, fun_sel, fun_ie, slp_ie, slp_sel, rue, rde, drv, slp_oe),
|
||||
Gpio15: (15, xtal_32p_pad, x32p_hold, x32p_mux_sel, x32p_fun_sel, x32p_fun_ie, x32p_slp_ie, x32p_slp_sel, x32p_rue, x32p_rde, x32p_drv, x32p_slp_oe),
|
||||
Gpio16: (16, xtal_32n_pad, x32n_hold, x32n_mux_sel, x32n_fun_sel, x32n_fun_ie, x32n_slp_ie, x32n_slp_sel, x32n_rue, x32n_rde, x32n_drv, x32pn_slp_oe),
|
||||
Gpio17: (17, pad_dac1, pdac1_hold, pdac1_mux_sel,pdac1_fun_sel,pdac1_fun_ie, pdac1_slp_ie, pdac1_slp_sel, pdac1_rue, pdac1_rde, pdac1_drv, pdac1_slp_oe),
|
||||
Gpio18: (18, pad_dac2, pdac2_hold, pdac2_mux_sel,pdac2_fun_sel,pdac2_fun_ie, pdac2_slp_ie, pdac2_slp_sel, pdac2_rue, pdac2_rde, pdac2_drv, pdac2_slp_oe),
|
||||
Gpio19: (19, rtc_pad19, rtc_pad19_hold, mux_sel, fun_sel, fun_ie, slp_ie, slp_sel, rue, rde, drv, slp_oe),
|
||||
Gpio20: (20, rtc_pad20, rtc_pad20_hold, mux_sel, fun_sel, fun_ie, slp_ie, slp_sel, rue, rde, drv, slp_oe),
|
||||
Gpio21: (21, rtc_pad21, rtc_pad21_hold, mux_sel, fun_sel, fun_ie, slp_ie, slp_sel, rue, rde, drv, slp_oe),
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user