1use cortexm4f::support::with_interrupts_disabled;
6use enum_primitive::cast::FromPrimitive;
7use enum_primitive::enum_from_primitive;
8use kernel::platform::chip::ClockInterface;
9use kernel::utilities::cells::OptionalCell;
10use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable};
11use kernel::utilities::registers::{register_bitfields, ReadWrite};
12use kernel::utilities::StaticRef;
13
14use crate::gpio;
15use crate::syscfg;
16
17#[repr(C)]
19struct ExtiRegisters {
20    imr: ReadWrite<u32, IMR::Register>,
22    emr: ReadWrite<u32, EMR::Register>,
24    rtsr: ReadWrite<u32, RTSR::Register>,
26    ftsr: ReadWrite<u32, FTSR::Register>,
28    swier: ReadWrite<u32, SWIER::Register>,
30    pr: ReadWrite<u32, PR::Register>,
32}
33
34register_bitfields![u32,
35    IMR [
36        MR0 OFFSET(0) NUMBITS(1) [],
38        MR1 OFFSET(1) NUMBITS(1) [],
40        MR2 OFFSET(2) NUMBITS(1) [],
42        MR3 OFFSET(3) NUMBITS(1) [],
44        MR4 OFFSET(4) NUMBITS(1) [],
46        MR5 OFFSET(5) NUMBITS(1) [],
48        MR6 OFFSET(6) NUMBITS(1) [],
50        MR7 OFFSET(7) NUMBITS(1) [],
52        MR8 OFFSET(8) NUMBITS(1) [],
54        MR9 OFFSET(9) NUMBITS(1) [],
56        MR10 OFFSET(10) NUMBITS(1) [],
58        MR11 OFFSET(11) NUMBITS(1) [],
60        MR12 OFFSET(12) NUMBITS(1) [],
62        MR13 OFFSET(13) NUMBITS(1) [],
64        MR14 OFFSET(14) NUMBITS(1) [],
66        MR15 OFFSET(15) NUMBITS(1) [],
68        MR16 OFFSET(16) NUMBITS(1) [],
70        MR17 OFFSET(17) NUMBITS(1) [],
72        MR18 OFFSET(18) NUMBITS(1) [],
74        MR19 OFFSET(19) NUMBITS(1) [],
76        MR20 OFFSET(20) NUMBITS(1) [],
78        MR21 OFFSET(21) NUMBITS(1) [],
80        MR22 OFFSET(22) NUMBITS(1) []
82    ],
83    EMR [
84        MR0 OFFSET(0) NUMBITS(1) [],
86        MR1 OFFSET(1) NUMBITS(1) [],
88        MR2 OFFSET(2) NUMBITS(1) [],
90        MR3 OFFSET(3) NUMBITS(1) [],
92        MR4 OFFSET(4) NUMBITS(1) [],
94        MR5 OFFSET(5) NUMBITS(1) [],
96        MR6 OFFSET(6) NUMBITS(1) [],
98        MR7 OFFSET(7) NUMBITS(1) [],
100        MR8 OFFSET(8) NUMBITS(1) [],
102        MR9 OFFSET(9) NUMBITS(1) [],
104        MR10 OFFSET(10) NUMBITS(1) [],
106        MR11 OFFSET(11) NUMBITS(1) [],
108        MR12 OFFSET(12) NUMBITS(1) [],
110        MR13 OFFSET(13) NUMBITS(1) [],
112        MR14 OFFSET(14) NUMBITS(1) [],
114        MR15 OFFSET(15) NUMBITS(1) [],
116        MR16 OFFSET(16) NUMBITS(1) [],
118        MR17 OFFSET(17) NUMBITS(1) [],
120        MR18 OFFSET(18) NUMBITS(1) [],
122        MR19 OFFSET(19) NUMBITS(1) [],
124        MR20 OFFSET(20) NUMBITS(1) [],
126        MR21 OFFSET(21) NUMBITS(1) [],
128        MR22 OFFSET(22) NUMBITS(1) []
130    ],
131    RTSR [
132        TR0 OFFSET(0) NUMBITS(1) [],
134        TR1 OFFSET(1) NUMBITS(1) [],
136        TR2 OFFSET(2) NUMBITS(1) [],
138        TR3 OFFSET(3) NUMBITS(1) [],
140        TR4 OFFSET(4) NUMBITS(1) [],
142        TR5 OFFSET(5) NUMBITS(1) [],
144        TR6 OFFSET(6) NUMBITS(1) [],
146        TR7 OFFSET(7) NUMBITS(1) [],
148        TR8 OFFSET(8) NUMBITS(1) [],
150        TR9 OFFSET(9) NUMBITS(1) [],
152        TR10 OFFSET(10) NUMBITS(1) [],
154        TR11 OFFSET(11) NUMBITS(1) [],
156        TR12 OFFSET(12) NUMBITS(1) [],
158        TR13 OFFSET(13) NUMBITS(1) [],
160        TR14 OFFSET(14) NUMBITS(1) [],
162        TR15 OFFSET(15) NUMBITS(1) [],
164        TR16 OFFSET(16) NUMBITS(1) [],
166        TR17 OFFSET(17) NUMBITS(1) [],
168        TR18 OFFSET(18) NUMBITS(1) [],
170        TR19 OFFSET(19) NUMBITS(1) [],
172        TR20 OFFSET(20) NUMBITS(1) [],
174        TR21 OFFSET(21) NUMBITS(1) [],
176        TR22 OFFSET(22) NUMBITS(1) []
178    ],
179    FTSR [
180        TR0 OFFSET(0) NUMBITS(1) [],
182        TR1 OFFSET(1) NUMBITS(1) [],
184        TR2 OFFSET(2) NUMBITS(1) [],
186        TR3 OFFSET(3) NUMBITS(1) [],
188        TR4 OFFSET(4) NUMBITS(1) [],
190        TR5 OFFSET(5) NUMBITS(1) [],
192        TR6 OFFSET(6) NUMBITS(1) [],
194        TR7 OFFSET(7) NUMBITS(1) [],
196        TR8 OFFSET(8) NUMBITS(1) [],
198        TR9 OFFSET(9) NUMBITS(1) [],
200        TR10 OFFSET(10) NUMBITS(1) [],
202        TR11 OFFSET(11) NUMBITS(1) [],
204        TR12 OFFSET(12) NUMBITS(1) [],
206        TR13 OFFSET(13) NUMBITS(1) [],
208        TR14 OFFSET(14) NUMBITS(1) [],
210        TR15 OFFSET(15) NUMBITS(1) [],
212        TR16 OFFSET(16) NUMBITS(1) [],
214        TR17 OFFSET(17) NUMBITS(1) [],
216        TR18 OFFSET(18) NUMBITS(1) [],
218        TR19 OFFSET(19) NUMBITS(1) [],
220        TR20 OFFSET(20) NUMBITS(1) [],
222        TR21 OFFSET(21) NUMBITS(1) [],
224        TR22 OFFSET(22) NUMBITS(1) []
226    ],
227    SWIER [
228        SWIER0 OFFSET(0) NUMBITS(1) [],
230        SWIER1 OFFSET(1) NUMBITS(1) [],
232        SWIER2 OFFSET(2) NUMBITS(1) [],
234        SWIER3 OFFSET(3) NUMBITS(1) [],
236        SWIER4 OFFSET(4) NUMBITS(1) [],
238        SWIER5 OFFSET(5) NUMBITS(1) [],
240        SWIER6 OFFSET(6) NUMBITS(1) [],
242        SWIER7 OFFSET(7) NUMBITS(1) [],
244        SWIER8 OFFSET(8) NUMBITS(1) [],
246        SWIER9 OFFSET(9) NUMBITS(1) [],
248        SWIER10 OFFSET(10) NUMBITS(1) [],
250        SWIER11 OFFSET(11) NUMBITS(1) [],
252        SWIER12 OFFSET(12) NUMBITS(1) [],
254        SWIER13 OFFSET(13) NUMBITS(1) [],
256        SWIER14 OFFSET(14) NUMBITS(1) [],
258        SWIER15 OFFSET(15) NUMBITS(1) [],
260        SWIER16 OFFSET(16) NUMBITS(1) [],
262        SWIER17 OFFSET(17) NUMBITS(1) [],
264        SWIER18 OFFSET(18) NUMBITS(1) [],
266        SWIER19 OFFSET(19) NUMBITS(1) [],
268        SWIER20 OFFSET(20) NUMBITS(1) [],
270        SWIER21 OFFSET(21) NUMBITS(1) [],
272        SWIER22 OFFSET(22) NUMBITS(1) []
274    ],
275    PR [
276        PR0 OFFSET(0) NUMBITS(1) [],
278        PR1 OFFSET(1) NUMBITS(1) [],
280        PR2 OFFSET(2) NUMBITS(1) [],
282        PR3 OFFSET(3) NUMBITS(1) [],
284        PR4 OFFSET(4) NUMBITS(1) [],
286        PR5 OFFSET(5) NUMBITS(1) [],
288        PR6 OFFSET(6) NUMBITS(1) [],
290        PR7 OFFSET(7) NUMBITS(1) [],
292        PR8 OFFSET(8) NUMBITS(1) [],
294        PR9 OFFSET(9) NUMBITS(1) [],
296        PR10 OFFSET(10) NUMBITS(1) [],
298        PR11 OFFSET(11) NUMBITS(1) [],
300        PR12 OFFSET(12) NUMBITS(1) [],
302        PR13 OFFSET(13) NUMBITS(1) [],
304        PR14 OFFSET(14) NUMBITS(1) [],
306        PR15 OFFSET(15) NUMBITS(1) [],
308        PR16 OFFSET(16) NUMBITS(1) [],
310        PR17 OFFSET(17) NUMBITS(1) [],
312        PR18 OFFSET(18) NUMBITS(1) [],
314        PR19 OFFSET(19) NUMBITS(1) [],
316        PR20 OFFSET(20) NUMBITS(1) [],
318        PR21 OFFSET(21) NUMBITS(1) [],
320        PR22 OFFSET(22) NUMBITS(1) []
322    ]
323];
324
325const EXTI_BASE: StaticRef<ExtiRegisters> =
326    unsafe { StaticRef::new(0x40013C00 as *const ExtiRegisters) };
327
328#[no_mangle]
363#[used]
364pub static mut EXTI_EVENTS: u32 = 0;
365
366enum_from_primitive! {
367    #[repr(u8)]
368    #[derive(Copy, Clone)]
369    pub enum LineId {
370        Exti0 = 0,
371        Exti1 = 1,
372        Exti2 = 2,
373        Exti3 = 3,
374        Exti4 = 4,
375        Exti5 = 5,
376        Exti6 = 6,
377        Exti7 = 7,
378        Exti8 = 8,
379        Exti9 = 9,
380        Exti10 = 10,
381        Exti11 = 11,
382        Exti12 = 12,
383        Exti13 = 13,
384        Exti14 = 14,
385        Exti15 = 15,
386    }
387}
388
389pub struct Exti<'a> {
391    registers: StaticRef<ExtiRegisters>,
392    clock: ExtiClock<'a>,
393    line_gpiopin_map: [OptionalCell<&'static gpio::Pin<'static>>; 16],
394    syscfg: &'a syscfg::Syscfg<'a>,
395}
396
397impl<'a> Exti<'a> {
398    pub const fn new(syscfg: &'a syscfg::Syscfg<'a>) -> Self {
399        Self {
400            registers: EXTI_BASE,
401            clock: ExtiClock(syscfg),
402            line_gpiopin_map: [
403                OptionalCell::empty(),
404                OptionalCell::empty(),
405                OptionalCell::empty(),
406                OptionalCell::empty(),
407                OptionalCell::empty(),
408                OptionalCell::empty(),
409                OptionalCell::empty(),
410                OptionalCell::empty(),
411                OptionalCell::empty(),
412                OptionalCell::empty(),
413                OptionalCell::empty(),
414                OptionalCell::empty(),
415                OptionalCell::empty(),
416                OptionalCell::empty(),
417                OptionalCell::empty(),
418                OptionalCell::empty(),
419            ],
420            syscfg,
421        }
422    }
423
424    pub fn is_enabled_clock(&self) -> bool {
425        self.clock.is_enabled()
426    }
427
428    pub fn enable_clock(&self) {
429        self.clock.enable();
430    }
431
432    pub fn disable_clock(&self) {
433        self.clock.disable();
434    }
435
436    pub fn associate_line_gpiopin(&self, lineid: LineId, pin: &'static gpio::Pin<'static>) {
437        self.line_gpiopin_map[usize::from(lineid as u8)].set(pin);
438        self.syscfg.configure_interrupt(pin.get_pinid());
439        pin.set_exti_lineid(lineid);
440
441        self.mask_interrupt(lineid);
444    }
445
446    pub fn mask_interrupt(&self, lineid: LineId) {
447        match lineid {
448            LineId::Exti0 => self.registers.imr.modify(IMR::MR0::CLEAR),
449            LineId::Exti1 => self.registers.imr.modify(IMR::MR1::CLEAR),
450            LineId::Exti2 => self.registers.imr.modify(IMR::MR2::CLEAR),
451            LineId::Exti3 => self.registers.imr.modify(IMR::MR3::CLEAR),
452            LineId::Exti4 => self.registers.imr.modify(IMR::MR4::CLEAR),
453            LineId::Exti5 => self.registers.imr.modify(IMR::MR5::CLEAR),
454            LineId::Exti6 => self.registers.imr.modify(IMR::MR6::CLEAR),
455            LineId::Exti7 => self.registers.imr.modify(IMR::MR7::CLEAR),
456            LineId::Exti8 => self.registers.imr.modify(IMR::MR8::CLEAR),
457            LineId::Exti9 => self.registers.imr.modify(IMR::MR9::CLEAR),
458            LineId::Exti10 => self.registers.imr.modify(IMR::MR10::CLEAR),
459            LineId::Exti11 => self.registers.imr.modify(IMR::MR11::CLEAR),
460            LineId::Exti12 => self.registers.imr.modify(IMR::MR12::CLEAR),
461            LineId::Exti13 => self.registers.imr.modify(IMR::MR13::CLEAR),
462            LineId::Exti14 => self.registers.imr.modify(IMR::MR14::CLEAR),
463            LineId::Exti15 => self.registers.imr.modify(IMR::MR15::CLEAR),
464        }
465    }
466
467    pub fn unmask_interrupt(&self, lineid: LineId) {
468        match lineid {
469            LineId::Exti0 => self.registers.imr.modify(IMR::MR0::SET),
470            LineId::Exti1 => self.registers.imr.modify(IMR::MR1::SET),
471            LineId::Exti2 => self.registers.imr.modify(IMR::MR2::SET),
472            LineId::Exti3 => self.registers.imr.modify(IMR::MR3::SET),
473            LineId::Exti4 => self.registers.imr.modify(IMR::MR4::SET),
474            LineId::Exti5 => self.registers.imr.modify(IMR::MR5::SET),
475            LineId::Exti6 => self.registers.imr.modify(IMR::MR6::SET),
476            LineId::Exti7 => self.registers.imr.modify(IMR::MR7::SET),
477            LineId::Exti8 => self.registers.imr.modify(IMR::MR8::SET),
478            LineId::Exti9 => self.registers.imr.modify(IMR::MR9::SET),
479            LineId::Exti10 => self.registers.imr.modify(IMR::MR10::SET),
480            LineId::Exti11 => self.registers.imr.modify(IMR::MR11::SET),
481            LineId::Exti12 => self.registers.imr.modify(IMR::MR12::SET),
482            LineId::Exti13 => self.registers.imr.modify(IMR::MR13::SET),
483            LineId::Exti14 => self.registers.imr.modify(IMR::MR14::SET),
484            LineId::Exti15 => self.registers.imr.modify(IMR::MR15::SET),
485        }
486    }
487
488    pub fn clear_pending(&self, lineid: LineId) {
490        match lineid {
491            LineId::Exti0 => self.registers.pr.write(PR::PR0::SET),
492            LineId::Exti1 => self.registers.pr.write(PR::PR1::SET),
493            LineId::Exti2 => self.registers.pr.write(PR::PR2::SET),
494            LineId::Exti3 => self.registers.pr.write(PR::PR3::SET),
495            LineId::Exti4 => self.registers.pr.write(PR::PR4::SET),
496            LineId::Exti5 => self.registers.pr.write(PR::PR5::SET),
497            LineId::Exti6 => self.registers.pr.write(PR::PR6::SET),
498            LineId::Exti7 => self.registers.pr.write(PR::PR7::SET),
499            LineId::Exti8 => self.registers.pr.write(PR::PR8::SET),
500            LineId::Exti9 => self.registers.pr.write(PR::PR9::SET),
501            LineId::Exti10 => self.registers.pr.write(PR::PR10::SET),
502            LineId::Exti11 => self.registers.pr.write(PR::PR11::SET),
503            LineId::Exti12 => self.registers.pr.write(PR::PR12::SET),
504            LineId::Exti13 => self.registers.pr.write(PR::PR13::SET),
505            LineId::Exti14 => self.registers.pr.write(PR::PR14::SET),
506            LineId::Exti15 => self.registers.pr.write(PR::PR15::SET),
507        }
508    }
509
510    pub fn is_pending(&self, lineid: LineId) -> bool {
511        let val = match lineid {
512            LineId::Exti0 => self.registers.pr.read(PR::PR0),
513            LineId::Exti1 => self.registers.pr.read(PR::PR1),
514            LineId::Exti2 => self.registers.pr.read(PR::PR2),
515            LineId::Exti3 => self.registers.pr.read(PR::PR3),
516            LineId::Exti4 => self.registers.pr.read(PR::PR4),
517            LineId::Exti5 => self.registers.pr.read(PR::PR5),
518            LineId::Exti6 => self.registers.pr.read(PR::PR6),
519            LineId::Exti7 => self.registers.pr.read(PR::PR7),
520            LineId::Exti8 => self.registers.pr.read(PR::PR8),
521            LineId::Exti9 => self.registers.pr.read(PR::PR9),
522            LineId::Exti10 => self.registers.pr.read(PR::PR10),
523            LineId::Exti11 => self.registers.pr.read(PR::PR11),
524            LineId::Exti12 => self.registers.pr.read(PR::PR12),
525            LineId::Exti13 => self.registers.pr.read(PR::PR13),
526            LineId::Exti14 => self.registers.pr.read(PR::PR14),
527            LineId::Exti15 => self.registers.pr.read(PR::PR15),
528        };
529        val > 0
530    }
531
532    pub fn select_rising_trigger(&self, lineid: LineId) {
533        match lineid {
534            LineId::Exti0 => self.registers.rtsr.modify(RTSR::TR0::SET),
535            LineId::Exti1 => self.registers.rtsr.modify(RTSR::TR1::SET),
536            LineId::Exti2 => self.registers.rtsr.modify(RTSR::TR2::SET),
537            LineId::Exti3 => self.registers.rtsr.modify(RTSR::TR3::SET),
538            LineId::Exti4 => self.registers.rtsr.modify(RTSR::TR4::SET),
539            LineId::Exti5 => self.registers.rtsr.modify(RTSR::TR5::SET),
540            LineId::Exti6 => self.registers.rtsr.modify(RTSR::TR6::SET),
541            LineId::Exti7 => self.registers.rtsr.modify(RTSR::TR7::SET),
542            LineId::Exti8 => self.registers.rtsr.modify(RTSR::TR8::SET),
543            LineId::Exti9 => self.registers.rtsr.modify(RTSR::TR9::SET),
544            LineId::Exti10 => self.registers.rtsr.modify(RTSR::TR10::SET),
545            LineId::Exti11 => self.registers.rtsr.modify(RTSR::TR11::SET),
546            LineId::Exti12 => self.registers.rtsr.modify(RTSR::TR12::SET),
547            LineId::Exti13 => self.registers.rtsr.modify(RTSR::TR13::SET),
548            LineId::Exti14 => self.registers.rtsr.modify(RTSR::TR14::SET),
549            LineId::Exti15 => self.registers.rtsr.modify(RTSR::TR15::SET),
550        }
551    }
552
553    pub fn deselect_rising_trigger(&self, lineid: LineId) {
554        match lineid {
555            LineId::Exti0 => self.registers.rtsr.modify(RTSR::TR0::CLEAR),
556            LineId::Exti1 => self.registers.rtsr.modify(RTSR::TR1::CLEAR),
557            LineId::Exti2 => self.registers.rtsr.modify(RTSR::TR2::CLEAR),
558            LineId::Exti3 => self.registers.rtsr.modify(RTSR::TR3::CLEAR),
559            LineId::Exti4 => self.registers.rtsr.modify(RTSR::TR4::CLEAR),
560            LineId::Exti5 => self.registers.rtsr.modify(RTSR::TR5::CLEAR),
561            LineId::Exti6 => self.registers.rtsr.modify(RTSR::TR6::CLEAR),
562            LineId::Exti7 => self.registers.rtsr.modify(RTSR::TR7::CLEAR),
563            LineId::Exti8 => self.registers.rtsr.modify(RTSR::TR8::CLEAR),
564            LineId::Exti9 => self.registers.rtsr.modify(RTSR::TR9::CLEAR),
565            LineId::Exti10 => self.registers.rtsr.modify(RTSR::TR10::CLEAR),
566            LineId::Exti11 => self.registers.rtsr.modify(RTSR::TR11::CLEAR),
567            LineId::Exti12 => self.registers.rtsr.modify(RTSR::TR12::CLEAR),
568            LineId::Exti13 => self.registers.rtsr.modify(RTSR::TR13::CLEAR),
569            LineId::Exti14 => self.registers.rtsr.modify(RTSR::TR14::CLEAR),
570            LineId::Exti15 => self.registers.rtsr.modify(RTSR::TR15::CLEAR),
571        }
572    }
573
574    pub fn select_falling_trigger(&self, lineid: LineId) {
575        match lineid {
576            LineId::Exti0 => self.registers.ftsr.modify(FTSR::TR0::SET),
577            LineId::Exti1 => self.registers.ftsr.modify(FTSR::TR1::SET),
578            LineId::Exti2 => self.registers.ftsr.modify(FTSR::TR2::SET),
579            LineId::Exti3 => self.registers.ftsr.modify(FTSR::TR3::SET),
580            LineId::Exti4 => self.registers.ftsr.modify(FTSR::TR4::SET),
581            LineId::Exti5 => self.registers.ftsr.modify(FTSR::TR5::SET),
582            LineId::Exti6 => self.registers.ftsr.modify(FTSR::TR6::SET),
583            LineId::Exti7 => self.registers.ftsr.modify(FTSR::TR7::SET),
584            LineId::Exti8 => self.registers.ftsr.modify(FTSR::TR8::SET),
585            LineId::Exti9 => self.registers.ftsr.modify(FTSR::TR9::SET),
586            LineId::Exti10 => self.registers.ftsr.modify(FTSR::TR10::SET),
587            LineId::Exti11 => self.registers.ftsr.modify(FTSR::TR11::SET),
588            LineId::Exti12 => self.registers.ftsr.modify(FTSR::TR12::SET),
589            LineId::Exti13 => self.registers.ftsr.modify(FTSR::TR13::SET),
590            LineId::Exti14 => self.registers.ftsr.modify(FTSR::TR14::SET),
591            LineId::Exti15 => self.registers.ftsr.modify(FTSR::TR15::SET),
592        }
593    }
594
595    pub fn deselect_falling_trigger(&self, lineid: LineId) {
596        match lineid {
597            LineId::Exti0 => self.registers.ftsr.modify(FTSR::TR0::CLEAR),
598            LineId::Exti1 => self.registers.ftsr.modify(FTSR::TR1::CLEAR),
599            LineId::Exti2 => self.registers.ftsr.modify(FTSR::TR2::CLEAR),
600            LineId::Exti3 => self.registers.ftsr.modify(FTSR::TR3::CLEAR),
601            LineId::Exti4 => self.registers.ftsr.modify(FTSR::TR4::CLEAR),
602            LineId::Exti5 => self.registers.ftsr.modify(FTSR::TR5::CLEAR),
603            LineId::Exti6 => self.registers.ftsr.modify(FTSR::TR6::CLEAR),
604            LineId::Exti7 => self.registers.ftsr.modify(FTSR::TR7::CLEAR),
605            LineId::Exti8 => self.registers.ftsr.modify(FTSR::TR8::CLEAR),
606            LineId::Exti9 => self.registers.ftsr.modify(FTSR::TR9::CLEAR),
607            LineId::Exti10 => self.registers.ftsr.modify(FTSR::TR10::CLEAR),
608            LineId::Exti11 => self.registers.ftsr.modify(FTSR::TR11::CLEAR),
609            LineId::Exti12 => self.registers.ftsr.modify(FTSR::TR12::CLEAR),
610            LineId::Exti13 => self.registers.ftsr.modify(FTSR::TR13::CLEAR),
611            LineId::Exti14 => self.registers.ftsr.modify(FTSR::TR14::CLEAR),
612            LineId::Exti15 => self.registers.ftsr.modify(FTSR::TR15::CLEAR),
613        }
614    }
615
616    pub fn handle_interrupt(&self) {
617        let mut exti_pr: u32 = 0;
618
619        unsafe {
626            with_interrupts_disabled(|| {
627                exti_pr = self.registers.pr.get();
628                self.registers.pr.set(exti_pr);
629            });
630        }
631
632        exti_pr &= 0x007fffff;
635
636        let mut flagged_bit = 0;
637
638        while exti_pr != 0 {
640            if (exti_pr & 0b1) != 0 {
641                if let Some(d) = LineId::from_u8(flagged_bit) {
642                    self.line_gpiopin_map[usize::from(d as u8)].map(|pin| pin.handle_interrupt());
643                }
644            }
645            flagged_bit += 1;
647            exti_pr >>= 1;
648        }
649    }
650}
651
652struct ExtiClock<'a>(&'a syscfg::Syscfg<'a>);
656
657impl ClockInterface for ExtiClock<'_> {
658    fn is_enabled(&self) -> bool {
659        self.0.is_enabled_clock()
660    }
661
662    fn enable(&self) {
663        self.0.enable_clock();
664    }
665
666    fn disable(&self) {
667        self.0.disable_clock();
668    }
669}