ariel_os_stm32/
extint_registry.rs1use ariel_os_embassy_common::gpio::input::InterruptError;
2use embassy_stm32::{
3 exti::{AnyChannel, Channel},
4 gpio::Pin,
5 peripherals, OptionalPeripherals, Peripheral,
6};
7use portable_atomic::{AtomicBool, AtomicU16, Ordering};
8
9pub static EXTINT_REGISTRY: ExtIntRegistry = ExtIntRegistry::new();
10
11pub struct ExtIntRegistry {
12 initialized: AtomicBool,
13 used_interrupt_channels: AtomicU16, }
15
16impl ExtIntRegistry {
17 const fn new() -> Self {
19 Self {
20 initialized: AtomicBool::new(false),
21 used_interrupt_channels: AtomicU16::new(0),
22 }
23 }
24
25 pub fn init(&self, peripherals: &mut OptionalPeripherals) {
26 peripherals.EXTI0.take().unwrap();
27 peripherals.EXTI1.take().unwrap();
28 peripherals.EXTI2.take().unwrap();
29 peripherals.EXTI3.take().unwrap();
30 peripherals.EXTI4.take().unwrap();
31 peripherals.EXTI5.take().unwrap();
32 peripherals.EXTI6.take().unwrap();
33 peripherals.EXTI7.take().unwrap();
34 peripherals.EXTI8.take().unwrap();
35 peripherals.EXTI9.take().unwrap();
36 peripherals.EXTI10.take().unwrap();
37 peripherals.EXTI11.take().unwrap();
38 peripherals.EXTI12.take().unwrap();
39 peripherals.EXTI13.take().unwrap();
40 peripherals.EXTI14.take().unwrap();
41 peripherals.EXTI15.take().unwrap();
42
43 self.initialized.store(true, Ordering::Release);
44
45 }
47
48 pub fn get_interrupt_channel_for_pin<P: Peripheral<P = T>, T: Pin>(
49 &self,
50 pin: P,
51 ) -> Result<AnyChannel, InterruptError> {
52 assert!(self.initialized.load(Ordering::Acquire));
54
55 let pin = pin.into_ref().map_into();
56 let pin_number = pin.pin();
57
58 let was_used = self
64 .used_interrupt_channels
65 .bit_set(pin_number.into(), Ordering::Relaxed);
66
67 if was_used {
68 return Err(InterruptError::IntChannelAlreadyUsed);
69 }
70
71 let ch_number = pin_number;
73
74 let ch = match ch_number {
80 0 => unsafe { peripherals::EXTI0::steal() }.degrade(),
81 1 => unsafe { peripherals::EXTI1::steal() }.degrade(),
82 2 => unsafe { peripherals::EXTI2::steal() }.degrade(),
83 3 => unsafe { peripherals::EXTI3::steal() }.degrade(),
84 4 => unsafe { peripherals::EXTI4::steal() }.degrade(),
85 5 => unsafe { peripherals::EXTI5::steal() }.degrade(),
86 6 => unsafe { peripherals::EXTI6::steal() }.degrade(),
87 7 => unsafe { peripherals::EXTI7::steal() }.degrade(),
88 8 => unsafe { peripherals::EXTI8::steal() }.degrade(),
89 9 => unsafe { peripherals::EXTI9::steal() }.degrade(),
90 10 => unsafe { peripherals::EXTI10::steal() }.degrade(),
91 11 => unsafe { peripherals::EXTI11::steal() }.degrade(),
92 12 => unsafe { peripherals::EXTI12::steal() }.degrade(),
93 13 => unsafe { peripherals::EXTI13::steal() }.degrade(),
94 14 => unsafe { peripherals::EXTI14::steal() }.degrade(),
95 15 => unsafe { peripherals::EXTI15::steal() }.degrade(),
96 _ => unreachable!(),
97 };
98
99 Ok(ch)
100 }
101}