From 52e5b94bd5c1896f5b05bbf1a46230063e2703c7 Mon Sep 17 00:00:00 2001 From: Kirill Mikhailov <62840029+playfulFence@users.noreply.github.com> Date: Fri, 5 Apr 2024 17:16:11 +0200 Subject: [PATCH] PCNT: Runtime ISR binding (#1396) * PCNT: Runtime ISR binding * Changelog entry * fmt + warnings * Unify `interrupt_handler` + alignment with latest changes --------- Co-authored-by: Scott Mabin --- esp-hal/CHANGELOG.md | 1 + esp-hal/src/pcnt/mod.rs | 24 ++++++++++++++------ examples/Cargo.toml | 1 + examples/src/bin/pcnt_encoder.rs | 39 +++++--------------------------- 4 files changed, 25 insertions(+), 40 deletions(-) diff --git a/esp-hal/CHANGELOG.md b/esp-hal/CHANGELOG.md index 96150e30e..ff635de5a 100644 --- a/esp-hal/CHANGELOG.md +++ b/esp-hal/CHANGELOG.md @@ -57,6 +57,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - ESP32-C6: The `gpio::lp_gpio` module has been renamed to `gpio::lp_io` to match the peripheral name (#1397) - Runtime ISR binding for assist_debug (#1395) - Runtime ISR binding for software interrupts, software interrupts are split now, interrupt-executor takes the software interrupt to use, interrupt-executor is easier to use (#1398) +- PCNT: Runtime ISR binding (#1396) - Runtime ISR binding for RTC (#1405) ### Removed diff --git a/esp-hal/src/pcnt/mod.rs b/esp-hal/src/pcnt/mod.rs index 41784d956..64fed30a1 100644 --- a/esp-hal/src/pcnt/mod.rs +++ b/esp-hal/src/pcnt/mod.rs @@ -34,7 +34,7 @@ //! //! // setup a pulse couter //! println!("setup pulse counter unit 0"); -//! let pcnt = PCNT::new(peripherals.PCNT); +//! let pcnt = PCNT::new(peripherals.PCNT, Some(interrupt_handler)); //! let mut u0 = pcnt.get_unit(unit_number); //! u0.configure(unit::Config { //! low_limit: -100, @@ -93,8 +93,6 @@ //! //! critical_section::with(|cs| UNIT0.borrow_ref_mut(cs).replace(u0)); //! -//! interrupt::enable(peripherals::Interrupt::PCNT, interrupt::Priority::Priority2).unwrap(); -//! //! let mut last_value: i32 = 0; //! loop { //! critical_section::with(|cs| { @@ -111,8 +109,8 @@ //! //! Where the `PCNT` interrupt handler is defined as: //! ```no_run -//! #[interrupt] -//! fn PCNT() { +//! #[handler(priority = esp_hal::interrupt::Priority::Priority2)] +//! fn interrupt_handler() { //! critical_section::with(|cs| { //! let mut u0 = UNIT0.borrow_ref_mut(cs); //! let u0 = u0.as_mut().unwrap(); @@ -134,7 +132,9 @@ use self::unit::Unit; use crate::{ + interrupt::{self, InterruptHandler}, peripheral::{Peripheral, PeripheralRef}, + peripherals::{self, Interrupt}, system::PeripheralClockControl, }; @@ -142,16 +142,26 @@ pub mod channel; pub mod unit; pub struct PCNT<'d> { - _instance: PeripheralRef<'d, crate::peripherals::PCNT>, + _instance: PeripheralRef<'d, peripherals::PCNT>, } impl<'d> PCNT<'d> { /// Return a new PCNT - pub fn new(_instance: impl Peripheral

+ 'd) -> Self { + pub fn new( + _instance: impl Peripheral

+ 'd, + interrupt: Option, + ) -> Self { crate::into_ref!(_instance); // Enable the PCNT peripherals clock in the system peripheral PeripheralClockControl::enable(crate::system::Peripheral::Pcnt); + if let Some(interrupt) = interrupt { + unsafe { + interrupt::bind_interrupt(Interrupt::PCNT, interrupt.handler()); + interrupt::enable(Interrupt::PCNT, interrupt.priority()).unwrap(); + } + } + PCNT { _instance } } diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 3886fe230..0b2545acb 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -35,6 +35,7 @@ lis3dh-async = "0.9.2" nb = "1.1.0" p192 = { version = "0.13.0", default-features = false, features = ["arithmetic"] } p256 = { version = "0.13.2", default-features = false, features = ["arithmetic"] } +portable-atomic = { version = "1.6.0", default-features = false } sha2 = { version = "0.10.8", default-features = false} smart-leds = "0.4.0" ssd1306 = "0.8.4" diff --git a/examples/src/bin/pcnt_encoder.rs b/examples/src/bin/pcnt_encoder.rs index 01a83f892..bd5d39109 100644 --- a/examples/src/bin/pcnt_encoder.rs +++ b/examples/src/bin/pcnt_encoder.rs @@ -11,22 +11,19 @@ #![no_std] #![no_main] -use core::{ - cell::RefCell, - cmp::min, - sync::atomic::{AtomicI32, Ordering}, -}; +use core::{cell::RefCell, cmp::min, sync::atomic::Ordering}; use critical_section::Mutex; use esp_backtrace as _; use esp_hal::{ gpio::IO, - interrupt::{self, Priority}, + interrupt::Priority, pcnt::{channel, channel::PcntSource, unit, PCNT}, - peripherals::{Interrupt, Peripherals}, + peripherals::Peripherals, prelude::*, }; use esp_println::println; +use portable_atomic::AtomicI32; static UNIT0: Mutex>> = Mutex::new(RefCell::new(None)); static VALUE: AtomicI32 = AtomicI32::new(0); @@ -39,7 +36,7 @@ fn main() -> ! { // Set up a pulse counter: println!("setup pulse counter unit 0"); - let pcnt = PCNT::new(peripherals.PCNT); + let pcnt = PCNT::new(peripherals.PCNT, Some(interrupt_handler)); let mut u0 = pcnt.get_unit(unit::Number::Unit1); u0.configure(unit::Config { low_limit: -100, @@ -97,8 +94,6 @@ fn main() -> ! { critical_section::with(|cs| UNIT0.borrow_ref_mut(cs).replace(u0)); - interrupt::enable(Interrupt::PCNT, Priority::Priority2).unwrap(); - let mut last_value: i32 = 0; loop { critical_section::with(|cs| { @@ -113,7 +108,7 @@ fn main() -> ! { } } -#[cfg(not(feature = "esp32s2"))] +#[handler(priority = Priority::Priority2)] fn interrupt_handler() { critical_section::with(|cs| { let mut u0 = UNIT0.borrow_ref_mut(cs); @@ -129,25 +124,3 @@ fn interrupt_handler() { } }); } - -#[cfg(feature = "esp32s2")] -fn interrupt_handler() { - critical_section::with(|cs| { - let mut u0 = UNIT0.borrow_ref_mut(cs); - let u0 = u0.as_mut().unwrap(); - if u0.interrupt_set() { - let events = u0.get_events(); - if events.high_limit { - VALUE.store(VALUE.load(Ordering::SeqCst) + 100, Ordering::SeqCst); - } else if events.low_limit { - VALUE.store(VALUE.load(Ordering::SeqCst) - 100, Ordering::SeqCst); - } - u0.reset_interrupt(); - } - }); -} - -#[interrupt] -fn PCNT() { - interrupt_handler(); -}