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::exti::{self, LineId};
16use crate::rcc;
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 GPIOF_BASE: StaticRef<GpioRegisters> =
389 unsafe { StaticRef::new(0x48001400 as *const GpioRegisters) };
390
391const GPIOE_BASE: StaticRef<GpioRegisters> =
392 unsafe { StaticRef::new(0x48001000 as *const GpioRegisters) };
393
394const GPIOD_BASE: StaticRef<GpioRegisters> =
395 unsafe { StaticRef::new(0x48000C00 as *const GpioRegisters) };
396
397const GPIOC_BASE: StaticRef<GpioRegisters> =
398 unsafe { StaticRef::new(0x48000800 as *const GpioRegisters) };
399
400const GPIOB_BASE: StaticRef<GpioRegisters> =
401 unsafe { StaticRef::new(0x48000400 as *const GpioRegisters) };
402
403const GPIOA_BASE: StaticRef<GpioRegisters> =
404 unsafe { StaticRef::new(0x48000000 as *const GpioRegisters) };
405
406#[repr(u32)]
411pub enum PortId {
412 A = 0b000,
413 B = 0b001,
414 C = 0b010,
415 D = 0b011,
416 E = 0b100,
417 F = 0b101,
418}
419
420#[rustfmt::skip]
431#[repr(u8)]
432#[derive(Copy, Clone)]
433pub enum PinId {
434 PA00 = 0b0000000, PA01 = 0b0000001, PA02 = 0b0000010, PA03 = 0b0000011,
435 PA04 = 0b0000100, PA05 = 0b0000101, PA06 = 0b0000110, PA07 = 0b0000111,
436 PA08 = 0b0001000, PA09 = 0b0001001, PA10 = 0b0001010, PA11 = 0b0001011,
437 PA12 = 0b0001100, PA13 = 0b0001101, PA14 = 0b0001110, PA15 = 0b0001111,
438
439 PB00 = 0b0010000, PB01 = 0b0010001, PB02 = 0b0010010, PB03 = 0b0010011,
440 PB04 = 0b0010100, PB05 = 0b0010101, PB06 = 0b0010110, PB07 = 0b0010111,
441 PB08 = 0b0011000, PB09 = 0b0011001, PB10 = 0b0011010, PB11 = 0b0011011,
442 PB12 = 0b0011100, PB13 = 0b0011101, PB14 = 0b0011110, PB15 = 0b0011111,
443
444 PC00 = 0b0100000, PC01 = 0b0100001, PC02 = 0b0100010, PC03 = 0b0100011,
445 PC04 = 0b0100100, PC05 = 0b0100101, PC06 = 0b0100110, PC07 = 0b0100111,
446 PC08 = 0b0101000, PC09 = 0b0101001, PC10 = 0b0101010, PC11 = 0b0101011,
447 PC12 = 0b0101100, PC13 = 0b0101101, PC14 = 0b0101110, PC15 = 0b0101111,
448
449 PD00 = 0b0110000, PD01 = 0b0110001, PD02 = 0b0110010, PD03 = 0b0110011,
450 PD04 = 0b0110100, PD05 = 0b0110101, PD06 = 0b0110110, PD07 = 0b0110111,
451 PD08 = 0b0111000, PD09 = 0b0111001, PD10 = 0b0111010, PD11 = 0b0111011,
452 PD12 = 0b0111100, PD13 = 0b0111101, PD14 = 0b0111110, PD15 = 0b0111111,
453
454 PE00 = 0b1000000, PE01 = 0b1000001, PE02 = 0b1000010, PE03 = 0b1000011,
455 PE04 = 0b1000100, PE05 = 0b1000101, PE06 = 0b1000110, PE07 = 0b1000111,
456 PE08 = 0b1001000, PE09 = 0b1001001, PE10 = 0b1001010, PE11 = 0b1001011,
457 PE12 = 0b1001100, PE13 = 0b1001101, PE14 = 0b1001110, PE15 = 0b1001111,
458
459 PF00 = 0b1010000, PF01 = 0b1010001, PF02 = 0b1010010, PF03 = 0b1010011,
460 PF04 = 0b1010100, PF05 = 0b1010101, PF06 = 0b1010110, PF07 = 0b1010111,
461 PF08 = 0b1011000, PF09 = 0b1011001, PF10 = 0b1011010, PF11 = 0b1011011,
462 PF12 = 0b1011100, PF13 = 0b1011101, PF14 = 0b1011110, PF15 = 0b1011111,
463}
464
465impl<'a> GpioPorts<'a> {
466 pub fn get_pin(&self, pinid: PinId) -> Option<&Pin<'a>> {
467 let mut port_num: u8 = pinid as u8;
468
469 port_num >>= 4;
471
472 let mut pin_num: u8 = pinid as u8;
473 pin_num &= 0b0001111;
475
476 self.pins[usize::from(port_num)][usize::from(pin_num)].as_ref()
477 }
478
479 pub fn get_port(&self, pinid: PinId) -> &Port {
480 let mut port_num: u8 = pinid as u8;
481
482 port_num >>= 4;
484 &self.ports[usize::from(port_num)]
485 }
486
487 pub fn get_port_from_port_id(&self, portid: PortId) -> &Port {
488 &self.ports[portid as usize]
489 }
490}
491
492impl PinId {
493 pub fn get_pin_number(&self) -> u8 {
496 let mut pin_num = *self as u8;
497
498 pin_num &= 0b00001111;
499 pin_num
500 }
501
502 pub fn get_port_number(&self) -> u8 {
504 let mut port_num: u8 = *self as u8;
505
506 port_num >>= 4;
508 port_num
509 }
510}
511
512enum_from_primitive! {
513 #[repr(u32)]
514 #[derive(PartialEq)]
515 pub enum Mode {
519 Input = 0b00,
520 GeneralPurposeOutputMode = 0b01,
521 AlternateFunctionMode = 0b10,
522 AnalogMode = 0b11,
523 }
524}
525
526#[repr(u32)]
540pub enum AlternateFunction {
541 AF0 = 0b0000,
542 AF1 = 0b0001,
543 AF2 = 0b0010,
544 AF3 = 0b0011,
545 AF4 = 0b0100,
546 AF5 = 0b0101,
547 AF6 = 0b0110,
548 AF7 = 0b0111,
549 AF8 = 0b1000,
550 AF9 = 0b1001,
551 AF10 = 0b1010,
552 AF11 = 0b1011,
553 AF12 = 0b1100,
554 AF13 = 0b1101,
555 AF14 = 0b1110,
556 AF15 = 0b1111,
557}
558
559enum_from_primitive! {
560 #[repr(u32)]
561 enum PullUpPullDown {
565 NoPullUpPullDown = 0b00,
566 PullUp = 0b01,
567 PullDown = 0b10,
568 }
569}
570
571macro_rules! declare_gpio_pins {
572 ($($pin:ident)*, $exti:expr) => {
573 [
574 $(Some(Pin::new(PinId::$pin, $exti)), )*
575 ]
576 }
577}
578
579pub struct GpioPorts<'a> {
584 ports: [Port<'a>; 6],
585 pins: [[Option<Pin<'a>>; 16]; 6],
586}
587
588impl<'a> GpioPorts<'a> {
589 pub fn new(rcc: &'a rcc::Rcc, exti: &'a exti::Exti<'a>) -> Self {
590 Self {
591 ports: [
592 Port {
593 registers: GPIOA_BASE,
594 clock: PortClock(rcc::PeripheralClock::new(
595 rcc::PeripheralClockType::AHB(rcc::HCLK::GPIOA),
596 rcc,
597 )),
598 },
599 Port {
600 registers: GPIOB_BASE,
601 clock: PortClock(rcc::PeripheralClock::new(
602 rcc::PeripheralClockType::AHB(rcc::HCLK::GPIOB),
603 rcc,
604 )),
605 },
606 Port {
607 registers: GPIOC_BASE,
608 clock: PortClock(rcc::PeripheralClock::new(
609 rcc::PeripheralClockType::AHB(rcc::HCLK::GPIOC),
610 rcc,
611 )),
612 },
613 Port {
614 registers: GPIOD_BASE,
615 clock: PortClock(rcc::PeripheralClock::new(
616 rcc::PeripheralClockType::AHB(rcc::HCLK::GPIOD),
617 rcc,
618 )),
619 },
620 Port {
621 registers: GPIOE_BASE,
622 clock: PortClock(rcc::PeripheralClock::new(
623 rcc::PeripheralClockType::AHB(rcc::HCLK::GPIOE),
624 rcc,
625 )),
626 },
627 Port {
628 registers: GPIOF_BASE,
629 clock: PortClock(rcc::PeripheralClock::new(
630 rcc::PeripheralClockType::AHB(rcc::HCLK::GPIOF),
631 rcc,
632 )),
633 },
634 ],
635 pins: [
636 declare_gpio_pins! {
637 PA00 PA01 PA02 PA03 PA04 PA05 PA06 PA07
638 PA08 PA09 PA10 PA11 PA12 PA13 PA14 PA15, exti
639 },
640 declare_gpio_pins! {
641 PB00 PB01 PB02 PB03 PB04 PB05 PB06 PB07
642 PB08 PB09 PB10 PB11 PB12 PB13 PB14 PB15, exti
643 },
644 declare_gpio_pins! {
645 PC00 PC01 PC02 PC03 PC04 PC05 PC06 PC07
646 PC08 PC09 PC10 PC11 PC12 PC13 PC14 PC15, exti
647 },
648 declare_gpio_pins! {
649 PD00 PD01 PD02 PD03 PD04 PD05 PD06 PD07
650 PD08 PD09 PD10 PD11 PD12 PD13 PD14 PD15, exti
651 },
652 declare_gpio_pins! {
653 PE00 PE01 PE02 PE03 PE04 PE05 PE06 PE07
654 PE08 PE09 PE10 PE11 PE12 PE13 PE14 PE15, exti
655 },
656 [
657 Some(Pin::new(PinId::PF00, exti)),
658 Some(Pin::new(PinId::PF01, exti)),
659 Some(Pin::new(PinId::PF02, exti)),
660 Some(Pin::new(PinId::PF03, exti)),
661 Some(Pin::new(PinId::PF04, exti)),
662 Some(Pin::new(PinId::PF05, exti)),
663 Some(Pin::new(PinId::PF06, exti)),
664 Some(Pin::new(PinId::PF07, exti)),
665 Some(Pin::new(PinId::PF08, exti)),
666 Some(Pin::new(PinId::PF09, exti)),
667 Some(Pin::new(PinId::PF10, exti)),
668 None,
669 None,
670 None,
671 None,
672 None,
673 ],
674 ],
675 }
676 }
677
678 pub fn setup_circular_deps(&'a self) {
679 for pin_group in self.pins.iter() {
680 for pin in pin_group {
681 pin.as_ref().map(|p| p.set_ports_ref(self));
682 }
683 }
684 }
685}
686
687pub struct Port<'a> {
688 registers: StaticRef<GpioRegisters>,
689 clock: PortClock<'a>,
690}
691
692impl Port<'_> {
693 pub fn is_enabled_clock(&self) -> bool {
694 self.clock.is_enabled()
695 }
696
697 pub fn enable_clock(&self) {
698 self.clock.enable();
699 }
700
701 pub fn disable_clock(&self) {
702 self.clock.disable();
703 }
704}
705
706struct PortClock<'a>(rcc::PeripheralClock<'a>);
707
708impl ClockInterface for PortClock<'_> {
709 fn is_enabled(&self) -> bool {
710 self.0.is_enabled()
711 }
712
713 fn enable(&self) {
714 self.0.enable();
715 }
716
717 fn disable(&self) {
718 self.0.disable();
719 }
720}
721
722pub struct Pin<'a> {
724 pinid: PinId,
725 ports_ref: OptionalCell<&'a GpioPorts<'a>>,
726 exti: &'a exti::Exti<'a>,
727 client: OptionalCell<&'a dyn hil::gpio::Client>,
728 exti_lineid: OptionalCell<exti::LineId>,
729}
730
731impl<'a> Pin<'a> {
732 pub const fn new(pinid: PinId, exti: &'a exti::Exti<'a>) -> Self {
733 Self {
734 pinid,
735 ports_ref: OptionalCell::empty(),
736 exti,
737 client: OptionalCell::empty(),
738 exti_lineid: OptionalCell::empty(),
739 }
740 }
741
742 pub fn set_ports_ref(&self, ports: &'a GpioPorts<'a>) {
743 self.ports_ref.set(ports);
744 }
745
746 pub fn set_client(&self, client: &'a dyn hil::gpio::Client) {
747 self.client.set(client);
748 }
749
750 pub fn handle_interrupt(&self) {
751 self.client.map(|client| client.fired());
752 }
753
754 pub fn get_mode(&self) -> Mode {
755 let port = self.ports_ref.unwrap_or_panic().get_port(self.pinid); let val = match self.pinid.get_pin_number() {
758 0b0000 => port.registers.moder.read(MODER::MODER0),
759 0b0001 => port.registers.moder.read(MODER::MODER1),
760 0b0010 => port.registers.moder.read(MODER::MODER2),
761 0b0011 => port.registers.moder.read(MODER::MODER3),
762 0b0100 => port.registers.moder.read(MODER::MODER4),
763 0b0101 => port.registers.moder.read(MODER::MODER5),
764 0b0110 => port.registers.moder.read(MODER::MODER6),
765 0b0111 => port.registers.moder.read(MODER::MODER7),
766 0b1000 => port.registers.moder.read(MODER::MODER8),
767 0b1001 => port.registers.moder.read(MODER::MODER9),
768 0b1010 => port.registers.moder.read(MODER::MODER10),
769 0b1011 => port.registers.moder.read(MODER::MODER11),
770 0b1100 => port.registers.moder.read(MODER::MODER12),
771 0b1101 => port.registers.moder.read(MODER::MODER13),
772 0b1110 => port.registers.moder.read(MODER::MODER14),
773 0b1111 => port.registers.moder.read(MODER::MODER15),
774 _ => 0,
775 };
776
777 Mode::from_u32(val).unwrap_or(Mode::Input)
778 }
779
780 pub fn set_mode(&self, mode: Mode) {
781 let port = self.ports_ref.unwrap_or_panic().get_port(self.pinid); match self.pinid.get_pin_number() {
784 0b0000 => port.registers.moder.modify(MODER::MODER0.val(mode as u32)),
785 0b0001 => port.registers.moder.modify(MODER::MODER1.val(mode as u32)),
786 0b0010 => port.registers.moder.modify(MODER::MODER2.val(mode as u32)),
787 0b0011 => port.registers.moder.modify(MODER::MODER3.val(mode as u32)),
788 0b0100 => port.registers.moder.modify(MODER::MODER4.val(mode as u32)),
789 0b0101 => port.registers.moder.modify(MODER::MODER5.val(mode as u32)),
790 0b0110 => port.registers.moder.modify(MODER::MODER6.val(mode as u32)),
791 0b0111 => port.registers.moder.modify(MODER::MODER7.val(mode as u32)),
792 0b1000 => port.registers.moder.modify(MODER::MODER8.val(mode as u32)),
793 0b1001 => port.registers.moder.modify(MODER::MODER9.val(mode as u32)),
794 0b1010 => port.registers.moder.modify(MODER::MODER10.val(mode as u32)),
795 0b1011 => port.registers.moder.modify(MODER::MODER11.val(mode as u32)),
796 0b1100 => port.registers.moder.modify(MODER::MODER12.val(mode as u32)),
797 0b1101 => port.registers.moder.modify(MODER::MODER13.val(mode as u32)),
798 0b1110 => port.registers.moder.modify(MODER::MODER14.val(mode as u32)),
799 0b1111 => port.registers.moder.modify(MODER::MODER15.val(mode as u32)),
800 _ => {}
801 }
802 }
803
804 pub fn set_alternate_function(&self, af: AlternateFunction) {
805 let port = self.ports_ref.unwrap_or_panic().get_port(self.pinid); match self.pinid.get_pin_number() {
808 0b0000 => port.registers.afrl.modify(AFRL::AFRL0.val(af as u32)),
809 0b0001 => port.registers.afrl.modify(AFRL::AFRL1.val(af as u32)),
810 0b0010 => port.registers.afrl.modify(AFRL::AFRL2.val(af as u32)),
811 0b0011 => port.registers.afrl.modify(AFRL::AFRL3.val(af as u32)),
812 0b0100 => port.registers.afrl.modify(AFRL::AFRL4.val(af as u32)),
813 0b0101 => port.registers.afrl.modify(AFRL::AFRL5.val(af as u32)),
814 0b0110 => port.registers.afrl.modify(AFRL::AFRL6.val(af as u32)),
815 0b0111 => port.registers.afrl.modify(AFRL::AFRL7.val(af as u32)),
816 0b1000 => port.registers.afrh.modify(AFRH::AFRH8.val(af as u32)),
817 0b1001 => port.registers.afrh.modify(AFRH::AFRH9.val(af as u32)),
818 0b1010 => port.registers.afrh.modify(AFRH::AFRH10.val(af as u32)),
819 0b1011 => port.registers.afrh.modify(AFRH::AFRH11.val(af as u32)),
820 0b1100 => port.registers.afrh.modify(AFRH::AFRH12.val(af as u32)),
821 0b1101 => port.registers.afrh.modify(AFRH::AFRH13.val(af as u32)),
822 0b1110 => port.registers.afrh.modify(AFRH::AFRH14.val(af as u32)),
823 0b1111 => port.registers.afrh.modify(AFRH::AFRH15.val(af as u32)),
824 _ => {}
825 }
826 }
827
828 pub fn get_pinid(&self) -> PinId {
829 self.pinid
830 }
831
832 pub unsafe fn enable_interrupt(&'static self) {
833 let exti_line_id = LineId::from_u8(self.pinid.get_pin_number()).unwrap();
834
835 self.exti.associate_line_gpiopin(exti_line_id, self);
836 }
837
838 pub fn set_exti_lineid(&self, lineid: exti::LineId) {
839 self.exti_lineid.set(lineid);
840 }
841
842 fn set_mode_output_pushpull(&self) {
843 let port = self.ports_ref.unwrap_or_panic().get_port(self.pinid); match self.pinid.get_pin_number() {
846 0b0000 => port.registers.otyper.modify(OTYPER::OT0::CLEAR),
847 0b0001 => port.registers.otyper.modify(OTYPER::OT1::CLEAR),
848 0b0010 => port.registers.otyper.modify(OTYPER::OT2::CLEAR),
849 0b0011 => port.registers.otyper.modify(OTYPER::OT3::CLEAR),
850 0b0100 => port.registers.otyper.modify(OTYPER::OT4::CLEAR),
851 0b0101 => port.registers.otyper.modify(OTYPER::OT5::CLEAR),
852 0b0110 => port.registers.otyper.modify(OTYPER::OT6::CLEAR),
853 0b0111 => port.registers.otyper.modify(OTYPER::OT7::CLEAR),
854 0b1000 => port.registers.otyper.modify(OTYPER::OT8::CLEAR),
855 0b1001 => port.registers.otyper.modify(OTYPER::OT9::CLEAR),
856 0b1010 => port.registers.otyper.modify(OTYPER::OT10::CLEAR),
857 0b1011 => port.registers.otyper.modify(OTYPER::OT11::CLEAR),
858 0b1100 => port.registers.otyper.modify(OTYPER::OT12::CLEAR),
859 0b1101 => port.registers.otyper.modify(OTYPER::OT13::CLEAR),
860 0b1110 => port.registers.otyper.modify(OTYPER::OT14::CLEAR),
861 0b1111 => port.registers.otyper.modify(OTYPER::OT15::CLEAR),
862 _ => {}
863 }
864 }
865
866 fn get_pullup_pulldown(&self) -> PullUpPullDown {
867 let port = self.ports_ref.unwrap_or_panic().get_port(self.pinid); let val = match self.pinid.get_pin_number() {
870 0b0000 => port.registers.pupdr.read(PUPDR::PUPDR0),
871 0b0001 => port.registers.pupdr.read(PUPDR::PUPDR1),
872 0b0010 => port.registers.pupdr.read(PUPDR::PUPDR2),
873 0b0011 => port.registers.pupdr.read(PUPDR::PUPDR3),
874 0b0100 => port.registers.pupdr.read(PUPDR::PUPDR4),
875 0b0101 => port.registers.pupdr.read(PUPDR::PUPDR5),
876 0b0110 => port.registers.pupdr.read(PUPDR::PUPDR6),
877 0b0111 => port.registers.pupdr.read(PUPDR::PUPDR7),
878 0b1000 => port.registers.pupdr.read(PUPDR::PUPDR8),
879 0b1001 => port.registers.pupdr.read(PUPDR::PUPDR9),
880 0b1010 => port.registers.pupdr.read(PUPDR::PUPDR10),
881 0b1011 => port.registers.pupdr.read(PUPDR::PUPDR11),
882 0b1100 => port.registers.pupdr.read(PUPDR::PUPDR12),
883 0b1101 => port.registers.pupdr.read(PUPDR::PUPDR13),
884 0b1110 => port.registers.pupdr.read(PUPDR::PUPDR14),
885 0b1111 => port.registers.pupdr.read(PUPDR::PUPDR15),
886 _ => 0,
887 };
888
889 PullUpPullDown::from_u32(val).unwrap_or(PullUpPullDown::NoPullUpPullDown)
890 }
891
892 fn set_pullup_pulldown(&self, pupd: PullUpPullDown) {
893 let port = self.ports_ref.unwrap_or_panic().get_port(self.pinid); match self.pinid.get_pin_number() {
896 0b0000 => port.registers.pupdr.modify(PUPDR::PUPDR0.val(pupd as u32)),
897 0b0001 => port.registers.pupdr.modify(PUPDR::PUPDR1.val(pupd as u32)),
898 0b0010 => port.registers.pupdr.modify(PUPDR::PUPDR2.val(pupd as u32)),
899 0b0011 => port.registers.pupdr.modify(PUPDR::PUPDR3.val(pupd as u32)),
900 0b0100 => port.registers.pupdr.modify(PUPDR::PUPDR4.val(pupd as u32)),
901 0b0101 => port.registers.pupdr.modify(PUPDR::PUPDR5.val(pupd as u32)),
902 0b0110 => port.registers.pupdr.modify(PUPDR::PUPDR6.val(pupd as u32)),
903 0b0111 => port.registers.pupdr.modify(PUPDR::PUPDR7.val(pupd as u32)),
904 0b1000 => port.registers.pupdr.modify(PUPDR::PUPDR8.val(pupd as u32)),
905 0b1001 => port.registers.pupdr.modify(PUPDR::PUPDR9.val(pupd as u32)),
906 0b1010 => port.registers.pupdr.modify(PUPDR::PUPDR10.val(pupd as u32)),
907 0b1011 => port.registers.pupdr.modify(PUPDR::PUPDR11.val(pupd as u32)),
908 0b1100 => port.registers.pupdr.modify(PUPDR::PUPDR12.val(pupd as u32)),
909 0b1101 => port.registers.pupdr.modify(PUPDR::PUPDR13.val(pupd as u32)),
910 0b1110 => port.registers.pupdr.modify(PUPDR::PUPDR14.val(pupd as u32)),
911 0b1111 => port.registers.pupdr.modify(PUPDR::PUPDR15.val(pupd as u32)),
912 _ => {}
913 }
914 }
915
916 fn set_output_high(&self) {
917 let port = self.ports_ref.unwrap_or_panic().get_port(self.pinid); match self.pinid.get_pin_number() {
920 0b0000 => port.registers.bsrr.write(BSRR::BS0::SET),
921 0b0001 => port.registers.bsrr.write(BSRR::BS1::SET),
922 0b0010 => port.registers.bsrr.write(BSRR::BS2::SET),
923 0b0011 => port.registers.bsrr.write(BSRR::BS3::SET),
924 0b0100 => port.registers.bsrr.write(BSRR::BS4::SET),
925 0b0101 => port.registers.bsrr.write(BSRR::BS5::SET),
926 0b0110 => port.registers.bsrr.write(BSRR::BS6::SET),
927 0b0111 => port.registers.bsrr.write(BSRR::BS7::SET),
928 0b1000 => port.registers.bsrr.write(BSRR::BS8::SET),
929 0b1001 => port.registers.bsrr.write(BSRR::BS9::SET),
930 0b1010 => port.registers.bsrr.write(BSRR::BS10::SET),
931 0b1011 => port.registers.bsrr.write(BSRR::BS11::SET),
932 0b1100 => port.registers.bsrr.write(BSRR::BS12::SET),
933 0b1101 => port.registers.bsrr.write(BSRR::BS13::SET),
934 0b1110 => port.registers.bsrr.write(BSRR::BS14::SET),
935 0b1111 => port.registers.bsrr.write(BSRR::BS15::SET),
936 _ => {}
937 }
938 }
939
940 fn set_output_low(&self) {
941 let port = self.ports_ref.unwrap_or_panic().get_port(self.pinid); match self.pinid.get_pin_number() {
944 0b0000 => port.registers.bsrr.write(BSRR::BR0::SET),
945 0b0001 => port.registers.bsrr.write(BSRR::BR1::SET),
946 0b0010 => port.registers.bsrr.write(BSRR::BR2::SET),
947 0b0011 => port.registers.bsrr.write(BSRR::BR3::SET),
948 0b0100 => port.registers.bsrr.write(BSRR::BR4::SET),
949 0b0101 => port.registers.bsrr.write(BSRR::BR5::SET),
950 0b0110 => port.registers.bsrr.write(BSRR::BR6::SET),
951 0b0111 => port.registers.bsrr.write(BSRR::BR7::SET),
952 0b1000 => port.registers.bsrr.write(BSRR::BR8::SET),
953 0b1001 => port.registers.bsrr.write(BSRR::BR9::SET),
954 0b1010 => port.registers.bsrr.write(BSRR::BR10::SET),
955 0b1011 => port.registers.bsrr.write(BSRR::BR11::SET),
956 0b1100 => port.registers.bsrr.write(BSRR::BR12::SET),
957 0b1101 => port.registers.bsrr.write(BSRR::BR13::SET),
958 0b1110 => port.registers.bsrr.write(BSRR::BR14::SET),
959 0b1111 => port.registers.bsrr.write(BSRR::BR15::SET),
960 _ => {}
961 }
962 }
963
964 fn is_output_high(&self) -> bool {
965 let port = self.ports_ref.unwrap_or_panic().get_port(self.pinid); match self.pinid.get_pin_number() {
968 0b0000 => port.registers.odr.is_set(ODR::ODR0),
969 0b0001 => port.registers.odr.is_set(ODR::ODR1),
970 0b0010 => port.registers.odr.is_set(ODR::ODR2),
971 0b0011 => port.registers.odr.is_set(ODR::ODR3),
972 0b0100 => port.registers.odr.is_set(ODR::ODR4),
973 0b0101 => port.registers.odr.is_set(ODR::ODR5),
974 0b0110 => port.registers.odr.is_set(ODR::ODR6),
975 0b0111 => port.registers.odr.is_set(ODR::ODR7),
976 0b1000 => port.registers.odr.is_set(ODR::ODR8),
977 0b1001 => port.registers.odr.is_set(ODR::ODR9),
978 0b1010 => port.registers.odr.is_set(ODR::ODR10),
979 0b1011 => port.registers.odr.is_set(ODR::ODR11),
980 0b1100 => port.registers.odr.is_set(ODR::ODR12),
981 0b1101 => port.registers.odr.is_set(ODR::ODR13),
982 0b1110 => port.registers.odr.is_set(ODR::ODR14),
983 0b1111 => port.registers.odr.is_set(ODR::ODR15),
984 _ => false,
985 }
986 }
987
988 fn toggle_output(&self) -> bool {
989 if self.is_output_high() {
990 self.set_output_low();
991 false
992 } else {
993 self.set_output_high();
994 true
995 }
996 }
997
998 fn read_input(&self) -> bool {
999 let port = self.ports_ref.unwrap_or_panic().get_port(self.pinid); match self.pinid.get_pin_number() {
1002 0b0000 => port.registers.idr.is_set(IDR::IDR0),
1003 0b0001 => port.registers.idr.is_set(IDR::IDR1),
1004 0b0010 => port.registers.idr.is_set(IDR::IDR2),
1005 0b0011 => port.registers.idr.is_set(IDR::IDR3),
1006 0b0100 => port.registers.idr.is_set(IDR::IDR4),
1007 0b0101 => port.registers.idr.is_set(IDR::IDR5),
1008 0b0110 => port.registers.idr.is_set(IDR::IDR6),
1009 0b0111 => port.registers.idr.is_set(IDR::IDR7),
1010 0b1000 => port.registers.idr.is_set(IDR::IDR8),
1011 0b1001 => port.registers.idr.is_set(IDR::IDR9),
1012 0b1010 => port.registers.idr.is_set(IDR::IDR10),
1013 0b1011 => port.registers.idr.is_set(IDR::IDR11),
1014 0b1100 => port.registers.idr.is_set(IDR::IDR12),
1015 0b1101 => port.registers.idr.is_set(IDR::IDR13),
1016 0b1110 => port.registers.idr.is_set(IDR::IDR14),
1017 0b1111 => port.registers.idr.is_set(IDR::IDR15),
1018 _ => false,
1019 }
1020 }
1021}
1022
1023impl hil::gpio::Configure for Pin<'_> {
1024 fn make_output(&self) -> hil::gpio::Configuration {
1026 self.set_mode(Mode::GeneralPurposeOutputMode);
1027 self.set_mode_output_pushpull();
1028 hil::gpio::Configuration::Output
1029 }
1030
1031 fn make_input(&self) -> hil::gpio::Configuration {
1036 self.set_mode(Mode::Input);
1037 hil::gpio::Configuration::Input
1038 }
1039
1040 fn deactivate_to_low_power(&self) {
1044 self.set_mode(Mode::AnalogMode);
1045 }
1046
1047 fn disable_output(&self) -> hil::gpio::Configuration {
1048 self.set_mode(Mode::AnalogMode);
1049 hil::gpio::Configuration::LowPower
1050 }
1051
1052 fn disable_input(&self) -> hil::gpio::Configuration {
1053 self.set_mode(Mode::AnalogMode);
1054 hil::gpio::Configuration::LowPower
1055 }
1056
1057 fn set_floating_state(&self, mode: hil::gpio::FloatingState) {
1058 match mode {
1059 hil::gpio::FloatingState::PullUp => self.set_pullup_pulldown(PullUpPullDown::PullUp),
1060 hil::gpio::FloatingState::PullDown => {
1061 self.set_pullup_pulldown(PullUpPullDown::PullDown)
1062 }
1063 hil::gpio::FloatingState::PullNone => {
1064 self.set_pullup_pulldown(PullUpPullDown::NoPullUpPullDown)
1065 }
1066 }
1067 }
1068
1069 fn floating_state(&self) -> hil::gpio::FloatingState {
1070 match self.get_pullup_pulldown() {
1071 PullUpPullDown::PullUp => hil::gpio::FloatingState::PullUp,
1072 PullUpPullDown::PullDown => hil::gpio::FloatingState::PullDown,
1073 PullUpPullDown::NoPullUpPullDown => hil::gpio::FloatingState::PullNone,
1074 }
1075 }
1076
1077 fn configuration(&self) -> hil::gpio::Configuration {
1078 match self.get_mode() {
1079 Mode::Input => hil::gpio::Configuration::Input,
1080 Mode::GeneralPurposeOutputMode => hil::gpio::Configuration::Output,
1081 Mode::AnalogMode => hil::gpio::Configuration::LowPower,
1082 Mode::AlternateFunctionMode => hil::gpio::Configuration::Function,
1083 }
1084 }
1085
1086 fn is_input(&self) -> bool {
1087 self.get_mode() == Mode::Input
1088 }
1089
1090 fn is_output(&self) -> bool {
1091 self.get_mode() == Mode::GeneralPurposeOutputMode
1092 }
1093}
1094
1095impl hil::gpio::Output for Pin<'_> {
1096 fn set(&self) {
1097 self.set_output_high();
1098 }
1099
1100 fn clear(&self) {
1101 self.set_output_low();
1102 }
1103
1104 fn toggle(&self) -> bool {
1105 self.toggle_output()
1106 }
1107}
1108
1109impl hil::gpio::Input for Pin<'_> {
1110 fn read(&self) -> bool {
1111 self.read_input()
1112 }
1113}
1114
1115impl<'a> hil::gpio::Interrupt<'a> for Pin<'a> {
1116 fn enable_interrupts(&self, mode: hil::gpio::InterruptEdge) {
1117 unsafe {
1118 atomic(|| {
1119 self.exti_lineid.map(|lineid| {
1120 let l = lineid;
1121
1122 self.exti.mask_interrupt(l);
1124 self.exti.clear_pending(l);
1125
1126 match mode {
1127 hil::gpio::InterruptEdge::EitherEdge => {
1128 self.exti.select_rising_trigger(l);
1129 self.exti.select_falling_trigger(l);
1130 }
1131 hil::gpio::InterruptEdge::RisingEdge => {
1132 self.exti.select_rising_trigger(l);
1133 self.exti.deselect_falling_trigger(l);
1134 }
1135 hil::gpio::InterruptEdge::FallingEdge => {
1136 self.exti.deselect_rising_trigger(l);
1137 self.exti.select_falling_trigger(l);
1138 }
1139 }
1140
1141 self.exti.unmask_interrupt(l);
1142 });
1143 });
1144 }
1145 }
1146
1147 fn disable_interrupts(&self) {
1148 unsafe {
1149 atomic(|| {
1150 self.exti_lineid.map(|lineid| {
1151 let l = lineid;
1152 self.exti.mask_interrupt(l);
1153 self.exti.clear_pending(l);
1154 });
1155 });
1156 }
1157 }
1158
1159 fn set_client(&self, client: &'a dyn hil::gpio::Client) {
1160 self.client.set(client);
1161 }
1162
1163 fn is_pending(&self) -> bool {
1164 self.exti_lineid
1165 .map_or(false, |lineid| self.exti.is_pending(lineid))
1166 }
1167}