1pub use crate::hal::digital::v2::PinState;
4use crate::hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin, ToggleableOutputPin};
5use core::convert::Infallible;
6use core::marker::PhantomData;
7
8use crate::pac::{self, EXTI, SYSCFG};
9use crate::rcc::{Enable, AHB2, APB2};
10
11mod convert;
12
13mod partially_erased;
14pub use partially_erased::{PEPin, PartiallyErasedPin};
15mod erased;
16pub use erased::{EPin, ErasedPin};
17
18pub trait GpioExt {
20 type Parts;
22
23 fn split(self, ahb: &mut AHB2) -> Self::Parts;
25}
26
27pub struct Input<IOCONF> {
29 _mode: PhantomData<IOCONF>,
30}
31
32pub struct Floating;
34pub struct PullDown;
36pub struct PullUp;
38
39pub struct Output<OTYPE> {
41 _mode: PhantomData<OTYPE>,
42}
43
44pub struct PushPull;
46pub struct OpenDrain;
48
49pub struct Analog;
51
52pub type Debugger = Alternate<PushPull, 0>;
53
54pub enum Speed {
56 Low = 0,
57 Medium = 1,
58 High = 2,
59 VeryHigh = 3,
60}
61
62pub trait PinExt {
63 type Mode;
64 fn pin_id(&self) -> u8;
66 fn port_id(&self) -> u8;
68}
69
70pub struct Alternate<MODE, const A: u8> {
72 _mode: PhantomData<MODE>,
73}
74
75#[derive(Debug, PartialEq)]
76pub enum Edge {
77 Rising,
78 Falling,
79 RisingFalling,
80}
81
82mod sealed {
83 pub trait Interruptable {}
85}
86
87use sealed::Interruptable;
88impl<MODE> Interruptable for Output<MODE> {}
89impl<MODE> Interruptable for Input<MODE> {}
90
91pub trait ExtiPin {
93 fn make_interrupt_source(&mut self, syscfg: &mut SYSCFG, apb2: &mut APB2);
94 fn trigger_on_edge(&mut self, exti: &mut EXTI, level: Edge);
95 fn enable_interrupt(&mut self, exti: &mut EXTI);
96 fn disable_interrupt(&mut self, exti: &mut EXTI);
97 fn clear_interrupt_pending_bit(&mut self);
98 fn check_interrupt(&self) -> bool;
99}
100
101impl<PIN> ExtiPin for PIN
102where
103 PIN: PinExt,
104 PIN::Mode: Interruptable,
105{
106 #[inline(always)]
108 fn make_interrupt_source(&mut self, syscfg: &mut SYSCFG, apb2: &mut APB2) {
109 SYSCFG::enable(apb2);
111
112 let i = self.pin_id();
113 let port = self.port_id() as u32;
114 let offset = 4 * (i % 4);
115 match i {
116 0..=3 => {
117 syscfg.exticr1.modify(|r, w| unsafe {
118 w.bits((r.bits() & !(0xf << offset)) | (port << offset))
119 });
120 }
121 4..=7 => {
122 syscfg.exticr2.modify(|r, w| unsafe {
123 w.bits((r.bits() & !(0xf << offset)) | (port << offset))
124 });
125 }
126 8..=11 => {
127 syscfg.exticr3.modify(|r, w| unsafe {
128 w.bits((r.bits() & !(0xf << offset)) | (port << offset))
129 });
130 }
131 12..=15 => {
132 syscfg.exticr4.modify(|r, w| unsafe {
133 w.bits((r.bits() & !(0xf << offset)) | (port << offset))
134 });
135 }
136 _ => unreachable!(),
137 }
138 }
139
140 #[inline(always)]
142 fn trigger_on_edge(&mut self, exti: &mut EXTI, edge: Edge) {
143 let i = self.pin_id();
144 match edge {
145 Edge::Rising => {
146 exti.rtsr1
147 .modify(|r, w| unsafe { w.bits(r.bits() | (1 << i)) });
148 exti.ftsr1
149 .modify(|r, w| unsafe { w.bits(r.bits() & !(1 << i)) });
150 }
151 Edge::Falling => {
152 exti.ftsr1
153 .modify(|r, w| unsafe { w.bits(r.bits() | (1 << i)) });
154 exti.rtsr1
155 .modify(|r, w| unsafe { w.bits(r.bits() & !(1 << i)) });
156 }
157 Edge::RisingFalling => {
158 exti.rtsr1
159 .modify(|r, w| unsafe { w.bits(r.bits() | (1 << i)) });
160 exti.ftsr1
161 .modify(|r, w| unsafe { w.bits(r.bits() | (1 << i)) });
162 }
163 }
164 }
165
166 #[inline(always)]
168 fn enable_interrupt(&mut self, exti: &mut EXTI) {
169 exti.imr1
170 .modify(|r, w| unsafe { w.bits(r.bits() | (1 << self.pin_id())) });
171 }
172
173 #[inline(always)]
175 fn disable_interrupt(&mut self, exti: &mut EXTI) {
176 exti.imr1
177 .modify(|r, w| unsafe { w.bits(r.bits() & !(1 << self.pin_id())) });
178 }
179
180 #[inline(always)]
182 fn clear_interrupt_pending_bit(&mut self) {
183 unsafe { (*EXTI::ptr()).pr1.write(|w| w.bits(1 << self.pin_id())) };
184 }
185
186 #[inline(always)]
188 fn check_interrupt(&self) -> bool {
189 unsafe { ((*EXTI::ptr()).pr1.read().bits() & (1 << self.pin_id())) != 0 }
190 }
191}
192
193pub struct MODER<const P: char> {
195 _0: (),
196}
197
198impl<const P: char> MODER<P> {
199 pub(crate) fn new() -> Self {
200 Self { _0: () }
201 }
202}
203
204pub struct OTYPER<const P: char> {
206 _0: (),
207}
208
209impl<const P: char> OTYPER<P> {
210 pub(crate) fn new() -> Self {
211 Self { _0: () }
212 }
213}
214
215pub struct OSPEEDR<const P: char> {
217 _0: (),
218}
219impl<const P: char> OSPEEDR<P> {
220 pub(crate) fn new() -> Self {
221 Self { _0: () }
222 }
223}
224
225pub struct PUPDR<const P: char> {
227 _0: (),
228}
229
230impl<const P: char> PUPDR<P> {
231 pub(crate) fn new() -> Self {
232 Self { _0: () }
233 }
234}
235
236macro_rules! gpio {
237 ($GPIOX:ident, $gpiox:ident, $PXx:ident, $port_id:literal, $extigpionr:expr, $({ $pwrenable:expr },)? [
238 $($PXi:ident: ($pxi:ident, $i:expr, $MODE:ty, $HL:ident, $exticri:ident),)+
239 ]) => {
240 pub mod $gpiox {
242 use crate::stm32::$GPIOX;
243
244 use crate::rcc::{AHB2, Enable, Reset};
245 use super::{Afr, Analog, GpioExt, Pin, H8, L8, MODER, OTYPER, OSPEEDR, PUPDR};
246
247 pub struct Parts {
249 pub afrh: Afr<H8, $port_id>,
251 pub afrl: Afr<L8, $port_id>,
253 pub moder: MODER<$port_id>,
255 pub otyper: OTYPER<$port_id>,
257 pub ospeedr: OSPEEDR<$port_id>,
259 pub pupdr: PUPDR<$port_id>,
261 $(
262 pub $pxi: $PXi<$MODE>,
264 )+
265 }
266
267 $(
268 pub type $PXi<MODE> = Pin<MODE, $HL, $port_id, $i>;
269 )+
270
271 impl GpioExt for $GPIOX {
272 type Parts = Parts;
273
274 fn split(self, ahb: &mut AHB2) -> Parts {
275 <$GPIOX>::enable(ahb);
276 <$GPIOX>::reset(ahb);
277 $($pwrenable)?
278
279 Parts {
280 afrh: Afr::new(),
281 afrl: Afr::new(),
282 moder: MODER::new(),
283 otyper: OTYPER::new(),
284 ospeedr: OSPEEDR::new(),
285 pupdr: PUPDR::new(),
286 $(
287 $pxi: $PXi::new(),
288 )+
289 }
290 }
291 }
292 }
293
294 pub use $gpiox::{
295 $($PXi,)*
296 };
297 }
298}
299
300pub struct Pin<MODE, HL, const P: char, const N: u8> {
307 _mode: PhantomData<(MODE, HL)>,
308}
309
310impl<MODE, HL, const P: char, const N: u8> Pin<MODE, HL, P, N> {
311 const fn new() -> Self {
312 Self { _mode: PhantomData }
313 }
314}
315
316impl<MODE, HL, const P: char, const N: u8> PinExt for Pin<MODE, HL, P, N> {
317 type Mode = MODE;
318
319 #[inline(always)]
320 fn pin_id(&self) -> u8 {
321 N
322 }
323 #[inline(always)]
324 fn port_id(&self) -> u8 {
325 P as u8 - b'A'
326 }
327}
328
329impl<MODE, HL, const P: char, const N: u8> Pin<Output<MODE>, HL, P, N> {
330 pub fn set_speed(self, speed: Speed) -> Self {
332 let offset = 2 * { N };
333
334 unsafe {
335 (*Gpio::<P>::ptr())
336 .ospeedr
337 .modify(|r, w| w.bits((r.bits() & !(0b11 << offset)) | ((speed as u32) << offset)))
338 };
339
340 self
341 }
342}
343
344impl<HL, const P: char, const N: u8> Pin<Output<OpenDrain>, HL, P, N> {
345 pub fn internal_pull_up(&mut self, _pupdr: &mut PUPDR<P>, on: bool) {
347 let offset = 2 * { N };
348 let value = if on { 0b01 } else { 0b00 };
349 unsafe {
350 (*Gpio::<P>::ptr())
351 .pupdr
352 .modify(|r, w| w.bits((r.bits() & !(0b11 << offset)) | (value << offset)))
353 };
354 }
355}
356
357impl<MODE, HL, const P: char, const N: u8, const A: u8> Pin<Alternate<MODE, A>, HL, P, N> {
358 pub fn set_speed(self, speed: Speed) -> Self {
360 let offset = 2 * { N };
361
362 unsafe {
363 (*Gpio::<P>::ptr())
364 .ospeedr
365 .modify(|r, w| w.bits((r.bits() & !(0b11 << offset)) | ((speed as u32) << offset)))
366 };
367
368 self
369 }
370
371 pub fn internal_pull_up(&mut self, _pupdr: &mut PUPDR<P>, on: bool) {
373 let offset = 2 * { N };
374 let value = if on { 0b01 } else { 0b00 };
375 unsafe {
376 (*Gpio::<P>::ptr())
377 .pupdr
378 .modify(|r, w| w.bits((r.bits() & !(0b11 << offset)) | (value << offset)))
379 };
380 }
381}
382
383impl<HL, const P: char, const N: u8, const A: u8> Pin<Alternate<PushPull, A>, HL, P, N> {
384 pub fn set_open_drain(self) -> Pin<Alternate<OpenDrain, A>, HL, P, N> {
386 let offset = { N };
387 unsafe {
388 (*Gpio::<P>::ptr())
389 .otyper
390 .modify(|r, w| w.bits(r.bits() | (1 << offset)))
391 };
392
393 Pin::new()
394 }
395}
396
397impl<MODE, HL, const P: char, const N: u8> Pin<MODE, HL, P, N> {
398 pub fn erase_number(self) -> PEPin<MODE, P> {
403 PEPin::new(N)
404 }
405
406 pub fn erase(self) -> EPin<MODE> {
411 EPin::new(P as u8 - b'A', N)
412 }
413}
414
415impl<MODE, HL, const P: char, const N: u8> Pin<MODE, HL, P, N> {
421 #[inline(always)]
426 fn _set_state(&mut self, state: PinState) {
427 match state {
428 PinState::High => self._set_high(),
429 PinState::Low => self._set_low(),
430 }
431 }
432 #[inline(always)]
433 fn _set_high(&mut self) {
434 unsafe { (*Gpio::<P>::ptr()).bsrr.write(|w| w.bits(1 << N)) }
436 }
437 #[inline(always)]
438 fn _set_low(&mut self) {
439 unsafe { (*Gpio::<P>::ptr()).bsrr.write(|w| w.bits(1 << (16 + N))) }
441 }
442
443 #[inline(always)]
444 fn _is_set_low(&self) -> bool {
445 unsafe { (*Gpio::<P>::ptr()).odr.read().bits() & (1 << N) == 0 }
447 }
448 #[inline(always)]
449 fn _is_low(&self) -> bool {
450 unsafe { (*Gpio::<P>::ptr()).idr.read().bits() & (1 << N) == 0 }
452 }
453}
454
455impl<MODE, HL, const P: char, const N: u8> Pin<Output<MODE>, HL, P, N> {
456 #[inline]
457 pub fn set_high(&mut self) {
458 self._set_high()
459 }
460 #[inline]
461 pub fn set_low(&mut self) {
462 self._set_low()
463 }
464 #[inline(always)]
465 pub fn get_state(&self) -> PinState {
466 if self._is_set_low() {
467 PinState::Low
468 } else {
469 PinState::High
470 }
471 }
472 #[inline(always)]
473 pub fn set_state(&mut self, state: PinState) {
474 match state {
475 PinState::Low => self._set_low(),
476 PinState::High => self._set_high(),
477 }
478 }
479 #[inline]
480 pub fn is_set_high(&self) -> bool {
481 !self._is_set_low()
482 }
483 #[inline]
484 pub fn is_set_low(&self) -> bool {
485 self._is_set_low()
486 }
487 #[inline]
488 pub fn toggle(&mut self) {
489 if self._is_set_low() {
490 self._set_high()
491 } else {
492 self._set_low()
493 }
494 }
495}
496
497impl<MODE, HL, const P: char, const N: u8> OutputPin for Pin<Output<MODE>, HL, P, N> {
498 type Error = Infallible;
499 #[inline]
500 fn set_high(&mut self) -> Result<(), Self::Error> {
501 self.set_high();
502 Ok(())
503 }
504 #[inline]
505 fn set_low(&mut self) -> Result<(), Self::Error> {
506 self.set_low();
507 Ok(())
508 }
509}
510
511impl<MODE, HL, const P: char, const N: u8> StatefulOutputPin for Pin<Output<MODE>, HL, P, N> {
512 #[inline]
513 fn is_set_high(&self) -> Result<bool, Self::Error> {
514 Ok(self.is_set_high())
515 }
516 #[inline]
517 fn is_set_low(&self) -> Result<bool, Self::Error> {
518 Ok(self.is_set_low())
519 }
520}
521
522impl<MODE, HL, const P: char, const N: u8> ToggleableOutputPin for Pin<Output<MODE>, HL, P, N> {
523 type Error = Infallible;
524
525 #[inline(always)]
526 fn toggle(&mut self) -> Result<(), Self::Error> {
527 self.toggle();
528 Ok(())
529 }
530}
531
532impl<MODE, HL, const P: char, const N: u8> Pin<Input<MODE>, HL, P, N> {
533 #[inline]
534 pub fn is_high(&self) -> bool {
535 !self._is_low()
536 }
537 #[inline]
538 pub fn is_low(&self) -> bool {
539 self._is_low()
540 }
541}
542
543impl<MODE, HL, const P: char, const N: u8> InputPin for Pin<Input<MODE>, HL, P, N> {
544 type Error = Infallible;
545 #[inline]
546 fn is_high(&self) -> Result<bool, Self::Error> {
547 Ok(self.is_high())
548 }
549
550 #[inline]
551 fn is_low(&self) -> Result<bool, Self::Error> {
552 Ok(self.is_low())
553 }
554}
555
556impl<HL, const P: char, const N: u8> Pin<Output<OpenDrain>, HL, P, N> {
557 #[inline]
558 pub fn is_high(&self) -> bool {
559 !self._is_low()
560 }
561 #[inline]
562 pub fn is_low(&self) -> bool {
563 self._is_low()
564 }
565}
566
567impl<HL, const P: char, const N: u8> InputPin for Pin<Output<OpenDrain>, HL, P, N> {
568 type Error = Infallible;
569 #[inline]
570 fn is_high(&self) -> Result<bool, Self::Error> {
571 Ok(self.is_high())
572 }
573
574 #[inline]
575 fn is_low(&self) -> Result<bool, Self::Error> {
576 Ok(self.is_low())
577 }
578}
579
580pub struct Afr<HL, const P: char> {
582 _afr: PhantomData<HL>,
583}
584
585impl<HL, const P: char> Afr<HL, P> {
586 pub(crate) fn new() -> Self {
587 Self { _afr: PhantomData }
588 }
589}
590
591macro_rules! af {
592 ($HL:ident, $AFR:ident, $afr:ident) => {
593 #[doc(hidden)]
594 pub struct $HL {
595 _0: (),
596 }
597
598 impl<const P: char> Afr<$HL, P> {
599 #[allow(dead_code)]
600 pub(crate) fn afr(&mut self) -> &pac::gpioa::$AFR {
601 unsafe { &(*Gpio::<P>::ptr()).$afr }
602 }
603 }
604 };
605}
606
607af!(H8, AFRH, afrh);
608af!(L8, AFRL, afrl);
609
610gpio!(GPIOA, gpioa, PAx, 'A', 0, [
611 PA0: (pa0, 0, Analog, L8, exticr1),
612 PA1: (pa1, 1, Analog, L8, exticr1),
613 PA2: (pa2, 2, Analog, L8, exticr1),
614 PA3: (pa3, 3, Analog, L8, exticr1),
615 PA4: (pa4, 4, Analog, L8, exticr2),
616 PA5: (pa5, 5, Analog, L8, exticr2),
617 PA6: (pa6, 6, Analog, L8, exticr2),
618 PA7: (pa7, 7, Analog, L8, exticr2),
619 PA8: (pa8, 8, Analog, H8, exticr3),
620 PA9: (pa9, 9, Analog, H8, exticr3),
621 PA10: (pa10, 10, Analog, H8, exticr3),
622 PA11: (pa11, 11, Analog, H8, exticr3),
623 PA12: (pa12, 12, Analog, H8, exticr4),
624 PA13: (pa13, 13, super::Debugger, H8, exticr4), PA14: (pa14, 14, super::Debugger, H8, exticr4), PA15: (pa15, 15, super::Debugger, H8, exticr4), ]);
628
629gpio!(GPIOB, gpiob, PBx, 'B', 1, [
630 PB0: (pb0, 0, Analog, L8, exticr1),
631 PB1: (pb1, 1, Analog, L8, exticr1),
632 PB2: (pb2, 2, Analog, L8, exticr1),
633 PB3: (pb3, 3, super::Debugger, L8, exticr1), PB4: (pb4, 4, super::Debugger, L8, exticr2), PB5: (pb5, 5, Analog, L8, exticr2),
636 PB6: (pb6, 6, Analog, L8, exticr2),
637 PB7: (pb7, 7, Analog, L8, exticr2),
638 PB8: (pb8, 8, Analog, H8, exticr3),
639 PB9: (pb9, 9, Analog, H8, exticr3),
640 PB10: (pb10, 10, Analog, H8, exticr3),
641 PB11: (pb11, 11, Analog, H8, exticr3),
642 PB12: (pb12, 12, Analog, H8, exticr4),
643 PB13: (pb13, 13, Analog, H8, exticr4),
644 PB14: (pb14, 14, Analog, H8, exticr4),
645 PB15: (pb15, 15, Analog, H8, exticr4),
646]);
647
648gpio!(GPIOC, gpioc, PCx, 'C', 2, [
649 PC0: (pc0, 0, Analog, L8, exticr1),
650 PC1: (pc1, 1, Analog, L8, exticr1),
651 PC2: (pc2, 2, Analog, L8, exticr1),
652 PC3: (pc3, 3, Analog, L8, exticr1),
653 PC4: (pc4, 4, Analog, L8, exticr2),
654 PC5: (pc5, 5, Analog, L8, exticr2),
655 PC6: (pc6, 6, Analog, L8, exticr2),
656 PC7: (pc7, 7, Analog, L8, exticr2),
657 PC8: (pc8, 8, Analog, H8, exticr3),
658 PC9: (pc9, 9, Analog, H8, exticr3),
659 PC10: (pc10, 10, Analog, H8, exticr3),
660 PC11: (pc11, 11, Analog, H8, exticr3),
661 PC12: (pc12, 12, Analog, H8, exticr4),
662 PC13: (pc13, 13, Analog, H8, exticr4),
663 PC14: (pc14, 14, Analog, H8, exticr4),
664 PC15: (pc15, 15, Analog, H8, exticr4),
665]);
666
667gpio!(GPIOD, gpiod, PDx, 'D', 3, [
668 PD0: (pd0, 0, Analog, L8, exticr1),
669 PD1: (pd1, 1, Analog, L8, exticr1),
670 PD2: (pd2, 2, Analog, L8, exticr1),
671 PD3: (pd3, 3, Analog, L8, exticr1),
672 PD4: (pd4, 4, Analog, L8, exticr2),
673 PD5: (pd5, 5, Analog, L8, exticr2),
674 PD6: (pd6, 6, Analog, L8, exticr2),
675 PD7: (pd7, 7, Analog, L8, exticr2),
676 PD8: (pd8, 8, Analog, H8, exticr3),
677 PD9: (pd9, 9, Analog, H8, exticr3),
678 PD10: (pd10, 10, Analog, H8, exticr3),
679 PD11: (pd11, 11, Analog, H8, exticr3),
680 PD12: (pd12, 12, Analog, H8, exticr4),
681 PD13: (pd13, 13, Analog, H8, exticr4),
682 PD14: (pd14, 14, Analog, H8, exticr4),
683 PD15: (pd15, 15, Analog, H8, exticr4),
684]);
685
686gpio!(GPIOE, gpioe, PEx, 'E', 4, [
687 PE0: (pe0, 0, Analog, L8, exticr1),
688 PE1: (pe1, 1, Analog, L8, exticr1),
689 PE2: (pe2, 2, Analog, L8, exticr1),
690 PE3: (pe3, 3, Analog, L8, exticr1),
691 PE4: (pe4, 4, Analog, L8, exticr2),
692 PE5: (pe5, 5, Analog, L8, exticr2),
693 PE6: (pe6, 6, Analog, L8, exticr2),
694 PE7: (pe7, 7, Analog, L8, exticr2),
695 PE8: (pe8, 8, Analog, H8, exticr3),
696 PE9: (pe9, 9, Analog, H8, exticr3),
697 PE10: (pe10, 10, Analog, H8, exticr3),
698 PE11: (pe11, 11, Analog, H8, exticr3),
699 PE12: (pe12, 12, Analog, H8, exticr4),
700 PE13: (pe13, 13, Analog, H8, exticr4),
701 PE14: (pe14, 14, Analog, H8, exticr4),
702 PE15: (pe15, 15, Analog, H8, exticr4),
703]);
704
705#[cfg(any(
706 feature = "stm32l475",
708 feature = "stm32l476",
709 feature = "stm32l485",
710 feature = "stm32l486",
711 feature = "stm32l496",
712 feature = "stm32l4a6",
713 feature = "stm32l4r9",
720 feature = "stm32l4s9",
721))]
722gpio!(GPIOF, gpiof, PFx, 'F', 5, [
723 PF0: (pf0, 0, Analog, L8, exticr1),
724 PF1: (pf1, 1, Analog, L8, exticr1),
725 PF2: (pf2, 2, Analog, L8, exticr1),
726 PF3: (pf3, 3, Analog, L8, exticr1),
727 PF4: (pf4, 4, Analog, L8, exticr2),
728 PF5: (pf5, 5, Analog, L8, exticr2),
729 PF6: (pf6, 6, Analog, L8, exticr2),
730 PF7: (pf7, 7, Analog, L8, exticr2),
731 PF8: (pf8, 8, Analog, H8, exticr3),
732 PF9: (pf9, 9, Analog, H8, exticr3),
733 PF10: (pf10, 10, Analog, H8, exticr3),
734 PF11: (pf11, 11, Analog, H8, exticr3),
735 PF12: (pf12, 12, Analog, H8, exticr4),
736 PF13: (pf13, 13, Analog, H8, exticr4),
737 PF14: (pf14, 14, Analog, H8, exticr4),
738 PF15: (pf15, 15, Analog, H8, exticr4),
739]);
740#[cfg(any(
741 feature = "stm32l475",
743 feature = "stm32l476",
744 feature = "stm32l485",
745 feature = "stm32l486",
746 feature = "stm32l496",
747 feature = "stm32l4a6",
748 feature = "stm32l4r9",
755 feature = "stm32l4s9",
756))]
757gpio!(GPIOG, gpiog, PGx, 'G', 6,
758 { unsafe { (*crate::pac::PWR::ptr()).cr2.modify(|_,w| w.iosv().set_bit()); } },
759[
760 PG0: (pg0, 0, Analog, L8, exticr1),
761 PG1: (pg1, 1, Analog, L8, exticr1),
762 PG2: (pg2, 2, Analog, L8, exticr1),
763 PG3: (pg3, 3, Analog, L8, exticr1),
764 PG4: (pg4, 4, Analog, L8, exticr2),
765 PG5: (pg5, 5, Analog, L8, exticr2),
766 PG6: (pg6, 6, Analog, L8, exticr2),
767 PG7: (pg7, 7, Analog, L8, exticr2),
768 PG8: (pg8, 8, Analog, H8, exticr3),
769 PG9: (pg9, 9, Analog, H8, exticr3),
770 PG10: (pg10, 10, Analog, H8, exticr3),
771 PG11: (pg11, 11, Analog, H8, exticr3),
772 PG12: (pg12, 12, Analog, H8, exticr4),
773 PG13: (pg13, 13, Analog, H8, exticr4),
774 PG14: (pg14, 14, Analog, H8, exticr4),
775 PG15: (pg15, 15, Analog, H8, exticr4),
776]);
777
778struct Gpio<const P: char>;
779impl<const P: char> Gpio<P> {
780 const fn ptr() -> *const crate::pac::gpioa::RegisterBlock {
781 match P {
782 'A' => crate::pac::GPIOA::ptr(),
783 'B' => crate::pac::GPIOB::ptr() as _,
784 'C' => crate::pac::GPIOC::ptr() as _,
785 'D' => crate::pac::GPIOD::ptr() as _,
786 'E' => crate::pac::GPIOE::ptr() as _,
787 #[cfg(any(
788 feature = "stm32l475",
790 feature = "stm32l476",
791 feature = "stm32l485",
792 feature = "stm32l486",
793 feature = "stm32l496",
794 feature = "stm32l4a6",
795 feature = "stm32l4r9",
802 feature = "stm32l4s9",
803 ))]
804 'F' => crate::pac::GPIOF::ptr() as _,
805 #[cfg(any(
806 feature = "stm32l475",
808 feature = "stm32l476",
809 feature = "stm32l485",
810 feature = "stm32l486",
811 feature = "stm32l496",
812 feature = "stm32l4a6",
813 feature = "stm32l4r9",
820 feature = "stm32l4s9",
821 ))]
822 'G' => crate::pac::GPIOG::ptr() as _,
823 _ => crate::pac::GPIOA::ptr(),
824 }
825 }
826}