diff options
| author | Dario Nieuwenhuis <[email protected]> | 2025-09-05 23:00:31 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2025-09-05 23:00:31 +0200 |
| commit | 7419b398bf7cc5c1ff164c504f4a4027cd6bcd3b (patch) | |
| tree | 9ea26e1059b70502d0e5929a72a9f50c8c43838b | |
| parent | a6562c4f033432e40970aafe82f33c5138adf84e (diff) | |
stm32/afio: use type inference for timer remaps as well.
| -rw-r--r-- | embassy-stm32/build.rs | 131 | ||||
| -rw-r--r-- | embassy-stm32/src/macros.rs | 55 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/complementary_pwm.rs | 39 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/input_capture.rs | 25 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/mod.rs | 43 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/one_pulse.rs | 66 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/pwm_input.rs | 8 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/qei.rs | 14 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/simple_pwm.rs | 31 | ||||
| -rw-r--r-- | examples/stm32f1/src/bin/input_capture.rs | 5 | ||||
| -rw-r--r-- | examples/stm32f1/src/bin/pwm_input.rs | 4 | ||||
| -rw-r--r-- | tests/stm32/src/bin/afio.rs | 24 |
12 files changed, 156 insertions, 289 deletions
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index f55e1e0c9..0d3582c9d 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs | |||
| @@ -1391,58 +1391,51 @@ fn main() { | |||
| 1391 | }) | 1391 | }) |
| 1392 | } | 1392 | } |
| 1393 | 1393 | ||
| 1394 | let pin_trait_impl = p | 1394 | let pin_trait_impl = if let Some(afio) = &p.afio { |
| 1395 | .afio | 1395 | let values = afio |
| 1396 | .as_ref() | 1396 | .values |
| 1397 | .and_then(|afio| { | 1397 | .iter() |
| 1398 | if p.name.starts_with("TIM") { | 1398 | .filter(|v| v.pins.contains(&pin.pin)) |
| 1399 | // timers are handled by timer_afio_impl!() | 1399 | .map(|v| v.value) |
| 1400 | return None; | 1400 | .collect::<Vec<_>>(); |
| 1401 | } | ||
| 1402 | |||
| 1403 | let values = afio | ||
| 1404 | .values | ||
| 1405 | .iter() | ||
| 1406 | .filter(|v| v.pins.contains(&pin.pin)) | ||
| 1407 | .map(|v| v.value) | ||
| 1408 | .collect::<Vec<_>>(); | ||
| 1409 | 1401 | ||
| 1410 | if values.is_empty() { | 1402 | if values.is_empty() { |
| 1411 | None | 1403 | None |
| 1412 | } else { | 1404 | } else { |
| 1413 | let setter = format_ident!("set_{}", afio.field.to_lowercase()); | 1405 | let reg = format_ident!("{}", afio.register.to_lowercase()); |
| 1414 | let type_and_values = if is_bool_field("AFIO", afio.register, afio.field) { | 1406 | let setter = format_ident!("set_{}", afio.field.to_lowercase()); |
| 1415 | let values = values.iter().map(|&v| v > 0); | 1407 | let type_and_values = if is_bool_field("AFIO", afio.register, afio.field) { |
| 1416 | quote!(AfioRemapBool, [#(#values),*]) | 1408 | let values = values.iter().map(|&v| v > 0); |
| 1417 | } else { | 1409 | quote!(AfioRemapBool, [#(#values),*]) |
| 1418 | quote!(AfioRemap, [#(#values),*]) | ||
| 1419 | }; | ||
| 1420 | |||
| 1421 | Some(quote! { | ||
| 1422 | pin_trait_afio_impl!(#tr, #peri, #pin_name, {#setter, #type_and_values}); | ||
| 1423 | }) | ||
| 1424 | } | ||
| 1425 | }) | ||
| 1426 | .unwrap_or_else(|| { | ||
| 1427 | let peripherals_with_afio = [ | ||
| 1428 | "CAN", | ||
| 1429 | "CEC", | ||
| 1430 | "ETH", | ||
| 1431 | "I2C", | ||
| 1432 | "SPI", | ||
| 1433 | "SUBGHZSPI", | ||
| 1434 | "USART", | ||
| 1435 | "UART", | ||
| 1436 | "LPUART", | ||
| 1437 | ]; | ||
| 1438 | let af_or_not_applicable = if peripherals_with_afio.iter().any(|&x| p.name.starts_with(x)) { | ||
| 1439 | quote!(0, crate::gpio::AfioRemapNotApplicable) | ||
| 1440 | } else { | 1410 | } else { |
| 1441 | quote!(#af) | 1411 | quote!(AfioRemap, [#(#values),*]) |
| 1442 | }; | 1412 | }; |
| 1443 | 1413 | ||
| 1444 | quote!(pin_trait_impl!(#tr, #peri, #pin_name, #af_or_not_applicable);) | 1414 | Some(quote! { |
| 1445 | }); | 1415 | pin_trait_afio_impl!(#tr, #peri, #pin_name, {#reg, #setter, #type_and_values}); |
| 1416 | }) | ||
| 1417 | } | ||
| 1418 | } else { | ||
| 1419 | let peripherals_with_afio = [ | ||
| 1420 | "CAN", | ||
| 1421 | "CEC", | ||
| 1422 | "ETH", | ||
| 1423 | "I2C", | ||
| 1424 | "SPI", | ||
| 1425 | "SUBGHZSPI", | ||
| 1426 | "USART", | ||
| 1427 | "UART", | ||
| 1428 | "LPUART", | ||
| 1429 | "TIM", | ||
| 1430 | ]; | ||
| 1431 | let af_or_not_applicable = if peripherals_with_afio.iter().any(|&x| p.name.starts_with(x)) { | ||
| 1432 | quote!(0, crate::gpio::AfioRemapNotApplicable) | ||
| 1433 | } else { | ||
| 1434 | quote!(#af) | ||
| 1435 | }; | ||
| 1436 | |||
| 1437 | Some(quote!(pin_trait_impl!(#tr, #peri, #pin_name, #af_or_not_applicable);)) | ||
| 1438 | }; | ||
| 1446 | 1439 | ||
| 1447 | g.extend(pin_trait_impl); | 1440 | g.extend(pin_trait_impl); |
| 1448 | } | 1441 | } |
| @@ -1970,48 +1963,6 @@ fn main() { | |||
| 1970 | }); | 1963 | }); |
| 1971 | 1964 | ||
| 1972 | // ======== | 1965 | // ======== |
| 1973 | // Generate timer AFIO impls | ||
| 1974 | |||
| 1975 | for p in METADATA.peripherals { | ||
| 1976 | if p.name.starts_with("TIM") { | ||
| 1977 | let pname = format_ident!("{}", p.name); | ||
| 1978 | let afio = if let Some(afio) = &p.afio { | ||
| 1979 | let register = format_ident!("{}", afio.register.to_lowercase()); | ||
| 1980 | let setter = format_ident!("set_{}", afio.field.to_lowercase()); | ||
| 1981 | |||
| 1982 | let swj_cfg = if afio.register == "MAPR" { | ||
| 1983 | quote!(w.set_swj_cfg(crate::pac::afio::vals::SwjCfg::NO_OP);) | ||
| 1984 | } else { | ||
| 1985 | quote!() | ||
| 1986 | }; | ||
| 1987 | let bool_eval = if is_bool_field("AFIO", &afio.register, &afio.field) { | ||
| 1988 | quote!(> 0) | ||
| 1989 | } else { | ||
| 1990 | quote!() | ||
| 1991 | }; | ||
| 1992 | |||
| 1993 | let values = afio.values.iter().map(|v| { | ||
| 1994 | let mapr_value = v.value; | ||
| 1995 | let pin = v.pins.iter().map(|p| { | ||
| 1996 | let port_num = p.chars().nth(1).unwrap() as u8 - b'A'; | ||
| 1997 | let pin_num = p[2..].parse::<u8>().unwrap(); | ||
| 1998 | port_num * 16 + pin_num | ||
| 1999 | }); | ||
| 2000 | quote!(#mapr_value, [#(#pin),*]) | ||
| 2001 | }); | ||
| 2002 | |||
| 2003 | quote! { | ||
| 2004 | , |v| crate::pac::AFIO.#register().modify(|w| { #swj_cfg w.#setter(v #bool_eval); }), #({#values}),* | ||
| 2005 | } | ||
| 2006 | } else { | ||
| 2007 | quote!() | ||
| 2008 | }; | ||
| 2009 | |||
| 2010 | g.extend(quote!(timer_afio_impl!(#pname #afio);)); | ||
| 2011 | } | ||
| 2012 | } | ||
| 2013 | |||
| 2014 | // ======== | ||
| 2015 | // Generate gpio_block() function | 1966 | // Generate gpio_block() function |
| 2016 | 1967 | ||
| 2017 | let gpio_base = METADATA.peripherals.iter().find(|p| p.name == "GPIOA").unwrap().address as usize; | 1968 | let gpio_base = METADATA.peripherals.iter().find(|p| p.name == "GPIOA").unwrap().address as usize; |
diff --git a/embassy-stm32/src/macros.rs b/embassy-stm32/src/macros.rs index f97843a7d..8a3abe1ee 100644 --- a/embassy-stm32/src/macros.rs +++ b/embassy-stm32/src/macros.rs | |||
| @@ -71,7 +71,31 @@ macro_rules! pin_trait_impl { | |||
| 71 | 71 | ||
| 72 | #[cfg(afio)] | 72 | #[cfg(afio)] |
| 73 | macro_rules! pin_trait_afio_impl { | 73 | macro_rules! pin_trait_afio_impl { |
| 74 | (crate::$mod:ident::$trait:ident, $instance:ident, $pin:ident, {$setter:ident, $type:ident, [$($val:expr),+]}) => { | 74 | (@set mapr, $setter:ident, $val:expr) => { |
| 75 | crate::pac::AFIO.mapr().modify(|w| { | ||
| 76 | w.set_swj_cfg(crate::pac::afio::vals::SwjCfg::NO_OP); | ||
| 77 | w.$setter($val); | ||
| 78 | }); | ||
| 79 | }; | ||
| 80 | (@set mapr2, $setter:ident, $val:expr) => { | ||
| 81 | crate::pac::AFIO.mapr2().modify(|w| { | ||
| 82 | w.$setter($val); | ||
| 83 | }); | ||
| 84 | }; | ||
| 85 | (crate::$mod:ident::$trait:ident<$mode:ident>, $instance:ident, $pin:ident, {$reg:ident, $setter:ident, $type:ident, [$($val:expr),+]}) => { | ||
| 86 | $( | ||
| 87 | impl crate::$mod::$trait<crate::peripherals::$instance, crate::$mod::$mode, crate::gpio::$type<$val>> for crate::peripherals::$pin { | ||
| 88 | fn af_num(&self) -> u8 { | ||
| 89 | 0 | ||
| 90 | } | ||
| 91 | |||
| 92 | fn afio_remap(&self) { | ||
| 93 | pin_trait_afio_impl!(@set $reg, $setter, $val); | ||
| 94 | } | ||
| 95 | } | ||
| 96 | )+ | ||
| 97 | }; | ||
| 98 | (crate::$mod:ident::$trait:ident, $instance:ident, $pin:ident, {$reg:ident, $setter:ident, $type:ident, [$($val:expr),+]}) => { | ||
| 75 | $( | 99 | $( |
| 76 | impl crate::$mod::$trait<crate::peripherals::$instance, crate::gpio::$type<$val>> for crate::peripherals::$pin { | 100 | impl crate::$mod::$trait<crate::peripherals::$instance, crate::gpio::$type<$val>> for crate::peripherals::$pin { |
| 77 | fn af_num(&self) -> u8 { | 101 | fn af_num(&self) -> u8 { |
| @@ -79,10 +103,7 @@ macro_rules! pin_trait_afio_impl { | |||
| 79 | } | 103 | } |
| 80 | 104 | ||
| 81 | fn afio_remap(&self) { | 105 | fn afio_remap(&self) { |
| 82 | crate::pac::AFIO.mapr().modify(|w| { | 106 | pin_trait_afio_impl!(@set $reg, $setter, $val); |
| 83 | w.set_swj_cfg(crate::pac::afio::vals::SwjCfg::NO_OP); | ||
| 84 | w.$setter($val); | ||
| 85 | }); | ||
| 86 | } | 107 | } |
| 87 | } | 108 | } |
| 88 | )+ | 109 | )+ |
| @@ -102,30 +123,6 @@ macro_rules! sel_trait_impl { | |||
| 102 | 123 | ||
| 103 | // ==================== | 124 | // ==================== |
| 104 | 125 | ||
| 105 | macro_rules! timer_afio_impl { | ||
| 106 | ($instance:ident $(, $set_afio:expr)? $(,{$mapr_value:literal, [$($pin:literal),*]})*) => { | ||
| 107 | impl crate::timer::Afio for crate::peripherals::$instance { | ||
| 108 | fn afio_mappings() -> &'static [crate::timer::AfioMapping] { | ||
| 109 | &[ | ||
| 110 | $( | ||
| 111 | crate::timer::AfioMapping { | ||
| 112 | value: $mapr_value, | ||
| 113 | pins: &[$($pin),*], | ||
| 114 | } | ||
| 115 | ),* | ||
| 116 | ] | ||
| 117 | } | ||
| 118 | |||
| 119 | #[allow(unused)] | ||
| 120 | fn set_afio(value: u8) { | ||
| 121 | $($set_afio(value);)? | ||
| 122 | } | ||
| 123 | } | ||
| 124 | }; | ||
| 125 | } | ||
| 126 | |||
| 127 | // ==================== | ||
| 128 | |||
| 129 | macro_rules! dma_trait { | 126 | macro_rules! dma_trait { |
| 130 | ($signal:ident, $instance:path$(, $mode:path)?) => { | 127 | ($signal:ident, $instance:path$(, $mode:path)?) => { |
| 131 | #[doc = concat!(stringify!($signal), " DMA request trait")] | 128 | #[doc = concat!(stringify!($signal), " DMA request trait")] |
diff --git a/embassy-stm32/src/timer/complementary_pwm.rs b/embassy-stm32/src/timer/complementary_pwm.rs index 08404cdd6..d3b84ed16 100644 --- a/embassy-stm32/src/timer/complementary_pwm.rs +++ b/embassy-stm32/src/timer/complementary_pwm.rs | |||
| @@ -16,21 +16,23 @@ use crate::Peri; | |||
| 16 | /// Complementary PWM pin wrapper. | 16 | /// Complementary PWM pin wrapper. |
| 17 | /// | 17 | /// |
| 18 | /// This wraps a pin to make it usable with PWM. | 18 | /// This wraps a pin to make it usable with PWM. |
| 19 | pub struct ComplementaryPwmPin<'d, T, C> { | 19 | pub struct ComplementaryPwmPin<'d, T, C, A> { |
| 20 | #[allow(unused)] | 20 | #[allow(unused)] |
| 21 | pin: Peri<'d, AnyPin>, | 21 | pin: Peri<'d, AnyPin>, |
| 22 | phantom: PhantomData<(T, C)>, | 22 | phantom: PhantomData<(T, C, A)>, |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | impl<'d, T: AdvancedInstance4Channel, C: TimerChannel> ComplementaryPwmPin<'d, T, C> { | 25 | impl<'d, T: AdvancedInstance4Channel, C: TimerChannel, A> ComplementaryPwmPin<'d, T, C, A> { |
| 26 | /// Create a new complementary PWM pin instance. | 26 | /// Create a new complementary PWM pin instance. |
| 27 | pub fn new(pin: Peri<'d, impl TimerComplementaryPin<T, C>>, output_type: OutputType) -> Self { | 27 | pub fn new(pin: Peri<'d, impl TimerComplementaryPin<T, C, A>>, output_type: OutputType) -> Self { |
| 28 | critical_section::with(|_| { | 28 | critical_section::with(|_| { |
| 29 | pin.set_low(); | 29 | pin.set_low(); |
| 30 | pin.set_as_af( | 30 | pin.set_as_af( |
| 31 | pin.af_num(), | 31 | pin.af_num(), |
| 32 | crate::gpio::AfType::output(output_type, crate::gpio::Speed::VeryHigh), | 32 | crate::gpio::AfType::output(output_type, crate::gpio::Speed::VeryHigh), |
| 33 | ); | 33 | ); |
| 34 | #[cfg(afio)] | ||
| 35 | pin.afio_remap(); | ||
| 34 | }); | 36 | }); |
| 35 | ComplementaryPwmPin { | 37 | ComplementaryPwmPin { |
| 36 | pin: pin.into(), | 38 | pin: pin.into(), |
| @@ -56,30 +58,19 @@ pub enum IdlePolarity { | |||
| 56 | impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> { | 58 | impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> { |
| 57 | /// Create a new complementary PWM driver. | 59 | /// Create a new complementary PWM driver. |
| 58 | #[allow(clippy::too_many_arguments, unused)] | 60 | #[allow(clippy::too_many_arguments, unused)] |
| 59 | pub fn new( | 61 | pub fn new<A>( |
| 60 | tim: Peri<'d, T>, | 62 | tim: Peri<'d, T>, |
| 61 | ch1: Option<PwmPin<'d, T, Ch1>>, | 63 | ch1: Option<PwmPin<'d, T, Ch1, A>>, |
| 62 | ch1n: Option<ComplementaryPwmPin<'d, T, Ch1>>, | 64 | ch1n: Option<ComplementaryPwmPin<'d, T, Ch1, A>>, |
| 63 | ch2: Option<PwmPin<'d, T, Ch2>>, | 65 | ch2: Option<PwmPin<'d, T, Ch2, A>>, |
| 64 | ch2n: Option<ComplementaryPwmPin<'d, T, Ch2>>, | 66 | ch2n: Option<ComplementaryPwmPin<'d, T, Ch2, A>>, |
| 65 | ch3: Option<PwmPin<'d, T, Ch3>>, | 67 | ch3: Option<PwmPin<'d, T, Ch3, A>>, |
| 66 | ch3n: Option<ComplementaryPwmPin<'d, T, Ch3>>, | 68 | ch3n: Option<ComplementaryPwmPin<'d, T, Ch3, A>>, |
| 67 | ch4: Option<PwmPin<'d, T, Ch4>>, | 69 | ch4: Option<PwmPin<'d, T, Ch4, A>>, |
| 68 | ch4n: Option<ComplementaryPwmPin<'d, T, Ch4>>, | 70 | ch4n: Option<ComplementaryPwmPin<'d, T, Ch4, A>>, |
| 69 | freq: Hertz, | 71 | freq: Hertz, |
| 70 | counting_mode: CountingMode, | 72 | counting_mode: CountingMode, |
| 71 | ) -> Self { | 73 | ) -> Self { |
| 72 | #[cfg(afio)] | ||
| 73 | super::set_afio::<T>(&[ | ||
| 74 | ch1.map(|p| p.pin), | ||
| 75 | ch1n.map(|p| p.pin), | ||
| 76 | ch2.map(|p| p.pin), | ||
| 77 | ch2n.map(|p| p.pin), | ||
| 78 | ch3.map(|p| p.pin), | ||
| 79 | ch3n.map(|p| p.pin), | ||
| 80 | ch4.map(|p| p.pin), | ||
| 81 | ch4n.map(|p| p.pin), | ||
| 82 | ]); | ||
| 83 | Self::new_inner(tim, freq, counting_mode) | 74 | Self::new_inner(tim, freq, counting_mode) |
| 84 | } | 75 | } |
| 85 | 76 | ||
diff --git a/embassy-stm32/src/timer/input_capture.rs b/embassy-stm32/src/timer/input_capture.rs index b717e6eac..262f9d067 100644 --- a/embassy-stm32/src/timer/input_capture.rs +++ b/embassy-stm32/src/timer/input_capture.rs | |||
| @@ -17,14 +17,14 @@ use crate::Peri; | |||
| 17 | /// Capture pin wrapper. | 17 | /// Capture pin wrapper. |
| 18 | /// | 18 | /// |
| 19 | /// This wraps a pin to make it usable with capture. | 19 | /// This wraps a pin to make it usable with capture. |
| 20 | pub struct CapturePin<'d, T, C> { | 20 | pub struct CapturePin<'d, T, C, A> { |
| 21 | #[allow(unused)] | 21 | #[allow(unused)] |
| 22 | pin: Peri<'d, AnyPin>, | 22 | pin: Peri<'d, AnyPin>, |
| 23 | phantom: PhantomData<(T, C)>, | 23 | phantom: PhantomData<(T, C, A)>, |
| 24 | } | 24 | } |
| 25 | impl<'d, T: GeneralInstance4Channel, C: TimerChannel> CapturePin<'d, T, C> { | 25 | impl<'d, T: GeneralInstance4Channel, C: TimerChannel, A> CapturePin<'d, T, C, A> { |
| 26 | /// Create a new capture pin instance. | 26 | /// Create a new capture pin instance. |
| 27 | pub fn new(pin: Peri<'d, impl TimerPin<T, C>>, pull: Pull) -> Self { | 27 | pub fn new(pin: Peri<'d, impl TimerPin<T, C, A>>, pull: Pull) -> Self { |
| 28 | pin.set_as_af(pin.af_num(), AfType::input(pull)); | 28 | pin.set_as_af(pin.af_num(), AfType::input(pull)); |
| 29 | CapturePin { | 29 | CapturePin { |
| 30 | pin: pin.into(), | 30 | pin: pin.into(), |
| @@ -41,23 +41,16 @@ pub struct InputCapture<'d, T: GeneralInstance4Channel> { | |||
| 41 | impl<'d, T: GeneralInstance4Channel> InputCapture<'d, T> { | 41 | impl<'d, T: GeneralInstance4Channel> InputCapture<'d, T> { |
| 42 | /// Create a new input capture driver. | 42 | /// Create a new input capture driver. |
| 43 | #[allow(unused)] | 43 | #[allow(unused)] |
| 44 | pub fn new( | 44 | pub fn new<A>( |
| 45 | tim: Peri<'d, T>, | 45 | tim: Peri<'d, T>, |
| 46 | ch1: Option<CapturePin<'d, T, Ch1>>, | 46 | ch1: Option<CapturePin<'d, T, Ch1, A>>, |
| 47 | ch2: Option<CapturePin<'d, T, Ch2>>, | 47 | ch2: Option<CapturePin<'d, T, Ch2, A>>, |
| 48 | ch3: Option<CapturePin<'d, T, Ch3>>, | 48 | ch3: Option<CapturePin<'d, T, Ch3, A>>, |
| 49 | ch4: Option<CapturePin<'d, T, Ch4>>, | 49 | ch4: Option<CapturePin<'d, T, Ch4, A>>, |
| 50 | _irq: impl Binding<T::CaptureCompareInterrupt, CaptureCompareInterruptHandler<T>> + 'd, | 50 | _irq: impl Binding<T::CaptureCompareInterrupt, CaptureCompareInterruptHandler<T>> + 'd, |
| 51 | freq: Hertz, | 51 | freq: Hertz, |
| 52 | counting_mode: CountingMode, | 52 | counting_mode: CountingMode, |
| 53 | ) -> Self { | 53 | ) -> Self { |
| 54 | #[cfg(afio)] | ||
| 55 | super::set_afio::<T>(&[ | ||
| 56 | ch1.map(|p| p.pin), | ||
| 57 | ch2.map(|p| p.pin), | ||
| 58 | ch3.map(|p| p.pin), | ||
| 59 | ch4.map(|p| p.pin), | ||
| 60 | ]); | ||
| 61 | Self::new_inner(tim, freq, counting_mode) | 54 | Self::new_inner(tim, freq, counting_mode) |
| 62 | } | 55 | } |
| 63 | 56 | ||
diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs index 38f4a1a51..b09bc7166 100644 --- a/embassy-stm32/src/timer/mod.rs +++ b/embassy-stm32/src/timer/mod.rs | |||
| @@ -14,8 +14,6 @@ pub mod pwm_input; | |||
| 14 | pub mod qei; | 14 | pub mod qei; |
| 15 | pub mod simple_pwm; | 15 | pub mod simple_pwm; |
| 16 | 16 | ||
| 17 | #[cfg(afio)] | ||
| 18 | use crate::gpio::SealedPin; | ||
| 19 | use crate::interrupt; | 17 | use crate::interrupt; |
| 20 | use crate::rcc::RccPeripheral; | 18 | use crate::rcc::RccPeripheral; |
| 21 | 19 | ||
| @@ -157,15 +155,9 @@ trait SealedInstance: RccPeripheral + PeripheralType { | |||
| 157 | fn state() -> &'static State; | 155 | fn state() -> &'static State; |
| 158 | } | 156 | } |
| 159 | 157 | ||
| 160 | #[allow(unused)] | ||
| 161 | pub(crate) trait Afio { | ||
| 162 | fn afio_mappings() -> &'static [AfioMapping]; | ||
| 163 | fn set_afio(value: u8); | ||
| 164 | } | ||
| 165 | |||
| 166 | /// Core timer instance. | 158 | /// Core timer instance. |
| 167 | #[allow(private_bounds)] | 159 | #[allow(private_bounds)] |
| 168 | pub trait CoreInstance: SealedInstance + Afio + 'static { | 160 | pub trait CoreInstance: SealedInstance + 'static { |
| 169 | /// Update Interrupt for this timer. | 161 | /// Update Interrupt for this timer. |
| 170 | type UpdateInterrupt: interrupt::typelevel::Interrupt; | 162 | type UpdateInterrupt: interrupt::typelevel::Interrupt; |
| 171 | 163 | ||
| @@ -231,15 +223,15 @@ pub trait AdvancedInstance2Channel: BasicInstance + GeneralInstance2Channel + Ad | |||
| 231 | /// Advanced 16-bit timer with 4 channels instance. | 223 | /// Advanced 16-bit timer with 4 channels instance. |
| 232 | pub trait AdvancedInstance4Channel: AdvancedInstance2Channel + GeneralInstance4Channel {} | 224 | pub trait AdvancedInstance4Channel: AdvancedInstance2Channel + GeneralInstance4Channel {} |
| 233 | 225 | ||
| 234 | pin_trait!(TimerPin, GeneralInstance4Channel, TimerChannel); | 226 | pin_trait!(TimerPin, GeneralInstance4Channel, TimerChannel, @A); |
| 235 | pin_trait!(ExternalTriggerPin, GeneralInstance4Channel); | 227 | pin_trait!(ExternalTriggerPin, GeneralInstance4Channel, @A); |
| 236 | 228 | ||
| 237 | pin_trait!(TimerComplementaryPin, AdvancedInstance4Channel, TimerChannel); | 229 | pin_trait!(TimerComplementaryPin, AdvancedInstance4Channel, TimerChannel, @A); |
| 238 | 230 | ||
| 239 | pin_trait!(BreakInputPin, AdvancedInstance4Channel, BreakInput); | 231 | pin_trait!(BreakInputPin, AdvancedInstance4Channel, BreakInput, @A); |
| 240 | 232 | ||
| 241 | pin_trait!(BreakInputComparator1Pin, AdvancedInstance4Channel, BreakInput); | 233 | pin_trait!(BreakInputComparator1Pin, AdvancedInstance4Channel, BreakInput, @A); |
| 242 | pin_trait!(BreakInputComparator2Pin, AdvancedInstance4Channel, BreakInput); | 234 | pin_trait!(BreakInputComparator2Pin, AdvancedInstance4Channel, BreakInput, @A); |
| 243 | 235 | ||
| 244 | // Update Event trigger DMA for every timer | 236 | // Update Event trigger DMA for every timer |
| 245 | dma_trait!(UpDma, BasicInstance); | 237 | dma_trait!(UpDma, BasicInstance); |
| @@ -458,24 +450,3 @@ impl<T: GeneralInstance1Channel> interrupt::typelevel::Handler<T::CaptureCompare | |||
| 458 | } | 450 | } |
| 459 | } | 451 | } |
| 460 | } | 452 | } |
| 461 | |||
| 462 | #[allow(unused)] | ||
| 463 | pub(crate) struct AfioMapping { | ||
| 464 | pub(crate) value: u8, | ||
| 465 | pub(crate) pins: &'static [u8], | ||
| 466 | } | ||
| 467 | |||
| 468 | #[cfg(afio)] | ||
| 469 | fn set_afio<'d, T: Afio>(pins: &[Option<embassy_hal_internal::Peri<'d, crate::gpio::AnyPin>>]) { | ||
| 470 | let mapping = T::afio_mappings() | ||
| 471 | .iter() | ||
| 472 | .find(|m| { | ||
| 473 | pins.iter() | ||
| 474 | .flatten() | ||
| 475 | .map(|p| (*p).pin_port()) | ||
| 476 | .all(|p| m.pins.contains(&p)) | ||
| 477 | }) | ||
| 478 | .expect("Should be called with a combination of timer pins supported by the hardware"); | ||
| 479 | |||
| 480 | T::set_afio(mapping.value); | ||
| 481 | } | ||
diff --git a/embassy-stm32/src/timer/one_pulse.rs b/embassy-stm32/src/timer/one_pulse.rs index 0267749e1..b15cea679 100644 --- a/embassy-stm32/src/timer/one_pulse.rs +++ b/embassy-stm32/src/timer/one_pulse.rs | |||
| @@ -15,6 +15,7 @@ use crate::gpio::{AfType, AnyPin, Pull}; | |||
| 15 | use crate::interrupt::typelevel::{Binding, Interrupt}; | 15 | use crate::interrupt::typelevel::{Binding, Interrupt}; |
| 16 | use crate::pac::timer::vals::Etp; | 16 | use crate::pac::timer::vals::Etp; |
| 17 | use crate::time::Hertz; | 17 | use crate::time::Hertz; |
| 18 | use crate::timer::TimerChannel; | ||
| 18 | use crate::Peri; | 19 | use crate::Peri; |
| 19 | 20 | ||
| 20 | /// External input marker type. | 21 | /// External input marker type. |
| @@ -61,58 +62,25 @@ impl SealedTriggerSource for Ch1 {} | |||
| 61 | impl SealedTriggerSource for Ch2 {} | 62 | impl SealedTriggerSource for Ch2 {} |
| 62 | impl SealedTriggerSource for Ext {} | 63 | impl SealedTriggerSource for Ext {} |
| 63 | 64 | ||
| 64 | trait SealedTimerTriggerPin<T, S>: crate::gpio::Pin {} | 65 | impl<'d, T: GeneralInstance4Channel, C: TriggerSource + TimerChannel> TriggerPin<'d, T, C> { |
| 65 | 66 | /// Create a new Channel trigger pin instance. | |
| 66 | /// Marker trait for a trigger pin. | 67 | pub fn new<A>(pin: Peri<'d, impl TimerPin<T, C, A>>, pull: Pull) -> Self { |
| 67 | #[expect(private_bounds)] | 68 | pin.set_as_af(pin.af_num(), AfType::input(pull)); |
| 68 | // TODO: find better naming scheme than prefixing all pin traits with "Timer". | 69 | #[cfg(afio)] |
| 69 | // The trait name cannot conflict with the corresponding type's name. | 70 | pin.afio_remap(); |
| 70 | // Applies to other timer submodules as well. | 71 | TriggerPin { |
| 71 | pub trait TimerTriggerPin<T, S>: SealedTimerTriggerPin<T, S> { | 72 | pin: pin.into(), |
| 72 | /// Get the AF number needed to use this pin as a trigger source. | 73 | phantom: PhantomData, |
| 73 | fn af_num(&self) -> u8; | 74 | } |
| 74 | } | ||
| 75 | |||
| 76 | impl<T, P, C> TimerTriggerPin<T, C> for P | ||
| 77 | where | ||
| 78 | T: GeneralInstance4Channel, | ||
| 79 | P: TimerPin<T, C>, | ||
| 80 | C: super::TimerChannel + TriggerSource, | ||
| 81 | { | ||
| 82 | fn af_num(&self) -> u8 { | ||
| 83 | TimerPin::af_num(self) | ||
| 84 | } | ||
| 85 | } | ||
| 86 | |||
| 87 | impl<T, P> TimerTriggerPin<T, Ext> for P | ||
| 88 | where | ||
| 89 | T: GeneralInstance4Channel, | ||
| 90 | P: ExternalTriggerPin<T>, | ||
| 91 | { | ||
| 92 | fn af_num(&self) -> u8 { | ||
| 93 | ExternalTriggerPin::af_num(self) | ||
| 94 | } | 75 | } |
| 95 | } | 76 | } |
| 96 | 77 | ||
| 97 | impl<T, P, C> SealedTimerTriggerPin<T, C> for P | 78 | impl<'d, T: GeneralInstance4Channel> TriggerPin<'d, T, Ext> { |
| 98 | where | 79 | /// Create a new external trigger pin instance. |
| 99 | T: GeneralInstance4Channel, | 80 | pub fn new_external<A>(pin: Peri<'d, impl ExternalTriggerPin<T, A>>, pull: Pull) -> Self { |
| 100 | P: TimerPin<T, C>, | ||
| 101 | C: super::TimerChannel + TriggerSource, | ||
| 102 | { | ||
| 103 | } | ||
| 104 | |||
| 105 | impl<T, P> SealedTimerTriggerPin<T, Ext> for P | ||
| 106 | where | ||
| 107 | T: GeneralInstance4Channel, | ||
| 108 | P: ExternalTriggerPin<T>, | ||
| 109 | { | ||
| 110 | } | ||
| 111 | |||
| 112 | impl<'d, T: GeneralInstance4Channel, C: TriggerSource> TriggerPin<'d, T, C> { | ||
| 113 | /// "Create a new Ch1 trigger pin instance. | ||
| 114 | pub fn new(pin: Peri<'d, impl TimerTriggerPin<T, C>>, pull: Pull) -> Self { | ||
| 115 | pin.set_as_af(pin.af_num(), AfType::input(pull)); | 81 | pin.set_as_af(pin.af_num(), AfType::input(pull)); |
| 82 | #[cfg(afio)] | ||
| 83 | pin.afio_remap(); | ||
| 116 | TriggerPin { | 84 | TriggerPin { |
| 117 | pin: pin.into(), | 85 | pin: pin.into(), |
| 118 | phantom: PhantomData, | 86 | phantom: PhantomData, |
| @@ -141,8 +109,6 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> { | |||
| 141 | pulse_end: u32, | 109 | pulse_end: u32, |
| 142 | counting_mode: CountingMode, | 110 | counting_mode: CountingMode, |
| 143 | ) -> Self { | 111 | ) -> Self { |
| 144 | #[cfg(afio)] | ||
| 145 | super::set_afio::<T>(&[Some(pin.pin)]); | ||
| 146 | let mut this = Self { inner: Timer::new(tim) }; | 112 | let mut this = Self { inner: Timer::new(tim) }; |
| 147 | 113 | ||
| 148 | this.inner.set_trigger_source(Ts::TI1F_ED); | 114 | this.inner.set_trigger_source(Ts::TI1F_ED); |
diff --git a/embassy-stm32/src/timer/pwm_input.rs b/embassy-stm32/src/timer/pwm_input.rs index c537e5268..62d7a8550 100644 --- a/embassy-stm32/src/timer/pwm_input.rs +++ b/embassy-stm32/src/timer/pwm_input.rs | |||
| @@ -18,19 +18,19 @@ pub struct PwmInput<'d, T: GeneralInstance4Channel> { | |||
| 18 | 18 | ||
| 19 | impl<'d, T: GeneralInstance4Channel> PwmInput<'d, T> { | 19 | impl<'d, T: GeneralInstance4Channel> PwmInput<'d, T> { |
| 20 | /// Create a new PWM input driver. | 20 | /// Create a new PWM input driver. |
| 21 | pub fn new_ch1(tim: Peri<'d, T>, pin: Peri<'d, impl TimerPin<T, Ch1>>, pull: Pull, freq: Hertz) -> Self { | 21 | pub fn new_ch1<A>(tim: Peri<'d, T>, pin: Peri<'d, impl TimerPin<T, Ch1, A>>, pull: Pull, freq: Hertz) -> Self { |
| 22 | pin.set_as_af(pin.af_num(), AfType::input(pull)); | 22 | pin.set_as_af(pin.af_num(), AfType::input(pull)); |
| 23 | #[cfg(afio)] | 23 | #[cfg(afio)] |
| 24 | super::set_afio::<T>(&[Some(pin.into())]); | 24 | pin.afio_remap(); |
| 25 | 25 | ||
| 26 | Self::new_inner(tim, freq, Channel::Ch1, Channel::Ch2) | 26 | Self::new_inner(tim, freq, Channel::Ch1, Channel::Ch2) |
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | /// Create a new PWM input driver. | 29 | /// Create a new PWM input driver. |
| 30 | pub fn new_ch2(tim: Peri<'d, T>, pin: Peri<'d, impl TimerPin<T, Ch2>>, pull: Pull, freq: Hertz) -> Self { | 30 | pub fn new_ch2<A>(tim: Peri<'d, T>, pin: Peri<'d, impl TimerPin<T, Ch2, A>>, pull: Pull, freq: Hertz) -> Self { |
| 31 | pin.set_as_af(pin.af_num(), AfType::input(pull)); | 31 | pin.set_as_af(pin.af_num(), AfType::input(pull)); |
| 32 | #[cfg(afio)] | 32 | #[cfg(afio)] |
| 33 | super::set_afio::<T>(&[Some(pin.into())]); | 33 | pin.afio_remap(); |
| 34 | 34 | ||
| 35 | Self::new_inner(tim, freq, Channel::Ch2, Channel::Ch1) | 35 | Self::new_inner(tim, freq, Channel::Ch2, Channel::Ch1) |
| 36 | } | 36 | } |
diff --git a/embassy-stm32/src/timer/qei.rs b/embassy-stm32/src/timer/qei.rs index 4e5a309ac..39d051294 100644 --- a/embassy-stm32/src/timer/qei.rs +++ b/embassy-stm32/src/timer/qei.rs | |||
| @@ -20,18 +20,20 @@ pub enum Direction { | |||
| 20 | } | 20 | } |
| 21 | 21 | ||
| 22 | /// Wrapper for using a pin with QEI. | 22 | /// Wrapper for using a pin with QEI. |
| 23 | pub struct QeiPin<'d, T, Channel> { | 23 | pub struct QeiPin<'d, T, Channel, A> { |
| 24 | #[allow(unused)] | 24 | #[allow(unused)] |
| 25 | pin: Peri<'d, AnyPin>, | 25 | pin: Peri<'d, AnyPin>, |
| 26 | phantom: PhantomData<(T, Channel)>, | 26 | phantom: PhantomData<(T, Channel, A)>, |
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | impl<'d, T: GeneralInstance4Channel, C: QeiChannel> QeiPin<'d, T, C> { | 29 | impl<'d, T: GeneralInstance4Channel, C: QeiChannel, A> QeiPin<'d, T, C, A> { |
| 30 | /// Create a new QEI pin instance. | 30 | /// Create a new QEI pin instance. |
| 31 | pub fn new(pin: Peri<'d, impl TimerPin<T, C>>) -> Self { | 31 | pub fn new(pin: Peri<'d, impl TimerPin<T, C, A>>) -> Self { |
| 32 | critical_section::with(|_| { | 32 | critical_section::with(|_| { |
| 33 | pin.set_low(); | 33 | pin.set_low(); |
| 34 | pin.set_as_af(pin.af_num(), AfType::input(Pull::None)); | 34 | pin.set_as_af(pin.af_num(), AfType::input(Pull::None)); |
| 35 | #[cfg(afio)] | ||
| 36 | pin.afio_remap(); | ||
| 35 | }); | 37 | }); |
| 36 | QeiPin { | 38 | QeiPin { |
| 37 | pin: pin.into(), | 39 | pin: pin.into(), |
| @@ -60,9 +62,7 @@ pub struct Qei<'d, T: GeneralInstance4Channel> { | |||
| 60 | impl<'d, T: GeneralInstance4Channel> Qei<'d, T> { | 62 | impl<'d, T: GeneralInstance4Channel> Qei<'d, T> { |
| 61 | /// Create a new quadrature decoder driver. | 63 | /// Create a new quadrature decoder driver. |
| 62 | #[allow(unused)] | 64 | #[allow(unused)] |
| 63 | pub fn new(tim: Peri<'d, T>, ch1: QeiPin<'d, T, Ch1>, ch2: QeiPin<'d, T, Ch2>) -> Self { | 65 | pub fn new<A>(tim: Peri<'d, T>, ch1: QeiPin<'d, T, Ch1, A>, ch2: QeiPin<'d, T, Ch2, A>) -> Self { |
| 64 | #[cfg(afio)] | ||
| 65 | super::set_afio::<T>(&[Some(ch1.pin), Some(ch2.pin)]); | ||
| 66 | Self::new_inner(tim) | 66 | Self::new_inner(tim) |
| 67 | } | 67 | } |
| 68 | 68 | ||
diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs index df86859fe..53f7cdd22 100644 --- a/embassy-stm32/src/timer/simple_pwm.rs +++ b/embassy-stm32/src/timer/simple_pwm.rs | |||
| @@ -14,10 +14,10 @@ use crate::Peri; | |||
| 14 | /// PWM pin wrapper. | 14 | /// PWM pin wrapper. |
| 15 | /// | 15 | /// |
| 16 | /// This wraps a pin to make it usable with PWM. | 16 | /// This wraps a pin to make it usable with PWM. |
| 17 | pub struct PwmPin<'d, T, C> { | 17 | pub struct PwmPin<'d, T, C, A> { |
| 18 | #[allow(unused)] | 18 | #[allow(unused)] |
| 19 | pub(crate) pin: Peri<'d, AnyPin>, | 19 | pub(crate) pin: Peri<'d, AnyPin>, |
| 20 | phantom: PhantomData<(T, C)>, | 20 | phantom: PhantomData<(T, C, A)>, |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | /// PWM pin config | 23 | /// PWM pin config |
| @@ -35,12 +35,14 @@ pub struct PwmPinConfig { | |||
| 35 | pub pull: Pull, | 35 | pub pull: Pull, |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | impl<'d, T: GeneralInstance4Channel, C: TimerChannel> PwmPin<'d, T, C> { | 38 | impl<'d, T: GeneralInstance4Channel, C: TimerChannel, A> PwmPin<'d, T, C, A> { |
| 39 | /// Create a new PWM pin instance. | 39 | /// Create a new PWM pin instance. |
| 40 | pub fn new(pin: Peri<'d, impl TimerPin<T, C>>, output_type: OutputType) -> Self { | 40 | pub fn new(pin: Peri<'d, impl TimerPin<T, C, A>>, output_type: OutputType) -> Self { |
| 41 | critical_section::with(|_| { | 41 | critical_section::with(|_| { |
| 42 | pin.set_low(); | 42 | pin.set_low(); |
| 43 | pin.set_as_af(pin.af_num(), AfType::output(output_type, Speed::VeryHigh)); | 43 | pin.set_as_af(pin.af_num(), AfType::output(output_type, Speed::VeryHigh)); |
| 44 | #[cfg(afio)] | ||
| 45 | pin.afio_remap(); | ||
| 44 | }); | 46 | }); |
| 45 | PwmPin { | 47 | PwmPin { |
| 46 | pin: pin.into(), | 48 | pin: pin.into(), |
| @@ -49,7 +51,7 @@ impl<'d, T: GeneralInstance4Channel, C: TimerChannel> PwmPin<'d, T, C> { | |||
| 49 | } | 51 | } |
| 50 | 52 | ||
| 51 | /// Create a new PWM pin instance with config. | 53 | /// Create a new PWM pin instance with config. |
| 52 | pub fn new_with_config(pin: Peri<'d, impl TimerPin<T, C>>, pin_config: PwmPinConfig) -> Self { | 54 | pub fn new_with_config(pin: Peri<'d, impl TimerPin<T, C, A>>, pin_config: PwmPinConfig) -> Self { |
| 53 | critical_section::with(|_| { | 55 | critical_section::with(|_| { |
| 54 | pin.set_low(); | 56 | pin.set_low(); |
| 55 | pin.set_as_af( | 57 | pin.set_as_af( |
| @@ -59,6 +61,8 @@ impl<'d, T: GeneralInstance4Channel, C: TimerChannel> PwmPin<'d, T, C> { | |||
| 59 | #[cfg(gpio_v2)] | 61 | #[cfg(gpio_v2)] |
| 60 | AfType::output_pull(pin_config.output_type, pin_config.speed, pin_config.pull), | 62 | AfType::output_pull(pin_config.output_type, pin_config.speed, pin_config.pull), |
| 61 | ); | 63 | ); |
| 64 | #[cfg(afio)] | ||
| 65 | pin.afio_remap(); | ||
| 62 | }); | 66 | }); |
| 63 | PwmPin { | 67 | PwmPin { |
| 64 | pin: pin.into(), | 68 | pin: pin.into(), |
| @@ -180,22 +184,15 @@ pub struct SimplePwm<'d, T: GeneralInstance4Channel> { | |||
| 180 | impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { | 184 | impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> { |
| 181 | /// Create a new simple PWM driver. | 185 | /// Create a new simple PWM driver. |
| 182 | #[allow(unused)] | 186 | #[allow(unused)] |
| 183 | pub fn new( | 187 | pub fn new<A>( |
| 184 | tim: Peri<'d, T>, | 188 | tim: Peri<'d, T>, |
| 185 | ch1: Option<PwmPin<'d, T, Ch1>>, | 189 | ch1: Option<PwmPin<'d, T, Ch1, A>>, |
| 186 | ch2: Option<PwmPin<'d, T, Ch2>>, | 190 | ch2: Option<PwmPin<'d, T, Ch2, A>>, |
| 187 | ch3: Option<PwmPin<'d, T, Ch3>>, | 191 | ch3: Option<PwmPin<'d, T, Ch3, A>>, |
| 188 | ch4: Option<PwmPin<'d, T, Ch4>>, | 192 | ch4: Option<PwmPin<'d, T, Ch4, A>>, |
| 189 | freq: Hertz, | 193 | freq: Hertz, |
| 190 | counting_mode: CountingMode, | 194 | counting_mode: CountingMode, |
| 191 | ) -> Self { | 195 | ) -> Self { |
| 192 | #[cfg(afio)] | ||
| 193 | super::set_afio::<T>(&[ | ||
| 194 | ch1.map(|p| p.pin), | ||
| 195 | ch2.map(|p| p.pin), | ||
| 196 | ch3.map(|p| p.pin), | ||
| 197 | ch4.map(|p| p.pin), | ||
| 198 | ]); | ||
| 199 | Self::new_inner(tim, freq, counting_mode) | 196 | Self::new_inner(tim, freq, counting_mode) |
| 200 | } | 197 | } |
| 201 | 198 | ||
diff --git a/examples/stm32f1/src/bin/input_capture.rs b/examples/stm32f1/src/bin/input_capture.rs index d747a43c2..b5b26938d 100644 --- a/examples/stm32f1/src/bin/input_capture.rs +++ b/examples/stm32f1/src/bin/input_capture.rs | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::gpio::{Level, Output, Pull, Speed}; | 6 | use embassy_stm32::gpio::{AfioRemap, Level, Output, Pull, Speed}; |
| 7 | use embassy_stm32::time::khz; | 7 | use embassy_stm32::time::khz; |
| 8 | use embassy_stm32::timer::input_capture::{CapturePin, InputCapture}; | 8 | use embassy_stm32::timer::input_capture::{CapturePin, InputCapture}; |
| 9 | use embassy_stm32::timer::{self, Channel}; | 9 | use embassy_stm32::timer::{self, Channel}; |
| @@ -40,7 +40,8 @@ async fn main(spawner: Spawner) { | |||
| 40 | spawner.spawn(unwrap!(blinky(p.PC13))); | 40 | spawner.spawn(unwrap!(blinky(p.PC13))); |
| 41 | 41 | ||
| 42 | let ch3 = CapturePin::new(p.PA2, Pull::None); | 42 | let ch3 = CapturePin::new(p.PA2, Pull::None); |
| 43 | let mut ic = InputCapture::new(p.TIM2, None, None, Some(ch3), None, Irqs, khz(1000), Default::default()); | 43 | let mut ic = |
| 44 | InputCapture::new::<AfioRemap<0>>(p.TIM2, None, None, Some(ch3), None, Irqs, khz(1000), Default::default()); | ||
| 44 | 45 | ||
| 45 | loop { | 46 | loop { |
| 46 | info!("wait for rising edge"); | 47 | info!("wait for rising edge"); |
diff --git a/examples/stm32f1/src/bin/pwm_input.rs b/examples/stm32f1/src/bin/pwm_input.rs index 63b899767..9ae747018 100644 --- a/examples/stm32f1/src/bin/pwm_input.rs +++ b/examples/stm32f1/src/bin/pwm_input.rs | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::gpio::{Level, Output, Pull, Speed}; | 6 | use embassy_stm32::gpio::{AfioRemap, Level, Output, Pull, Speed}; |
| 7 | use embassy_stm32::time::khz; | 7 | use embassy_stm32::time::khz; |
| 8 | use embassy_stm32::timer::pwm_input::PwmInput; | 8 | use embassy_stm32::timer::pwm_input::PwmInput; |
| 9 | use embassy_stm32::{bind_interrupts, peripherals, timer, Peri}; | 9 | use embassy_stm32::{bind_interrupts, peripherals, timer, Peri}; |
| @@ -38,7 +38,7 @@ async fn main(spawner: Spawner) { | |||
| 38 | 38 | ||
| 39 | spawner.spawn(unwrap!(blinky(p.PC13))); | 39 | spawner.spawn(unwrap!(blinky(p.PC13))); |
| 40 | 40 | ||
| 41 | let mut pwm_input = PwmInput::new_ch1(p.TIM2, p.PA0, Pull::None, khz(10)); | 41 | let mut pwm_input = PwmInput::new_ch1::<AfioRemap<0>>(p.TIM2, p.PA0, Pull::None, khz(10)); |
| 42 | pwm_input.enable(); | 42 | pwm_input.enable(); |
| 43 | 43 | ||
| 44 | loop { | 44 | loop { |
diff --git a/tests/stm32/src/bin/afio.rs b/tests/stm32/src/bin/afio.rs index c684b7b3e..cc44dc59c 100644 --- a/tests/stm32/src/bin/afio.rs +++ b/tests/stm32/src/bin/afio.rs | |||
| @@ -6,7 +6,7 @@ mod common; | |||
| 6 | 6 | ||
| 7 | use common::*; | 7 | use common::*; |
| 8 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 9 | use embassy_stm32::gpio::{OutputType, Pull}; | 9 | use embassy_stm32::gpio::{AfioRemap, OutputType, Pull}; |
| 10 | use embassy_stm32::pac::AFIO; | 10 | use embassy_stm32::pac::AFIO; |
| 11 | use embassy_stm32::time::khz; | 11 | use embassy_stm32::time::khz; |
| 12 | use embassy_stm32::timer::complementary_pwm::{ComplementaryPwm, ComplementaryPwmPin}; | 12 | use embassy_stm32::timer::complementary_pwm::{ComplementaryPwm, ComplementaryPwmPin}; |
| @@ -173,7 +173,7 @@ async fn main(_spawner: Spawner) { | |||
| 173 | { | 173 | { |
| 174 | // no remap | 174 | // no remap |
| 175 | afio_registers_set_remap(); | 175 | afio_registers_set_remap(); |
| 176 | SimplePwm::new( | 176 | SimplePwm::new::<AfioRemap<0>>( |
| 177 | p.TIM1.reborrow(), | 177 | p.TIM1.reborrow(), |
| 178 | Some(PwmPin::new(p.PA8.reborrow(), OutputType::PushPull)), | 178 | Some(PwmPin::new(p.PA8.reborrow(), OutputType::PushPull)), |
| 179 | Some(PwmPin::new(p.PA9.reborrow(), OutputType::PushPull)), | 179 | Some(PwmPin::new(p.PA9.reborrow(), OutputType::PushPull)), |
| @@ -187,7 +187,7 @@ async fn main(_spawner: Spawner) { | |||
| 187 | { | 187 | { |
| 188 | // no remap | 188 | // no remap |
| 189 | afio_registers_set_remap(); | 189 | afio_registers_set_remap(); |
| 190 | SimplePwm::new( | 190 | SimplePwm::new::<AfioRemap<0>>( |
| 191 | p.TIM1.reborrow(), | 191 | p.TIM1.reborrow(), |
| 192 | Some(PwmPin::new(p.PA8.reborrow(), OutputType::PushPull)), | 192 | Some(PwmPin::new(p.PA8.reborrow(), OutputType::PushPull)), |
| 193 | None, | 193 | None, |
| @@ -201,7 +201,7 @@ async fn main(_spawner: Spawner) { | |||
| 201 | { | 201 | { |
| 202 | // partial remap | 202 | // partial remap |
| 203 | reset_afio_registers(); | 203 | reset_afio_registers(); |
| 204 | ComplementaryPwm::new( | 204 | ComplementaryPwm::new::<AfioRemap<1>>( |
| 205 | p.TIM1.reborrow(), | 205 | p.TIM1.reborrow(), |
| 206 | Some(PwmPin::new(p.PA8.reborrow(), OutputType::PushPull)), | 206 | Some(PwmPin::new(p.PA8.reborrow(), OutputType::PushPull)), |
| 207 | None, | 207 | None, |
| @@ -219,7 +219,7 @@ async fn main(_spawner: Spawner) { | |||
| 219 | { | 219 | { |
| 220 | // partial remap | 220 | // partial remap |
| 221 | reset_afio_registers(); | 221 | reset_afio_registers(); |
| 222 | ComplementaryPwm::new( | 222 | ComplementaryPwm::new::<AfioRemap<1>>( |
| 223 | p.TIM1.reborrow(), | 223 | p.TIM1.reborrow(), |
| 224 | Some(PwmPin::new(p.PA8.reborrow(), OutputType::PushPull)), | 224 | Some(PwmPin::new(p.PA8.reborrow(), OutputType::PushPull)), |
| 225 | Some(ComplementaryPwmPin::new(p.PA7.reborrow(), OutputType::PushPull)), | 225 | Some(ComplementaryPwmPin::new(p.PA7.reborrow(), OutputType::PushPull)), |
| @@ -237,7 +237,7 @@ async fn main(_spawner: Spawner) { | |||
| 237 | { | 237 | { |
| 238 | // partial remap | 238 | // partial remap |
| 239 | reset_afio_registers(); | 239 | reset_afio_registers(); |
| 240 | InputCapture::new( | 240 | InputCapture::new::<AfioRemap<1>>( |
| 241 | p.TIM1.reborrow(), | 241 | p.TIM1.reborrow(), |
| 242 | Some(CapturePin::new(p.PA8.reborrow(), Pull::Down)), | 242 | Some(CapturePin::new(p.PA8.reborrow(), Pull::Down)), |
| 243 | None, | 243 | None, |
| @@ -252,13 +252,13 @@ async fn main(_spawner: Spawner) { | |||
| 252 | { | 252 | { |
| 253 | // partial remap | 253 | // partial remap |
| 254 | reset_afio_registers(); | 254 | reset_afio_registers(); |
| 255 | PwmInput::new_ch1(p.TIM1.reborrow(), p.PA8.reborrow(), Pull::Down, khz(10)); | 255 | PwmInput::new_ch1::<AfioRemap<1>>(p.TIM1.reborrow(), p.PA8.reborrow(), Pull::Down, khz(10)); |
| 256 | defmt::assert_eq!(AFIO.mapr().read().tim1_remap(), 1); | 256 | defmt::assert_eq!(AFIO.mapr().read().tim1_remap(), 1); |
| 257 | } | 257 | } |
| 258 | { | 258 | { |
| 259 | // partial remap | 259 | // partial remap |
| 260 | reset_afio_registers(); | 260 | reset_afio_registers(); |
| 261 | Qei::new( | 261 | Qei::new::<AfioRemap<1>>( |
| 262 | p.TIM1.reborrow(), | 262 | p.TIM1.reborrow(), |
| 263 | QeiPin::new(p.PA8.reborrow()), | 263 | QeiPin::new(p.PA8.reborrow()), |
| 264 | QeiPin::new(p.PA9.reborrow()), | 264 | QeiPin::new(p.PA9.reborrow()), |
| @@ -270,7 +270,7 @@ async fn main(_spawner: Spawner) { | |||
| 270 | { | 270 | { |
| 271 | // no remap | 271 | // no remap |
| 272 | afio_registers_set_remap(); | 272 | afio_registers_set_remap(); |
| 273 | SimplePwm::new( | 273 | SimplePwm::new::<AfioRemap<0>>( |
| 274 | p.TIM2.reborrow(), | 274 | p.TIM2.reborrow(), |
| 275 | Some(PwmPin::new(p.PA0.reborrow(), OutputType::PushPull)), | 275 | Some(PwmPin::new(p.PA0.reborrow(), OutputType::PushPull)), |
| 276 | Some(PwmPin::new(p.PA1.reborrow(), OutputType::PushPull)), | 276 | Some(PwmPin::new(p.PA1.reborrow(), OutputType::PushPull)), |
| @@ -284,7 +284,7 @@ async fn main(_spawner: Spawner) { | |||
| 284 | { | 284 | { |
| 285 | // partial remap 1 | 285 | // partial remap 1 |
| 286 | reset_afio_registers(); | 286 | reset_afio_registers(); |
| 287 | SimplePwm::new( | 287 | SimplePwm::new::<AfioRemap<1>>( |
| 288 | p.TIM2.reborrow(), | 288 | p.TIM2.reborrow(), |
| 289 | Some(PwmPin::new(p.PA15.reborrow(), OutputType::PushPull)), | 289 | Some(PwmPin::new(p.PA15.reborrow(), OutputType::PushPull)), |
| 290 | Some(PwmPin::new(p.PB3.reborrow(), OutputType::PushPull)), | 290 | Some(PwmPin::new(p.PB3.reborrow(), OutputType::PushPull)), |
| @@ -298,7 +298,7 @@ async fn main(_spawner: Spawner) { | |||
| 298 | { | 298 | { |
| 299 | // partial remap 2 | 299 | // partial remap 2 |
| 300 | reset_afio_registers(); | 300 | reset_afio_registers(); |
| 301 | SimplePwm::new( | 301 | SimplePwm::new::<AfioRemap<2>>( |
| 302 | p.TIM2.reborrow(), | 302 | p.TIM2.reborrow(), |
| 303 | Some(PwmPin::new(p.PA0.reborrow(), OutputType::PushPull)), | 303 | Some(PwmPin::new(p.PA0.reborrow(), OutputType::PushPull)), |
| 304 | Some(PwmPin::new(p.PA1.reborrow(), OutputType::PushPull)), | 304 | Some(PwmPin::new(p.PA1.reborrow(), OutputType::PushPull)), |
| @@ -312,7 +312,7 @@ async fn main(_spawner: Spawner) { | |||
| 312 | { | 312 | { |
| 313 | // full remap | 313 | // full remap |
| 314 | reset_afio_registers(); | 314 | reset_afio_registers(); |
| 315 | SimplePwm::new( | 315 | SimplePwm::new::<AfioRemap<3>>( |
| 316 | p.TIM2.reborrow(), | 316 | p.TIM2.reborrow(), |
| 317 | Some(PwmPin::new(p.PA15.reborrow(), OutputType::PushPull)), | 317 | Some(PwmPin::new(p.PA15.reborrow(), OutputType::PushPull)), |
| 318 | Some(PwmPin::new(p.PB3.reborrow(), OutputType::PushPull)), | 318 | Some(PwmPin::new(p.PB3.reborrow(), OutputType::PushPull)), |
