Add parameter for enabling pull-up and pull-down in RP PWM input mode

This commit is contained in:
pawel00100 2024-01-24 23:24:26 +01:00 committed by Dario Nieuwenhuis
parent 9d0b682b2d
commit 143b288333
3 changed files with 73 additions and 11 deletions

View File

@ -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<P = T> + 'd,
a: Option<PeripheralRef<'d, AnyPin>>,
b: Option<PeripheralRef<'d, AnyPin>>,
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<P = T> + '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<P = T> + 'd,
b: impl Peripheral<P = impl ChannelBPin<T>> + '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<P = T> + 'd,
a: impl Peripheral<P = impl ChannelAPin<T>> + 'd,
b: impl Peripheral<P = impl ChannelBPin<T>> + '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.

View File

@ -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 {

View File

@ -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();
}