diff options
| author | huntc <[email protected]> | 2022-01-23 16:21:34 +1100 |
|---|---|---|
| committer | huntc <[email protected]> | 2022-01-23 16:29:52 +1100 |
| commit | 7598b8a40fba7e7035d67da5867f27d16818ea62 (patch) | |
| tree | 50bfb0e528a67f149d1570dc1f5ffafa0b37c8bb /embassy-nrf/src | |
| parent | 6b0cb0609b4bfa3e464e4603ce373a9de9886103 (diff) | |
Permit many sequences to be passed
Sequences are now passed in via the start method to avoid having to stop the PWM and restart it. Sequences continue to be constrained with the same lifetime of the Pwm object itself. The pwm_sequence example has been extended to illustrate multiple sequences being passed around.
Diffstat (limited to 'embassy-nrf/src')
| -rw-r--r-- | embassy-nrf/src/pwm.rs | 62 |
1 files changed, 32 insertions, 30 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()); |
