Skip to content

Commit 7fcddf8

Browse files
Add Pwm::clear_output_pin and test it in the demo
1 parent 04836dd commit 7fcddf8

File tree

2 files changed

+31
-3
lines changed

2 files changed

+31
-3
lines changed

examples/pwm-demo/src/main.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,20 @@ const APP: () = {
6767
let led3 = p0.p0_15.into_push_pull_output(Level::High).degrade();
6868
let led4 = p0.p0_16.into_push_pull_output(Level::High).degrade();
6969

70-
let pwm = Pwm::new(ctx.device.PWM0);
70+
let mut pwm = Pwm::new(ctx.device.PWM0);
7171
pwm.set_period(500u32.hz())
7272
.set_output_pin(Channel::C0, led1)
7373
.set_output_pin(Channel::C1, led2)
7474
.set_output_pin(Channel::C2, led3)
7575
.set_output_pin(Channel::C3, led4)
76-
.enable_interrupt(PwmEvent::Stopped)
77-
.enable();
76+
.enable_interrupt(PwmEvent::Stopped);
77+
78+
// In addition to `set_output_pin`, `swap_output_pin` and `clear_output_pin` can be used to
79+
// get the old pin back.
80+
let led1 = pwm.clear_output_pin(Channel::C0).unwrap();
81+
assert!(pwm.swap_output_pin(Channel::C0, led1).is_none());
82+
83+
pwm.enable();
7884

7985
let gpiote = Gpiote::new(ctx.device.GPIOTE);
8086
gpiote.port().input_pin(&btn1).low();

nrf-hal-common/src/pwm.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ where
130130
}
131131

132132
/// Sets the associated output pin for the PWM channel.
133+
///
134+
/// Modifying the pin configuration while the PWM instance is enabled is not recommended.
133135
#[inline(always)]
134136
pub fn set_output_pin(&self, channel: Channel, pin: Pin<Output<PushPull>>) -> &Self {
135137
self.pwm.psel.out[usize::from(channel)].write(|w| {
@@ -140,6 +142,8 @@ where
140142
}
141143

142144
/// Sets the output pin of `channel`, and returns the old pin (if any).
145+
///
146+
/// Modifying the pin configuration while the PWM instance is enabled is not recommended.
143147
pub fn swap_output_pin(
144148
&mut self,
145149
channel: Channel,
@@ -157,6 +161,24 @@ where
157161
old
158162
}
159163

164+
/// Disables the output pin of `channel`.
165+
///
166+
/// The output pin is returned, if one was previously configured.
167+
///
168+
/// Modifying the pin configuration while the PWM instance is enabled is not recommended.
169+
pub fn clear_output_pin(&mut self, channel: Channel) -> Option<Pin<Output<PushPull>>> {
170+
// (needs `&mut self` because it reads, then writes, to the register)
171+
let psel = &self.pwm.psel.out[usize::from(channel)];
172+
let old = psel.read();
173+
let old = if old.connect().is_connected() {
174+
unsafe { Some(Pin::from_psel_bits(old.bits())) }
175+
} else {
176+
None
177+
};
178+
psel.reset();
179+
old
180+
}
181+
160182
/// Enables the PWM generator.
161183
#[inline(always)]
162184
pub fn enable(&self) {

0 commit comments

Comments
 (0)