diff --git a/embassy-nrf/src/pwm.rs b/embassy-nrf/src/pwm.rs index 3fdc37ec0..cffe5a3b0 100644 --- a/embassy-nrf/src/pwm.rs +++ b/embassy-nrf/src/pwm.rs @@ -63,14 +63,7 @@ impl<'d, T: Instance> SequencePwm<'d, T> { ch2: impl Unborrow + 'd, ch3: impl Unborrow + 'd, config: SequenceConfig, - sequence: &'d [u16], ) -> Result { - slice_in_ram_or(sequence, Error::DMABufferNotInDataMemory)?; - - if sequence.len() > 32767 { - return Err(Error::SequenceTooLong); - } - unborrow!(ch0, ch1, ch2, ch3); let r = T::regs(); @@ -110,28 +103,6 @@ impl<'d, T: Instance> SequencePwm<'d, T> { r.events_seqstarted[0].reset(); r.events_seqstarted[1].reset(); - r.seq0 - .ptr - .write(|w| unsafe { w.bits(sequence.as_ptr() as u32) }); - r.seq0 - .cnt - .write(|w| unsafe { w.bits(sequence.len() as u32) }); - r.seq0.refresh.write(|w| unsafe { w.bits(config.refresh) }); - r.seq0 - .enddelay - .write(|w| unsafe { w.bits(config.end_delay) }); - - r.seq1 - .ptr - .write(|w| unsafe { w.bits(sequence.as_ptr() as u32) }); - r.seq1 - .cnt - .write(|w| unsafe { w.bits(sequence.len() as u32) }); - r.seq1.refresh.write(|w| unsafe { w.bits(config.refresh) }); - r.seq1 - .enddelay - .write(|w| unsafe { w.bits(config.end_delay) }); - r.decoder.write(|w| { w.load().bits(config.sequence_load as u8); w.mode().refresh_count() @@ -146,6 +117,16 @@ impl<'d, T: Instance> SequencePwm<'d, T> { r.countertop .write(|w| unsafe { w.countertop().bits(config.max_duty) }); + r.seq0.refresh.write(|w| unsafe { w.bits(config.refresh) }); + r.seq0 + .enddelay + .write(|w| unsafe { w.bits(config.end_delay) }); + + r.seq1.refresh.write(|w| unsafe { w.bits(config.refresh) }); + r.seq1 + .enddelay + .write(|w| unsafe { w.bits(config.end_delay) }); + Ok(Self { phantom: PhantomData, ch0: ch0.degrade_optional(), @@ -157,12 +138,33 @@ impl<'d, T: Instance> SequencePwm<'d, T> { /// Start or restart playback #[inline(always)] - pub fn start(&self, times: SequenceMode) -> Result<(), Error> { + pub fn start(&self, sequence: &'d [u16], times: SequenceMode) -> Result<(), Error> { + slice_in_ram_or(sequence, Error::DMABufferNotInDataMemory)?; + + if sequence.len() > 32767 { + return Err(Error::SequenceTooLong); + } + if let SequenceMode::Times(0) = times { return Err(Error::SequenceTimesAtLeastOne); } + let r = T::regs(); + r.seq0 + .ptr + .write(|w| unsafe { w.bits(sequence.as_ptr() as u32) }); + r.seq0 + .cnt + .write(|w| unsafe { w.bits(sequence.len() as u32) }); + + r.seq1 + .ptr + .write(|w| unsafe { w.bits(sequence.as_ptr() as u32) }); + r.seq1 + .cnt + .write(|w| unsafe { w.bits(sequence.len() as u32) }); + self.stop(); r.enable.write(|w| w.enable().enabled()); diff --git a/examples/nrf/src/bin/pwm_sequence.rs b/examples/nrf/src/bin/pwm_sequence.rs index 8f57b5245..9877b54a6 100644 --- a/examples/nrf/src/bin/pwm_sequence.rs +++ b/examples/nrf/src/bin/pwm_sequence.rs @@ -13,7 +13,8 @@ use embassy_nrf::Peripherals; #[embassy::main] async fn main(_spawner: Spawner, p: Peripherals) { - let seq_values: [u16; 5] = [1000, 250, 100, 50, 0]; + let seq_values_1: [u16; 5] = [1000, 250, 100, 50, 0]; + let seq_values_2: [u16; 5] = [0, 50, 100, 250, 1000]; let mut config = SequenceConfig::default(); config.prescaler = Prescaler::Div128; @@ -25,18 +26,17 @@ async fn main(_spawner: Spawner, p: Peripherals) { // thus our sequence takes 5 * 5000ms or 25 seconds let pwm = unwrap!(SequencePwm::new( - p.PWM0, - p.P0_13, - NoPin, - NoPin, - NoPin, - config, - &seq_values + p.PWM0, p.P0_13, NoPin, NoPin, NoPin, config, )); - let _ = pwm.start(SequenceMode::Infinite); + let _ = pwm.start(&seq_values_1, SequenceMode::Infinite); info!("pwm started!"); + Timer::after(Duration::from_millis(20000)).await; + info!("pwm starting with another sequence!"); + + let _ = pwm.start(&seq_values_2, SequenceMode::Infinite); + // we can abort a sequence if we need to before its complete with pwm.stop() // or stop is also implicitly called when the pwm peripheral is dropped // when it goes out of scope diff --git a/examples/nrf/src/bin/pwm_sequence_ppi.rs b/examples/nrf/src/bin/pwm_sequence_ppi.rs index aaea9ff00..f72ccc112 100644 --- a/examples/nrf/src/bin/pwm_sequence_ppi.rs +++ b/examples/nrf/src/bin/pwm_sequence_ppi.rs @@ -27,16 +27,10 @@ async fn main(_spawner: Spawner, p: Peripherals) { config.refresh = 30; let pwm = unwrap!(SequencePwm::new( - p.PWM0, - p.P0_13, - NoPin, - NoPin, - NoPin, - config, - &seq_values + p.PWM0, p.P0_13, NoPin, NoPin, NoPin, config, )); - let _ = pwm.start(SequenceMode::Times(1)); + let _ = pwm.start(&seq_values, SequenceMode::Times(1)); // pwm.stop() deconfigures pins, and then the task_start_seq0 task cant work // so its going to have to start running in order load the configuration