1use cortexm4f::support::with_interrupts_disabled;
6use enum_primitive::cast::FromPrimitive;
7use enum_primitive::enum_from_primitive;
8use kernel::hil;
9use kernel::platform::chip::ClockInterface;
10use kernel::utilities::cells::OptionalCell;
11use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable};
12use kernel::utilities::registers::{register_bitfields, ReadOnly, ReadWrite, WriteOnly};
13use kernel::utilities::StaticRef;
14
15use crate::clocks::{phclk, Stm32f4Clocks};
16use crate::exti::{self, LineId};
17
18#[repr(C)]
20struct GpioRegisters {
21    moder: ReadWrite<u32, MODER::Register>,
23    otyper: ReadWrite<u32, OTYPER::Register>,
25    ospeedr: ReadWrite<u32, OSPEEDR::Register>,
27    pupdr: ReadWrite<u32, PUPDR::Register>,
29    idr: ReadOnly<u32, IDR::Register>,
31    odr: ReadWrite<u32, ODR::Register>,
33    bsrr: WriteOnly<u32, BSRR::Register>,
35    lckr: ReadWrite<u32, LCKR::Register>,
37    afrl: ReadWrite<u32, AFRL::Register>,
39    afrh: ReadWrite<u32, AFRH::Register>,
41}
42
43register_bitfields![u32,
44    MODER [
45        MODER15 OFFSET(30) NUMBITS(2) [],
47        MODER14 OFFSET(28) NUMBITS(2) [],
49        MODER13 OFFSET(26) NUMBITS(2) [],
51        MODER12 OFFSET(24) NUMBITS(2) [],
53        MODER11 OFFSET(22) NUMBITS(2) [],
55        MODER10 OFFSET(20) NUMBITS(2) [],
57        MODER9 OFFSET(18) NUMBITS(2) [],
59        MODER8 OFFSET(16) NUMBITS(2) [],
61        MODER7 OFFSET(14) NUMBITS(2) [],
63        MODER6 OFFSET(12) NUMBITS(2) [],
65        MODER5 OFFSET(10) NUMBITS(2) [],
67        MODER4 OFFSET(8) NUMBITS(2) [],
69        MODER3 OFFSET(6) NUMBITS(2) [],
71        MODER2 OFFSET(4) NUMBITS(2) [],
73        MODER1 OFFSET(2) NUMBITS(2) [],
75        MODER0 OFFSET(0) NUMBITS(2) []
77    ],
78    OTYPER [
79        OT15 OFFSET(15) NUMBITS(1) [],
81        OT14 OFFSET(14) NUMBITS(1) [],
83        OT13 OFFSET(13) NUMBITS(1) [],
85        OT12 OFFSET(12) NUMBITS(1) [],
87        OT11 OFFSET(11) NUMBITS(1) [],
89        OT10 OFFSET(10) NUMBITS(1) [],
91        OT9 OFFSET(9) NUMBITS(1) [],
93        OT8 OFFSET(8) NUMBITS(1) [],
95        OT7 OFFSET(7) NUMBITS(1) [],
97        OT6 OFFSET(6) NUMBITS(1) [],
99        OT5 OFFSET(5) NUMBITS(1) [],
101        OT4 OFFSET(4) NUMBITS(1) [],
103        OT3 OFFSET(3) NUMBITS(1) [],
105        OT2 OFFSET(2) NUMBITS(1) [],
107        OT1 OFFSET(1) NUMBITS(1) [],
109        OT0 OFFSET(0) NUMBITS(1) []
111    ],
112    OSPEEDR [
113        OSPEEDR15 OFFSET(30) NUMBITS(2) [],
115        OSPEEDR14 OFFSET(28) NUMBITS(2) [],
117        OSPEEDR13 OFFSET(26) NUMBITS(2) [],
119        OSPEEDR12 OFFSET(24) NUMBITS(2) [],
121        OSPEEDR11 OFFSET(22) NUMBITS(2) [],
123        OSPEEDR10 OFFSET(20) NUMBITS(2) [],
125        OSPEEDR9 OFFSET(18) NUMBITS(2) [],
127        OSPEEDR8 OFFSET(16) NUMBITS(2) [],
129        OSPEEDR7 OFFSET(14) NUMBITS(2) [],
131        OSPEEDR6 OFFSET(12) NUMBITS(2) [],
133        OSPEEDR5 OFFSET(10) NUMBITS(2) [],
135        OSPEEDR4 OFFSET(8) NUMBITS(2) [],
137        OSPEEDR3 OFFSET(6) NUMBITS(2) [],
139        OSPEEDR2 OFFSET(4) NUMBITS(2) [],
141        OSPEEDR1 OFFSET(2) NUMBITS(2) [],
143        OSPEEDR0 OFFSET(0) NUMBITS(2) []
145    ],
146    PUPDR [
147        PUPDR15 OFFSET(30) NUMBITS(2) [],
149        PUPDR14 OFFSET(28) NUMBITS(2) [],
151        PUPDR13 OFFSET(26) NUMBITS(2) [],
153        PUPDR12 OFFSET(24) NUMBITS(2) [],
155        PUPDR11 OFFSET(22) NUMBITS(2) [],
157        PUPDR10 OFFSET(20) NUMBITS(2) [],
159        PUPDR9 OFFSET(18) NUMBITS(2) [],
161        PUPDR8 OFFSET(16) NUMBITS(2) [],
163        PUPDR7 OFFSET(14) NUMBITS(2) [],
165        PUPDR6 OFFSET(12) NUMBITS(2) [],
167        PUPDR5 OFFSET(10) NUMBITS(2) [],
169        PUPDR4 OFFSET(8) NUMBITS(2) [],
171        PUPDR3 OFFSET(6) NUMBITS(2) [],
173        PUPDR2 OFFSET(4) NUMBITS(2) [],
175        PUPDR1 OFFSET(2) NUMBITS(2) [],
177        PUPDR0 OFFSET(0) NUMBITS(2) []
179    ],
180    IDR [
181        IDR15 OFFSET(15) NUMBITS(1) [],
183        IDR14 OFFSET(14) NUMBITS(1) [],
185        IDR13 OFFSET(13) NUMBITS(1) [],
187        IDR12 OFFSET(12) NUMBITS(1) [],
189        IDR11 OFFSET(11) NUMBITS(1) [],
191        IDR10 OFFSET(10) NUMBITS(1) [],
193        IDR9 OFFSET(9) NUMBITS(1) [],
195        IDR8 OFFSET(8) NUMBITS(1) [],
197        IDR7 OFFSET(7) NUMBITS(1) [],
199        IDR6 OFFSET(6) NUMBITS(1) [],
201        IDR5 OFFSET(5) NUMBITS(1) [],
203        IDR4 OFFSET(4) NUMBITS(1) [],
205        IDR3 OFFSET(3) NUMBITS(1) [],
207        IDR2 OFFSET(2) NUMBITS(1) [],
209        IDR1 OFFSET(1) NUMBITS(1) [],
211        IDR0 OFFSET(0) NUMBITS(1) []
213    ],
214    ODR [
215        ODR15 OFFSET(15) NUMBITS(1) [],
217        ODR14 OFFSET(14) NUMBITS(1) [],
219        ODR13 OFFSET(13) NUMBITS(1) [],
221        ODR12 OFFSET(12) NUMBITS(1) [],
223        ODR11 OFFSET(11) NUMBITS(1) [],
225        ODR10 OFFSET(10) NUMBITS(1) [],
227        ODR9 OFFSET(9) NUMBITS(1) [],
229        ODR8 OFFSET(8) NUMBITS(1) [],
231        ODR7 OFFSET(7) NUMBITS(1) [],
233        ODR6 OFFSET(6) NUMBITS(1) [],
235        ODR5 OFFSET(5) NUMBITS(1) [],
237        ODR4 OFFSET(4) NUMBITS(1) [],
239        ODR3 OFFSET(3) NUMBITS(1) [],
241        ODR2 OFFSET(2) NUMBITS(1) [],
243        ODR1 OFFSET(1) NUMBITS(1) [],
245        ODR0 OFFSET(0) NUMBITS(1) []
247    ],
248    BSRR [
249        BR15 OFFSET(31) NUMBITS(1) [],
251        BR14 OFFSET(30) NUMBITS(1) [],
253        BR13 OFFSET(29) NUMBITS(1) [],
255        BR12 OFFSET(28) NUMBITS(1) [],
257        BR11 OFFSET(27) NUMBITS(1) [],
259        BR10 OFFSET(26) NUMBITS(1) [],
261        BR9 OFFSET(25) NUMBITS(1) [],
263        BR8 OFFSET(24) NUMBITS(1) [],
265        BR7 OFFSET(23) NUMBITS(1) [],
267        BR6 OFFSET(22) NUMBITS(1) [],
269        BR5 OFFSET(21) NUMBITS(1) [],
271        BR4 OFFSET(20) NUMBITS(1) [],
273        BR3 OFFSET(19) NUMBITS(1) [],
275        BR2 OFFSET(18) NUMBITS(1) [],
277        BR1 OFFSET(17) NUMBITS(1) [],
279        BR0 OFFSET(16) NUMBITS(1) [],
281        BS15 OFFSET(15) NUMBITS(1) [],
283        BS14 OFFSET(14) NUMBITS(1) [],
285        BS13 OFFSET(13) NUMBITS(1) [],
287        BS12 OFFSET(12) NUMBITS(1) [],
289        BS11 OFFSET(11) NUMBITS(1) [],
291        BS10 OFFSET(10) NUMBITS(1) [],
293        BS9 OFFSET(9) NUMBITS(1) [],
295        BS8 OFFSET(8) NUMBITS(1) [],
297        BS7 OFFSET(7) NUMBITS(1) [],
299        BS6 OFFSET(6) NUMBITS(1) [],
301        BS5 OFFSET(5) NUMBITS(1) [],
303        BS4 OFFSET(4) NUMBITS(1) [],
305        BS3 OFFSET(3) NUMBITS(1) [],
307        BS2 OFFSET(2) NUMBITS(1) [],
309        BS1 OFFSET(1) NUMBITS(1) [],
311        BS0 OFFSET(0) NUMBITS(1) []
313    ],
314    LCKR [
315        LCKK OFFSET(16) NUMBITS(1) [],
317        LCK15 OFFSET(15) NUMBITS(1) [],
319        LCK14 OFFSET(14) NUMBITS(1) [],
321        LCK13 OFFSET(13) NUMBITS(1) [],
323        LCK12 OFFSET(12) NUMBITS(1) [],
325        LCK11 OFFSET(11) NUMBITS(1) [],
327        LCK10 OFFSET(10) NUMBITS(1) [],
329        LCK9 OFFSET(9) NUMBITS(1) [],
331        LCK8 OFFSET(8) NUMBITS(1) [],
333        LCK7 OFFSET(7) NUMBITS(1) [],
335        LCK6 OFFSET(6) NUMBITS(1) [],
337        LCK5 OFFSET(5) NUMBITS(1) [],
339        LCK4 OFFSET(4) NUMBITS(1) [],
341        LCK3 OFFSET(3) NUMBITS(1) [],
343        LCK2 OFFSET(2) NUMBITS(1) [],
345        LCK1 OFFSET(1) NUMBITS(1) [],
347        LCK0 OFFSET(0) NUMBITS(1) []
349    ],
350    AFRL [
351        AFRL7 OFFSET(28) NUMBITS(4) [],
353        AFRL6 OFFSET(24) NUMBITS(4) [],
355        AFRL5 OFFSET(20) NUMBITS(4) [],
357        AFRL4 OFFSET(16) NUMBITS(4) [],
359        AFRL3 OFFSET(12) NUMBITS(4) [],
361        AFRL2 OFFSET(8) NUMBITS(4) [],
363        AFRL1 OFFSET(4) NUMBITS(4) [],
365        AFRL0 OFFSET(0) NUMBITS(4) []
367    ],
368    AFRH [
369        AFRH15 OFFSET(28) NUMBITS(4) [],
371        AFRH14 OFFSET(24) NUMBITS(4) [],
373        AFRH13 OFFSET(20) NUMBITS(4) [],
375        AFRH12 OFFSET(16) NUMBITS(4) [],
377        AFRH11 OFFSET(12) NUMBITS(4) [],
379        AFRH10 OFFSET(8) NUMBITS(4) [],
381        AFRH9 OFFSET(4) NUMBITS(4) [],
383        AFRH8 OFFSET(0) NUMBITS(4) []
385    ]
386];
387
388const GPIOH_BASE: StaticRef<GpioRegisters> =
389    unsafe { StaticRef::new(0x40021C00 as *const GpioRegisters) };
390
391const GPIOG_BASE: StaticRef<GpioRegisters> =
392    unsafe { StaticRef::new(0x40021800 as *const GpioRegisters) };
393
394const GPIOF_BASE: StaticRef<GpioRegisters> =
395    unsafe { StaticRef::new(0x40021400 as *const GpioRegisters) };
396
397const GPIOE_BASE: StaticRef<GpioRegisters> =
398    unsafe { StaticRef::new(0x40021000 as *const GpioRegisters) };
399
400const GPIOD_BASE: StaticRef<GpioRegisters> =
401    unsafe { StaticRef::new(0x40020C00 as *const GpioRegisters) };
402
403const GPIOC_BASE: StaticRef<GpioRegisters> =
404    unsafe { StaticRef::new(0x40020800 as *const GpioRegisters) };
405
406const GPIOB_BASE: StaticRef<GpioRegisters> =
407    unsafe { StaticRef::new(0x40020400 as *const GpioRegisters) };
408
409const GPIOA_BASE: StaticRef<GpioRegisters> =
410    unsafe { StaticRef::new(0x40020000 as *const GpioRegisters) };
411
412#[repr(u32)]
417pub enum PortId {
418    A = 0b000,
419    B = 0b001,
420    C = 0b010,
421    D = 0b011,
422    E = 0b100,
423    F = 0b101,
424    G = 0b110,
425    H = 0b111,
426}
427
428#[rustfmt::skip]
439#[repr(u8)]
440#[derive(Copy, Clone)]
441pub enum PinId {
442    PA00 = 0b0000000, PA01 = 0b0000001, PA02 = 0b0000010, PA03 = 0b0000011,
443    PA04 = 0b0000100, PA05 = 0b0000101, PA06 = 0b0000110, PA07 = 0b0000111,
444    PA08 = 0b0001000, PA09 = 0b0001001, PA10 = 0b0001010, PA11 = 0b0001011,
445    PA12 = 0b0001100, PA13 = 0b0001101, PA14 = 0b0001110, PA15 = 0b0001111,
446
447    PB00 = 0b0010000, PB01 = 0b0010001, PB02 = 0b0010010, PB03 = 0b0010011,
448    PB04 = 0b0010100, PB05 = 0b0010101, PB06 = 0b0010110, PB07 = 0b0010111,
449    PB08 = 0b0011000, PB09 = 0b0011001, PB10 = 0b0011010, PB11 = 0b0011011,
450    PB12 = 0b0011100, PB13 = 0b0011101, PB14 = 0b0011110, PB15 = 0b0011111,
451
452    PC00 = 0b0100000, PC01 = 0b0100001, PC02 = 0b0100010, PC03 = 0b0100011,
453    PC04 = 0b0100100, PC05 = 0b0100101, PC06 = 0b0100110, PC07 = 0b0100111,
454    PC08 = 0b0101000, PC09 = 0b0101001, PC10 = 0b0101010, PC11 = 0b0101011,
455    PC12 = 0b0101100, PC13 = 0b0101101, PC14 = 0b0101110, PC15 = 0b0101111,
456
457    PD00 = 0b0110000, PD01 = 0b0110001, PD02 = 0b0110010, PD03 = 0b0110011,
458    PD04 = 0b0110100, PD05 = 0b0110101, PD06 = 0b0110110, PD07 = 0b0110111,
459    PD08 = 0b0111000, PD09 = 0b0111001, PD10 = 0b0111010, PD11 = 0b0111011,
460    PD12 = 0b0111100, PD13 = 0b0111101, PD14 = 0b0111110, PD15 = 0b0111111,
461
462    PE00 = 0b1000000, PE01 = 0b1000001, PE02 = 0b1000010, PE03 = 0b1000011,
463    PE04 = 0b1000100, PE05 = 0b1000101, PE06 = 0b1000110, PE07 = 0b1000111,
464    PE08 = 0b1001000, PE09 = 0b1001001, PE10 = 0b1001010, PE11 = 0b1001011,
465    PE12 = 0b1001100, PE13 = 0b1001101, PE14 = 0b1001110, PE15 = 0b1001111,
466
467    PF00 = 0b1010000, PF01 = 0b1010001, PF02 = 0b1010010, PF03 = 0b1010011,
468    PF04 = 0b1010100, PF05 = 0b1010101, PF06 = 0b1010110, PF07 = 0b1010111,
469    PF08 = 0b1011000, PF09 = 0b1011001, PF10 = 0b1011010, PF11 = 0b1011011,
470    PF12 = 0b1011100, PF13 = 0b1011101, PF14 = 0b1011110, PF15 = 0b1011111,
471
472    PG00 = 0b1100000, PG01 = 0b1100001, PG02 = 0b1100010, PG03 = 0b1100011,
473    PG04 = 0b1100100, PG05 = 0b1100101, PG06 = 0b1100110, PG07 = 0b1100111,
474    PG08 = 0b1101000, PG09 = 0b1101001, PG10 = 0b1101010, PG11 = 0b1101011,
475    PG12 = 0b1101100, PG13 = 0b1101101, PG14 = 0b1101110, PG15 = 0b1101111,
476
477    PH00 = 0b1110000, PH01 = 0b1110001,
478}
479
480impl<'a> GpioPorts<'a> {
481    pub fn get_pin(&self, pinid: PinId) -> Option<&Pin<'a>> {
482        let mut port_num: u8 = pinid as u8;
483
484        port_num >>= 4;
486
487        let mut pin_num: u8 = pinid as u8;
488        pin_num &= 0b0001111;
490
491        self.pins[usize::from(port_num)][usize::from(pin_num)].as_ref()
492    }
493
494    pub fn get_port(&self, pinid: PinId) -> &Port {
495        let mut port_num: u8 = pinid as u8;
496
497        port_num >>= 4;
499        &self.ports[usize::from(port_num)]
500    }
501
502    pub fn get_port_from_port_id(&self, portid: PortId) -> &Port {
503        &self.ports[portid as usize]
504    }
505}
506
507impl PinId {
508    pub fn get_pin_number(&self) -> u8 {
511        let mut pin_num = *self as u8;
512
513        pin_num &= 0b00001111;
514        pin_num
515    }
516
517    pub fn get_port_number(&self) -> u8 {
519        let mut port_num: u8 = *self as u8;
520
521        port_num >>= 4;
523        port_num
524    }
525}
526
527enum_from_primitive! {
528    #[repr(u32)]
529    #[derive(PartialEq)]
530    pub enum Mode {
534        Input = 0b00,
535        GeneralPurposeOutputMode = 0b01,
536        AlternateFunctionMode = 0b10,
537        AnalogMode = 0b11,
538    }
539}
540
541#[repr(u32)]
555pub enum AlternateFunction {
556    AF0 = 0b0000,
557    AF1 = 0b0001,
558    AF2 = 0b0010,
559    AF3 = 0b0011,
560    AF4 = 0b0100,
561    AF5 = 0b0101,
562    AF6 = 0b0110,
563    AF7 = 0b0111,
564    AF8 = 0b1000,
565    AF9 = 0b1001,
566    AF10 = 0b1010,
567    AF11 = 0b1011,
568    AF12 = 0b1100,
569    AF13 = 0b1101,
570    AF14 = 0b1110,
571    AF15 = 0b1111,
572}
573
574enum_from_primitive! {
575    #[repr(u32)]
576    enum PullUpPullDown {
580        NoPullUpPullDown = 0b00,
581        PullUp = 0b01,
582        PullDown = 0b10,
583    }
584}
585
586pub struct Port<'a> {
587    registers: StaticRef<GpioRegisters>,
588    clock: PortClock<'a>,
589}
590
591macro_rules! declare_gpio_pins {
592    ($($pin:ident)*, $exti:expr) => {
593        [
594            $(Some(Pin::new(PinId::$pin, $exti)), )*
595        ]
596    }
597}
598
599pub struct GpioPorts<'a> {
606    ports: [Port<'a>; 8],
607    pub pins: [[Option<Pin<'a>>; 16]; 8],
608}
609
610impl<'a> GpioPorts<'a> {
611    pub fn new(clocks: &'a dyn Stm32f4Clocks, exti: &'a exti::Exti<'a>) -> Self {
612        Self {
613            ports: [
614                Port {
615                    registers: GPIOA_BASE,
616                    clock: PortClock(phclk::PeripheralClock::new(
617                        phclk::PeripheralClockType::AHB1(phclk::HCLK1::GPIOA),
618                        clocks,
619                    )),
620                },
621                Port {
622                    registers: GPIOB_BASE,
623                    clock: PortClock(phclk::PeripheralClock::new(
624                        phclk::PeripheralClockType::AHB1(phclk::HCLK1::GPIOB),
625                        clocks,
626                    )),
627                },
628                Port {
629                    registers: GPIOC_BASE,
630                    clock: PortClock(phclk::PeripheralClock::new(
631                        phclk::PeripheralClockType::AHB1(phclk::HCLK1::GPIOC),
632                        clocks,
633                    )),
634                },
635                Port {
636                    registers: GPIOD_BASE,
637                    clock: PortClock(phclk::PeripheralClock::new(
638                        phclk::PeripheralClockType::AHB1(phclk::HCLK1::GPIOD),
639                        clocks,
640                    )),
641                },
642                Port {
643                    registers: GPIOE_BASE,
644                    clock: PortClock(phclk::PeripheralClock::new(
645                        phclk::PeripheralClockType::AHB1(phclk::HCLK1::GPIOE),
646                        clocks,
647                    )),
648                },
649                Port {
650                    registers: GPIOF_BASE,
651                    clock: PortClock(phclk::PeripheralClock::new(
652                        phclk::PeripheralClockType::AHB1(phclk::HCLK1::GPIOF),
653                        clocks,
654                    )),
655                },
656                Port {
657                    registers: GPIOG_BASE,
658                    clock: PortClock(phclk::PeripheralClock::new(
659                        phclk::PeripheralClockType::AHB1(phclk::HCLK1::GPIOG),
660                        clocks,
661                    )),
662                },
663                Port {
664                    registers: GPIOH_BASE,
665                    clock: PortClock(phclk::PeripheralClock::new(
666                        phclk::PeripheralClockType::AHB1(phclk::HCLK1::GPIOH),
667                        clocks,
668                    )),
669                },
670            ],
671            pins: [
672                declare_gpio_pins! {
673                    PA00 PA01 PA02 PA03 PA04 PA05 PA06 PA07
674                    PA08 PA09 PA10 PA11 PA12 PA13 PA14 PA15, exti
675                },
676                declare_gpio_pins! {
677                    PB00 PB01 PB02 PB03 PB04 PB05 PB06 PB07
678                    PB08 PB09 PB10 PB11 PB12 PB13 PB14 PB15, exti
679                },
680                declare_gpio_pins! {
681                    PC00 PC01 PC02 PC03 PC04 PC05 PC06 PC07
682                    PC08 PC09 PC10 PC11 PC12 PC13 PC14 PC15, exti
683                },
684                declare_gpio_pins! {
685                    PD00 PD01 PD02 PD03 PD04 PD05 PD06 PD07
686                    PD08 PD09 PD10 PD11 PD12 PD13 PD14 PD15, exti
687                },
688                declare_gpio_pins! {
689                    PE00 PE01 PE02 PE03 PE04 PE05 PE06 PE07
690                    PE08 PE09 PE10 PE11 PE12 PE13 PE14 PE15, exti
691                },
692                declare_gpio_pins! {
693                    PF00 PF01 PF02 PF03 PF04 PF05 PF06 PF07
694                    PF08 PF09 PF10 PF11 PF12 PF13 PF14 PF15, exti
695                },
696                declare_gpio_pins! {
697                    PG00 PG01 PG02 PG03 PG04 PG05 PG06 PG07
698                    PG08 PG09 PG10 PG11 PG12 PG13 PG14 PG15, exti
699                },
700                [
701                    Some(Pin::new(PinId::PH00, exti)),
702                    Some(Pin::new(PinId::PH01, exti)),
703                    None,
704                    None,
705                    None,
706                    None,
707                    None,
708                    None,
709                    None,
710                    None,
711                    None,
712                    None,
713                    None,
714                    None,
715                    None,
716                    None,
717                ],
718            ],
719        }
720    }
721
722    pub fn setup_circular_deps(&'a self) {
723        for pin_group in self.pins.iter() {
724            for pin in pin_group {
725                pin.as_ref().map(|p| p.set_ports_ref(self));
726            }
727        }
728    }
729}
730
731impl Port<'_> {
732    pub fn is_enabled_clock(&self) -> bool {
733        self.clock.is_enabled()
734    }
735
736    pub fn enable_clock(&self) {
737        self.clock.enable();
738    }
739
740    pub fn disable_clock(&self) {
741        self.clock.disable();
742    }
743}
744
745struct PortClock<'a>(phclk::PeripheralClock<'a>);
746
747impl ClockInterface for PortClock<'_> {
748    fn is_enabled(&self) -> bool {
749        self.0.is_enabled()
750    }
751
752    fn enable(&self) {
753        self.0.enable();
754    }
755
756    fn disable(&self) {
757        self.0.disable();
758    }
759}
760
761pub struct Pin<'a> {
763    pinid: PinId,
764    ports_ref: OptionalCell<&'a GpioPorts<'a>>,
765    exti: &'a exti::Exti<'a>,
766    client: OptionalCell<&'a dyn hil::gpio::Client>,
767    exti_lineid: OptionalCell<exti::LineId>,
768}
769
770impl<'a> Pin<'a> {
771    pub const fn new(pinid: PinId, exti: &'a exti::Exti<'a>) -> Self {
772        Self {
773            pinid,
774            ports_ref: OptionalCell::empty(),
775            exti,
776            client: OptionalCell::empty(),
777            exti_lineid: OptionalCell::empty(),
778        }
779    }
780
781    pub fn set_ports_ref(&self, ports: &'a GpioPorts<'a>) {
782        self.ports_ref.set(ports);
783    }
784
785    pub fn set_client(&self, client: &'a dyn hil::gpio::Client) {
786        self.client.set(client);
787    }
788
789    pub fn handle_interrupt(&self) {
790        self.client.map(|client| client.fired());
791    }
792
793    pub fn get_mode(&self) -> Mode {
794        let port = self.ports_ref.unwrap_or_panic().get_port(self.pinid); let val = match self.pinid.get_pin_number() {
797            0b0000 => port.registers.moder.read(MODER::MODER0),
798            0b0001 => port.registers.moder.read(MODER::MODER1),
799            0b0010 => port.registers.moder.read(MODER::MODER2),
800            0b0011 => port.registers.moder.read(MODER::MODER3),
801            0b0100 => port.registers.moder.read(MODER::MODER4),
802            0b0101 => port.registers.moder.read(MODER::MODER5),
803            0b0110 => port.registers.moder.read(MODER::MODER6),
804            0b0111 => port.registers.moder.read(MODER::MODER7),
805            0b1000 => port.registers.moder.read(MODER::MODER8),
806            0b1001 => port.registers.moder.read(MODER::MODER9),
807            0b1010 => port.registers.moder.read(MODER::MODER10),
808            0b1011 => port.registers.moder.read(MODER::MODER11),
809            0b1100 => port.registers.moder.read(MODER::MODER12),
810            0b1101 => port.registers.moder.read(MODER::MODER13),
811            0b1110 => port.registers.moder.read(MODER::MODER14),
812            0b1111 => port.registers.moder.read(MODER::MODER15),
813            _ => 0,
814        };
815
816        Mode::from_u32(val).unwrap_or(Mode::Input)
817    }
818
819    pub fn set_mode(&self, mode: Mode) {
820        let port = self.ports_ref.unwrap_or_panic().get_port(self.pinid); match self.pinid.get_pin_number() {
823            0b0000 => port.registers.moder.modify(MODER::MODER0.val(mode as u32)),
824            0b0001 => port.registers.moder.modify(MODER::MODER1.val(mode as u32)),
825            0b0010 => port.registers.moder.modify(MODER::MODER2.val(mode as u32)),
826            0b0011 => port.registers.moder.modify(MODER::MODER3.val(mode as u32)),
827            0b0100 => port.registers.moder.modify(MODER::MODER4.val(mode as u32)),
828            0b0101 => port.registers.moder.modify(MODER::MODER5.val(mode as u32)),
829            0b0110 => port.registers.moder.modify(MODER::MODER6.val(mode as u32)),
830            0b0111 => port.registers.moder.modify(MODER::MODER7.val(mode as u32)),
831            0b1000 => port.registers.moder.modify(MODER::MODER8.val(mode as u32)),
832            0b1001 => port.registers.moder.modify(MODER::MODER9.val(mode as u32)),
833            0b1010 => port.registers.moder.modify(MODER::MODER10.val(mode as u32)),
834            0b1011 => port.registers.moder.modify(MODER::MODER11.val(mode as u32)),
835            0b1100 => port.registers.moder.modify(MODER::MODER12.val(mode as u32)),
836            0b1101 => port.registers.moder.modify(MODER::MODER13.val(mode as u32)),
837            0b1110 => port.registers.moder.modify(MODER::MODER14.val(mode as u32)),
838            0b1111 => port.registers.moder.modify(MODER::MODER15.val(mode as u32)),
839            _ => {}
840        }
841    }
842
843    pub fn set_alternate_function(&self, af: AlternateFunction) {
844        let port = self.ports_ref.unwrap_or_panic().get_port(self.pinid); match self.pinid.get_pin_number() {
847            0b0000 => port.registers.afrl.modify(AFRL::AFRL0.val(af as u32)),
848            0b0001 => port.registers.afrl.modify(AFRL::AFRL1.val(af as u32)),
849            0b0010 => port.registers.afrl.modify(AFRL::AFRL2.val(af as u32)),
850            0b0011 => port.registers.afrl.modify(AFRL::AFRL3.val(af as u32)),
851            0b0100 => port.registers.afrl.modify(AFRL::AFRL4.val(af as u32)),
852            0b0101 => port.registers.afrl.modify(AFRL::AFRL5.val(af as u32)),
853            0b0110 => port.registers.afrl.modify(AFRL::AFRL6.val(af as u32)),
854            0b0111 => port.registers.afrl.modify(AFRL::AFRL7.val(af as u32)),
855            0b1000 => port.registers.afrh.modify(AFRH::AFRH8.val(af as u32)),
856            0b1001 => port.registers.afrh.modify(AFRH::AFRH9.val(af as u32)),
857            0b1010 => port.registers.afrh.modify(AFRH::AFRH10.val(af as u32)),
858            0b1011 => port.registers.afrh.modify(AFRH::AFRH11.val(af as u32)),
859            0b1100 => port.registers.afrh.modify(AFRH::AFRH12.val(af as u32)),
860            0b1101 => port.registers.afrh.modify(AFRH::AFRH13.val(af as u32)),
861            0b1110 => port.registers.afrh.modify(AFRH::AFRH14.val(af as u32)),
862            0b1111 => port.registers.afrh.modify(AFRH::AFRH15.val(af as u32)),
863            _ => {}
864        }
865    }
866
867    pub fn get_pinid(&self) -> PinId {
868        self.pinid
869    }
870
871    pub unsafe fn enable_interrupt(&'static self) {
872        let exti_line_id = LineId::from_u8(self.pinid.get_pin_number()).unwrap();
873
874        self.exti.associate_line_gpiopin(exti_line_id, self);
875    }
876
877    pub fn set_exti_lineid(&self, lineid: exti::LineId) {
878        self.exti_lineid.set(lineid);
879    }
880
881    fn set_mode_output_pushpull(&self) {
882        let port = self.ports_ref.unwrap_or_panic().get_port(self.pinid); match self.pinid.get_pin_number() {
885            0b0000 => port.registers.otyper.modify(OTYPER::OT0::CLEAR),
886            0b0001 => port.registers.otyper.modify(OTYPER::OT1::CLEAR),
887            0b0010 => port.registers.otyper.modify(OTYPER::OT2::CLEAR),
888            0b0011 => port.registers.otyper.modify(OTYPER::OT3::CLEAR),
889            0b0100 => port.registers.otyper.modify(OTYPER::OT4::CLEAR),
890            0b0101 => port.registers.otyper.modify(OTYPER::OT5::CLEAR),
891            0b0110 => port.registers.otyper.modify(OTYPER::OT6::CLEAR),
892            0b0111 => port.registers.otyper.modify(OTYPER::OT7::CLEAR),
893            0b1000 => port.registers.otyper.modify(OTYPER::OT8::CLEAR),
894            0b1001 => port.registers.otyper.modify(OTYPER::OT9::CLEAR),
895            0b1010 => port.registers.otyper.modify(OTYPER::OT10::CLEAR),
896            0b1011 => port.registers.otyper.modify(OTYPER::OT11::CLEAR),
897            0b1100 => port.registers.otyper.modify(OTYPER::OT12::CLEAR),
898            0b1101 => port.registers.otyper.modify(OTYPER::OT13::CLEAR),
899            0b1110 => port.registers.otyper.modify(OTYPER::OT14::CLEAR),
900            0b1111 => port.registers.otyper.modify(OTYPER::OT15::CLEAR),
901            _ => {}
902        }
903    }
904
905    pub fn set_speed(&self) {
906        let port = self.ports_ref.unwrap_or_panic().get_port(self.pinid); match self.pinid.get_pin_number() {
909            0b0000 => port.registers.ospeedr.modify(OSPEEDR::OSPEEDR0.val(0b11)),
910            0b0001 => port.registers.ospeedr.modify(OSPEEDR::OSPEEDR1.val(0b11)),
911            0b0010 => port.registers.ospeedr.modify(OSPEEDR::OSPEEDR2.val(0b11)),
912            0b0011 => port.registers.ospeedr.modify(OSPEEDR::OSPEEDR3.val(0b11)),
913            0b0100 => port.registers.ospeedr.modify(OSPEEDR::OSPEEDR4.val(0b11)),
914            0b0101 => port.registers.ospeedr.modify(OSPEEDR::OSPEEDR5.val(0b11)),
915            0b0110 => port.registers.ospeedr.modify(OSPEEDR::OSPEEDR6.val(0b11)),
916            0b0111 => port.registers.ospeedr.modify(OSPEEDR::OSPEEDR7.val(0b11)),
917            0b1000 => port.registers.ospeedr.modify(OSPEEDR::OSPEEDR8.val(0b11)),
918            0b1001 => port.registers.ospeedr.modify(OSPEEDR::OSPEEDR9.val(0b11)),
919            0b1010 => port.registers.ospeedr.modify(OSPEEDR::OSPEEDR10.val(0b11)),
920            0b1011 => port.registers.ospeedr.modify(OSPEEDR::OSPEEDR11.val(0b11)),
921            0b1100 => port.registers.ospeedr.modify(OSPEEDR::OSPEEDR12.val(0b11)),
922            0b1101 => port.registers.ospeedr.modify(OSPEEDR::OSPEEDR13.val(0b11)),
923            0b1110 => port.registers.ospeedr.modify(OSPEEDR::OSPEEDR14.val(0b11)),
924            0b1111 => port.registers.ospeedr.modify(OSPEEDR::OSPEEDR15.val(0b11)),
925            _ => {}
926        }
927    }
928
929    pub fn set_mode_output_opendrain(&self) {
930        let port = self.ports_ref.unwrap_or_panic().get_port(self.pinid); match self.pinid.get_pin_number() {
933            0b0000 => port.registers.otyper.modify(OTYPER::OT0::SET),
934            0b0001 => port.registers.otyper.modify(OTYPER::OT1::SET),
935            0b0010 => port.registers.otyper.modify(OTYPER::OT2::SET),
936            0b0011 => port.registers.otyper.modify(OTYPER::OT3::SET),
937            0b0100 => port.registers.otyper.modify(OTYPER::OT4::SET),
938            0b0101 => port.registers.otyper.modify(OTYPER::OT5::SET),
939            0b0110 => port.registers.otyper.modify(OTYPER::OT6::SET),
940            0b0111 => port.registers.otyper.modify(OTYPER::OT7::SET),
941            0b1000 => port.registers.otyper.modify(OTYPER::OT8::SET),
942            0b1001 => port.registers.otyper.modify(OTYPER::OT9::SET),
943            0b1010 => port.registers.otyper.modify(OTYPER::OT10::SET),
944            0b1011 => port.registers.otyper.modify(OTYPER::OT11::SET),
945            0b1100 => port.registers.otyper.modify(OTYPER::OT12::SET),
946            0b1101 => port.registers.otyper.modify(OTYPER::OT13::SET),
947            0b1110 => port.registers.otyper.modify(OTYPER::OT14::SET),
948            0b1111 => port.registers.otyper.modify(OTYPER::OT15::SET),
949            _ => {}
950        }
951    }
952
953    fn get_pullup_pulldown(&self) -> PullUpPullDown {
954        let port = self.ports_ref.unwrap_or_panic().get_port(self.pinid); let val = match self.pinid.get_pin_number() {
957            0b0000 => port.registers.pupdr.read(PUPDR::PUPDR0),
958            0b0001 => port.registers.pupdr.read(PUPDR::PUPDR1),
959            0b0010 => port.registers.pupdr.read(PUPDR::PUPDR2),
960            0b0011 => port.registers.pupdr.read(PUPDR::PUPDR3),
961            0b0100 => port.registers.pupdr.read(PUPDR::PUPDR4),
962            0b0101 => port.registers.pupdr.read(PUPDR::PUPDR5),
963            0b0110 => port.registers.pupdr.read(PUPDR::PUPDR6),
964            0b0111 => port.registers.pupdr.read(PUPDR::PUPDR7),
965            0b1000 => port.registers.pupdr.read(PUPDR::PUPDR8),
966            0b1001 => port.registers.pupdr.read(PUPDR::PUPDR9),
967            0b1010 => port.registers.pupdr.read(PUPDR::PUPDR10),
968            0b1011 => port.registers.pupdr.read(PUPDR::PUPDR11),
969            0b1100 => port.registers.pupdr.read(PUPDR::PUPDR12),
970            0b1101 => port.registers.pupdr.read(PUPDR::PUPDR13),
971            0b1110 => port.registers.pupdr.read(PUPDR::PUPDR14),
972            0b1111 => port.registers.pupdr.read(PUPDR::PUPDR15),
973            _ => 0,
974        };
975
976        PullUpPullDown::from_u32(val).unwrap_or(PullUpPullDown::NoPullUpPullDown)
977    }
978
979    fn set_pullup_pulldown(&self, pupd: PullUpPullDown) {
980        let port = self.ports_ref.unwrap_or_panic().get_port(self.pinid); match self.pinid.get_pin_number() {
983            0b0000 => port.registers.pupdr.modify(PUPDR::PUPDR0.val(pupd as u32)),
984            0b0001 => port.registers.pupdr.modify(PUPDR::PUPDR1.val(pupd as u32)),
985            0b0010 => port.registers.pupdr.modify(PUPDR::PUPDR2.val(pupd as u32)),
986            0b0011 => port.registers.pupdr.modify(PUPDR::PUPDR3.val(pupd as u32)),
987            0b0100 => port.registers.pupdr.modify(PUPDR::PUPDR4.val(pupd as u32)),
988            0b0101 => port.registers.pupdr.modify(PUPDR::PUPDR5.val(pupd as u32)),
989            0b0110 => port.registers.pupdr.modify(PUPDR::PUPDR6.val(pupd as u32)),
990            0b0111 => port.registers.pupdr.modify(PUPDR::PUPDR7.val(pupd as u32)),
991            0b1000 => port.registers.pupdr.modify(PUPDR::PUPDR8.val(pupd as u32)),
992            0b1001 => port.registers.pupdr.modify(PUPDR::PUPDR9.val(pupd as u32)),
993            0b1010 => port.registers.pupdr.modify(PUPDR::PUPDR10.val(pupd as u32)),
994            0b1011 => port.registers.pupdr.modify(PUPDR::PUPDR11.val(pupd as u32)),
995            0b1100 => port.registers.pupdr.modify(PUPDR::PUPDR12.val(pupd as u32)),
996            0b1101 => port.registers.pupdr.modify(PUPDR::PUPDR13.val(pupd as u32)),
997            0b1110 => port.registers.pupdr.modify(PUPDR::PUPDR14.val(pupd as u32)),
998            0b1111 => port.registers.pupdr.modify(PUPDR::PUPDR15.val(pupd as u32)),
999            _ => {}
1000        }
1001    }
1002
1003    fn set_output_high(&self) {
1004        let port = self.ports_ref.unwrap_or_panic().get_port(self.pinid); match self.pinid.get_pin_number() {
1007            0b0000 => port.registers.bsrr.write(BSRR::BS0::SET),
1008            0b0001 => port.registers.bsrr.write(BSRR::BS1::SET),
1009            0b0010 => port.registers.bsrr.write(BSRR::BS2::SET),
1010            0b0011 => port.registers.bsrr.write(BSRR::BS3::SET),
1011            0b0100 => port.registers.bsrr.write(BSRR::BS4::SET),
1012            0b0101 => port.registers.bsrr.write(BSRR::BS5::SET),
1013            0b0110 => port.registers.bsrr.write(BSRR::BS6::SET),
1014            0b0111 => port.registers.bsrr.write(BSRR::BS7::SET),
1015            0b1000 => port.registers.bsrr.write(BSRR::BS8::SET),
1016            0b1001 => port.registers.bsrr.write(BSRR::BS9::SET),
1017            0b1010 => port.registers.bsrr.write(BSRR::BS10::SET),
1018            0b1011 => port.registers.bsrr.write(BSRR::BS11::SET),
1019            0b1100 => port.registers.bsrr.write(BSRR::BS12::SET),
1020            0b1101 => port.registers.bsrr.write(BSRR::BS13::SET),
1021            0b1110 => port.registers.bsrr.write(BSRR::BS14::SET),
1022            0b1111 => port.registers.bsrr.write(BSRR::BS15::SET),
1023            _ => {}
1024        }
1025    }
1026
1027    fn set_output_low(&self) {
1028        let port = self.ports_ref.unwrap_or_panic().get_port(self.pinid); match self.pinid.get_pin_number() {
1031            0b0000 => port.registers.bsrr.write(BSRR::BR0::SET),
1032            0b0001 => port.registers.bsrr.write(BSRR::BR1::SET),
1033            0b0010 => port.registers.bsrr.write(BSRR::BR2::SET),
1034            0b0011 => port.registers.bsrr.write(BSRR::BR3::SET),
1035            0b0100 => port.registers.bsrr.write(BSRR::BR4::SET),
1036            0b0101 => port.registers.bsrr.write(BSRR::BR5::SET),
1037            0b0110 => port.registers.bsrr.write(BSRR::BR6::SET),
1038            0b0111 => port.registers.bsrr.write(BSRR::BR7::SET),
1039            0b1000 => port.registers.bsrr.write(BSRR::BR8::SET),
1040            0b1001 => port.registers.bsrr.write(BSRR::BR9::SET),
1041            0b1010 => port.registers.bsrr.write(BSRR::BR10::SET),
1042            0b1011 => port.registers.bsrr.write(BSRR::BR11::SET),
1043            0b1100 => port.registers.bsrr.write(BSRR::BR12::SET),
1044            0b1101 => port.registers.bsrr.write(BSRR::BR13::SET),
1045            0b1110 => port.registers.bsrr.write(BSRR::BR14::SET),
1046            0b1111 => port.registers.bsrr.write(BSRR::BR15::SET),
1047            _ => {}
1048        }
1049    }
1050
1051    fn is_output_high(&self) -> bool {
1052        let port = self.ports_ref.unwrap_or_panic().get_port(self.pinid); match self.pinid.get_pin_number() {
1055            0b0000 => port.registers.odr.is_set(ODR::ODR0),
1056            0b0001 => port.registers.odr.is_set(ODR::ODR1),
1057            0b0010 => port.registers.odr.is_set(ODR::ODR2),
1058            0b0011 => port.registers.odr.is_set(ODR::ODR3),
1059            0b0100 => port.registers.odr.is_set(ODR::ODR4),
1060            0b0101 => port.registers.odr.is_set(ODR::ODR5),
1061            0b0110 => port.registers.odr.is_set(ODR::ODR6),
1062            0b0111 => port.registers.odr.is_set(ODR::ODR7),
1063            0b1000 => port.registers.odr.is_set(ODR::ODR8),
1064            0b1001 => port.registers.odr.is_set(ODR::ODR9),
1065            0b1010 => port.registers.odr.is_set(ODR::ODR10),
1066            0b1011 => port.registers.odr.is_set(ODR::ODR11),
1067            0b1100 => port.registers.odr.is_set(ODR::ODR12),
1068            0b1101 => port.registers.odr.is_set(ODR::ODR13),
1069            0b1110 => port.registers.odr.is_set(ODR::ODR14),
1070            0b1111 => port.registers.odr.is_set(ODR::ODR15),
1071            _ => false,
1072        }
1073    }
1074
1075    fn toggle_output(&self) -> bool {
1076        if self.is_output_high() {
1077            self.set_output_low();
1078            false
1079        } else {
1080            self.set_output_high();
1081            true
1082        }
1083    }
1084
1085    fn read_input(&self) -> bool {
1086        let port = self.ports_ref.unwrap_or_panic().get_port(self.pinid); match self.pinid.get_pin_number() {
1089            0b0000 => port.registers.idr.is_set(IDR::IDR0),
1090            0b0001 => port.registers.idr.is_set(IDR::IDR1),
1091            0b0010 => port.registers.idr.is_set(IDR::IDR2),
1092            0b0011 => port.registers.idr.is_set(IDR::IDR3),
1093            0b0100 => port.registers.idr.is_set(IDR::IDR4),
1094            0b0101 => port.registers.idr.is_set(IDR::IDR5),
1095            0b0110 => port.registers.idr.is_set(IDR::IDR6),
1096            0b0111 => port.registers.idr.is_set(IDR::IDR7),
1097            0b1000 => port.registers.idr.is_set(IDR::IDR8),
1098            0b1001 => port.registers.idr.is_set(IDR::IDR9),
1099            0b1010 => port.registers.idr.is_set(IDR::IDR10),
1100            0b1011 => port.registers.idr.is_set(IDR::IDR11),
1101            0b1100 => port.registers.idr.is_set(IDR::IDR12),
1102            0b1101 => port.registers.idr.is_set(IDR::IDR13),
1103            0b1110 => port.registers.idr.is_set(IDR::IDR14),
1104            0b1111 => port.registers.idr.is_set(IDR::IDR15),
1105            _ => false,
1106        }
1107    }
1108}
1109
1110impl hil::gpio::Configure for Pin<'_> {
1111    fn make_output(&self) -> hil::gpio::Configuration {
1113        self.set_mode(Mode::GeneralPurposeOutputMode);
1114        self.set_mode_output_pushpull();
1115        hil::gpio::Configuration::Output
1116    }
1117
1118    fn make_input(&self) -> hil::gpio::Configuration {
1123        self.set_mode(Mode::Input);
1124        hil::gpio::Configuration::Input
1125    }
1126
1127    fn deactivate_to_low_power(&self) {
1131        self.set_mode(Mode::AnalogMode);
1132    }
1133
1134    fn disable_output(&self) -> hil::gpio::Configuration {
1135        self.set_mode(Mode::AnalogMode);
1136        hil::gpio::Configuration::LowPower
1137    }
1138
1139    fn disable_input(&self) -> hil::gpio::Configuration {
1140        self.set_mode(Mode::AnalogMode);
1141        hil::gpio::Configuration::LowPower
1142    }
1143
1144    fn set_floating_state(&self, mode: hil::gpio::FloatingState) {
1145        match mode {
1146            hil::gpio::FloatingState::PullUp => self.set_pullup_pulldown(PullUpPullDown::PullUp),
1147            hil::gpio::FloatingState::PullDown => {
1148                self.set_pullup_pulldown(PullUpPullDown::PullDown)
1149            }
1150            hil::gpio::FloatingState::PullNone => {
1151                self.set_pullup_pulldown(PullUpPullDown::NoPullUpPullDown)
1152            }
1153        }
1154    }
1155
1156    fn floating_state(&self) -> hil::gpio::FloatingState {
1157        match self.get_pullup_pulldown() {
1158            PullUpPullDown::PullUp => hil::gpio::FloatingState::PullUp,
1159            PullUpPullDown::PullDown => hil::gpio::FloatingState::PullDown,
1160            PullUpPullDown::NoPullUpPullDown => hil::gpio::FloatingState::PullNone,
1161        }
1162    }
1163
1164    fn configuration(&self) -> hil::gpio::Configuration {
1165        match self.get_mode() {
1166            Mode::Input => hil::gpio::Configuration::Input,
1167            Mode::GeneralPurposeOutputMode => hil::gpio::Configuration::Output,
1168            Mode::AnalogMode => hil::gpio::Configuration::LowPower,
1169            Mode::AlternateFunctionMode => hil::gpio::Configuration::Function,
1170        }
1171    }
1172
1173    fn is_input(&self) -> bool {
1174        self.get_mode() == Mode::Input
1175    }
1176
1177    fn is_output(&self) -> bool {
1178        self.get_mode() == Mode::GeneralPurposeOutputMode
1179    }
1180}
1181
1182impl hil::gpio::Output for Pin<'_> {
1183    fn set(&self) {
1184        self.set_output_high();
1185    }
1186
1187    fn clear(&self) {
1188        self.set_output_low();
1189    }
1190
1191    fn toggle(&self) -> bool {
1192        self.toggle_output()
1193    }
1194}
1195
1196impl hil::gpio::Input for Pin<'_> {
1197    fn read(&self) -> bool {
1198        self.read_input()
1199    }
1200}
1201
1202impl<'a> hil::gpio::Interrupt<'a> for Pin<'a> {
1203    fn enable_interrupts(&self, mode: hil::gpio::InterruptEdge) {
1204        unsafe {
1205            with_interrupts_disabled(|| {
1206                self.exti_lineid.map(|lineid| {
1207                    let l = lineid;
1208
1209                    self.exti.mask_interrupt(l);
1211                    self.exti.clear_pending(l);
1212
1213                    match mode {
1214                        hil::gpio::InterruptEdge::EitherEdge => {
1215                            self.exti.select_rising_trigger(l);
1216                            self.exti.select_falling_trigger(l);
1217                        }
1218                        hil::gpio::InterruptEdge::RisingEdge => {
1219                            self.exti.select_rising_trigger(l);
1220                            self.exti.deselect_falling_trigger(l);
1221                        }
1222                        hil::gpio::InterruptEdge::FallingEdge => {
1223                            self.exti.deselect_rising_trigger(l);
1224                            self.exti.select_falling_trigger(l);
1225                        }
1226                    }
1227
1228                    self.exti.unmask_interrupt(l);
1229                });
1230            });
1231        }
1232    }
1233
1234    fn disable_interrupts(&self) {
1235        unsafe {
1236            with_interrupts_disabled(|| {
1237                self.exti_lineid.map(|lineid| {
1238                    let l = lineid;
1239                    self.exti.mask_interrupt(l);
1240                    self.exti.clear_pending(l);
1241                });
1242            });
1243        }
1244    }
1245
1246    fn set_client(&self, client: &'a dyn hil::gpio::Client) {
1247        self.client.set(client);
1248    }
1249
1250    fn is_pending(&self) -> bool {
1251        self.exti_lineid
1252            .map_or(false, |lineid| self.exti.is_pending(lineid))
1253    }
1254}