diff options
| -rw-r--r-- | embassy-nrf/src/pwm.rs | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/embassy-nrf/src/pwm.rs b/embassy-nrf/src/pwm.rs index 077a27cd0..e4ddda395 100644 --- a/embassy-nrf/src/pwm.rs +++ b/embassy-nrf/src/pwm.rs | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | use core::marker::PhantomData; | 3 | use core::marker::PhantomData; |
| 4 | use core::sync::atomic::{compiler_fence, Ordering}; | 4 | use core::sync::atomic::{compiler_fence, Ordering}; |
| 5 | use embassy::util::Unborrow; | 5 | use embassy::util::Unborrow; |
| 6 | use embassy_hal_common::unborrow; | 6 | use embassy_hal_common::{low_power_wait_until, unborrow}; |
| 7 | 7 | ||
| 8 | use crate::gpio::sealed::Pin as _; | 8 | use crate::gpio::sealed::Pin as _; |
| 9 | use crate::gpio::{AnyPin, OptionalPin as GpioOptionalPin}; | 9 | use crate::gpio::{AnyPin, OptionalPin as GpioOptionalPin}; |
| @@ -157,12 +157,19 @@ impl<'d, T: Instance> SequencePwm<'d, T> { | |||
| 157 | 157 | ||
| 158 | r.enable.write(|w| w.enable().enabled()); | 158 | r.enable.write(|w| w.enable().enabled()); |
| 159 | 159 | ||
| 160 | // defensive before seqstart | ||
| 161 | compiler_fence(Ordering::SeqCst); | ||
| 162 | |||
| 160 | match times { | 163 | match times { |
| 161 | // just the one time, no loop count | 164 | // just the one time, no loop count |
| 162 | SequenceMode::Times(1) => { | 165 | SequenceMode::Times(1) => { |
| 163 | r.loop_.write(|w| w.cnt().disabled()); | 166 | r.loop_.write(|w| w.cnt().disabled()); |
| 164 | // tasks_seqstart() doesn't exist in all svds so write its bit instead | 167 | // tasks_seqstart() doesn't exist in all svds so write its bit instead |
| 165 | r.tasks_seqstart[0].write(|w| unsafe { w.bits(0x01) }); | 168 | r.tasks_seqstart[0].write(|w| unsafe { w.bits(0x01) }); |
| 169 | |||
| 170 | // defensive wait until waveform is loaded after seqstart | ||
| 171 | low_power_wait_until(|| r.events_seqend[0].read().bits() == 1); | ||
| 172 | r.events_seqend[0].write(|w| w); | ||
| 166 | } | 173 | } |
| 167 | // loop count is how many times to play BOTH sequences | 174 | // loop count is how many times to play BOTH sequences |
| 168 | // 2 total (1 x 2) | 175 | // 2 total (1 x 2) |
| @@ -177,17 +184,30 @@ impl<'d, T: Instance> SequencePwm<'d, T> { | |||
| 177 | if odd { | 184 | if odd { |
| 178 | // tasks_seqstart() doesn't exist in all svds so write its bit instead | 185 | // tasks_seqstart() doesn't exist in all svds so write its bit instead |
| 179 | r.tasks_seqstart[1].write(|w| unsafe { w.bits(0x01) }); | 186 | r.tasks_seqstart[1].write(|w| unsafe { w.bits(0x01) }); |
| 187 | |||
| 188 | // defensive wait until waveform is loaded after seqstart | ||
| 189 | low_power_wait_until(|| r.events_seqend[1].read().bits() == 1); | ||
| 190 | r.events_seqend[1].write(|w| w); | ||
| 180 | } else { | 191 | } else { |
| 181 | // tasks_seqstart() doesn't exist in all svds so write its bit instead | 192 | // tasks_seqstart() doesn't exist in all svds so write its bit instead |
| 182 | r.tasks_seqstart[0].write(|w| unsafe { w.bits(0x01) }); | 193 | r.tasks_seqstart[0].write(|w| unsafe { w.bits(0x01) }); |
| 194 | |||
| 195 | // defensive wait until waveform is loaded after seqstart | ||
| 196 | low_power_wait_until(|| r.events_seqend[0].read().bits() == 1); | ||
| 197 | r.events_seqend[0].write(|w| w); | ||
| 183 | } | 198 | } |
| 184 | } | 199 | } |
| 185 | // to play infinitely, repeat the sequence one time, then have loops done self trigger seq0 again | 200 | // to play infinitely, repeat the sequence one time, then have loops done self trigger seq0 again |
| 186 | SequenceMode::Infinite => { | 201 | SequenceMode::Infinite => { |
| 187 | r.loop_.write(|w| unsafe { w.cnt().bits(0x1) }); | 202 | r.loop_.write(|w| unsafe { w.cnt().bits(0x1) }); |
| 188 | r.shorts.write(|w| w.loopsdone_seqstart0().enabled()); | 203 | r.shorts.write(|w| w.loopsdone_seqstart0().enabled()); |
| 204 | |||
| 189 | // tasks_seqstart() doesn't exist in all svds so write its bit instead | 205 | // tasks_seqstart() doesn't exist in all svds so write its bit instead |
| 190 | r.tasks_seqstart[0].write(|w| unsafe { w.bits(0x01) }); | 206 | r.tasks_seqstart[0].write(|w| unsafe { w.bits(0x01) }); |
| 207 | |||
| 208 | // defensive wait until waveform is loaded after seqstart | ||
| 209 | low_power_wait_until(|| r.events_seqend[0].read().bits() == 1); | ||
| 210 | r.events_seqend[0].write(|w| w); | ||
| 191 | } | 211 | } |
| 192 | } | 212 | } |
| 193 | 213 | ||
| @@ -201,6 +221,8 @@ impl<'d, T: Instance> SequencePwm<'d, T> { | |||
| 201 | 221 | ||
| 202 | r.shorts.reset(); | 222 | r.shorts.reset(); |
| 203 | 223 | ||
| 224 | compiler_fence(Ordering::SeqCst); | ||
| 225 | |||
| 204 | // tasks_stop() doesn't exist in all svds so write its bit instead | 226 | // tasks_stop() doesn't exist in all svds so write its bit instead |
| 205 | r.tasks_stop.write(|w| unsafe { w.bits(0x01) }); | 227 | r.tasks_stop.write(|w| unsafe { w.bits(0x01) }); |
| 206 | } | 228 | } |
| @@ -404,6 +426,8 @@ impl<'d, T: Instance> SimplePwm<'d, T> { | |||
| 404 | 426 | ||
| 405 | r.shorts.reset(); | 427 | r.shorts.reset(); |
| 406 | 428 | ||
| 429 | compiler_fence(Ordering::SeqCst); | ||
| 430 | |||
| 407 | // tasks_stop() doesn't exist in all svds so write its bit instead | 431 | // tasks_stop() doesn't exist in all svds so write its bit instead |
| 408 | r.tasks_stop.write(|w| unsafe { w.bits(0x01) }); | 432 | r.tasks_stop.write(|w| unsafe { w.bits(0x01) }); |
| 409 | } | 433 | } |
| @@ -432,11 +456,15 @@ impl<'d, T: Instance> SimplePwm<'d, T> { | |||
| 432 | .ptr | 456 | .ptr |
| 433 | .write(|w| unsafe { w.bits(&self.duty as *const _ as u32) }); | 457 | .write(|w| unsafe { w.bits(&self.duty as *const _ as u32) }); |
| 434 | 458 | ||
| 435 | // todo justify? should i fence elsehwere we task start? or | 459 | // defensive before seqstart |
| 436 | compiler_fence(Ordering::SeqCst); | 460 | compiler_fence(Ordering::SeqCst); |
| 437 | 461 | ||
| 438 | // tasks_seqstart() doesn't exist in all svds so write its bit instead | 462 | // tasks_seqstart() doesn't exist in all svds so write its bit instead |
| 439 | r.tasks_seqstart[0].write(|w| unsafe { w.bits(1) }); | 463 | r.tasks_seqstart[0].write(|w| unsafe { w.bits(1) }); |
| 464 | |||
| 465 | // defensive wait until waveform is loaded after seqstart | ||
| 466 | low_power_wait_until(|| r.events_seqend[0].read().bits() == 1); | ||
| 467 | r.events_seqend[0].write(|w| w); | ||
| 440 | } | 468 | } |
| 441 | 469 | ||
| 442 | /// Sets the PWM clock prescaler. | 470 | /// Sets the PWM clock prescaler. |
