main: first implementation of a way to handle interrupts from sensors. untested!!

This commit is contained in:
2026-03-11 13:59:56 +01:00
parent 94144ab4b3
commit ccb2680954
4 changed files with 89 additions and 5 deletions

62
src/gpio_interrupt.rs Normal file
View File

@@ -0,0 +1,62 @@
use core::cell::RefCell;
use alloc::sync::Arc;
use critical_section::Mutex;
use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, signal::Signal};
use esp_hal::gpio::Input;
pub struct InterruptDispatch<'a, const COUNT: usize> {
interrupts: [PinInterrupt<'a>; COUNT]
}
impl<'a, const COUNT: usize> InterruptDispatch<'a, COUNT> {
pub fn new(interrupts: [PinInterrupt<'a>; COUNT]) -> Self {
Self { interrupts }
}
pub fn process_interrupts(&self) {
for interrupt in &self.interrupts {
interrupt.handle_interrupt();
}
}
}
#[derive(Clone)]
pub struct PinInterrupt<'a> {
pin: Arc<Mutex<RefCell<Input<'a>>>>,
signal: Arc<Signal<CriticalSectionRawMutex, esp_hal::gpio::Level>>,
event: esp_hal::gpio::Event
}
impl<'a> PinInterrupt<'a> {
pub fn new(pin: Input<'a>, event: esp_hal::gpio::Event) -> Self {
Self {
pin: Arc::new(Mutex::new(RefCell::new(pin))),
signal: Arc::new(Signal::new()),
event
}
}
pub fn handle_interrupt(&self) {
critical_section::with(|cs| {
let locked = self.pin.borrow(cs);
let mut pin = locked.borrow_mut();
if pin.is_interrupt_set() {
pin.clear_interrupt();
self.signal.signal(pin.level());
}
});
}
pub fn listen(&self) {
critical_section::with(|cs| {
let locked = self.pin.borrow(cs);
let mut pin = locked.borrow_mut();
pin.listen(self.event);
});
}
pub async fn wait_for_interrupt(&self) -> esp_hal::gpio::Level {
self.signal.wait().await
}
}