aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-nrf/src/pwm.rs62
-rw-r--r--examples/nrf/src/bin/pwm_sequence.rs18
-rw-r--r--examples/nrf/src/bin/pwm_sequence_ppi.rs10
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]
15async fn main(_spawner: Spawner, p: Peripherals) { 15async 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