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    imr1: ReadWrite<u32, IMR1::Register>,
22    emr1: ReadWrite<u32, EMR1::Register>,
24    rtsr1: ReadWrite<u32, RTSR1::Register>,
26    ftsr1: ReadWrite<u32, FTSR1::Register>,
28    swier1: ReadWrite<u32, SWIER1::Register>,
30    pr1: ReadWrite<u32, PR1::Register>,
32
33    imr2: ReadWrite<u32, IMR2::Register>,
35    emr2: ReadWrite<u32, EMR2::Register>,
37    rtsr2: ReadWrite<u32, RTSR2::Register>,
39    ftsr2: ReadWrite<u32, FTSR2::Register>,
41    swier2: ReadWrite<u32, SWIER2::Register>,
43    pr2: ReadWrite<u32, PR2::Register>,
45}
46
47register_bitfields![u32,
48    IMR1 [
49        MR0 OFFSET(0) NUMBITS(1) [],
51        MR1 OFFSET(1) NUMBITS(1) [],
53        MR2 OFFSET(2) NUMBITS(1) [],
55        MR3 OFFSET(3) NUMBITS(1) [],
57        MR4 OFFSET(4) NUMBITS(1) [],
59        MR5 OFFSET(5) NUMBITS(1) [],
61        MR6 OFFSET(6) NUMBITS(1) [],
63        MR7 OFFSET(7) NUMBITS(1) [],
65        MR8 OFFSET(8) NUMBITS(1) [],
67        MR9 OFFSET(9) NUMBITS(1) [],
69        MR10 OFFSET(10) NUMBITS(1) [],
71        MR11 OFFSET(11) NUMBITS(1) [],
73        MR12 OFFSET(12) NUMBITS(1) [],
75        MR13 OFFSET(13) NUMBITS(1) [],
77        MR14 OFFSET(14) NUMBITS(1) [],
79        MR15 OFFSET(15) NUMBITS(1) [],
81        MR16 OFFSET(16) NUMBITS(1) [],
83        MR17 OFFSET(17) NUMBITS(1) [],
85        MR18 OFFSET(18) NUMBITS(1) [],
87        MR19 OFFSET(19) NUMBITS(1) [],
89        MR20 OFFSET(20) NUMBITS(1) [],
91        MR21 OFFSET(21) NUMBITS(1) [],
93        MR22 OFFSET(22) NUMBITS(1) [],
95        MR23 OFFSET(23) NUMBITS(1) [],
97        MR24 OFFSET(24) NUMBITS(1) [],
99        MR25 OFFSET(25) NUMBITS(1) [],
101        MR26 OFFSET(26) NUMBITS(1) [],
103        MR27 OFFSET(27) NUMBITS(1) [],
105        MR28 OFFSET(28) NUMBITS(1) [],
107        MR29 OFFSET(29) NUMBITS(1) [],
109        MR30 OFFSET(30) NUMBITS(1) [],
111        MR31 OFFSET(31) NUMBITS(1) []
113    ],
114    EMR1 [
115        MR0 OFFSET(0) NUMBITS(1) [],
117        MR1 OFFSET(1) NUMBITS(1) [],
119        MR2 OFFSET(2) NUMBITS(1) [],
121        MR3 OFFSET(3) NUMBITS(1) [],
123        MR4 OFFSET(4) NUMBITS(1) [],
125        MR5 OFFSET(5) NUMBITS(1) [],
127        MR6 OFFSET(6) NUMBITS(1) [],
129        MR7 OFFSET(7) NUMBITS(1) [],
131        MR8 OFFSET(8) NUMBITS(1) [],
133        MR9 OFFSET(9) NUMBITS(1) [],
135        MR10 OFFSET(10) NUMBITS(1) [],
137        MR11 OFFSET(11) NUMBITS(1) [],
139        MR12 OFFSET(12) NUMBITS(1) [],
141        MR13 OFFSET(13) NUMBITS(1) [],
143        MR14 OFFSET(14) NUMBITS(1) [],
145        MR15 OFFSET(15) NUMBITS(1) [],
147        MR16 OFFSET(16) NUMBITS(1) [],
149        MR17 OFFSET(17) NUMBITS(1) [],
151        MR18 OFFSET(18) NUMBITS(1) [],
153        MR19 OFFSET(19) NUMBITS(1) [],
155        MR20 OFFSET(20) NUMBITS(1) [],
157        MR21 OFFSET(21) NUMBITS(1) [],
159        MR22 OFFSET(22) NUMBITS(1) [],
161        MR23 OFFSET(23) NUMBITS(1) [],
163        MR24 OFFSET(24) NUMBITS(1) [],
165        MR25 OFFSET(25) NUMBITS(1) [],
167        MR26 OFFSET(26) NUMBITS(1) [],
169        MR27 OFFSET(27) NUMBITS(1) [],
171        MR28 OFFSET(28) NUMBITS(1) [],
173        MR29 OFFSET(29) NUMBITS(1) [],
175        MR30 OFFSET(30) NUMBITS(1) [],
177        MR31 OFFSET(31) NUMBITS(1) []
179    ],
180    RTSR1 [
181        TR0 OFFSET(0) NUMBITS(1) [],
183        TR1 OFFSET(1) NUMBITS(1) [],
185        TR2 OFFSET(2) NUMBITS(1) [],
187        TR3 OFFSET(3) NUMBITS(1) [],
189        TR4 OFFSET(4) NUMBITS(1) [],
191        TR5 OFFSET(5) NUMBITS(1) [],
193        TR6 OFFSET(6) NUMBITS(1) [],
195        TR7 OFFSET(7) NUMBITS(1) [],
197        TR8 OFFSET(8) NUMBITS(1) [],
199        TR9 OFFSET(9) NUMBITS(1) [],
201        TR10 OFFSET(10) NUMBITS(1) [],
203        TR11 OFFSET(11) NUMBITS(1) [],
205        TR12 OFFSET(12) NUMBITS(1) [],
207        TR13 OFFSET(13) NUMBITS(1) [],
209        TR14 OFFSET(14) NUMBITS(1) [],
211        TR15 OFFSET(15) NUMBITS(1) [],
213        TR16 OFFSET(16) NUMBITS(1) [],
215        TR17 OFFSET(17) NUMBITS(1) [],
217        TR18 OFFSET(18) NUMBITS(1) [],
219        TR19 OFFSET(19) NUMBITS(1) [],
221        TR20 OFFSET(20) NUMBITS(1) [],
223        TR21 OFFSET(21) NUMBITS(1) [],
225        TR22 OFFSET(22) NUMBITS(1) [],
227        TR29 OFFSET(29) NUMBITS(1) [],
229        TR30 OFFSET(30) NUMBITS(1) [],
231        TR31 OFFSET(31) NUMBITS(1) []
233    ],
234    FTSR1 [
235        TR0 OFFSET(0) NUMBITS(1) [],
237        TR1 OFFSET(1) NUMBITS(1) [],
239        TR2 OFFSET(2) NUMBITS(1) [],
241        TR3 OFFSET(3) NUMBITS(1) [],
243        TR4 OFFSET(4) NUMBITS(1) [],
245        TR5 OFFSET(5) NUMBITS(1) [],
247        TR6 OFFSET(6) NUMBITS(1) [],
249        TR7 OFFSET(7) NUMBITS(1) [],
251        TR8 OFFSET(8) NUMBITS(1) [],
253        TR9 OFFSET(9) NUMBITS(1) [],
255        TR10 OFFSET(10) NUMBITS(1) [],
257        TR11 OFFSET(11) NUMBITS(1) [],
259        TR12 OFFSET(12) NUMBITS(1) [],
261        TR13 OFFSET(13) NUMBITS(1) [],
263        TR14 OFFSET(14) NUMBITS(1) [],
265        TR15 OFFSET(15) NUMBITS(1) [],
267        TR16 OFFSET(16) NUMBITS(1) [],
269        TR17 OFFSET(17) NUMBITS(1) [],
271        TR18 OFFSET(18) NUMBITS(1) [],
273        TR19 OFFSET(19) NUMBITS(1) [],
275        TR20 OFFSET(20) NUMBITS(1) [],
277        TR21 OFFSET(21) NUMBITS(1) [],
279        TR22 OFFSET(22) NUMBITS(1) [],
281        TR29 OFFSET(29) NUMBITS(1) [],
283        TR30 OFFSET(30) NUMBITS(1) [],
285        TR31 OFFSET(31) NUMBITS(1) []
287    ],
288    SWIER1 [
289        SWIER0 OFFSET(0) NUMBITS(1) [],
291        SWIER1 OFFSET(1) NUMBITS(1) [],
293        SWIER2 OFFSET(2) NUMBITS(1) [],
295        SWIER3 OFFSET(3) NUMBITS(1) [],
297        SWIER4 OFFSET(4) NUMBITS(1) [],
299        SWIER5 OFFSET(5) NUMBITS(1) [],
301        SWIER6 OFFSET(6) NUMBITS(1) [],
303        SWIER7 OFFSET(7) NUMBITS(1) [],
305        SWIER8 OFFSET(8) NUMBITS(1) [],
307        SWIER9 OFFSET(9) NUMBITS(1) [],
309        SWIER10 OFFSET(10) NUMBITS(1) [],
311        SWIER11 OFFSET(11) NUMBITS(1) [],
313        SWIER12 OFFSET(12) NUMBITS(1) [],
315        SWIER13 OFFSET(13) NUMBITS(1) [],
317        SWIER14 OFFSET(14) NUMBITS(1) [],
319        SWIER15 OFFSET(15) NUMBITS(1) [],
321        SWIER16 OFFSET(16) NUMBITS(1) [],
323        SWIER17 OFFSET(17) NUMBITS(1) [],
325        SWIER18 OFFSET(18) NUMBITS(1) [],
327        SWIER19 OFFSET(19) NUMBITS(1) [],
329        SWIER20 OFFSET(20) NUMBITS(1) [],
331        SWIER21 OFFSET(21) NUMBITS(1) [],
333        SWIER22 OFFSET(22) NUMBITS(1) [],
335        SWIER29 OFFSET(29) NUMBITS(1) [],
337        SWIER30 OFFSET(30) NUMBITS(1) [],
339        SWIER31 OFFSET(31) NUMBITS(1) []
341    ],
342    PR1 [
343        PR0 OFFSET(0) NUMBITS(1) [],
345        PR1 OFFSET(1) NUMBITS(1) [],
347        PR2 OFFSET(2) NUMBITS(1) [],
349        PR3 OFFSET(3) NUMBITS(1) [],
351        PR4 OFFSET(4) NUMBITS(1) [],
353        PR5 OFFSET(5) NUMBITS(1) [],
355        PR6 OFFSET(6) NUMBITS(1) [],
357        PR7 OFFSET(7) NUMBITS(1) [],
359        PR8 OFFSET(8) NUMBITS(1) [],
361        PR9 OFFSET(9) NUMBITS(1) [],
363        PR10 OFFSET(10) NUMBITS(1) [],
365        PR11 OFFSET(11) NUMBITS(1) [],
367        PR12 OFFSET(12) NUMBITS(1) [],
369        PR13 OFFSET(13) NUMBITS(1) [],
371        PR14 OFFSET(14) NUMBITS(1) [],
373        PR15 OFFSET(15) NUMBITS(1) [],
375        PR16 OFFSET(16) NUMBITS(1) [],
377        PR17 OFFSET(17) NUMBITS(1) [],
379        PR18 OFFSET(18) NUMBITS(1) [],
381        PR19 OFFSET(19) NUMBITS(1) [],
383        PR20 OFFSET(20) NUMBITS(1) [],
385        PR21 OFFSET(21) NUMBITS(1) [],
387        PR22 OFFSET(22) NUMBITS(1) [],
389        PR29 OFFSET(29) NUMBITS(1) [],
391        PR30 OFFSET(30) NUMBITS(1) [],
393        PR31 OFFSET(31) NUMBITS(1) []
395    ],
396    IMR2 [
397        MR32 OFFSET(0) NUMBITS(1) [],
399        MR33 OFFSET(1) NUMBITS(1) [],
401        MR34 OFFSET(2) NUMBITS(1) [],
403        MR35 OFFSET(3) NUMBITS(1) []
405    ],
406    EMR2 [
407        MR32 OFFSET(0) NUMBITS(1) [],
409        MR33 OFFSET(1) NUMBITS(1) [],
411        MR34 OFFSET(2) NUMBITS(1) [],
413        MR35 OFFSET(3) NUMBITS(1) []
415    ],
416    RTSR2 [
417        TR32 OFFSET(0) NUMBITS(1) [],
419        TR33 OFFSET(1) NUMBITS(1) []
421    ],
422    FTSR2 [
423        TR32 OFFSET(0) NUMBITS(1) [],
425        TR33 OFFSET(1) NUMBITS(1) []
427    ],
428    SWIER2 [
429        SWIER32 OFFSET(0) NUMBITS(1) [],
431        SWIER33 OFFSET(1) NUMBITS(1) []
433    ],
434    PR2 [
435        PR32 OFFSET(0) NUMBITS(1) [],
437        PR33 OFFSET(1) NUMBITS(1) []
439    ]
440];
441
442const EXTI_BASE: StaticRef<ExtiRegisters> =
443    unsafe { StaticRef::new(0x4001_0400 as *const ExtiRegisters) };
444
445#[no_mangle]
483#[used]
484pub static mut EXTI_EVENTS: u32 = 0;
485
486enum_from_primitive! {
487    #[repr(u8)]
488    #[derive(Copy, Clone)]
489    pub enum LineId {
490        Exti0 = 0,
491        Exti1 = 1,
492        Exti2 = 2,
493        Exti3 = 3,
494        Exti4 = 4,
495        Exti5 = 5,
496        Exti6 = 6,
497        Exti7 = 7,
498        Exti8 = 8,
499        Exti9 = 9,
500        Exti10 = 10,
501        Exti11 = 11,
502        Exti12 = 12,
503        Exti13 = 13,
504        Exti14 = 14,
505        Exti15 = 15,
506    }
507}
508
509pub struct Exti<'a> {
511    registers: StaticRef<ExtiRegisters>,
512    clock: ExtiClock<'a>,
513    line_gpiopin_map: [OptionalCell<&'static gpio::Pin<'static>>; 16],
514    syscfg: &'a syscfg::Syscfg<'a>,
515}
516
517impl<'a> Exti<'a> {
518    pub const fn new(syscfg: &'a syscfg::Syscfg<'a>) -> Exti<'a> {
519        Exti {
520            registers: EXTI_BASE,
521            clock: ExtiClock(syscfg),
522            line_gpiopin_map: [
523                OptionalCell::empty(),
524                OptionalCell::empty(),
525                OptionalCell::empty(),
526                OptionalCell::empty(),
527                OptionalCell::empty(),
528                OptionalCell::empty(),
529                OptionalCell::empty(),
530                OptionalCell::empty(),
531                OptionalCell::empty(),
532                OptionalCell::empty(),
533                OptionalCell::empty(),
534                OptionalCell::empty(),
535                OptionalCell::empty(),
536                OptionalCell::empty(),
537                OptionalCell::empty(),
538                OptionalCell::empty(),
539            ],
540            syscfg,
541        }
542    }
543
544    pub fn is_enabled_clock(&self) -> bool {
545        self.clock.is_enabled()
546    }
547
548    pub fn enable_clock(&self) {
549        self.clock.enable();
550    }
551
552    pub fn disable_clock(&self) {
553        self.clock.disable();
554    }
555
556    pub fn associate_line_gpiopin(&self, lineid: LineId, pin: &'static gpio::Pin<'static>) {
557        self.line_gpiopin_map[usize::from(lineid as u8)].set(pin);
558        self.syscfg.configure_interrupt(pin.get_pinid());
559        pin.set_exti_lineid(lineid);
560
561        self.mask_interrupt(lineid);
564    }
565
566    pub fn mask_interrupt(&self, lineid: LineId) {
567        match lineid {
568            LineId::Exti0 => self.registers.imr1.modify(IMR1::MR0::CLEAR),
569            LineId::Exti1 => self.registers.imr1.modify(IMR1::MR1::CLEAR),
570            LineId::Exti2 => self.registers.imr1.modify(IMR1::MR2::CLEAR),
571            LineId::Exti3 => self.registers.imr1.modify(IMR1::MR3::CLEAR),
572            LineId::Exti4 => self.registers.imr1.modify(IMR1::MR4::CLEAR),
573            LineId::Exti5 => self.registers.imr1.modify(IMR1::MR5::CLEAR),
574            LineId::Exti6 => self.registers.imr1.modify(IMR1::MR6::CLEAR),
575            LineId::Exti7 => self.registers.imr1.modify(IMR1::MR7::CLEAR),
576            LineId::Exti8 => self.registers.imr1.modify(IMR1::MR8::CLEAR),
577            LineId::Exti9 => self.registers.imr1.modify(IMR1::MR9::CLEAR),
578            LineId::Exti10 => self.registers.imr1.modify(IMR1::MR10::CLEAR),
579            LineId::Exti11 => self.registers.imr1.modify(IMR1::MR11::CLEAR),
580            LineId::Exti12 => self.registers.imr1.modify(IMR1::MR12::CLEAR),
581            LineId::Exti13 => self.registers.imr1.modify(IMR1::MR13::CLEAR),
582            LineId::Exti14 => self.registers.imr1.modify(IMR1::MR14::CLEAR),
583            LineId::Exti15 => self.registers.imr1.modify(IMR1::MR15::CLEAR),
584        }
585    }
586
587    pub fn unmask_interrupt(&self, lineid: LineId) {
588        match lineid {
589            LineId::Exti0 => self.registers.imr1.modify(IMR1::MR0::SET),
590            LineId::Exti1 => self.registers.imr1.modify(IMR1::MR1::SET),
591            LineId::Exti2 => self.registers.imr1.modify(IMR1::MR2::SET),
592            LineId::Exti3 => self.registers.imr1.modify(IMR1::MR3::SET),
593            LineId::Exti4 => self.registers.imr1.modify(IMR1::MR4::SET),
594            LineId::Exti5 => self.registers.imr1.modify(IMR1::MR5::SET),
595            LineId::Exti6 => self.registers.imr1.modify(IMR1::MR6::SET),
596            LineId::Exti7 => self.registers.imr1.modify(IMR1::MR7::SET),
597            LineId::Exti8 => self.registers.imr1.modify(IMR1::MR8::SET),
598            LineId::Exti9 => self.registers.imr1.modify(IMR1::MR9::SET),
599            LineId::Exti10 => self.registers.imr1.modify(IMR1::MR10::SET),
600            LineId::Exti11 => self.registers.imr1.modify(IMR1::MR11::SET),
601            LineId::Exti12 => self.registers.imr1.modify(IMR1::MR12::SET),
602            LineId::Exti13 => self.registers.imr1.modify(IMR1::MR13::SET),
603            LineId::Exti14 => self.registers.imr1.modify(IMR1::MR14::SET),
604            LineId::Exti15 => self.registers.imr1.modify(IMR1::MR15::SET),
605        }
606    }
607
608    pub fn clear_pending(&self, lineid: LineId) {
610        match lineid {
611            LineId::Exti0 => self.registers.pr1.write(PR1::PR0::SET),
612            LineId::Exti1 => self.registers.pr1.write(PR1::PR1::SET),
613            LineId::Exti2 => self.registers.pr1.write(PR1::PR2::SET),
614            LineId::Exti3 => self.registers.pr1.write(PR1::PR3::SET),
615            LineId::Exti4 => self.registers.pr1.write(PR1::PR4::SET),
616            LineId::Exti5 => self.registers.pr1.write(PR1::PR5::SET),
617            LineId::Exti6 => self.registers.pr1.write(PR1::PR6::SET),
618            LineId::Exti7 => self.registers.pr1.write(PR1::PR7::SET),
619            LineId::Exti8 => self.registers.pr1.write(PR1::PR8::SET),
620            LineId::Exti9 => self.registers.pr1.write(PR1::PR9::SET),
621            LineId::Exti10 => self.registers.pr1.write(PR1::PR10::SET),
622            LineId::Exti11 => self.registers.pr1.write(PR1::PR11::SET),
623            LineId::Exti12 => self.registers.pr1.write(PR1::PR12::SET),
624            LineId::Exti13 => self.registers.pr1.write(PR1::PR13::SET),
625            LineId::Exti14 => self.registers.pr1.write(PR1::PR14::SET),
626            LineId::Exti15 => self.registers.pr1.write(PR1::PR15::SET),
627        }
628    }
629
630    pub fn is_pending(&self, lineid: LineId) -> bool {
631        let val = match lineid {
632            LineId::Exti0 => self.registers.pr1.read(PR1::PR0),
633            LineId::Exti1 => self.registers.pr1.read(PR1::PR1),
634            LineId::Exti2 => self.registers.pr1.read(PR1::PR2),
635            LineId::Exti3 => self.registers.pr1.read(PR1::PR3),
636            LineId::Exti4 => self.registers.pr1.read(PR1::PR4),
637            LineId::Exti5 => self.registers.pr1.read(PR1::PR5),
638            LineId::Exti6 => self.registers.pr1.read(PR1::PR6),
639            LineId::Exti7 => self.registers.pr1.read(PR1::PR7),
640            LineId::Exti8 => self.registers.pr1.read(PR1::PR8),
641            LineId::Exti9 => self.registers.pr1.read(PR1::PR9),
642            LineId::Exti10 => self.registers.pr1.read(PR1::PR10),
643            LineId::Exti11 => self.registers.pr1.read(PR1::PR11),
644            LineId::Exti12 => self.registers.pr1.read(PR1::PR12),
645            LineId::Exti13 => self.registers.pr1.read(PR1::PR13),
646            LineId::Exti14 => self.registers.pr1.read(PR1::PR14),
647            LineId::Exti15 => self.registers.pr1.read(PR1::PR15),
648        };
649        val > 0
650    }
651
652    pub fn select_rising_trigger(&self, lineid: LineId) {
653        match lineid {
654            LineId::Exti0 => self.registers.rtsr1.modify(RTSR1::TR0::SET),
655            LineId::Exti1 => self.registers.rtsr1.modify(RTSR1::TR1::SET),
656            LineId::Exti2 => self.registers.rtsr1.modify(RTSR1::TR2::SET),
657            LineId::Exti3 => self.registers.rtsr1.modify(RTSR1::TR3::SET),
658            LineId::Exti4 => self.registers.rtsr1.modify(RTSR1::TR4::SET),
659            LineId::Exti5 => self.registers.rtsr1.modify(RTSR1::TR5::SET),
660            LineId::Exti6 => self.registers.rtsr1.modify(RTSR1::TR6::SET),
661            LineId::Exti7 => self.registers.rtsr1.modify(RTSR1::TR7::SET),
662            LineId::Exti8 => self.registers.rtsr1.modify(RTSR1::TR8::SET),
663            LineId::Exti9 => self.registers.rtsr1.modify(RTSR1::TR9::SET),
664            LineId::Exti10 => self.registers.rtsr1.modify(RTSR1::TR10::SET),
665            LineId::Exti11 => self.registers.rtsr1.modify(RTSR1::TR11::SET),
666            LineId::Exti12 => self.registers.rtsr1.modify(RTSR1::TR12::SET),
667            LineId::Exti13 => self.registers.rtsr1.modify(RTSR1::TR13::SET),
668            LineId::Exti14 => self.registers.rtsr1.modify(RTSR1::TR14::SET),
669            LineId::Exti15 => self.registers.rtsr1.modify(RTSR1::TR15::SET),
670        }
671    }
672
673    pub fn deselect_rising_trigger(&self, lineid: LineId) {
674        match lineid {
675            LineId::Exti0 => self.registers.rtsr1.modify(RTSR1::TR0::CLEAR),
676            LineId::Exti1 => self.registers.rtsr1.modify(RTSR1::TR1::CLEAR),
677            LineId::Exti2 => self.registers.rtsr1.modify(RTSR1::TR2::CLEAR),
678            LineId::Exti3 => self.registers.rtsr1.modify(RTSR1::TR3::CLEAR),
679            LineId::Exti4 => self.registers.rtsr1.modify(RTSR1::TR4::CLEAR),
680            LineId::Exti5 => self.registers.rtsr1.modify(RTSR1::TR5::CLEAR),
681            LineId::Exti6 => self.registers.rtsr1.modify(RTSR1::TR6::CLEAR),
682            LineId::Exti7 => self.registers.rtsr1.modify(RTSR1::TR7::CLEAR),
683            LineId::Exti8 => self.registers.rtsr1.modify(RTSR1::TR8::CLEAR),
684            LineId::Exti9 => self.registers.rtsr1.modify(RTSR1::TR9::CLEAR),
685            LineId::Exti10 => self.registers.rtsr1.modify(RTSR1::TR10::CLEAR),
686            LineId::Exti11 => self.registers.rtsr1.modify(RTSR1::TR11::CLEAR),
687            LineId::Exti12 => self.registers.rtsr1.modify(RTSR1::TR12::CLEAR),
688            LineId::Exti13 => self.registers.rtsr1.modify(RTSR1::TR13::CLEAR),
689            LineId::Exti14 => self.registers.rtsr1.modify(RTSR1::TR14::CLEAR),
690            LineId::Exti15 => self.registers.rtsr1.modify(RTSR1::TR15::CLEAR),
691        }
692    }
693
694    pub fn select_falling_trigger(&self, lineid: LineId) {
695        match lineid {
696            LineId::Exti0 => self.registers.ftsr1.modify(FTSR1::TR0::SET),
697            LineId::Exti1 => self.registers.ftsr1.modify(FTSR1::TR1::SET),
698            LineId::Exti2 => self.registers.ftsr1.modify(FTSR1::TR2::SET),
699            LineId::Exti3 => self.registers.ftsr1.modify(FTSR1::TR3::SET),
700            LineId::Exti4 => self.registers.ftsr1.modify(FTSR1::TR4::SET),
701            LineId::Exti5 => self.registers.ftsr1.modify(FTSR1::TR5::SET),
702            LineId::Exti6 => self.registers.ftsr1.modify(FTSR1::TR6::SET),
703            LineId::Exti7 => self.registers.ftsr1.modify(FTSR1::TR7::SET),
704            LineId::Exti8 => self.registers.ftsr1.modify(FTSR1::TR8::SET),
705            LineId::Exti9 => self.registers.ftsr1.modify(FTSR1::TR9::SET),
706            LineId::Exti10 => self.registers.ftsr1.modify(FTSR1::TR10::SET),
707            LineId::Exti11 => self.registers.ftsr1.modify(FTSR1::TR11::SET),
708            LineId::Exti12 => self.registers.ftsr1.modify(FTSR1::TR12::SET),
709            LineId::Exti13 => self.registers.ftsr1.modify(FTSR1::TR13::SET),
710            LineId::Exti14 => self.registers.ftsr1.modify(FTSR1::TR14::SET),
711            LineId::Exti15 => self.registers.ftsr1.modify(FTSR1::TR15::SET),
712        }
713    }
714
715    pub fn deselect_falling_trigger(&self, lineid: LineId) {
716        match lineid {
717            LineId::Exti0 => self.registers.ftsr1.modify(FTSR1::TR0::CLEAR),
718            LineId::Exti1 => self.registers.ftsr1.modify(FTSR1::TR1::CLEAR),
719            LineId::Exti2 => self.registers.ftsr1.modify(FTSR1::TR2::CLEAR),
720            LineId::Exti3 => self.registers.ftsr1.modify(FTSR1::TR3::CLEAR),
721            LineId::Exti4 => self.registers.ftsr1.modify(FTSR1::TR4::CLEAR),
722            LineId::Exti5 => self.registers.ftsr1.modify(FTSR1::TR5::CLEAR),
723            LineId::Exti6 => self.registers.ftsr1.modify(FTSR1::TR6::CLEAR),
724            LineId::Exti7 => self.registers.ftsr1.modify(FTSR1::TR7::CLEAR),
725            LineId::Exti8 => self.registers.ftsr1.modify(FTSR1::TR8::CLEAR),
726            LineId::Exti9 => self.registers.ftsr1.modify(FTSR1::TR9::CLEAR),
727            LineId::Exti10 => self.registers.ftsr1.modify(FTSR1::TR10::CLEAR),
728            LineId::Exti11 => self.registers.ftsr1.modify(FTSR1::TR11::CLEAR),
729            LineId::Exti12 => self.registers.ftsr1.modify(FTSR1::TR12::CLEAR),
730            LineId::Exti13 => self.registers.ftsr1.modify(FTSR1::TR13::CLEAR),
731            LineId::Exti14 => self.registers.ftsr1.modify(FTSR1::TR14::CLEAR),
732            LineId::Exti15 => self.registers.ftsr1.modify(FTSR1::TR15::CLEAR),
733        }
734    }
735
736    pub fn handle_interrupt(&self) {
737        let mut exti_pr: u32 = 0;
738
739        unsafe {
746            with_interrupts_disabled(|| {
747                exti_pr = self.registers.pr1.get();
748                self.registers.pr1.set(exti_pr);
749            });
750        }
751
752        exti_pr |= 0x007fffff;
755
756        let mut flagged_bit = 0;
757
758        while exti_pr != 0 {
760            if (exti_pr & 0b1) != 0 {
761                if let Some(d) = LineId::from_u8(flagged_bit) {
762                    self.line_gpiopin_map[usize::from(d as u8)].map(|pin| pin.handle_interrupt());
763                }
764            }
765            flagged_bit += 1;
767            exti_pr >>= 1;
768        }
769    }
770}
771
772struct ExtiClock<'a>(&'a syscfg::Syscfg<'a>);
775
776impl ClockInterface for ExtiClock<'_> {
777    fn is_enabled(&self) -> bool {
778        self.0.is_enabled_clock()
779    }
780
781    fn enable(&self) {
782        self.0.enable_clock();
783    }
784
785    fn disable(&self) {
786        self.0.disable_clock();
787    }
788}