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, afio};
8use crate::rcc::Rcc;
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 rcc.enable(&self);
20 rcc.reset(&self);
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;