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
2 changes: 1 addition & 1 deletion esp-hal/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ For help getting started with this HAL, please refer to [The Rust on ESP Book] a
| --------------- |:-----:|:--------:|:--------:|:--------:|:--------:|:---------:|:--------:|:--------:|:--------:|:--------:|:---------:|
| LEDC | ⚒️ | ⚒️ | ⚒️ | [❌][5161] [^1] | ⚒️ | [❌][5418] [^1] | ⚒️ | ❌ | ⚒️ | ⚒️ | ❌ |
| MCPWM | ⚒️ | | | [❌][5154] [^1] | ⚒️ | | ⚒️ | ❌ | | ⚒️ | ❌ |
| PCNT | ⚒️ | | | ⚒️ | ⚒️ | | ⚒️ | | ⚒️ | ⚒️ | |
| PCNT | ⚒️ | | | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ |
| RTC Timekeeping | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ |
| SDM | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ |
| SYSTIMER | | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ |
Expand Down
22 changes: 2 additions & 20 deletions esp-hal/src/gpio/interrupt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,12 @@
//! (If the user were to clear the interrupt status, we would need to re-enable
//! it, for PinFuture to detect the completion).

use portable_atomic::{AtomicPtr, Ordering};
use portable_atomic::Ordering;
use strum::EnumCount;

use crate::{
gpio::{AnyPin, GPIO_LOCK, GpioBank, InputPin, low_level::set_int_enable},
private::CFnPtr,
ram,
};
#[cfg(feature = "rt")]
Expand All @@ -66,27 +67,8 @@ use crate::{
system::Cpu,
};

/// Convenience constant for `Option::None` pin
pub(super) static USER_INTERRUPT_HANDLER: CFnPtr = CFnPtr::new();

pub(super) struct CFnPtr(AtomicPtr<()>);
impl CFnPtr {
pub const fn new() -> Self {
Self(AtomicPtr::new(core::ptr::null_mut()))
}

pub fn store(&self, f: extern "C" fn()) {
self.0.store(f as *mut (), Ordering::Relaxed);
}

pub fn call(&self) {
let ptr = self.0.load(Ordering::Relaxed);
if !ptr.is_null() {
unsafe { (core::mem::transmute::<*mut (), extern "C" fn()>(ptr))() };
}
}
}

#[cfg(feature = "rt")]
pub(crate) fn bind_default_interrupt_handler() {
// We first check if a handler is set in the vector table.
Expand Down
149 changes: 35 additions & 114 deletions esp-hal/src/pcnt/channel.rs
Original file line number Diff line number Diff line change
@@ -1,36 +1,33 @@
//! # PCNT - Channel Configuration
//!
//! ## Overview
//! The `channel` module allows users to configure and manage individual
//! channels of the `PCNT` peripheral. It provides methods to set various
//! parameters for each channel, such as control modes for signal edges, action
//! on control level, and configurations for positive and negative edge count
//! modes.
//! The `channel` module configures the two channels of a PCNT unit: control
//! modes for signal edges, action on control level, and positive/negative edge
//! count modes.

use core::marker::PhantomData;

#[cfg(not(esp32s31))]
pub use crate::pac::pcnt::unit::conf0::{CTRL_MODE as CtrlMode, EDGE_MODE as EdgeMode};
use crate::{
gpio::{InputSignal, interconnect::PeripheralInput},
peripherals::PCNT,
system::GenericPeripheralGuard,
};
#[cfg(esp32s31)]
pub use crate::peripherals::overlay_pcnt::{CtrlMode, EdgeMode};
use crate::{gpio::interconnect::PeripheralInput, pcnt::AnyPcntUnit, system::PeripheralGuard};

/// Represents a channel within a pulse counter unit.
pub struct Channel<'d, const UNIT: usize, const NUM: usize> {
_phantom: PhantomData<&'d ()>,
pub struct Channel<'d, const NUM: usize> {
unit: AnyPcntUnit<'d>,
// Individual channels are not Send, since they share registers.
_not_send: PhantomData<*const ()>,
_guard: GenericPeripheralGuard<{ crate::system::Peripheral::Pcnt as u8 }>,
_guard: PeripheralGuard,
}

