diff options
| -rw-r--r-- | embassy-nrf/src/pwm.rs | 62 | ||||
| -rw-r--r-- | examples/nrf/src/bin/pwm_sequence.rs | 18 | ||||
| -rw-r--r-- | examples/nrf/src/bin/pwm_sequence_ppi.rs | 10 |
3 files changed, 43 insertions, 47 deletions
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> { | |||
| 63 | ch2: impl Unborrow<Target = impl GpioOptionalPin> + 'd, | 63 | ch2: impl Unborrow<Target = impl GpioOptionalPin> + 'd, |
| 64 | ch3: impl Unborrow<Target = impl GpioOptionalPin> + 'd, | 64 | ch3: impl Unborrow<Target = impl GpioOptionalPin> + 'd, |
| 65 | config: SequenceConfig, | 65 | config: SequenceConfig, |
| 66 | sequence: &'d [u16], | ||
| 67 | ) -> Result<Self, Error> { | 66 | ) -> Result<Self, Error> { |
| 68 | slice_in_ram_or(sequence, Error::DMABufferNotInDataMemory)?; | ||
| 69 | |||
| 70 | if sequence.len() > 32767 { | ||
| 71 | return Err(Error::SequenceTooLong); | ||
| 72 | } | ||
| 73 | |||
| 74 | unborrow!(ch0, ch1, ch2, ch3); | 67 | unborrow!(ch0, ch1, ch2, ch3); |
| 75 | 68 | ||
| 76 | let r = T::regs(); | 69 | let r = T::regs(); |
| @@ -110,28 +103,6 @@ impl<'d, T: Instance> SequencePwm<'d, T> { | |||
| 110 | r.events_seqstarted[0].reset(); | 103 | r.events_seqstarted[0].reset(); |
| 111 | r.events_seqstarted[1].reset(); | 104 | r.events_seqstarted[1].reset(); |
| 112 | 105 | ||
| 113 | r.seq0 | ||
| 114 | .ptr | ||
| 115 | .write(|w| unsafe { w.bits(sequence.as_ptr() as u32) }); | ||
| 116 | r.seq0 | ||
| 117 | .cnt | ||
| 118 | .write(|w| unsafe { w.bits(sequence.len() as u32) }); | ||
| 119 | r.seq0.refresh.write(|w| unsafe { w.bits(config.refresh) }); | ||
| 120 | r.seq0 | ||
| 121 | .enddelay | ||
| 122 | .write(|w| unsafe { w.bits(config.end_delay) }); | ||
| 123 | |||
| 124 | r.seq1 | ||
| 125 | .ptr | ||
| 126 | .write(|w| unsafe { w.bits(sequence.as_ptr() as u32) }); | ||
| 127 | r.seq1 | ||
| 128 | .cnt | ||
| 129 | .write(|w| unsafe { w.bits(sequence.len() as u32) }); | ||
| 130 | r.seq1.refresh.write(|w| unsafe { w.bits(config.refresh) }); | ||
| 131 | r.seq1 | ||
| 132 | .enddelay | ||
| 133 | .write(|w| unsafe { w.bits(config.end_delay) }); | ||
| 134 | |||
| 135 | r.decoder.write(|w| { | 106 | r.decoder.write(|w| { |
| 136 | w.load().bits(config.sequence_load as u8); | 107 | w.load().bits(config.sequence_load as u8); |
| 137 | w.mode().refresh_count() | 108 | w.mode().refresh_count() |
| @@ -146,6 +117,16 @@ impl<'d, T: Instance> SequencePwm<'d, T> { | |||
| 146 | r.countertop | 117 | r.countertop |
| 147 | .write(|w| unsafe { w.countertop().bits(config.max_duty) }); | 118 | .write(|w| unsafe { w.countertop().bits(config.max_duty) }); |
| 148 | 119 | ||
| 120 | r.seq0.refresh.write(|w| unsafe { w.bits(config.refresh) }); | ||
| 121 | r.seq0 | ||
| 122 | .enddelay | ||
| 123 | .write(|w| unsafe { w.bits(config.end_delay) }); | ||
| 124 | |||
| 125 | r.seq1.refresh.write(|w| unsafe { w.bits(config.refresh) }); | ||
| 126 | r.seq1 | ||
| 127 | .enddelay | ||
| 128 | .write(|w| unsafe { w.bits(config.end_delay) }); | ||
| 129 | |||
| 149 | Ok(Self { | 130 | Ok(Self { |
| 150 | phantom: PhantomData, | 131 | phantom: PhantomData, |
| 151 | ch0: ch0.degrade_optional(), | 132 | ch0: ch0.degrade_optional(), |
| @@ -157,12 +138,33 @@ impl<'d, T: Instance> SequencePwm<'d, T> { | |||
| 157 | 138 | ||
| 158 | /// Start or restart playback | 139 | /// Start or restart playback |
| 159 | #[inline(always)] | 140 | #[inline(always)] |
| 160 | pub fn start(&self, times: SequenceMode) -> Result<(), Error> { | 141 | pub fn start(&self, sequence: &'d [u16], times: SequenceMode) -> Result<(), Error> { |
| 142 | slice_in_ram_or(sequence, Error::DMABufferNotInDataMemory)?; | ||
| 143 | |||
| 144 | if sequence.len() > 32767 { | ||
| 145 | return Err(Error::SequenceTooLong); | ||
| 146 | } | ||
| 147 | |||
| 161 | if let SequenceMode::Times(0) = times { | 148 | if let SequenceMode::Times(0) = times { |
| 162 | return Err(Error::SequenceTimesAtLeastOne); | 149 | return Err(Error::SequenceTimesAtLeastOne); |
| 163 | } | 150 | } |
| 151 | |||
| 164 | let r = T::regs(); | 152 | let r = T::regs(); |
| 165 | 153 | ||
| 154 | r.seq0 | ||
| 155 | .ptr | ||
| 156 | .write(|w| unsafe { w.bits(sequence.as_ptr() as u32) }); | ||
| 157 | r.seq0 | ||
| 158 | .cnt | ||
| 159 | .write(|w| unsafe { w.bits(sequence.len() as u32) }); | ||
| 160 | |||
| 161 | r.seq1 | ||
| 162 | .ptr | ||
| 163 | .write(|w| unsafe { w.bits(sequence.as_ptr() as u32) }); | ||
| 164 | r.seq1 | ||
| 165 | .cnt | ||
| 166 | .write(|w| unsafe { w.bits(sequence.len() as u32) }); | ||
| 167 | |||
| 166 | self.stop(); | 168 | self.stop(); |
| 167 | 169 | ||
| 168 | r.enable.write(|w| w.enable().enabled()); | 170 | 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; | |||
| 13 | 13 | ||
| 14 | #[embassy::main] | 14 | #[embassy::main] |
| 15 | async fn main(_spawner: Spawner, p: Peripherals) { | 15 | async fn main(_spawner: Spawner, p: Peripherals) { |
| 16 | let seq_values: [u16; 5] = [1000, 250, 100, 50, 0]; | 16 | let seq_values_1: [u16; 5] = [1000, 250, 100, 50, 0]; |
| 17 | let seq_values_2: [u16; 5] = [0, 50, 100, 250, 1000]; | ||
| 17 | 18 | ||
| 18 | let mut config = SequenceConfig::default(); | 19 | let mut config = SequenceConfig::default(); |
| 19 | config.prescaler = Prescaler::Div128; | 20 | config.prescaler = Prescaler::Div128; |
| @@ -25,18 +26,17 @@ async fn main(_spawner: Spawner, p: Peripherals) { | |||
| 25 | // thus our sequence takes 5 * 5000ms or 25 seconds | 26 | // thus our sequence takes 5 * 5000ms or 25 seconds |
| 26 | 27 | ||
| 27 | let pwm = unwrap!(SequencePwm::new( | 28 | let pwm = unwrap!(SequencePwm::new( |
| 28 | p.PWM0, | 29 | p.PWM0, p.P0_13, NoPin, NoPin, NoPin, config, |
| 29 | p.P0_13, | ||
| 30 | NoPin, | ||
| 31 | NoPin, | ||
| 32 | NoPin, | ||
| 33 | config, | ||
| 34 | &seq_values | ||
| 35 | )); | 30 | )); |
| 36 | let _ = pwm.start(SequenceMode::Infinite); | 31 | let _ = pwm.start(&seq_values_1, SequenceMode::Infinite); |
| 37 | 32 | ||
| 38 | info!("pwm started!"); | 33 | info!("pwm started!"); |
| 39 | 34 | ||
| 35 | Timer::after(Duration::from_millis(20000)).await; | ||
| 36 | info!("pwm starting with another sequence!"); | ||
| 37 | |||
| 38 | let _ = pwm.start(&seq_values_2, SequenceMode::Infinite); | ||
| 39 | |||
| 40 | // we can abort a sequence if we need to before its complete with pwm.stop() | 40 | // we can abort a sequence if we need to before its complete with pwm.stop() |
| 41 | // or stop is also implicitly called when the pwm peripheral is dropped | 41 | // or stop is also implicitly called when the pwm peripheral is dropped |
| 42 | // when it goes out of scope | 42 | // 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) { | |||
| 27 | config.refresh = 30; | 27 | config.refresh = 30; |
| 28 | 28 | ||
| 29 | let pwm = unwrap!(SequencePwm::new( | 29 | let pwm = unwrap!(SequencePwm::new( |
| 30 | p.PWM0, | 30 | p.PWM0, p.P0_13, NoPin, NoPin, NoPin, config, |
| 31 | p.P0_13, | ||
| 32 | NoPin, | ||
| 33 | NoPin, | ||
| 34 | NoPin, | ||
| 35 | config, | ||
| 36 | &seq_values | ||
| 37 | )); | 31 | )); |
| 38 | 32 | ||
| 39 | let _ = pwm.start(SequenceMode::Times(1)); | 33 | let _ = pwm.start(&seq_values, SequenceMode::Times(1)); |
| 40 | // pwm.stop() deconfigures pins, and then the task_start_seq0 task cant work | 34 | // pwm.stop() deconfigures pins, and then the task_start_seq0 task cant work |
| 41 | // so its going to have to start running in order load the configuration | 35 | // so its going to have to start running in order load the configuration |
| 42 | 36 | ||
