aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacob Rosenthal <[email protected]>2021-11-01 08:54:07 -0700
committerJacob Rosenthal <[email protected]>2021-11-01 08:54:07 -0700
commit12b2c5d5f70b836c853c000f036df2bdc255098d (patch)
tree682111848ac6e510789c6739d56d60b31891d3dd
parent90be851e4b52703b4297615253bc7a89fdd03b9f (diff)
better not as a constructor?
-rw-r--r--embassy-nrf/src/pwm.rs60
-rw-r--r--examples/nrf/src/bin/pwm_sequence.rs11
-rw-r--r--examples/nrf/src/bin/pwm_simple_sin.rs11
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)]
58pub enum LoopMode { 58pub 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`
66pub struct LoopingConfig<'a> { 66pub 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;
7use defmt::*; 7use defmt::*;
8use embassy::executor::Spawner; 8use embassy::executor::Spawner;
9use embassy::time::{Duration, Timer}; 9use embassy::time::{Duration, Timer};
10use embassy_nrf::pwm::{CounterMode, LoopMode, LoopingConfig, Prescaler, Pwm, SequenceLoad}; 10use embassy_nrf::pwm::{CounterMode, Prescaler, Pwm, SequenceConfig, SequenceLoad, SequenceMode};
11use embassy_nrf::Peripherals; 11use 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::*;
9use embassy::executor::Spawner; 9use embassy::executor::Spawner;
10use embassy::time::{Duration, Timer}; 10use embassy::time::{Duration, Timer};
11use embassy_nrf::gpio::NoPin; 11use embassy_nrf::gpio::NoPin;
12use embassy_nrf::pwm::{CounterMode, LoopMode, LoopingConfig, Prescaler, Pwm, SequenceLoad}; 12use embassy_nrf::pwm::{CounterMode, Prescaler, Pwm, SequenceConfig, SequenceLoad, SequenceMode};
13use embassy_nrf::Peripherals; 13use embassy_nrf::Peripherals;
14use micromath::F32Ext; 14use 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;