1pub mod timer_remap;
4pub mod uart_remap;
5
6use crate::gpio::{self, Alternate, Cr, Debugger, Floating, Input, OpenDrain, PushPull};
7use crate::pac::{self, AFIO, RCC, afio};
8use crate::rcc::{Enable, Reset};
9use core::marker::PhantomData;
10
11type MaprBits = <afio::mapr::MAPRrs as RegisterSpec>::Ux;
12
13pub trait AfioInit {
14    fn constrain(self, rcc: &mut RCC) -> Afio;
15}
16
17impl AfioInit for AFIO {
18    fn constrain(self, rcc: &mut RCC) -> Afio {
19        AFIO::enable(rcc);
20        AFIO::reset(rcc);
21
22        Afio {
23            _reg: self,
24            evcr: EVCR,
25            mapr: MAPR { jtag_enabled: true },
26            exticr1: EXTICR1,
27            exticr2: EXTICR2,
28            exticr3: EXTICR3,
29            exticr4: EXTICR4,
30            mapr2: MAPR2,
31        }
32    }
33}
34
35pub struct Afio {
45    _reg: AFIO,
46    pub evcr: EVCR,
47    pub mapr: MAPR,
48    pub exticr1: EXTICR1,
49    pub exticr2: EXTICR2,
50    pub exticr3: EXTICR3,
51    pub exticr4: EXTICR4,
52    pub mapr2: MAPR2,
53}
54
55#[non_exhaustive]
56pub struct EVCR;
57
58impl EVCR {
59    pub fn evcr(&mut self) -> &afio::EVCR {
60        unsafe { (*AFIO::ptr()).evcr() }
61    }
62}
63
64pub trait RemapMode<REG> {
66    fn remap(afio: &mut Afio);
67}
68pub struct RemapDefault<REG>(PhantomData<REG>);
69pub struct RemapPartial1<REG>(PhantomData<REG>);
70pub struct RemapPartial2<REG>(PhantomData<REG>);
71pub struct RemapFull<REG>(PhantomData<REG>);
72pub struct NonePin {}
73pub const NONE_PIN: Option<NonePin> = None::<NonePin>;
74
75#[non_exhaustive]
86pub struct MAPR {
87    jtag_enabled: bool,
88}
89
90impl MAPR {
91    fn mapr(&mut self) -> &afio::MAPR {
92        unsafe { (*AFIO::ptr()).mapr() }
93    }
94
95    pub fn modify_mapr<F>(&mut self, mod_fn: F) -> MaprBits
96    where
97        F: for<'w> FnOnce(&afio::mapr::R, &'w mut afio::mapr::W) -> &'w mut afio::mapr::W,
98    {
99        let debug_bits = if self.jtag_enabled { 0b000 } else { 0b010 };
100        self.mapr()
101            .modify(unsafe { |r, w| mod_fn(r, w).swj_cfg().bits(debug_bits) })
102    }
103
104    #[allow(clippy::redundant_field_names, clippy::type_complexity)]
106    pub fn disable_jtag(
107        &mut self,
108        pa15: gpio::PA15<Debugger>,
109        pb3: gpio::PB3<Debugger>,
110        pb4: gpio::PB4<Debugger>,
111    ) -> (gpio::PA15, gpio::PB3, gpio::PB4) {
112        self.jtag_enabled = false;
113        self.modify_mapr(|_, w| w);
115
116        unsafe { (pa15.activate(), pb3.activate(), pb4.activate()) }
118    }
119}
120
121#[non_exhaustive]
122pub struct EXTICR1;
123
124impl EXTICR1 {
125    pub fn exticr1(&mut self) -> &afio::EXTICR1 {
126        unsafe { (*AFIO::ptr()).exticr1() }
127    }
128}
129
130#[non_exhaustive]
131pub struct EXTICR2;
132
133impl EXTICR2 {
134    pub fn exticr2(&mut self) -> &afio::EXTICR2 {
135        unsafe { (*AFIO::ptr()).exticr2() }
136    }
137}
138
139#[non_exhaustive]
140pub struct EXTICR3;
141
142impl EXTICR3 {
143    pub fn exticr3(&mut self) -> &afio::EXTICR3 {
144        unsafe { (*AFIO::ptr()).exticr3() }
145    }
146}
147
148#[non_exhaustive]
149pub struct EXTICR4;
150
151impl EXTICR4 {
152    pub fn exticr4(&mut self) -> &afio::EXTICR4 {
153        unsafe { (*AFIO::ptr()).exticr4() }
154    }
155}
156
157#[non_exhaustive]
158pub struct MAPR2;
159
160impl MAPR2 {
161    pub fn mapr2(&mut self) -> &afio::MAPR2 {
162        unsafe { (*AFIO::ptr()).mapr2() }
163    }
164
165    pub fn modify_mapr<F>(&mut self, mod_fn: F)
166    where
167        F: for<'w> FnOnce(&afio::mapr2::R, &'w mut afio::mapr2::W) -> &'w mut afio::mapr2::W,
168    {
169        self.mapr2().modify(|r, w| mod_fn(r, w));
170    }
171}
172
173pub trait Remap: Sized {
174    type Mapr;
175    #[doc(hidden)]
176    fn rmp(mapr: &mut Self::Mapr, to: u8);
177    fn remap<const R: u8>(self, mapr: &mut Self::Mapr) -> Rmp<Self, R> {
178        Self::rmp(mapr, R);
179        Rmp(self)
180    }
181}
182
183macro_rules! remap {
184    ($(
185        $PER:ty: $MAPR:ident, $w:ident: $field:ident $(, { $allowed:pat })?;
186    )+) => {
187        $(
188            remap!($PER: $MAPR, $w: $field $(, { $allowed })?);
189        )+
190    };
191    ($PER:ty: $MAPR:ident, bool: $field:ident) => {
192        impl Remap for $PER {
193            type Mapr = $MAPR;
194            fn rmp(mapr: &mut Self::Mapr, to: u8) {
195                assert!(matches!(to, 0 | 1));
196                mapr.modify_mapr(|_, w| w.$field().bit(to != 0));
197            }
198        }
199    };
200    ($PER:ty: $MAPR:ident, u8: $field:ident $(, {$allowed:pat })?) => {
201        impl Remap for $PER {
202            type Mapr = $MAPR;
203            fn rmp(mapr: &mut Self::Mapr, to: u8) {
204                $(assert!(matches!(to, $allowed)))?;
205                mapr.modify_mapr(|_, w| unsafe { w.$field().bits(to) });
206            }
207        }
208    };
209}
210use remap;
211
212remap! {
213    pac::SPI1: MAPR, bool: spi1_remap;
214    pac::I2C1: MAPR, bool: i2c1_remap;
215    pac::USART1: MAPR, bool: usart1_remap;
216    pac::USART2: MAPR, bool: usart2_remap;
217    pac::USART3: MAPR, u8: usart3_remap, { 0 | 1 | 3 };
218    pac::TIM2: MAPR, u8: tim2_remap, { 0..=3 };
219    pac::TIM3: MAPR, u8: tim3_remap, { 0 | 2 | 3 };
220}
221
222#[cfg(feature = "medium")]
223remap! {
224    pac::TIM4: MAPR, bool: tim4_remap;
225}
226
227#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity"))]
228remap! {
229    pac::TIM1: MAPR, u8: tim1_remap, { 0 | 1 | 3 };
230}
231
232#[cfg(feature = "stm32f103")]
233remap! {
234    pac::CAN: MAPR, u8: can_remap, { 0 | 2 | 3 };
235}
236
237#[cfg(feature = "connectivity")]
238remap! {
239    pac::CAN1: MAPR, u8: can1_remap, { 0 | 2 | 3 };
240    pac::CAN2: MAPR, bool: can2_remap;
242    pac::SPI3: MAPR, bool: spi3_remap;
243}
244
245#[cfg(feature = "xl")]
246remap! {
247    pac::TIM9: MAPR2, bool: tim9_remap;
248    pac::TIM10: MAPR2, bool: tim10_remap;
249    pac::TIM11: MAPR2, bool: tim11_remap;
250}
251#[cfg(any(feature = "xl", all(feature = "stm32f100", feature = "high")))]
252remap! {
253    pac::TIM13: MAPR2, bool: tim13_remap;
254    pac::TIM14: MAPR2, bool: tim14_remap;
255}
256
257pub struct Rmp<T, const R: u8>(pub(crate) T);
258
259impl<T> From<T> for Rmp<T, 0> {
260    fn from(value: T) -> Self {
261        Self(value)
262    }
263}
264
265pub trait RFrom<T, const R: u8> {
266    fn rfrom(value: T) -> Self;
267}
268
269impl<T, const R: u8> RFrom<T, R> for T {
270    fn rfrom(value: T) -> Self {
271        value
272    }
273}
274
275pub trait RInto<T, const R: u8> {
276    fn rinto(self) -> T;
277}
278
279impl<S, T, const R: u8> RInto<T, R> for S
280where
281    T: RFrom<Self, R>,
282{
283    fn rinto(self) -> T {
284        T::rfrom(self)
285    }
286}
287
288pub trait CanCommon {
293    type Tx;
297    type Rx<PULL>;
301}
302
303#[cfg(feature = "has-can")]
304pub mod can1 {
305    use super::*;
306
307    pin! {
308        <Tx, Alternate<PushPull>> for [
309            PA12: [0],
310            PB9:  [2],
311            PD1:  [3],
312        ],
313    }
314    pin! {
315        <Rx, Input> default:Floating for [
316            PA11: [0],
317            PB8:  [2],
318            PD0:  [3],
319        ],
320    }
321
322    #[cfg(not(feature = "connectivity"))]
323    use pac::CAN as CAN1;
324    #[cfg(feature = "connectivity")]
325    use pac::CAN1;
326    impl CanCommon for CAN1 {
327        type Tx = Tx;
328        type Rx<PULL> = Rx<PULL>;
329    }
330}
331
332#[cfg(feature = "connectivity")]
333pub mod can2 {
334    use super::*;
335
336    pin! {
337        <Tx, Alternate<PushPull>> for [
338            PB6:  [0],
339            PB13: [1],
340        ],
341    }
342    pin! {
343        <Rx, Input> default:Floating for [
344            PB5:  [0],
345            PB12: [1],
346        ],
347    }
348
349    impl CanCommon for pac::CAN2 {
350        type Tx = Tx;
351        type Rx<PULL> = Rx<PULL>;
352    }
353}
354
355pub trait I2cCommon {
357    type Scl;
361    type Sda;
365    type Smba;
367}
368
369pub mod i2c1 {
370    use super::*;
371
372    pin! {
373        <Scl, Alternate<OpenDrain>> for [
374            PB6: [0],
375            PB8: [1],
376        ],
377        <Sda, Alternate<OpenDrain>> for [
378            PB7: [0],
379            PB9: [1],
380        ],
381        <Smba, Alternate<OpenDrain>> for [
382            PB5: [0, 1],
383        ],
384    }
385
386    impl I2cCommon for pac::I2C1 {
387        type Scl = Scl;
388        type Sda = Sda;
389        type Smba = Smba;
390    }
391}
392pub mod i2c2 {
393    use super::*;
394
395    pin! {
396        <Scl, Alternate<OpenDrain>> for [
397            PB10: [0],
398        ],
399        <Sda, Alternate<OpenDrain>> for [
400            PB11: [0],
401        ],
402        <Smba, Alternate<OpenDrain>> for [
403            PB12: [0],
404        ],
405    }
406
407    impl I2cCommon for pac::I2C2 {
408        type Scl = Scl;
409        type Sda = Sda;
410        type Smba = Smba;
411    }
412}
413
414pub trait SpiCommon {
416    type MSck;
420    type SSck;
424    type Mi<PULL>;
428    type So<Otype>;
432    type Mo;
436    type Si<PULL>;
440    type Nss;
444    type Ss<PULL>;
448}
449
450pub mod spi1 {
451    use super::*;
452
453    pin! {
454        <Si, Input> default:Floating && <Mo, Alternate<PushPull>> for [
455            PA7: [0],
456            PB5: [1],
457        ],
458        <Ss, Input> default:Floating && <Nss, Alternate<PushPull>>  for [
459            PA4: [0],
460            PA15: [1],
461        ],
462    }
463    pin! {
464        <SSck, Input<Floating>> && <MSck, Alternate<PushPull>> for [
465            PA5: [0],
466            PB3: [1],
467        ],
468    }
469    pin! {
470        <Mi, Input> default:Floating && <So, Alternate> default:PushPull for [
471            PA6: [0],
472            PB4: [1],
473        ],
474    }
475
476    impl SpiCommon for pac::SPI1 {
477        type MSck = MSck;
478        type SSck = SSck;
479        type Mi<PULL> = Mi<PULL>;
480        type So<Otype> = So<Otype>;
481        type Mo = Mo;
482        type Si<PULL> = Si<PULL>;
483        type Nss = Nss;
484        type Ss<PULL> = Ss<PULL>;
485    }
486}
487
488pub mod spi2 {
489    use super::*;
490
491    pin! {
492        <Si, Input> default:Floating && <Mo, Alternate<PushPull>> for [
493            PB15: [0],
494        ],
495        <Ss, Input> default:Floating && <Nss, Alternate<PushPull>> for [
496            PB12: [0],
497        ],
498    }
499    pin! {
500        <SSck, Input<Floating>> && <MSck, Alternate<PushPull>> for [
501            PB13: [0],
502        ],
503    }
504    pin! {
505        <Mi, Input> default:Floating && <So, Alternate> default:PushPull for [
506            PB14: [0],
507        ],
508    }
509
510    impl SpiCommon for pac::SPI2 {
511        type MSck = MSck;
512        type SSck = SSck;
513        type Mi<PULL> = Mi<PULL>;
514        type So<Otype> = So<Otype>;
515        type Mo = Mo;
516        type Si<PULL> = Si<PULL>;
517        type Nss = Nss;
518        type Ss<PULL> = Ss<PULL>;
519    }
520}
521#[cfg(any(feature = "high", feature = "connectivity"))]
522pub mod spi3 {
523    use super::*;
524
525    #[cfg(not(feature = "connectivity"))]
526    pin! {
527        <Si, Input> default:Floating && <Mo, Alternate<PushPull>> for [
528            PB5: [0],
529        ],
530        <Ss, Input> default:Floating && <Nss, Alternate<PushPull>> for [
531            PA15: [0],
532        ],
533    }
534    #[cfg(not(feature = "connectivity"))]
535    pin! {
536        <SSck, Input<Floating>> && <MSck, Alternate<PushPull>> for [
537            PB3: [0],
538        ],
539    }
540    #[cfg(not(feature = "connectivity"))]
541    pin! {
542        <Mi, Input> default:Floating && <So, Alternate> default:PushPull for [
543            PB4: [0],
544        ],
545    }
546
547    #[cfg(feature = "connectivity")]
548    pin! {
549        <Si, Input> default:Floating && <Mo, Alternate<PushPull>> for [
550            PB5: [0],
551            PC12: [1],
552        ],
553        <Ss, Input> default:Floating && <Nss, Alternate<PushPull>> for [
554            PA15: [0],
555            PA4: [1],
556        ],
557    }
558    #[cfg(feature = "connectivity")]
559    pin! {
560        <SSck, Input<Floating>> && <MSck, Alternate<PushPull>> for [
561            PB3: [0],
562            PC10: [1],
563        ],
564    }
565    #[cfg(feature = "connectivity")]
566    pin! {
567        <Mi, Input> default:Floating && <So, Alternate> default:PushPull for [
568            PB4: [0],
569            PC11: [1],
570        ],
571    }
572
573    impl SpiCommon for pac::SPI3 {
574        type MSck = MSck;
575        type SSck = SSck;
576        type Mi<PULL> = Mi<PULL>;
577        type So<Otype> = So<Otype>;
578        type Mo = Mo;
579        type Si<PULL> = Si<PULL>;
580        type Nss = Nss;
581        type Ss<PULL> = Ss<PULL>;
582    }
583}
584
585pub trait SerialAsync {
587    type Rx<PULL>;
591    type Tx<Otype>;
595}
596pub trait SerialSync {
600    type Ck;
601}
602pub trait SerialFlowControl {
604    type Cts<PULL>;
608    type Rts;
612}
613
614pub mod usart1 {
615    use super::*;
616
617    pin! {
618        <Tx, Alternate> default:PushPull for [
619            PA9: [0],
620            PB6: [1],
621        ],
622    }
623    pin! {
624        <Rx, Input> default:Floating for [
625            PA10: [0],
626            PB7:  [1],
627        ],
628        <Cts, Input> default:Floating for [
629            PA11: [0, 1],
630        ],
631    }
632
633    pin! {
634        <Ck, Alternate<PushPull>> for [
635            PA8: [0, 1],
636        ],
637        <Rts, Alternate<PushPull>> for [
638            PA12: [0, 1],
639        ],
640    }
641
642    impl SerialAsync for pac::USART1 {
643        type Rx<PULL> = Rx<PULL>;
644        type Tx<Otype> = Tx<Otype>;
645    }
646
647    impl SerialSync for pac::USART1 {
648        type Ck = Ck;
649    }
650
651    impl SerialFlowControl for pac::USART1 {
652        type Cts<PULL> = Cts<PULL>;
653        type Rts = Rts;
654    }
655}
656
657pub mod usart2 {
658    use super::*;
659
660    pin! {
661        <Tx, Alternate> default:PushPull for [
662            PA2: [0],
663            PD5: [1],
664        ],
665    }
666    pin! {
667        <Rx, Input> default:Floating for [
668            PA3: [0],
669            PD6:  [1],
670        ],
671        <Cts, Input> default:Floating for [
672            PA0: [0],
673            PD3: [1],
674        ],
675    }
676
677    pin! {
678        <Ck, Alternate<PushPull>> for [
679            PA4: [0],
680            PD7: [1],
681        ],
682        <Rts, Alternate<PushPull>> for [
683            PA1: [0],
684            PD4:  [1],
685        ],
686    }
687
688    impl SerialAsync for pac::USART2 {
689        type Rx<PULL> = Rx<PULL>;
690        type Tx<Otype> = Tx<Otype>;
691    }
692
693    impl SerialSync for pac::USART2 {
694        type Ck = Ck;
695    }
696
697    impl SerialFlowControl for pac::USART2 {
698        type Cts<PULL> = Cts<PULL>;
699        type Rts = Rts;
700    }
701}
702
703pub mod usart3 {
704    use super::*;
705
706    pin! {
707        <Tx, Alternate> default:PushPull for [
708            PB10: [0],
709            PC10: [1],
710            PD8:  [3],
711        ],
712    }
713    pin! {
714        <Rx, Input> default:Floating for [
715            PB11: [0],
716            PC11: [1],
717            PD9:  [3],
718        ],
719        <Cts, Input> default:Floating for [
720            PB13: [0, 1],
721            PD11: [3],
722        ],
723    }
724
725    pin! {
726        <Ck, Alternate<PushPull>> for [
727            PB12: [0],
728            PC12: [1],
729            PD10: [3],
730        ],
731        <Rts, Alternate<PushPull>> for [
732            PB14: [0, 1],
733            PD12: [3],
734        ],
735    }
736
737    impl SerialAsync for pac::USART3 {
738        type Rx<PULL> = Rx<PULL>;
739        type Tx<Otype> = Tx<Otype>;
740    }
741
742    impl SerialSync for pac::USART3 {
743        type Ck = Ck;
744    }
745
746    impl SerialFlowControl for pac::USART3 {
747        type Cts<PULL> = Cts<PULL>;
748        type Rts = Rts;
749    }
750}
751
752#[cfg(any(all(feature = "stm32f103", feature = "high"), feature = "connectivity"))]
753pub mod uart4 {
754    use super::*;
755
756    pin! {
757        <Tx, Alternate> default:PushPull for [
758            PC10: [0],
759        ],
760    }
761    pin! {
762        <Rx, Input> default:Floating for [
763            PC11: [0],
764        ],
765    }
766
767    impl SerialAsync for pac::UART4 {
768        type Rx<PULL> = Rx<PULL>;
769        type Tx<Otype> = Tx<Otype>;
770    }
771}
772
773#[cfg(any(all(feature = "stm32f103", feature = "high"), feature = "connectivity"))]
774pub mod uart5 {
775    use super::*;
776
777    pin! {
778        <Tx, Alternate> default:PushPull for [
779            PC12: [0],
780        ],
781    }
782    pin! {
783        <Rx, Input> default:Floating for [
784            PD2: [0],
785        ],
786    }
787
788    impl SerialAsync for pac::UART5 {
789        type Rx<PULL> = Rx<PULL>;
790        type Tx<Otype> = Tx<Otype>;
791    }
792}
793
794pub trait TimC<const C: u8> {
796    type In;
800    type Out;
804}
805
806pub trait TimNC<const C: u8> {
810    type ChN;
811}
812
813pub trait TimBkin {
817    type Bkin;
818}
819
820pub trait TimEtr {
824    type Etr;
825}
826
827pub mod tim1 {
828    use super::*;
829
830    pin! {
831        <Etr, Input<Floating>> for [
832            PA12: [0, 1],
833            PE7:  [3],
834        ],
835        <Bkin, Input<Floating>> for [
836            PB12: [0],
837            PA6:  [1],
838            PE15: [3],
839        ],
840    }
841    pin! {
842        <Ch1In, Input<Floating>> && <Ch1Out, Alternate<PushPull>> for [
843            PA8:  [0, 1],
844            PE9:  [3],
845        ],
846        <Ch2In, Input<Floating>> && <Ch2Out, Alternate<PushPull>> for [
847            PA9:  [0, 1],
848            PE11: [3],
849        ],
850        <Ch3In, Input<Floating>> && <Ch3Out, Alternate<PushPull>> for [
851            PA10: [0, 1],
852            PE13: [3],
853        ],
854        <Ch4In, Input<Floating>> && <Ch4Out, Alternate<PushPull>> for [
855            PA11: [0, 1],
856            PE14: [3],
857        ],
858    }
859
860    pin! {
861        <Ch1N, Alternate<PushPull>> for [
862            PB13: [0],
863            PA7:  [1],
864            PE8:  [3],
865        ],
866        <Ch2N, Alternate<PushPull>> for [
867            PB14: [0],
868            PB0:  [1],
869            PE10: [3],
870        ],
871        <Ch3N, Alternate<PushPull>> for [
872            PB15: [0],
873            PB1:  [1],
874            PE12: [3],
875        ],
876    }
877
878    use pac::TIM1 as TIM;
879    impl TimEtr for TIM {
880        type Etr = Etr;
881    }
882    impl TimBkin for TIM {
883        type Bkin = Bkin;
884    }
885    impl TimC<0> for TIM {
886        type In = Ch1In;
887        type Out = Ch1Out;
888    }
889    impl TimC<1> for TIM {
890        type In = Ch2In;
891        type Out = Ch2Out;
892    }
893    impl TimC<2> for TIM {
894        type In = Ch3In;
895        type Out = Ch3Out;
896    }
897    impl TimC<3> for TIM {
898        type In = Ch4In;
899        type Out = Ch4Out;
900    }
901    impl TimNC<0> for TIM {
902        type ChN = Ch1N;
903    }
904    impl TimNC<1> for TIM {
905        type ChN = Ch2N;
906    }
907    impl TimNC<2> for TIM {
908        type ChN = Ch3N;
909    }
910}
911
912pub mod tim2 {
913    use super::*;
914
915    pin! {
916        <Etr, Input<Floating>> for [
917            PA0:  [0, 2],
918            PA15: [1, 3],
919        ],
920    }
921    pin! {
922        <Ch1In, Input<Floating>> && <Ch1Out, Alternate<PushPull>> for [
923            PA0:  [0, 2],
924            PA15: [1, 3],
925        ],
926        <Ch2In, Input<Floating>> && <Ch2Out, Alternate<PushPull>> for [
927            PA1:  [0, 2],
928            PB3:  [1, 3],
929        ],
930        <Ch3In, Input<Floating>> && <Ch3Out, Alternate<PushPull>> for [
931            PA2:  [0, 1],
932            PB10: [2, 3],
933        ],
934        <Ch4In, Input<Floating>> && <Ch4Out, Alternate<PushPull>> for [
935            PA3:  [0, 1],
936            PB11: [2, 3],
937        ],
938    }
939
940    use pac::TIM2 as TIM;
941    impl TimEtr for TIM {
942        type Etr = Etr;
943    }
944    impl TimC<0> for TIM {
945        type In = Ch1In;
946        type Out = Ch1Out;
947    }
948    impl TimC<1> for TIM {
949        type In = Ch2In;
950        type Out = Ch2Out;
951    }
952    impl TimC<2> for TIM {
953        type In = Ch3In;
954        type Out = Ch3Out;
955    }
956    impl TimC<3> for TIM {
957        type In = Ch4In;
958        type Out = Ch4Out;
959    }
960}
961
962pub mod tim3 {
963    use super::*;
964
965    pin! {
966        <Etr, Input<Floating>> for [
967            PD2:  [0, 2, 3],
968        ],
969    }
970    pin! {
971        <Ch1In, Input<Floating>> && <Ch1Out, Alternate<PushPull>> for [
972            PA6:  [0],
973            PB4:  [2],
974            PC6:  [3],
975        ],
976        <Ch2In, Input<Floating>> && <Ch2Out, Alternate<PushPull>> for [
977            PA7:  [0],
978            PB5:  [2],
979            PC7:  [3],
980        ],
981        <Ch3In, Input<Floating>> && <Ch3Out, Alternate<PushPull>> for [
982            PB0:  [0, 2],
983            PC8:  [3],
984        ],
985        <Ch4In, Input<Floating>> && <Ch4Out, Alternate<PushPull>> for [
986            PB1:  [0, 2],
987            PC9:  [3],
988        ],
989    }
990
991    use pac::TIM3 as TIM;
992    impl TimEtr for TIM {
993        type Etr = Etr;
994    }
995    impl TimC<0> for TIM {
996        type In = Ch1In;
997        type Out = Ch1Out;
998    }
999    impl TimC<1> for TIM {
1000        type In = Ch2In;
1001        type Out = Ch2Out;
1002    }
1003    impl TimC<2> for TIM {
1004        type In = Ch3In;
1005        type Out = Ch3Out;
1006    }
1007    impl TimC<3> for TIM {
1008        type In = Ch4In;
1009        type Out = Ch4Out;
1010    }
1011}
1012
1013pub mod tim4 {
1014    use super::*;
1015
1016    pin! {
1017        <Etr, Input<Floating>> for [
1018            PE0:  [0, 1],
1019        ],
1020    }
1021    pin! {
1022        <Ch1In, Input<Floating>> && <Ch1Out, Alternate<PushPull>> for [
1023            PB6:  [0],
1024            PD12: [1],
1025        ],
1026        <Ch2In, Input<Floating>> && <Ch2Out, Alternate<PushPull>> for [
1027            PB7:  [0],
1028            PD13: [1],
1029        ],
1030        <Ch3In, Input<Floating>> && <Ch3Out, Alternate<PushPull>> for [
1031            PB8:  [0],
1032            PD14: [1],
1033        ],
1034        <Ch4In, Input<Floating>> && <Ch4Out, Alternate<PushPull>> for [
1035            PB9:  [0],
1036            PD15: [1],
1037        ],
1038    }
1039
1040    use pac::TIM4 as TIM;
1041    impl TimEtr for TIM {
1042        type Etr = Etr;
1043    }
1044    impl TimC<0> for TIM {
1045        type In = Ch1In;
1046        type Out = Ch1Out;
1047    }
1048    impl TimC<1> for TIM {
1049        type In = Ch2In;
1050        type Out = Ch2Out;
1051    }
1052    impl TimC<2> for TIM {
1053        type In = Ch3In;
1054        type Out = Ch3Out;
1055    }
1056    impl TimC<3> for TIM {
1057        type In = Ch4In;
1058        type Out = Ch4Out;
1059    }
1060}
1061
1062macro_rules! pin_mode {
1063    ( $($(#[$docs:meta])* <$name:ident, $MODE:ty> for [$(
1064        $PX:ident: [$($remap:literal),+],
1065    )*],)*) => {
1066        $(
1067            $(#[$docs])*
1069            pub enum $name {
1070                $(
1071                    $PX(gpio::$PX<$MODE>),
1072                )*
1073            }
1074
1075            $(
1076                $(
1077                    impl RFrom<gpio::$PX<$MODE>, $remap> for $name {
1078                        fn rfrom(p: gpio::$PX<$MODE>) -> Self {
1079                            Self::$PX(p)
1080                        }
1081                    }
1082                )+
1083
1084                impl<MODE> TryFrom<$name> for gpio::$PX<MODE>
1085                where
1086                    MODE: $crate::gpio::PinMode,
1087                    $MODE: $crate::gpio::PinMode,
1088                {
1089                    type Error = ();
1090
1091                    fn try_from(a: $name) -> Result<Self, Self::Error> {
1092                        #[allow(irrefutable_let_patterns)]
1093                        if let $name::$PX(p) = a {
1094                            Ok(p.into_mode(&mut Cr))
1095                        } else {
1096                            Err(())
1097                        }
1098                    }
1099                }
1100            )*
1101        )*
1102    };
1103}
1104use pin_mode;
1105
1106macro_rules! pin_default_mode {
1107    ( $($(#[$docs:meta])* <$name:ident, $M:ident> default:$DefaultMode:ident for [$(
1108        $PX:ident: [$($remap:literal),+],
1109    )*],)*) => {
1110        $(
1111            $(#[$docs])*
1113            pub enum $name<MODE = $DefaultMode> {
1114                $(
1115                    $PX(gpio::$PX<$M<MODE>>),
1116                )*
1117            }
1118
1119            $(
1120                $(
1121                    impl<MODE> RFrom<gpio::$PX<$M<MODE>>, $remap> for $name<MODE> {
1122                        fn rfrom(p: gpio::$PX<$M<MODE>>) -> Self {
1123                            Self::$PX(p)
1124                        }
1125                    }
1126                )+
1127
1128                impl<OUTMODE> TryFrom<$name> for gpio::$PX<OUTMODE>
1129                where
1130                    OUTMODE: $crate::gpio::PinMode,
1131                {
1132                    type Error = ();
1133
1134                    fn try_from(a: $name) -> Result<Self, Self::Error> {
1135                        #[allow(irrefutable_let_patterns)]
1136                        if let $name::$PX(p) = a {
1137                            Ok(p.into_mode(&mut Cr))
1138                        } else {
1139                            Err(())
1140                        }
1141                    }
1142                }
1143            )*
1144        )*
1145    };
1146}
1147use pin_default_mode;
1148
1149macro_rules! pin {
1150    ( $($(#[$docs:meta])* <$name:ident, Input<$MODE:ident>> && <$name2:ident, Alternate<$MODE2:ident>> for [$(
1151        $PX:ident: [$($remap:literal),+],
1152    )*],)*) => {
1153        pin! {
1154            $($(#[$docs])* <$name, Input<$MODE>> for [$(
1155                $PX: [$($remap),+],
1156            )*],)*
1157        }
1158        pin! {
1159            $($(#[$docs])* <$name2, Alternate<$MODE2>> for [$(
1160                $PX: [$($remap),+],
1161            )*],)*
1162        }
1163    };
1164
1165    ( $($(#[$docs:meta])* <$name:ident, Input> default:$DefaultMode:ident && <$name2:ident, Alternate<$MODE2:ident>> for [$(
1166        $PX:ident: [$($remap:literal),+],
1167    )*],)*) => {
1168        pin! {
1169            $($(#[$docs])* <$name, Input> default:$DefaultMode for [$(
1170                $PX: [$($remap),+],
1171            )*],)*
1172        }
1173        pin! {
1174            $($(#[$docs])* <$name2, Alternate<$MODE2>> for [$(
1175                $PX: [$($remap),+],
1176            )*],)*
1177        }
1178    };
1179
1180    ( $($(#[$docs:meta])* <$name:ident, Input> default:$DefaultMode:ident && <$name2:ident, Alternate> default:$DefaultMode2:ident for [$(
1181        $PX:ident: [$($remap:literal),+],
1182    )*],)*) => {
1183        pin! {
1184            $($(#[$docs])* <$name, Input> default:$DefaultMode for [$(
1185                $PX: [$($remap),+],
1186            )*],)*
1187        }
1188        pin! {
1189            $($(#[$docs])* <$name2, Alternate> default:$DefaultMode2 for [$(
1190                $PX: [$($remap),+],
1191            )*],)*
1192        }
1193    };
1194
1195    ( $($(#[$docs:meta])* <$name:ident, Input<$MODE:ident>> for [$(
1196        $PX:ident: [$($remap:literal),+],
1197    )*],)*) => {
1198        pin_mode! {
1199            $($(#[$docs])* <$name, Input<$MODE>> for [$(
1200                $PX: [$($remap),+],
1201            )*],)*
1202        }
1203    };
1204    ( $($(#[$docs:meta])* <$name:ident, Alternate<$MODE:ident>> for [$(
1205        $PX:ident: [$($remap:literal),+],
1206    )*],)*) => {
1207        pin_mode! {
1208            $($(#[$docs])* <$name, Alternate<$MODE>> for [$(
1209                $PX: [$($remap),+],
1210            )*],)*
1211        }
1212
1213        $(
1214            $(
1215                $(
1216                    impl RFrom<gpio::$PX, $remap> for $name {
1217                        fn rfrom(p: gpio::$PX) -> Self {
1218                            Self::$PX(p.into_mode(&mut Cr))
1219                        }
1220                    }
1221                )+
1222            )*
1223        )*
1224    };
1225    ( $($(#[$docs:meta])* <$name:ident, Input> default:$DefaultMode:ident for [$(
1226        $PX:ident: [$($remap:literal),+],
1227    )*],)*) => {
1228        pin_default_mode! {
1229            $($(#[$docs])* <$name, Input> default:$DefaultMode for [$(
1230                $PX: [$($remap),+],
1231            )*],)*
1232        }
1233    };
1234    ( $($(#[$docs:meta])* <$name:ident, Alternate> default:$DefaultMode:ident for [$(
1235        $PX:ident: [$($remap:literal),+],
1236    )*],)*) => {
1237        pin_default_mode! {
1238            $($(#[$docs])* <$name, Alternate> default:$DefaultMode for [$(
1239                $PX: [$($remap),+],
1240            )*],)*
1241        }
1242        $(
1243            $(
1244                $(
1245                    impl<MODE> RFrom<gpio::$PX, $remap> for $name<MODE>
1246                    where Alternate<MODE>: $crate::gpio::PinMode,
1247                    {
1248                        fn rfrom(p: gpio::$PX) -> Self {
1249                            Self::$PX(p.into_mode(&mut Cr))
1250                        }
1251                    }
1252                )+
1253            )*
1254        )*
1255    };
1256}
1257use pin;
1258use stm32f1::RegisterSpec;