diff --git a/embassy-rp/src/pwm.rs b/embassy-rp/src/pwm.rs index 7613e4e58..a1f400cfb 100644 --- a/embassy-rp/src/pwm.rs +++ b/embassy-rp/src/pwm.rs @@ -6,7 +6,7 @@ use fixed::FixedU16; use pac::pwm::regs::{ChDiv, Intr}; use pac::pwm::vals::Divmode; -use crate::gpio::{AnyPin, Pin as GpioPin, SealedPin as _}; +use crate::gpio::{AnyPin, Pin as GpioPin, Pull, SealedPin as _}; use crate::{pac, peripherals, RegExt}; /// The configuration of a PWM slice. @@ -92,6 +92,7 @@ impl<'d, T: Slice> Pwm<'d, T> { inner: impl Peripheral

+ 'd, a: Option>, b: Option>, + b_pull: Pull, config: Config, divmode: Divmode, ) -> Self { @@ -110,6 +111,10 @@ impl<'d, T: Slice> Pwm<'d, T> { } if let Some(pin) = &b { pin.gpio().ctrl().write(|w| w.set_funcsel(4)); + pin.pad_ctrl().modify(|w| { + w.set_pue(b_pull == Pull::Up); + w.set_pde(b_pull == Pull::Down); + }); } Self { inner, @@ -121,7 +126,7 @@ impl<'d, T: Slice> Pwm<'d, T> { /// Create PWM driver without any configured pins. #[inline] pub fn new_free(inner: impl Peripheral

+ 'd, config: Config) -> Self { - Self::new_inner(inner, None, None, config, Divmode::DIV) + Self::new_inner(inner, None, None, Pull::None, config, Divmode::DIV) } /// Create PWM driver with a single 'a' as output. @@ -132,7 +137,7 @@ impl<'d, T: Slice> Pwm<'d, T> { config: Config, ) -> Self { into_ref!(a); - Self::new_inner(inner, Some(a.map_into()), None, config, Divmode::DIV) + Self::new_inner(inner, Some(a.map_into()), None, Pull::None, config, Divmode::DIV) } /// Create PWM driver with a single 'b' pin as output. @@ -143,7 +148,7 @@ impl<'d, T: Slice> Pwm<'d, T> { config: Config, ) -> Self { into_ref!(b); - Self::new_inner(inner, None, Some(b.map_into()), config, Divmode::DIV) + Self::new_inner(inner, None, Some(b.map_into()), Pull::None, config, Divmode::DIV) } /// Create PWM driver with a 'a' and 'b' pins as output. @@ -155,7 +160,14 @@ impl<'d, T: Slice> Pwm<'d, T> { config: Config, ) -> Self { into_ref!(a, b); - Self::new_inner(inner, Some(a.map_into()), Some(b.map_into()), config, Divmode::DIV) + Self::new_inner( + inner, + Some(a.map_into()), + Some(b.map_into()), + Pull::None, + config, + Divmode::DIV, + ) } /// Create PWM driver with a single 'b' as input pin. @@ -163,11 +175,12 @@ impl<'d, T: Slice> Pwm<'d, T> { pub fn new_input( inner: impl Peripheral

+ 'd, b: impl Peripheral

> + 'd, + b_pull: Pull, mode: InputMode, config: Config, ) -> Self { into_ref!(b); - Self::new_inner(inner, None, Some(b.map_into()), config, mode.into()) + Self::new_inner(inner, None, Some(b.map_into()), b_pull, config, mode.into()) } /// Create PWM driver with a 'a' and 'b' pins in the desired input mode. @@ -176,11 +189,19 @@ impl<'d, T: Slice> Pwm<'d, T> { inner: impl Peripheral

+ 'd, a: impl Peripheral

> + 'd, b: impl Peripheral