impl<const UNIT: usize, const NUM: usize> Channel<'_, UNIT, NUM> {
/// return a new Channel
pub(super) fn new() -> Self {
let guard = GenericPeripheralGuard::new();
impl<'d, const NUM: usize> Channel<'d, NUM> {
pub(super) fn new(unit: AnyPcntUnit<'d>) -> Self {
const { assert!(NUM < 2) };
let guard = PeripheralGuard::new(unit.info().peripheral);

Self {
_phantom: PhantomData,
unit,
_not_send: PhantomData,
_guard: guard,
}
Expand All @@ -42,8 +39,11 @@ impl<const UNIT: usize, const NUM: usize> Channel<'_, UNIT, NUM> {
/// * `low` - The behaviour of the channel when the control signal is low.
/// * `high` - The behaviour of the channel when the control signal is high.
pub fn set_ctrl_mode(&self, low: CtrlMode, high: CtrlMode) {
let pcnt = PCNT::regs();
let conf0 = pcnt.unit(UNIT).conf0();
let conf0 = self
.unit
.register_block()
.unit(self.unit.info().unit)
.conf0();

conf0.modify(|_, w| {
w.ch_hctrl_mode(NUM as u8).variant(high);
Expand All @@ -57,8 +57,11 @@ impl<const UNIT: usize, const NUM: usize> Channel<'_, UNIT, NUM> {
/// * `neg_edge` - The effect on the counter when the input signal goes 1 -> 0.
/// * `pos_edge` - The effect on the counter when the input signal goes 0 -> 1.
pub fn set_input_mode(&self, neg_edge: EdgeMode, pos_edge: EdgeMode) {
let pcnt = PCNT::regs();
let conf0 = pcnt.unit(UNIT).conf0();
let conf0 = self
.unit
.register_block()
.unit(self.unit.info().unit)
.conf0();

conf0.modify(|_, w| {
w.ch_neg_mode(NUM as u8).variant(neg_edge);
Expand All @@ -67,52 +70,11 @@ impl<const UNIT: usize, const NUM: usize> Channel<'_, UNIT, NUM> {
}

/// Set the control signal (pin/high/low) for this channel
pub fn set_ctrl_signal<'d>(&self, source: impl PeripheralInput<'d>) -> &Self {
let signal = match UNIT {
0 => match NUM {
0 => InputSignal::PCNT0_CTRL_CH0,
1 => InputSignal::PCNT0_CTRL_CH1,
_ => unreachable!(),
},
1 => match NUM {
0 => InputSignal::PCNT1_CTRL_CH0,
1 => InputSignal::PCNT1_CTRL_CH1,
_ => unreachable!(),
},
2 => match NUM {
0 => InputSignal::PCNT2_CTRL_CH0,
1 => InputSignal::PCNT2_CTRL_CH1,
_ => unreachable!(),
},
3 => match NUM {
0 => InputSignal::PCNT3_CTRL_CH0,
1 => InputSignal::PCNT3_CTRL_CH1,
_ => unreachable!(),
},
#[cfg(esp32)]
4 => match NUM {
0 => InputSignal::PCNT4_CTRL_CH0,
1 => InputSignal::PCNT4_CTRL_CH1,
_ => unreachable!(),
},
#[cfg(esp32)]
5 => match NUM {
0 => InputSignal::PCNT5_CTRL_CH0,
1 => InputSignal::PCNT5_CTRL_CH1,
_ => unreachable!(),
},
#[cfg(esp32)]
6 => match NUM {
0 => InputSignal::PCNT6_CTRL_CH0,
1 => InputSignal::PCNT6_CTRL_CH1,
_ => unreachable!(),
},
#[cfg(esp32)]
7 => match NUM {
0 => InputSignal::PCNT7_CTRL_CH0,
1 => InputSignal::PCNT7_CTRL_CH1,
_ => unreachable!(),
},
pub fn set_ctrl_signal<'p>(&self, source: impl PeripheralInput<'p>) -> &Self {
let info = self.unit.info();
let signal = match NUM {
0 => info.ctrl_ch0,
1 => info.ctrl_ch1,
_ => unreachable!(),
};

Expand All @@ -127,52 +89,11 @@ impl<const UNIT: usize, const NUM: usize> Channel<'_, UNIT, NUM> {
}

/// Set the edge signal (pin/high/low) for this channel
pub fn set_edge_signal<'d>(&self, source: impl PeripheralInput<'d>) -> &Self {
let signal = match UNIT {
0 => match NUM {
0 => InputSignal::PCNT0_SIG_CH0,
1 => InputSignal::PCNT0_SIG_CH1,
_ => unreachable!(),
},
1 => match NUM {
0 => InputSignal::PCNT1_SIG_CH0,
1 => InputSignal::PCNT1_SIG_CH1,
_ => unreachable!(),
},
2 => match NUM {
0 => InputSignal::PCNT2_SIG_CH0,
1 => InputSignal::PCNT2_SIG_CH1,
_ => unreachable!(),
},
3 => match NUM {
0 => InputSignal::PCNT3_SIG_CH0,
1 => InputSignal::PCNT3_SIG_CH1,
_ => unreachable!(),
},
#[cfg(esp32)]
4 => match NUM {
0 => InputSignal::PCNT4_SIG_CH0,
1 => InputSignal::PCNT4_SIG_CH1,
_ => unreachable!(),
},
#[cfg(esp32)]
5 => match NUM {
0 => InputSignal::PCNT5_SIG_CH0,
1 => InputSignal::PCNT5_SIG_CH1,
_ => unreachable!(),
},
#[cfg(esp32)]
6 => match NUM {
0 => InputSignal::PCNT6_SIG_CH0,
1 => InputSignal::PCNT6_SIG_CH1,
_ => unreachable!(),
},
#[cfg(esp32)]
7 => match NUM {
0 => InputSignal::PCNT7_SIG_CH0,
1 => InputSignal::PCNT7_SIG_CH1,
_ => unreachable!(),
},
pub fn set_edge_signal<'p>(&self, source: impl PeripheralInput<'p>) -> &Self {
let info = self.unit.info();
let signal = match NUM {
0 => info.sig_ch0,
1 => info.sig_ch1,
_ => unreachable!(),
};

Expand Down
Loading