use super::{ChId, Channel};
use crate::pac;
mod pin;
impl<Id: ChId, F> Channel<Id, F> {
fn with_disable(&mut self, fun: impl Fn(&mut pac::Eic)) {
self.eic.ctrl().modify(|_, w| w.enable().clear_bit());
self.enable_sync();
fun(&mut self.eic);
self.eic.ctrl().modify(|_, w| w.enable().set_bit());
self.enable_sync();
}
fn enable_sync(&mut self) {
while self.eic.status().read().syncbusy().bit_is_set() {
core::hint::spin_loop();
}
}
}
#[cfg(feature = "async")]
pub(super) mod async_api {
use crate::async_hal::interrupts::{Binding, EIC as EicInterrupt, Handler, Interrupt};
use crate::eic::{Eic, EicFuture, NUM_CHANNELS};
use crate::pac;
use crate::util::BitIter;
use core::marker::PhantomData;
use embassy_sync::waitqueue::AtomicWaker;
pub struct InterruptHandler {
_private: (),
}
impl crate::typelevel::Sealed for InterruptHandler {}
impl Handler<EicInterrupt> for InterruptHandler {
unsafe fn on_interrupt() {
let eic = unsafe { pac::Peripherals::steal().eic };
let pending_interrupts = BitIter(eic.intflag().read().bits());
for channel in pending_interrupts {
let mask = 1 << channel;
eic.intenclr().write(|w| unsafe { w.bits(mask) });
WAKERS[channel as usize].wake();
}
}
}
impl Eic {
pub fn into_future<I>(self, _irq: I) -> Eic<EicFuture>
where
I: Binding<EicInterrupt, InterruptHandler>,
{
EicInterrupt::unpend();
unsafe { EicInterrupt::enable() };
Eic {
eic: self.eic,
_irqs: PhantomData,
}
}
}
#[allow(clippy::declare_interior_mutable_const)]
const NEW_WAKER: AtomicWaker = AtomicWaker::new();
pub(super) static WAKERS: [AtomicWaker; NUM_CHANNELS] = [NEW_WAKER; NUM_CHANNELS];
}