> + 'd, + b_pull: Pull, mode: InputMode, config: Config, ) -> Self { into_ref!(a, b); - Self::new_inner(inner, Some(a.map_into()), Some(b.map_into()), config, mode.into()) + Self::new_inner( + inner, + Some(a.map_into()), + Some(b.map_into()), + b_pull, + config, + mode.into(), + ) } /// Set the PWM config. diff --git a/examples/rp/src/bin/pwm_input.rs b/examples/rp/src/bin/pwm_input.rs index 0652dc42b..bf454a936 100644 --- a/examples/rp/src/bin/pwm_input.rs +++ b/examples/rp/src/bin/pwm_input.rs @@ -5,6 +5,7 @@ use defmt::*; use embassy_executor::Spawner; +use embassy_rp::gpio::Pull; use embassy_rp::pwm::{Config, InputMode, Pwm}; use embassy_time::{Duration, Ticker}; use {defmt_rtt as _, panic_probe as _}; @@ -14,7 +15,7 @@ async fn main(_spawner: Spawner) { let p = embassy_rp::init(Default::default()); let cfg: Config = Default::default(); - let pwm = Pwm::new_input(p.PWM_SLICE2, p.PIN_5, InputMode::RisingEdge, cfg); + let pwm = Pwm::new_input(p.PWM_SLICE2, p.PIN_5, Pull::None, InputMode::RisingEdge, cfg); let mut ticker = Ticker::every(Duration::from_secs(1)); loop { diff --git a/tests/rp/src/bin/pwm.rs b/tests/rp/src/bin/pwm.rs index 4b02e5bab..c05197000 100644 --- a/tests/rp/src/bin/pwm.rs +++ b/tests/rp/src/bin/pwm.rs @@ -94,7 +94,7 @@ async fn main(_spawner: Spawner) { // Test level-gated { let mut pin2 = Output::new(&mut p11, Level::Low); - let pwm = Pwm::new_input(&mut p.PWM_SLICE3, &mut p7, InputMode::Level, cfg.clone()); + let pwm = Pwm::new_input(&mut p.PWM_SLICE3, &mut p7, Pull::None, InputMode::Level, cfg.clone()); assert_eq!(pwm.counter(), 0); Timer::after_millis(5).await; assert_eq!(pwm.counter(), 0); @@ -110,7 +110,13 @@ async fn main(_spawner: Spawner) { // Test rising-gated { let mut pin2 = Output::new(&mut p11, Level::Low); - let pwm = Pwm::new_input(&mut p.PWM_SLICE3, &mut p7, InputMode::RisingEdge, cfg.clone()); + let pwm = Pwm::new_input( + &mut p.PWM_SLICE3, + &mut p7, + Pull::None, + InputMode::RisingEdge, + cfg.clone(), + ); assert_eq!(pwm.counter(), 0); Timer::after_millis(5).await; assert_eq!(pwm.counter(), 0); @@ -125,7 +131,13 @@ async fn main(_spawner: Spawner) { // Test falling-gated { let mut pin2 = Output::new(&mut p11, Level::High); - let pwm = Pwm::new_input(&mut p.PWM_SLICE3, &mut p7, InputMode::FallingEdge, cfg.clone()); + let pwm = Pwm::new_input( + &mut p.PWM_SLICE3, + &mut p7, + Pull::None, + InputMode::FallingEdge, + cfg.clone(), + ); assert_eq!(pwm.counter(), 0); Timer::after_millis(5).await; assert_eq!(pwm.counter(), 0); @@ -137,6 +149,34 @@ async fn main(_spawner: Spawner) { assert_eq!(pwm.counter(), 1); } + // pull-down + { + let pin2 = Input::new(&mut p11, Pull::None); + Pwm::new_input( + &mut p.PWM_SLICE3, + &mut p7, + Pull::Down, + InputMode::FallingEdge, + cfg.clone(), + ); + Timer::after_millis(1).await; + assert!(pin2.is_low()); + } + + // pull-up + { + let pin2 = Input::new(&mut p11, Pull::None); + Pwm::new_input( + &mut p.PWM_SLICE3, + &mut p7, + Pull::Up, + InputMode::FallingEdge, + cfg.clone(), + ); + Timer::after_millis(1).await; + assert!(pin2.is_high()); + } + info!("Test OK"); cortex_m::asm::bkpt(); }