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