Skip to content

Commit

Permalink
Touch pin definition overhaul (#2109)
Browse files Browse the repository at this point in the history
* Merge touch macros

* Add missing touch pins, remove trait impl indirection

* Remove unused stuff

---------

Co-authored-by: Juraj Sadel <[email protected]>
  • Loading branch information
bugadani and JurajSadel authored Sep 9, 2024
1 parent 82a9abf commit 05941cc
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 151 deletions.
1 change: 1 addition & 0 deletions esp-hal/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Renamed `touch::Continous` to `touch::Continuous`. (#2094)
- The (previously undocumented) `ErasedPin` enum has been replaced with the `ErasedPin` struct. (#2094)
- Renamed and merged `Rtc::get_time_us` and `Rtc::get_time_ms` into `Rtc::time_since_boot` (#1883)
- ESP32: Added support for touch sensing on GPIO32 and 33 (#2109)

### Fixed

Expand Down
185 changes: 62 additions & 123 deletions esp-hal/src/gpio/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,15 @@ pub(crate) use crate::gpio;
#[cfg(any(xtensa, esp32c3, esp32c2))]
pub(crate) use crate::rtc_pins;
pub use crate::soc::gpio::*;
#[cfg(touch)]
pub(crate) use crate::touch;
use crate::{
interrupt::InterruptHandler,
peripheral::{Peripheral, PeripheralRef},
peripherals::{GPIO, IO_MUX},
private,
InterruptConfigurable,
};
#[cfg(touch)]
pub(crate) use crate::{touch_common, touch_into};

mod any_pin;
mod dummy_pin;
Expand Down Expand Up @@ -177,15 +177,6 @@ pub enum Pull {
Down,
}

/// RTC input pin mode
pub struct RtcInput;

/// RTC output pin mode
pub struct RtcOutput;

/// Analog mode
pub struct Analog;

/// Drive strength (values are approximates)
pub enum DriveStrength {
/// Drive strength of approximately 5mA.
Expand Down Expand Up @@ -260,11 +251,6 @@ pub trait RtcPinWithResistors: RtcPin {
fn rtcio_pulldown(&mut self, enable: bool);
}

/// Marker for RTC pins which support input mode
pub trait RtcInputPin: RtcPin {}
/// Marker for RTC pins which support output mode
pub trait RtcOutputPin: RtcPin {}

/// Common trait implemented by pins
pub trait Pin: private::Sealed {
/// GPIO number
Expand Down Expand Up @@ -1091,28 +1077,6 @@ where
}
}

#[cfg(touch)]
impl<const GPIONUM: u8> TouchPin for GpioPin<GPIONUM>
where
Self: GpioProperties<IsTouch = True>,
{
fn set_touch(&self, _: private::Internal) {
crate::soc::gpio::internal_into_touch(GPIONUM);
}

fn get_touch_measurement(&self, _: private::Internal) -> u16 {
crate::soc::gpio::internal_get_touch_measurement(GPIONUM)
}

fn get_touch_nr(&self, _: private::Internal) -> u8 {
crate::soc::gpio::internal_get_touch_nr(GPIONUM)
}

fn set_threshold(&self, threshold: u16, _: private::Internal) {
crate::soc::gpio::internal_set_threshold(GPIONUM, threshold)
}
}

/// General Purpose Input/Output driver
pub struct Io {
_io_mux: IO_MUX,
Expand Down Expand Up @@ -1609,11 +1573,10 @@ macro_rules! analog {
}
}

/// normal touch pin initialization. This is separate from touch_common, as we
/// need to handle some touch_pads differently
/// Common functionality for all touch pads
#[doc(hidden)]
#[macro_export]
macro_rules! touch_into {
macro_rules! touch {
(@pin_specific $touch_num:expr, true) => {
paste::paste! {
unsafe { &*RTC_IO::ptr() }.[< touch_pad $touch_num >]().write(|w| unsafe {
Expand Down Expand Up @@ -1644,98 +1607,74 @@ macro_rules! touch_into {
};

(
$( ( $touch_num:expr, $pin_num:expr, $rtc_pin:expr, $touch_thres_reg:expr, $touch_thres_field:expr , $needs_extra_setup:tt ))+
$(
(
$touch_num:literal, $pin_num:literal, $rtc_pin:literal, $touch_out_reg:expr, $meas_field: expr, $touch_thres_reg:expr, $touch_thres_field:expr, $normal_pin:literal
)
)+
) => {
pub(crate) fn internal_into_touch(pin: u8) {
match pin {
$(
$pin_num => {
use $crate::peripherals::{GPIO, RTC_IO, SENS};
$(
impl $crate::gpio::TouchPin for GpioPin<$pin_num>
where
Self: $crate::gpio::GpioProperties<IsTouch = $crate::gpio::True>,
{
fn set_touch(&self, _: $crate::private::Internal) {
use $crate::peripherals::{GPIO, RTC_IO, SENS};

let gpio = unsafe { &*GPIO::ptr() };
let rtcio = unsafe { &*RTC_IO::ptr() };
let sens = unsafe { &*SENS::ptr() };
let gpio = unsafe { &*GPIO::ptr() };
let rtcio = unsafe { &*RTC_IO::ptr() };
let sens = unsafe { &*SENS::ptr() };

// Pad to normal mode (not open-drain)
gpio.pin($rtc_pin).write(|w| w.pad_driver().clear_bit());
// Pad to normal mode (not open-drain)
gpio.pin($rtc_pin).write(|w| w.pad_driver().clear_bit());

// clear output
rtcio.enable_w1tc().write(|w| unsafe { w.enable_w1tc().bits(1 << $rtc_pin) });
paste::paste! {
sens . $touch_thres_reg ()
.write(|w| unsafe {
w. $touch_thres_field ().bits(
0b0 // Default: 0 for esp32 gets overridden later anyway.
)
});

$crate::touch_into!( @pin_specific $touch_num, $needs_extra_setup );

// enable the pin
sens.sar_touch_enable().modify(|r, w| unsafe {
w.touch_pad_worken().bits(
r.touch_pad_worken().bits() | ( 1 << [< $touch_num >] )
)
});
}
}
)+
// clear output
rtcio
.enable_w1tc()
.write(|w| unsafe { w.enable_w1tc().bits(1 << $rtc_pin) });
paste::paste! {
sens . $touch_thres_reg ()
.write(|w| unsafe {
w. $touch_thres_field ().bits(
0b0 // Default: 0 for esp32 gets overridden later anyway.
)
});

_ => unreachable!(),
$crate::touch!( @pin_specific $touch_num, $normal_pin );

// enable the pin
sens.sar_touch_enable().modify(|r, w| unsafe {
w.touch_pad_worken().bits(
r.touch_pad_worken().bits() | ( 1 << [< $touch_num >] )
)
});
}
}
}
};
}

/// Common functionality for all touch pads
#[doc(hidden)]
#[macro_export]
macro_rules! touch_common {
(
$(
(
$touch_num:expr, $pin_num:expr, $touch_out_reg:expr, $meas_field: expr, $touch_thres_reg:expr, $touch_thres_field:expr
)
)+
) => {
pub(crate) fn internal_get_touch_measurement(pin: u8) -> u16 {
match pin {
$(
$pin_num => {
paste::paste! {
unsafe { &* $crate::peripherals::SENS::ptr() }
. $touch_out_reg ()
.read()
. $meas_field ()
.bits()
}
},
)+
_ => unreachable!(),
fn get_touch_measurement(&self, _: $crate::private::Internal) -> u16 {
paste::paste! {
unsafe { &* $crate::peripherals::SENS::ptr() }
. $touch_out_reg ()
.read()
. $meas_field ()
.bits()
}
}
}
pub(crate) fn internal_get_touch_nr(pin: u8) -> u8 {
match pin {
$($pin_num => $touch_num,)+
_ => unreachable!(),

fn get_touch_nr(&self, _: $crate::private::Internal) -> u8 {
$touch_num
}
}
pub(crate) fn internal_set_threshold(pin: u8, threshold: u16) {
match pin {
$(
$pin_num => {
paste::paste! {
unsafe { &* $crate::peripherals::SENS::ptr() }
. $touch_thres_reg ()
.write(|w| unsafe {
w. $touch_thres_field ().bits(threshold)
});
}
},
)+
_ => unreachable!(),

fn set_threshold(&self, threshold: u16, _: $crate::private::Internal) {
paste::paste! {
unsafe { &* $crate::peripherals::SENS::ptr() }
. $touch_thres_reg ()
.write(|w| unsafe {
w. $touch_thres_field ().bits(threshold)
});
}
}
}
})+
};
}

Expand Down
42 changes: 14 additions & 28 deletions esp-hal/src/soc/esp32/gpio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -793,8 +793,8 @@ crate::gpio::gpio! {
(25, 0, InputOutputAnalog (5 => EMAC_RXD0) ())
(26, 0, InputOutputAnalog (5 => EMAC_RXD1) ())
(27, 0, InputOutputAnalogTouch (5 => EMAC_RX_DV) ())
(32, 1, InputOutputAnalog)
(33, 1, InputOutputAnalog)
(32, 1, InputOutputAnalogTouch)
(33, 1, InputOutputAnalogTouch)
(34, 1, InputOnlyAnalog)
(35, 1, InputOnlyAnalog)
(36, 1, InputOnlyAnalog)
Expand Down Expand Up @@ -845,33 +845,19 @@ crate::gpio::rtc_pins! {
(27, 17, touch_pad7(), "", touch_pad7_hold_force, rue, rde )
}

crate::gpio::touch_into! {
// (touch_nr, pin_nr, rtc_pin, touch_comb_reg_nr, normal_pin)
(0, 4, 10, sar_touch_thres1, touch_out_th0, true )
(1, 0, 11, sar_touch_thres1, touch_out_th1, true )
(2, 2, 12, sar_touch_thres2, touch_out_th2, true )
(3, 15, 13, sar_touch_thres2, touch_out_th3, true )
(4, 13, 14, sar_touch_thres3, touch_out_th4, true )
(5, 12, 15, sar_touch_thres3, touch_out_th5, true )
(6, 14, 16, sar_touch_thres4, touch_out_th6, true )
(7, 27, 17, sar_touch_thres4, touch_out_th7, true )
crate::gpio::touch! {
// touch_nr, pin_nr, rtc_pin, touch_out_reg, meas_field, touch_thres_reg, touch_thres_field, normal_pin
(0, 4, 10, sar_touch_out1, touch_meas_out0, sar_touch_thres1, touch_out_th0, true)
(1, 0, 11, sar_touch_out1, touch_meas_out1, sar_touch_thres1, touch_out_th1, true)
(2, 2, 12, sar_touch_out2, touch_meas_out2, sar_touch_thres2, touch_out_th2, true)
(3, 15, 13, sar_touch_out2, touch_meas_out3, sar_touch_thres2, touch_out_th3, true)
(4, 13, 14, sar_touch_out3, touch_meas_out4, sar_touch_thres3, touch_out_th4, true)
(5, 12, 15, sar_touch_out3, touch_meas_out5, sar_touch_thres3, touch_out_th5, true)
(6, 14, 16, sar_touch_out4, touch_meas_out6, sar_touch_thres4, touch_out_th6, true)
(7, 27, 17, sar_touch_out4, touch_meas_out7, sar_touch_thres4, touch_out_th7, true)
// ---
(8, 33, 8, sar_touch_thres5, touch_out_th8, false )
(9, 32, 9, sar_touch_thres5, touch_out_th9, false )
}

crate::gpio::touch_common! {
// (touch_nr, pin_nr, touch_out_reg, touch_thres_reg )
(0, 4, sar_touch_out1, touch_meas_out0, sar_touch_thres1, touch_out_th0)
(1, 0, sar_touch_out1, touch_meas_out1, sar_touch_thres1, touch_out_th1)
(2, 2, sar_touch_out2, touch_meas_out2, sar_touch_thres2, touch_out_th2)
(3, 15, sar_touch_out2, touch_meas_out3, sar_touch_thres2, touch_out_th3)
(4, 13, sar_touch_out3, touch_meas_out4, sar_touch_thres3, touch_out_th4)
(5, 12, sar_touch_out3, touch_meas_out5, sar_touch_thres3, touch_out_th5)
(6, 14, sar_touch_out4, touch_meas_out6, sar_touch_thres4, touch_out_th6)
(7, 27, sar_touch_out4, touch_meas_out7, sar_touch_thres4, touch_out_th7)
(8, 33, sar_touch_out5, touch_meas_out8, sar_touch_thres5, touch_out_th8)
(9, 32, sar_touch_out5, touch_meas_out9, sar_touch_thres5, touch_out_th9)
(8, 33, 8, sar_touch_out5, touch_meas_out8, sar_touch_thres5, touch_out_th8, false)
(9, 32, 9, sar_touch_out5, touch_meas_out9, sar_touch_thres5, touch_out_th9, false)
}

impl InterruptStatusRegisterAccess for InterruptStatusRegisterAccessBank0 {
Expand Down

0 comments on commit 05941cc

Please sign in to comment.