Skip to content

Commit

Permalink
Work with GPIO signals
Browse files Browse the repository at this point in the history
  • Loading branch information
bugadani committed Nov 4, 2024
1 parent 885e2bd commit ff92b5f
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 42 deletions.
3 changes: 3 additions & 0 deletions esp-hal/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `gpio::{GpioPin, AnyPin, Flex, Output, OutputOpenDrain}::split()` to obtain peripheral interconnect signals. (#2418)
- `gpio::Input::{split(), into_peripheral_output()}` when used with output pins. (#2418)
- `gpio::Output::peripheral_input()` (#2418)
- GPIO ETM tasks and events now accept `InputSignal` and `OutputSignal` (#2427)

### Changed

Expand Down Expand Up @@ -73,11 +74,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Removed the pin type parameters from `lcd_cam::cam::{RxEightBits, RxSixteenBits}` (#2388)
- Most of the async-specific constructors (`new_async`, `new_async_no_transceiver`) have been removed. (#2430)
- The `configure_for_async` DMA functions have been removed (#2430)
- `gpio::{Input, Output, OutputOpenDrain, Flex, GpioPin}::{peripheral_input, into_peripheral_output}` have been removed. (#2418)
- The `GpioEtm` prefix has been removed from `gpio::etm` types (#2427)
- The `TimerEtm` prefix has been removed from `timer::timg::etm` types (#2427)
- The `SysTimerEtm` prefix has been removed from `timer::systimer::etm` types (#2427)
- The `GpioEtmEventRising`, `GpioEtmEventFalling`, `GpioEtmEventAny` types have been replaced with `Event` (#2427)
- The `TaskSet`, `TaskClear`, `TaskToggle` types have been replaced with `Event` (#2427)
- The `TaskSet`, `TaskClear`, `TaskToggle` types have been replaced with `Task` (#2427)

## [0.21.1]

Expand Down
2 changes: 1 addition & 1 deletion esp-hal/MIGRATING-0.21.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ The previous signal function have been replaced by `split`. This change affects
`into_peripheral_output`, `split` (for output pins only) and `peripheral_input` have been added to
the GPIO drivers (`Input`, `Output`, `OutputOpenDrain` and `Flex`) instead.

# ETM simplifications
## ETM changes

- The types are no longer prefixed with `GpioEtm`, `TimerEtm` or `SysTimerEtm`. You can still use
import aliasses in case you need to differentiate due to name collisions
Expand Down
20 changes: 9 additions & 11 deletions esp-hal/src/etm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,8 @@
//! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::gpio::Io;
//! # use esp_hal::gpio::etm::GpioEtmChannels;
//! # use esp_hal::gpio::etm::{Channels, InputConfig, OutputConfig};
//! # use esp_hal::etm::Etm;
//! # use esp_hal::gpio::etm::GpioEtmInputConfig;
//! # use esp_hal::gpio::etm::GpioEtmOutputConfig;
//! # use esp_hal::gpio::Pull;
//! # use esp_hal::gpio::Level;
//!
Expand All @@ -36,18 +34,18 @@
//! let button = io.pins.gpio9;
//!
//! // setup ETM
//! let gpio_ext = GpioEtmChannels::new(peripherals.GPIO_SD);
//! let gpio_ext = Channels::new(peripherals.GPIO_SD);
//! let led_task = gpio_ext.channel0_task.toggle(
//! &mut led,
//! GpioEtmOutputConfig {
//! open_drain: false,
//! pull: Pull::None,
//! initial_state: Level::Low,
//! },
//! &mut led,
//! OutputConfig {
//! open_drain: false,
//! pull: Pull::None,
//! initial_state: Level::Low,
//! },
//! );
//! let button_event = gpio_ext
//! .channel0_event
//! .falling_edge(button, GpioEtmInputConfig { pull: Pull::Down });
//! .falling_edge(button, InputConfig { pull: Pull::Down });
//!
//! let etm = Etm::new(peripherals.SOC_ETM);
//! let channel0 = etm.channel0;
Expand Down
28 changes: 16 additions & 12 deletions esp-hal/src/gpio/etm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
//! # use esp_hal::gpio::etm::OutputConfig;
//! # use esp_hal::gpio::Pull;
//! # use esp_hal::gpio::Level;
//!
//! #
//! # let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
//! # let mut led = io.pins.gpio1;
//! # let button = io.pins.gpio9;
Expand All @@ -55,7 +55,11 @@
use core::marker::PhantomData;

use crate::{
gpio::{Level, Pull},
gpio::{
interconnect::{InputSignal, OutputSignal},
Level,
Pull,
},
peripheral::{Peripheral, PeripheralRef},
peripherals::GPIO_SD,
private,
Expand Down Expand Up @@ -147,7 +151,7 @@ impl<const C: u8> EventChannel<C> {
/// Trigger at rising edge
pub fn rising_edge<'d>(
self,
pin: impl Peripheral<P = impl super::InputPin> + 'd,
pin: impl Peripheral<P = impl Into<InputSignal>> + 'd,
pin_config: InputConfig,
) -> Event<'d> {
self.into_event(pin, pin_config, EventKind::Rising)
Expand All @@ -156,7 +160,7 @@ impl<const C: u8> EventChannel<C> {
/// Trigger at falling edge
pub fn falling_edge<'d>(
self,
pin: impl Peripheral<P = impl super::InputPin> + 'd,
pin: impl Peripheral<P = impl Into<InputSignal>> + 'd,
pin_config: InputConfig,
) -> Event<'d> {
self.into_event(pin, pin_config, EventKind::Falling)
Expand All @@ -165,19 +169,19 @@ impl<const C: u8> EventChannel<C> {
/// Trigger at any edge
pub fn any_edge<'d>(
self,
pin: impl Peripheral<P = impl super::InputPin> + 'd,
pin: impl Peripheral<P = impl Into<InputSignal>> + 'd,
pin_config: InputConfig,
) -> Event<'d> {
self.into_event(pin, pin_config, EventKind::Any)
}

fn into_event<'d>(
self,
pin: impl Peripheral<P = impl super::InputPin> + 'd,
pin: impl Peripheral<P = impl Into<InputSignal>> + 'd,
pin_config: InputConfig,
kind: EventKind,
) -> Event<'d> {
crate::into_ref!(pin);
crate::into_mapped_ref!(pin);

pin.init_input(pin_config.pull, private::Internal);

Expand Down Expand Up @@ -255,7 +259,7 @@ impl<const C: u8> TaskChannel<C> {
/// Task to set a high level
pub fn set<'d>(
self,
pin: impl Peripheral<P = impl super::OutputPin> + 'd,
pin: impl Peripheral<P = impl Into<OutputSignal>> + 'd,
pin_config: OutputConfig,
) -> Task<'d> {
self.into_task(pin, pin_config, TaskKind::Set)
Expand All @@ -264,7 +268,7 @@ impl<const C: u8> TaskChannel<C> {
/// Task to set a low level
pub fn clear<'d>(
self,
pin: impl Peripheral<P = impl super::OutputPin> + 'd,
pin: impl Peripheral<P = impl Into<OutputSignal>> + 'd,
pin_config: OutputConfig,
) -> Task<'d> {
self.into_task(pin, pin_config, TaskKind::Clear)
Expand All @@ -273,19 +277,19 @@ impl<const C: u8> TaskChannel<C> {
/// Task to toggle the level
pub fn toggle<'d>(
self,
pin: impl Peripheral<P = impl super::OutputPin> + 'd,
pin: impl Peripheral<P = impl Into<OutputSignal>> + 'd,
pin_config: OutputConfig,
) -> Task<'d> {
self.into_task(pin, pin_config, TaskKind::Toggle)
}

fn into_task<'d>(
self,
pin: impl Peripheral<P = impl super::OutputPin> + 'd,
pin: impl Peripheral<P = impl Into<OutputSignal>> + 'd,
pin_config: OutputConfig,
kind: TaskKind,
) -> Task<'d> {
crate::into_ref!(pin);
crate::into_mapped_ref!(pin);

pin.set_output_high(pin_config.initial_state.into(), private::Internal);
if pin_config.open_drain {
Expand Down
40 changes: 30 additions & 10 deletions esp-hal/src/gpio/interconnect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,15 @@ pub struct InputSignal {
is_inverted: bool,
}

impl<P> From<P> for InputSignal
where
P: InputPin,
{
fn from(input: P) -> Self {
Self::new(input.degrade())
}
}

impl Clone for InputSignal {
fn clone(&self) -> Self {
Self {
Expand Down Expand Up @@ -87,6 +96,11 @@ impl InputSignal {
}
}

/// Returns the GPIO number of the underlying pin.
pub fn number(&self) -> u8 {
self.pin.number()
}

/// Returns the current signal level.
pub fn get_level(&self) -> Level {
self.is_input_high(private::Internal).into()
Expand Down Expand Up @@ -120,9 +134,7 @@ impl InputSignal {
w.in_sel().bits(input)
});
}
}

impl InputSignal {
/// Connect the pin to a peripheral input signal.
///
/// Since there can only be one input signal connected to a peripheral at a
Expand Down Expand Up @@ -191,6 +203,15 @@ pub struct OutputSignal {
is_inverted: bool,
}

impl<P> From<P> for OutputSignal
where
P: OutputPin,
{
fn from(input: P) -> Self {
Self::new(input.degrade())
}
}

impl Peripheral for OutputSignal {
type P = Self;

Expand All @@ -212,6 +233,11 @@ impl OutputSignal {
}
}

/// Returns the GPIO number of the underlying pin.
pub fn number(&self) -> u8 {
self.pin.number()
}

/// Inverts the peripheral's output signal.
///
/// Calling this function multiple times toggles the setting.
Expand Down Expand Up @@ -268,9 +294,7 @@ impl OutputSignal {
w.oen_inv_sel().bit(invert_enable)
});
}
}

impl OutputSignal {
/// Connect the pin to a peripheral input signal.
///
/// Since there can only be one signal connected to a peripheral input at a
Expand Down Expand Up @@ -434,9 +458,7 @@ where
P: InputPin,
{
fn from(input: P) -> Self {
Self(InputConnectionInner::Input(InputSignal::new(
input.degrade(),
)))
Self(InputConnectionInner::Input(InputSignal::from(input)))
}
}

Expand Down Expand Up @@ -527,9 +549,7 @@ where
P: OutputPin,
{
fn from(input: P) -> Self {
Self(OutputConnectionInner::Output(OutputSignal::new(
input.degrade(),
)))
Self(OutputConnectionInner::Output(OutputSignal::from(input)))
}
}

Expand Down
6 changes: 3 additions & 3 deletions examples/src/bin/etm_blinky_systimer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use esp_backtrace as _;
use esp_hal::{
etm::Etm,
gpio::{
etm::{GpioEtmChannels, GpioEtmOutputConfig},
etm::{Channels, OutputConfig},
Io,
Level,
Pull,
Expand All @@ -35,10 +35,10 @@ fn main() -> ! {
let mut led = io.pins.gpio1;

// setup ETM
let gpio_ext = GpioEtmChannels::new(peripherals.GPIO_SD);
let gpio_ext = Channels::new(peripherals.GPIO_SD);
let led_task = gpio_ext.channel0_task.toggle(
&mut led,
GpioEtmOutputConfig {
OutputConfig {
open_drain: false,
pull: Pull::None,
initial_state: Level::High,
Expand Down
11 changes: 6 additions & 5 deletions examples/src/bin/etm_gpio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use esp_backtrace as _;
use esp_hal::{
etm::Etm,
gpio::{
etm::{GpioEtmChannels, GpioEtmInputConfig, GpioEtmOutputConfig},
etm::{Channels, InputConfig, OutputConfig},
Io,
Level,
Output,
Expand All @@ -26,24 +26,25 @@ fn main() -> ! {
let peripherals = esp_hal::init(esp_hal::Config::default());

let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);

let mut led = Output::new(io.pins.gpio1, Level::Low);
let button = io.pins.gpio9;

led.set_high();

// setup ETM
let gpio_ext = GpioEtmChannels::new(peripherals.GPIO_SD);
let gpio_ext = Channels::new(peripherals.GPIO_SD);
let led_task = gpio_ext.channel0_task.toggle(
&mut led,
GpioEtmOutputConfig {
led,
OutputConfig {
open_drain: false,
pull: Pull::None,
initial_state: Level::Low,
},
);
let button_event = gpio_ext
.channel0_event
.falling_edge(button, GpioEtmInputConfig { pull: Pull::Down });
.falling_edge(button, InputConfig { pull: Pull::Down });

let etm = Etm::new(peripherals.SOC_ETM);
let channel0 = etm.channel0;
Expand Down

0 comments on commit ff92b5f

Please sign in to comment.