Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 48 additions & 59 deletions esp-hal/src/gpio/rtc_io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use core::marker::PhantomData;

use super::{InputPin, OutputPin, RtcPin};
use crate::{
gpio::RtcFunction,
gpio::{Pin, RtcFunction, RtcPinWithResistors},
peripherals::{GPIO, RTC_IO},
};

Expand Down Expand Up @@ -73,64 +73,57 @@ impl<'d, const PIN: u8> LowPowerOutput<'d, PIN> {
}
}

/// A GPIO input pin configured for low power operation
pub struct LowPowerInput<'d, const PIN: u8> {
phantom: PhantomData<&'d mut ()>,
/// A GPIO input pin configured for low power operation.
pub struct LowPowerInput<'d, P> {
pin: P,
phantom: PhantomData<&'d ()>,
}

impl<'d, const PIN: u8> LowPowerInput<'d, PIN> {
/// Create a new input pin for use by the low-power core
pub fn new<P>(pin: P) -> Self
where
P: InputPin + RtcPin + 'd,
{
impl<'d, P> LowPowerInput<'d, P>
where
P: InputPin + RtcPinWithResistors + 'd,
{
/// Create a new input pin for use by the low-power core.
pub fn new(pin: P) -> Self {
pin.rtc_set_config(true, true, RtcFunction::Rtc);

let this = Self {
phantom: PhantomData,
};
this.input_enable(true);
this.pullup_enable(false);
this.pulldown_enable(false);

this
}
pin.rtcio_pullup(false);
pin.rtcio_pulldown(false);

fn input_enable(&self, enable: bool) {
RTC_IO::regs()
.touch_pad(PIN as usize)
.modify(|_, w| w.fun_ie().bit(enable));
Self {
pin,
phantom: PhantomData,
}
}

/// Sets pull-up enable for the pin
pub fn pullup_enable(&self, enable: bool) {
RTC_IO::regs()
.touch_pad(PIN as usize)
.modify(|_, w| w.rue().bit(enable));
/// Sets pull-up enable for the pin.
pub fn pullup_enable(&mut self, enable: bool) {
self.pin.rtcio_pullup(enable);
}

/// Sets pull-down enable for the pin
pub fn pulldown_enable(&self, enable: bool) {
RTC_IO::regs()
.touch_pad(PIN as usize)
.modify(|_, w| w.rde().bit(enable));
/// Sets pull-down enable for the pin.
pub fn pulldown_enable(&mut self, enable: bool) {
self.pin.rtcio_pulldown(enable);
}
}

/// A GPIO open-drain output pin configured for low power operation
pub struct LowPowerOutputOpenDrain<'d, const PIN: u8> {
/// A GPIO open-drain output pin configured for low power operation.
pub struct LowPowerOutputOpenDrain<'d, P> {
pin: P,
phantom: PhantomData<&'d ()>,
}

impl<'d, const PIN: u8> LowPowerOutputOpenDrain<'d, PIN> {
/// Create a new output pin for use by the low-power core
pub fn new<P>(pin: P) -> Self
where
P: InputPin + OutputPin + RtcPin + 'd,
{
impl<'d, P> LowPowerOutputOpenDrain<'d, P>
where
P: InputPin + OutputPin + RtcPinWithResistors + Pin + 'd,
{
/// Create a new output pin for use by the low-power core.
pub fn new(pin: P) -> Self {
// We can now call trait methods directly on the pin.
pin.rtc_set_config(true, true, RtcFunction::Rtc);

let this = Self {
let mut this = Self {
pin,
phantom: PhantomData,
};

Expand All @@ -143,43 +136,39 @@ impl<'d, const PIN: u8> LowPowerOutputOpenDrain<'d, PIN> {
this
}

fn output_enable(&self, enable: bool) {
fn output_enable(&mut self, enable: bool) {
let rtc_io = RTC_IO::regs();
let rtc_pin = self.pin.rtc_number();

if enable {
rtc_io
.rtc_gpio_enable_w1ts()
.write(|w| unsafe { w.rtc_gpio_enable_w1ts().bits(1 << PIN) });
.write(|w| unsafe { w.rtc_gpio_enable_w1ts().bits(1 << rtc_pin) });
} else {
rtc_io
.enable_w1tc()
.write(|w| unsafe { w.enable_w1tc().bits(1 << PIN) });
.write(|w| unsafe { w.enable_w1tc().bits(1 << rtc_pin) });
}
}

fn input_enable(&self, enable: bool) {
RTC_IO::regs()
.touch_pad(PIN as usize)
.modify(|_, w| w.fun_ie().bit(enable));
fn input_enable(&mut self, enable: bool) {
self.pin.rtc_set_config(enable, true, RtcFunction::Rtc);
}

/// Sets pull-up enable for the pin
pub fn pullup_enable(&self, enable: bool) {
RTC_IO::regs()
.touch_pad(PIN as usize)
.modify(|_, w| w.rue().bit(enable));
pub fn pullup_enable(&mut self, enable: bool) {
self.pin.rtcio_pullup(enable);
}

/// Sets pull-down enable for the pin
pub fn pulldown_enable(&self, enable: bool) {
RTC_IO::regs()
.touch_pad(PIN as usize)
.modify(|_, w| w.rde().bit(enable));
pub fn pulldown_enable(&mut self, enable: bool) {
self.pin.rtcio_pulldown(enable);
}

fn set_open_drain_output(&self, enable: bool) {
fn set_open_drain_output(&mut self, enable: bool) {
let pin_number = self.pin.number();
GPIO::regs()
.pin(PIN as usize)
.pin(pin_number as usize)
.modify(|_, w| w.pad_driver().bit(enable));
}
}
12 changes: 6 additions & 6 deletions esp-hal/src/soc/esp32s3/gpio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,14 @@ macro_rules! rtcio_analog {
$pin_num
}

/// Set the RTC properties of the pin. If `mux` is true then then pin is
/// Set the RTC properties of the pin. If `mux` is true then the pin is
/// routed to RTC, when false it is routed to IO_MUX.
fn rtc_set_config(&self, input_enable: bool, mux: bool, func: $crate::gpio::RtcFunction) {
enable_iomux_clk_gate();

// We need `paste` to rewrite something in each function, so that rustc
// doesn't trip over trying to substitute a partial expression as `$pin_reg`
// Access the RTC_IO register for this pin
$crate::peripherals::[<RTC _IO>]::regs()
.$pin_reg.modify(|_,w| unsafe {
.$pin_reg.modify(|_, w| unsafe {
w.fun_ie().bit(input_enable);
w.mux_sel().bit(mux);
w.fun_sel().bits(func as u8)
Expand Down Expand Up @@ -85,9 +84,10 @@ macro_rules! rtcio_analog {
rtcio.enable_w1tc().write(|w| unsafe { w.enable_w1tc().bits(1 << self.rtc_number()) });

// disable open drain
rtcio.pin(self.rtc_number() as usize).modify(|_,w| w.pad_driver().bit(false));
rtcio.pin(self.rtc_number() as usize).modify(|_, w| w.pad_driver().bit(false));

rtcio.$pin_reg.modify(|_,w| {
// configure pin register
rtcio.$pin_reg.modify(|_, w| {
w.fun_ie().clear_bit();

// Connect pin to analog / RTC module instead of standard GPIO
Expand Down
Loading