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 <scott@mabez.dev>
This commit is contained in:
Kirill Mikhailov 2024-04-05 17:16:11 +02:00 committed by GitHub
parent 1e6165e04b
commit 52e5b94bd5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 25 additions and 40 deletions

View File

@ -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) - 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 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) - 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) - Runtime ISR binding for RTC (#1405)
### Removed ### Removed

View File

@ -34,7 +34,7 @@
//! //!
//! // setup a pulse couter //! // setup a pulse couter
//! println!("setup pulse counter unit 0"); //! 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); //! let mut u0 = pcnt.get_unit(unit_number);
//! u0.configure(unit::Config { //! u0.configure(unit::Config {
//! low_limit: -100, //! low_limit: -100,
@ -93,8 +93,6 @@
//! //!
//! critical_section::with(|cs| UNIT0.borrow_ref_mut(cs).replace(u0)); //! 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; //! let mut last_value: i32 = 0;
//! loop { //! loop {
//! critical_section::with(|cs| { //! critical_section::with(|cs| {
@ -111,8 +109,8 @@
//! //!
//! Where the `PCNT` interrupt handler is defined as: //! Where the `PCNT` interrupt handler is defined as:
//! ```no_run //! ```no_run
//! #[interrupt] //! #[handler(priority = esp_hal::interrupt::Priority::Priority2)]
//! fn PCNT() { //! fn interrupt_handler() {
//! critical_section::with(|cs| { //! critical_section::with(|cs| {
//! let mut u0 = UNIT0.borrow_ref_mut(cs); //! let mut u0 = UNIT0.borrow_ref_mut(cs);
//! let u0 = u0.as_mut().unwrap(); //! let u0 = u0.as_mut().unwrap();
@ -134,7 +132,9 @@
use self::unit::Unit; use self::unit::Unit;
use crate::{ use crate::{
interrupt::{self, InterruptHandler},
peripheral::{Peripheral, PeripheralRef}, peripheral::{Peripheral, PeripheralRef},
peripherals::{self, Interrupt},
system::PeripheralClockControl, system::PeripheralClockControl,
}; };
@ -142,16 +142,26 @@ pub mod channel;
pub mod unit; pub mod unit;
pub struct PCNT<'d> { pub struct PCNT<'d> {
_instance: PeripheralRef<'d, crate::peripherals::PCNT>, _instance: PeripheralRef<'d, peripherals::PCNT>,
} }
impl<'d> PCNT<'d> { impl<'d> PCNT<'d> {
/// Return a new PCNT /// Return a new PCNT
pub fn new(_instance: impl Peripheral<P = crate::peripherals::PCNT> + 'd) -> Self { pub fn new(
_instance: impl Peripheral<P = peripherals::PCNT> + 'd,
interrupt: Option<InterruptHandler>,
) -> Self {
crate::into_ref!(_instance); crate::into_ref!(_instance);
// Enable the PCNT peripherals clock in the system peripheral // Enable the PCNT peripherals clock in the system peripheral
PeripheralClockControl::enable(crate::system::Peripheral::Pcnt); 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 } PCNT { _instance }
} }

View File

@ -35,6 +35,7 @@ lis3dh-async = "0.9.2"
nb = "1.1.0" nb = "1.1.0"
p192 = { version = "0.13.0", default-features = false, features = ["arithmetic"] } p192 = { version = "0.13.0", default-features = false, features = ["arithmetic"] }
p256 = { version = "0.13.2", 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} sha2 = { version = "0.10.8", default-features = false}
smart-leds = "0.4.0" smart-leds = "0.4.0"
ssd1306 = "0.8.4" ssd1306 = "0.8.4"

View File

@ -11,22 +11,19 @@
#![no_std] #![no_std]
#![no_main] #![no_main]
use core::{ use core::{cell::RefCell, cmp::min, sync::atomic::Ordering};
cell::RefCell,
cmp::min,
sync::atomic::{AtomicI32, Ordering},
};
use critical_section::Mutex; use critical_section::Mutex;
use esp_backtrace as _; use esp_backtrace as _;
use esp_hal::{ use esp_hal::{
gpio::IO, gpio::IO,
interrupt::{self, Priority}, interrupt::Priority,
pcnt::{channel, channel::PcntSource, unit, PCNT}, pcnt::{channel, channel::PcntSource, unit, PCNT},
peripherals::{Interrupt, Peripherals}, peripherals::Peripherals,
prelude::*, prelude::*,
}; };
use esp_println::println; use esp_println::println;
use portable_atomic::AtomicI32;
static UNIT0: Mutex<RefCell<Option<unit::Unit>>> = Mutex::new(RefCell::new(None)); static UNIT0: Mutex<RefCell<Option<unit::Unit>>> = Mutex::new(RefCell::new(None));
static VALUE: AtomicI32 = AtomicI32::new(0); static VALUE: AtomicI32 = AtomicI32::new(0);
@ -39,7 +36,7 @@ fn main() -> ! {
// Set up a pulse counter: // Set up a pulse counter:
println!("setup pulse counter unit 0"); 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); let mut u0 = pcnt.get_unit(unit::Number::Unit1);
u0.configure(unit::Config { u0.configure(unit::Config {
low_limit: -100, low_limit: -100,
@ -97,8 +94,6 @@ fn main() -> ! {
critical_section::with(|cs| UNIT0.borrow_ref_mut(cs).replace(u0)); critical_section::with(|cs| UNIT0.borrow_ref_mut(cs).replace(u0));
interrupt::enable(Interrupt::PCNT, Priority::Priority2).unwrap();
let mut last_value: i32 = 0; let mut last_value: i32 = 0;
loop { loop {
critical_section::with(|cs| { critical_section::with(|cs| {
@ -113,7 +108,7 @@ fn main() -> ! {
} }
} }
#[cfg(not(feature = "esp32s2"))] #[handler(priority = Priority::Priority2)]
fn interrupt_handler() { fn interrupt_handler() {
critical_section::with(|cs| { critical_section::with(|cs| {
let mut u0 = UNIT0.borrow_ref_mut(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();
}