ariel_os_nrf/
extint_registry.rs1use ariel_os_embassy_common::gpio::input::InterruptError;
2use embassy_nrf::{gpio::Pin, Peripheral};
3use portable_atomic::{AtomicU8, Ordering};
4
5#[cfg(context = "nrf51")]
6const INT_CHANNEL_COUNT: u8 = 4;
7#[cfg(not(context = "nrf51"))]
8const INT_CHANNEL_COUNT: u8 = 8;
9
10pub static EXTINT_REGISTRY: ExtIntRegistry = ExtIntRegistry::new();
11
12pub struct ExtIntRegistry {
13 used_interrupt_channel_count: AtomicU8,
14}
15
16impl ExtIntRegistry {
17 #[expect(clippy::new_without_default)]
18 #[must_use]
19 pub const fn new() -> Self {
20 Self {
21 used_interrupt_channel_count: AtomicU8::new(0),
22 }
23 }
24
25 pub fn use_interrupt_for_pin<PIN: Peripheral<P: Pin>>(
26 &self,
27 _pin: &mut PIN, ) -> Result<(), InterruptError> {
29 let update_res = self.used_interrupt_channel_count.fetch_update(
31 Ordering::AcqRel,
32 Ordering::Acquire,
33 |c| {
34 if c == INT_CHANNEL_COUNT {
35 None
36 } else {
37 Some(c + 1)
39 }
40 },
41 );
42
43 if update_res.is_err() {
44 return Err(InterruptError::NoIntChannelAvailable);
45 }
46
47 Ok(())
48 }
49}