nrf: PWMAudioOut: Remove the need to wait in "pause"

The original formulation was because I saw the need to avoid a transition
from playing to stopped exactly when a resume was taking place.  However,
@tannewt was concerned about this pause causing trouble, because it could
be relatively lengthy (several ms even in a typical case).

After reflection, I've convinced myself that updating the registers
in this order in resume avoids a window where a "stopped" event can
be missed as long as the shortcut is updated first.

Testing re-performed: pause/resume testing of looped RawSample and
WaveFile audio sources.
This commit is contained in:
Jeff Epler 2019-08-03 08:19:25 -05:00
parent 76f65ac694
commit 77bc1ba03e
1 changed files with 5 additions and 4 deletions

View File

@ -295,19 +295,20 @@ bool common_hal_audiopwmio_pwmaudioout_get_playing(audiopwmio_pwmaudioout_obj_t*
* Perhaps the way forward is to divide even "single buffer" samples into tasks of * Perhaps the way forward is to divide even "single buffer" samples into tasks of
* only a few ms long, so that they can be stopped/restarted quickly enough that it * only a few ms long, so that they can be stopped/restarted quickly enough that it
* feels instant. (This also saves on memory, for long in-memory "single buffer" * feels instant. (This also saves on memory, for long in-memory "single buffer"
* samples!) * samples, since we have to locally take a resampled copy!)
*/ */
void common_hal_audiopwmio_pwmaudioout_pause(audiopwmio_pwmaudioout_obj_t* self) { void common_hal_audiopwmio_pwmaudioout_pause(audiopwmio_pwmaudioout_obj_t* self) {
self->paused = true; self->paused = true;
self->pwm->SHORTS = NRF_PWM_SHORT_SEQEND1_STOP_MASK; self->pwm->SHORTS = NRF_PWM_SHORT_SEQEND1_STOP_MASK;
while(!self->pwm->EVENTS_STOPPED) { /* NOTHING */ }
} }
void common_hal_audiopwmio_pwmaudioout_resume(audiopwmio_pwmaudioout_obj_t* self) { void common_hal_audiopwmio_pwmaudioout_resume(audiopwmio_pwmaudioout_obj_t* self) {
self->paused = false; self->paused = false;
self->pwm->SHORTS = NRF_PWM_SHORT_LOOPSDONE_SEQSTART0_MASK; self->pwm->SHORTS = NRF_PWM_SHORT_LOOPSDONE_SEQSTART0_MASK;
self->pwm->EVENTS_STOPPED = 0; if (self->pwm->EVENTS_STOPPED) {
self->pwm->TASKS_SEQSTART[0] = 1; self->pwm->EVENTS_STOPPED = 0;
self->pwm->TASKS_SEQSTART[0] = 1;
}
} }
bool common_hal_audiopwmio_pwmaudioout_get_paused(audiopwmio_pwmaudioout_obj_t* self) { bool common_hal_audiopwmio_pwmaudioout_get_paused(audiopwmio_pwmaudioout_obj_t* self) {