main: first implementation of a way to handle interrupts from sensors. untested!!
This commit is contained in:
62
src/gpio_interrupt.rs
Normal file
62
src/gpio_interrupt.rs
Normal 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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user