diff options
| author | Jacob Rosenthal <[email protected]> | 2021-11-01 08:54:07 -0700 |
|---|---|---|
| committer | Jacob Rosenthal <[email protected]> | 2021-11-01 08:54:07 -0700 |
| commit | 12b2c5d5f70b836c853c000f036df2bdc255098d (patch) | |
| tree | 682111848ac6e510789c6739d56d60b31891d3dd | |
| parent | 90be851e4b52703b4297615253bc7a89fdd03b9f (diff) | |
better not as a constructor?
| -rw-r--r-- | embassy-nrf/src/pwm.rs | 60 | ||||
| -rw-r--r-- | examples/nrf/src/bin/pwm_sequence.rs | 11 | ||||
| -rw-r--r-- | examples/nrf/src/bin/pwm_simple_sin.rs | 11 |
3 files changed, 22 insertions, 60 deletions
diff --git a/embassy-nrf/src/pwm.rs b/embassy-nrf/src/pwm.rs index 8775c8896..d9d69170b 100644 --- a/embassy-nrf/src/pwm.rs +++ b/embassy-nrf/src/pwm.rs | |||
| @@ -55,7 +55,7 @@ pub struct Pwm<'d, T: Instance> { | |||
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | #[derive(Debug, Eq, PartialEq, Clone, Copy)] | 57 | #[derive(Debug, Eq, PartialEq, Clone, Copy)] |
| 58 | pub enum LoopMode { | 58 | pub enum SequenceMode { |
| 59 | /// Run sequence n Times total | 59 | /// Run sequence n Times total |
| 60 | Times(u16), | 60 | Times(u16), |
| 61 | /// Repeat until `stop` is called. | 61 | /// Repeat until `stop` is called. |
| @@ -63,7 +63,7 @@ pub enum LoopMode { | |||
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | /// Configure an infinite looping sequence for `simple_playback` | 65 | /// Configure an infinite looping sequence for `simple_playback` |
| 66 | pub struct LoopingConfig<'a> { | 66 | pub struct SequenceConfig<'a> { |
| 67 | /// Selects up mode or up-and-down mode for the counter | 67 | /// Selects up mode or up-and-down mode for the counter |
| 68 | pub counter_mode: CounterMode, | 68 | pub counter_mode: CounterMode, |
| 69 | // Top value to be compared against buffer values | 69 | // Top value to be compared against buffer values |
| @@ -79,7 +79,7 @@ pub struct LoopingConfig<'a> { | |||
| 79 | /// Number of Times PWM periods after the sequence ends before starting the next sequence | 79 | /// Number of Times PWM periods after the sequence ends before starting the next sequence |
| 80 | pub end_delay: u32, | 80 | pub end_delay: u32, |
| 81 | /// How many times to play the sequence | 81 | /// How many times to play the sequence |
| 82 | pub times: LoopMode, | 82 | pub times: SequenceMode, |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | 85 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
| @@ -132,6 +132,9 @@ impl<'d, T: Instance> Pwm<'d, T> { | |||
| 132 | pin.set_low(); | 132 | pin.set_low(); |
| 133 | pin.conf().write(|w| w.dir().output()); | 133 | pin.conf().write(|w| w.dir().output()); |
| 134 | } | 134 | } |
| 135 | |||
| 136 | // if NoPin provided writes disconnected (top bit 1) 0x80000000 else | ||
| 137 | // writes pin number ex 13 (0x0D) which is connected (top bit 0) | ||
| 135 | r.psel.out[0].write(|w| unsafe { w.bits(ch0.psel_bits()) }); | 138 | r.psel.out[0].write(|w| unsafe { w.bits(ch0.psel_bits()) }); |
| 136 | r.psel.out[1].write(|w| unsafe { w.bits(ch1.psel_bits()) }); | 139 | r.psel.out[1].write(|w| unsafe { w.bits(ch1.psel_bits()) }); |
| 137 | r.psel.out[2].write(|w| unsafe { w.bits(ch2.psel_bits()) }); | 140 | r.psel.out[2].write(|w| unsafe { w.bits(ch2.psel_bits()) }); |
| @@ -166,54 +169,18 @@ impl<'d, T: Instance> Pwm<'d, T> { | |||
| 166 | } | 169 | } |
| 167 | 170 | ||
| 168 | /// Returns a configured pwm that has had start called on it | 171 | /// Returns a configured pwm that has had start called on it |
| 169 | pub fn simple_playback( | 172 | pub fn play_sequence(&self, config: SequenceConfig) -> Result<(), Error> { |
| 170 | _pwm: impl Unborrow<Target = T> + 'd, | ||
| 171 | ch0: impl Unborrow<Target = impl GpioOptionalPin> + 'd, | ||
| 172 | ch1: impl Unborrow<Target = impl GpioOptionalPin> + 'd, | ||
| 173 | ch2: impl Unborrow<Target = impl GpioOptionalPin> + 'd, | ||
| 174 | ch3: impl Unborrow<Target = impl GpioOptionalPin> + 'd, | ||
| 175 | config: LoopingConfig, | ||
| 176 | ) -> Result<Self, Error> { | ||
| 177 | slice_in_ram_or(config.sequence, Error::DMABufferNotInDataMemory)?; | 173 | slice_in_ram_or(config.sequence, Error::DMABufferNotInDataMemory)?; |
| 178 | 174 | ||
| 179 | if config.sequence.len() > 32767 { | 175 | if config.sequence.len() > 32767 { |
| 180 | return Err(Error::SequenceTooLong); | 176 | return Err(Error::SequenceTooLong); |
| 181 | } | 177 | } |
| 182 | if let LoopMode::Times(0) = config.times { | 178 | if let SequenceMode::Times(0) = config.times { |
| 183 | return Err(Error::SequenceTooShort); | 179 | return Err(Error::SequenceTooShort); |
| 184 | } | 180 | } |
| 185 | 181 | ||
| 186 | unborrow!(ch0, ch1, ch2, ch3); | ||
| 187 | |||
| 188 | let r = T::regs(); | 182 | let r = T::regs(); |
| 189 | 183 | ||
| 190 | if let Some(pin) = ch0.pin_mut() { | ||
| 191 | pin.set_low(); | ||
| 192 | pin.conf().write(|w| w.dir().output()); | ||
| 193 | } | ||
| 194 | |||
| 195 | if let Some(pin) = ch1.pin_mut() { | ||
| 196 | pin.set_low(); | ||
| 197 | pin.conf().write(|w| w.dir().output()); | ||
| 198 | } | ||
| 199 | if let Some(pin) = ch2.pin_mut() { | ||
| 200 | pin.set_low(); | ||
| 201 | pin.conf().write(|w| w.dir().output()); | ||
| 202 | } | ||
| 203 | if let Some(pin) = ch3.pin_mut() { | ||
| 204 | pin.set_low(); | ||
| 205 | pin.conf().write(|w| w.dir().output()); | ||
| 206 | } | ||
| 207 | |||
| 208 | // if NoPin provided writes disconnected (top bit 1) 0x80000000 else | ||
| 209 | // writes pin number ex 13 (0x0D) which is connected (top bit 0) | ||
| 210 | r.psel.out[0].write(|w| unsafe { w.bits(ch0.psel_bits()) }); | ||
| 211 | r.psel.out[1].write(|w| unsafe { w.bits(ch1.psel_bits()) }); | ||
| 212 | r.psel.out[2].write(|w| unsafe { w.bits(ch2.psel_bits()) }); | ||
| 213 | r.psel.out[3].write(|w| unsafe { w.bits(ch3.psel_bits()) }); | ||
| 214 | |||
| 215 | r.enable.write(|w| w.enable().enabled()); | ||
| 216 | |||
| 217 | r.mode | 184 | r.mode |
| 218 | .write(|w| unsafe { w.bits(config.counter_mode as u32) }); | 185 | .write(|w| unsafe { w.bits(config.counter_mode as u32) }); |
| 219 | r.prescaler | 186 | r.prescaler |
| @@ -250,7 +217,7 @@ impl<'d, T: Instance> Pwm<'d, T> { | |||
| 250 | 217 | ||
| 251 | match config.times { | 218 | match config.times { |
| 252 | // just the one time, no loop count | 219 | // just the one time, no loop count |
| 253 | LoopMode::Times(1) => { | 220 | SequenceMode::Times(1) => { |
| 254 | r.loop_.write(|w| w.cnt().disabled()); | 221 | r.loop_.write(|w| w.cnt().disabled()); |
| 255 | // tasks_seqstart doesnt exist in all svds so write its bit instead | 222 | // tasks_seqstart doesnt exist in all svds so write its bit instead |
| 256 | r.tasks_seqstart[0].write(|w| unsafe { w.bits(0x01) }); | 223 | r.tasks_seqstart[0].write(|w| unsafe { w.bits(0x01) }); |
| @@ -258,7 +225,7 @@ impl<'d, T: Instance> Pwm<'d, T> { | |||
| 258 | // loop count is how many times to play BOTH sequences | 225 | // loop count is how many times to play BOTH sequences |
| 259 | // 2 total (1 x 2) | 226 | // 2 total (1 x 2) |
| 260 | // 3 total, (2 x 2) - 1 | 227 | // 3 total, (2 x 2) - 1 |
| 261 | LoopMode::Times(n) => { | 228 | SequenceMode::Times(n) => { |
| 262 | let odd = n & 1 == 1; | 229 | let odd = n & 1 == 1; |
| 263 | let times = if odd { (n / 2) + 1 } else { n / 2 }; | 230 | let times = if odd { (n / 2) + 1 } else { n / 2 }; |
| 264 | 231 | ||
| @@ -273,17 +240,14 @@ impl<'d, T: Instance> Pwm<'d, T> { | |||
| 273 | } | 240 | } |
| 274 | } | 241 | } |
| 275 | // to play infinitely, repeat the sequence one time, then have loops done self trigger seq0 again | 242 | // to play infinitely, repeat the sequence one time, then have loops done self trigger seq0 again |
| 276 | LoopMode::Infinite => { | 243 | SequenceMode::Infinite => { |
| 277 | r.loop_.write(|w| unsafe { w.cnt().bits(0x1) }); | 244 | r.loop_.write(|w| unsafe { w.cnt().bits(0x1) }); |
| 278 | r.shorts.write(|w| w.loopsdone_seqstart0().enabled()); | 245 | r.shorts.write(|w| w.loopsdone_seqstart0().enabled()); |
| 279 | // tasks_seqstart doesnt exist in all svds so write its bit instead | 246 | // tasks_seqstart doesnt exist in all svds so write its bit instead |
| 280 | r.tasks_seqstart[0].write(|w| unsafe { w.bits(0x01) }); | 247 | r.tasks_seqstart[0].write(|w| unsafe { w.bits(0x01) }); |
| 281 | } | 248 | } |
| 282 | } | 249 | } |
| 283 | 250 | Ok(()) | |
| 284 | Ok(Self { | ||
| 285 | phantom: PhantomData, | ||
| 286 | }) | ||
| 287 | } | 251 | } |
| 288 | 252 | ||
| 289 | /// Stop playback | 253 | /// Stop playback |
diff --git a/examples/nrf/src/bin/pwm_sequence.rs b/examples/nrf/src/bin/pwm_sequence.rs index 40ba7ab1c..066ab3c03 100644 --- a/examples/nrf/src/bin/pwm_sequence.rs +++ b/examples/nrf/src/bin/pwm_sequence.rs | |||
| @@ -7,7 +7,7 @@ mod example_common; | |||
| 7 | use defmt::*; | 7 | use defmt::*; |
| 8 | use embassy::executor::Spawner; | 8 | use embassy::executor::Spawner; |
| 9 | use embassy::time::{Duration, Timer}; | 9 | use embassy::time::{Duration, Timer}; |
| 10 | use embassy_nrf::pwm::{CounterMode, LoopMode, LoopingConfig, Prescaler, Pwm, SequenceLoad}; | 10 | use embassy_nrf::pwm::{CounterMode, Prescaler, Pwm, SequenceConfig, SequenceLoad, SequenceMode}; |
| 11 | use embassy_nrf::Peripherals; | 11 | use embassy_nrf::Peripherals; |
| 12 | 12 | ||
| 13 | #[embassy::main] | 13 | #[embassy::main] |
| @@ -16,7 +16,7 @@ async fn main(_spawner: Spawner, p: Peripherals) { | |||
| 16 | 0x8000, 0, 0, 0, 0, 0x8000, 0, 0, 0, 0, 0x8000, 0, 0, 0, 0, 0x8000, | 16 | 0x8000, 0, 0, 0, 0, 0x8000, 0, 0, 0, 0, 0x8000, 0, 0, 0, 0, 0x8000, |
| 17 | ]; | 17 | ]; |
| 18 | 18 | ||
| 19 | let config = LoopingConfig { | 19 | let config = SequenceConfig { |
| 20 | counter_mode: CounterMode::Up, | 20 | counter_mode: CounterMode::Up, |
| 21 | top: 15625, | 21 | top: 15625, |
| 22 | prescaler: Prescaler::Div128, | 22 | prescaler: Prescaler::Div128, |
| @@ -24,12 +24,11 @@ async fn main(_spawner: Spawner, p: Peripherals) { | |||
| 24 | sequence_load: SequenceLoad::Individual, | 24 | sequence_load: SequenceLoad::Individual, |
| 25 | refresh: 0, | 25 | refresh: 0, |
| 26 | end_delay: 0, | 26 | end_delay: 0, |
| 27 | times: LoopMode::Times(5), | 27 | times: SequenceMode::Times(5), |
| 28 | }; | 28 | }; |
| 29 | 29 | ||
| 30 | let _pwm = unwrap!(Pwm::simple_playback( | 30 | let pwm = Pwm::new(p.PWM0, p.P0_13, p.P0_15, p.P0_16, p.P0_14); |
| 31 | p.PWM0, p.P0_13, p.P0_15, p.P0_16, p.P0_14, config | 31 | unwrap!(pwm.play_sequence(config)); |
| 32 | )); | ||
| 33 | info!("pwm started!"); | 32 | info!("pwm started!"); |
| 34 | 33 | ||
| 35 | loop { | 34 | loop { |
diff --git a/examples/nrf/src/bin/pwm_simple_sin.rs b/examples/nrf/src/bin/pwm_simple_sin.rs index c1af0db8c..3c1bddbc7 100644 --- a/examples/nrf/src/bin/pwm_simple_sin.rs +++ b/examples/nrf/src/bin/pwm_simple_sin.rs | |||
| @@ -9,7 +9,7 @@ use defmt::*; | |||
| 9 | use embassy::executor::Spawner; | 9 | use embassy::executor::Spawner; |
| 10 | use embassy::time::{Duration, Timer}; | 10 | use embassy::time::{Duration, Timer}; |
| 11 | use embassy_nrf::gpio::NoPin; | 11 | use embassy_nrf::gpio::NoPin; |
| 12 | use embassy_nrf::pwm::{CounterMode, LoopMode, LoopingConfig, Prescaler, Pwm, SequenceLoad}; | 12 | use embassy_nrf::pwm::{CounterMode, Prescaler, Pwm, SequenceConfig, SequenceLoad, SequenceMode}; |
| 13 | use embassy_nrf::Peripherals; | 13 | use embassy_nrf::Peripherals; |
| 14 | use micromath::F32Ext; | 14 | use micromath::F32Ext; |
| 15 | 15 | ||
| @@ -20,7 +20,7 @@ async fn main(_spawner: Spawner, p: Peripherals) { | |||
| 20 | // probably not best use of resources to create the table at runtime, but makes testing fast | 20 | // probably not best use of resources to create the table at runtime, but makes testing fast |
| 21 | let seq_values: [u16; 220] = core::array::from_fn(|n| ((W1 * n as f32).sin() * 10000.0) as u16); | 21 | let seq_values: [u16; 220] = core::array::from_fn(|n| ((W1 * n as f32).sin() * 10000.0) as u16); |
| 22 | 22 | ||
| 23 | let config = LoopingConfig { | 23 | let config = SequenceConfig { |
| 24 | counter_mode: CounterMode::UpAndDown, | 24 | counter_mode: CounterMode::UpAndDown, |
| 25 | top: 12000, | 25 | top: 12000, |
| 26 | prescaler: Prescaler::Div16, | 26 | prescaler: Prescaler::Div16, |
| @@ -28,12 +28,11 @@ async fn main(_spawner: Spawner, p: Peripherals) { | |||
| 28 | sequence_load: SequenceLoad::Common, | 28 | sequence_load: SequenceLoad::Common, |
| 29 | refresh: 0, | 29 | refresh: 0, |
| 30 | end_delay: 0, | 30 | end_delay: 0, |
| 31 | times: LoopMode::Infinite, | 31 | times: SequenceMode::Infinite, |
| 32 | }; | 32 | }; |
| 33 | 33 | ||
| 34 | let pwm = unwrap!(Pwm::simple_playback( | 34 | let pwm = Pwm::new(p.PWM0, p.P0_13, NoPin, NoPin, NoPin); |
| 35 | p.PWM0, p.P0_13, NoPin, NoPin, NoPin, config | 35 | unwrap!(pwm.play_sequence(config)); |
| 36 | )); | ||
| 37 | info!("pwm started!"); | 36 | info!("pwm started!"); |
| 38 | 37 | ||
| 39 | Timer::after(Duration::from_millis(20000)).await; | 38 | Timer::after(Duration::from_millis(20000)).await; |
