1use cortexm4f::support::atomic;
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 atomic(|| {
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 atomic(|| {
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}