Clear the pending IRQ in the NVIC as well.
This commit is contained in:
parent
00d5f63e7c
commit
affd3fcc2a
|
@ -322,6 +322,7 @@ bool common_hal_audiobusio_i2sout_get_playing(audiobusio_i2sout_obj_t* self) {
|
|||
void i2s_background(void) {
|
||||
if (NVIC_GetPendingIRQ(I2S_IRQn) && NRF_I2S->EVENTS_TXPTRUPD) {
|
||||
NRF_I2S->EVENTS_TXPTRUPD = 0;
|
||||
NVIC_ClearPendingIRQ(I2S_IRQn);
|
||||
if (instance) {
|
||||
i2s_buffer_fill(instance);
|
||||
} else {
|
||||
|
|
|
@ -88,7 +88,6 @@ void audiopwmout_reset() {
|
|||
}
|
||||
|
||||
STATIC void fill_buffers(audiopwmio_pwmaudioout_obj_t *self, int buf) {
|
||||
self->pwm->EVENTS_SEQSTARTED[1-buf] = 0;
|
||||
uint16_t *dev_buffer = self->buffers[buf];
|
||||
uint8_t *buffer;
|
||||
uint32_t buffer_length;
|
||||
|
@ -145,8 +144,15 @@ STATIC void audiopwmout_background_obj(audiopwmio_pwmaudioout_obj_t *self) {
|
|||
if (stopped)
|
||||
self->pwm->TASKS_STOP = 1;
|
||||
} else if (!self->paused && !self->single_buffer) {
|
||||
if (self->pwm->EVENTS_SEQSTARTED[0]) fill_buffers(self, 1);
|
||||
if (self->pwm->EVENTS_SEQSTARTED[1]) fill_buffers(self, 0);
|
||||
if (self->pwm->EVENTS_SEQSTARTED[0]) {
|
||||
fill_buffers(self, 1);
|
||||
self->pwm->EVENTS_SEQSTARTED[0] = 0;
|
||||
}
|
||||
if (self->pwm->EVENTS_SEQSTARTED[1]) {
|
||||
fill_buffers(self, 0);
|
||||
self->pwm->EVENTS_SEQSTARTED[1] = 0;
|
||||
}
|
||||
NVIC_ClearPendingIRQ(self->pwm_irq);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -168,7 +174,8 @@ void audiopwmout_background() {
|
|||
// Caller validates that pins are free.
|
||||
void common_hal_audiopwmio_pwmaudioout_construct(audiopwmio_pwmaudioout_obj_t* self,
|
||||
const mcu_pin_obj_t* left_channel, const mcu_pin_obj_t* right_channel, uint16_t quiescent_value) {
|
||||
self->pwm = pwmout_allocate(256, PWM_PRESCALER_PRESCALER_DIV_1, true, NULL, NULL);
|
||||
self->pwm = pwmout_allocate(256, PWM_PRESCALER_PRESCALER_DIV_1, true, NULL, NULL,
|
||||
&self->pwm_irq);
|
||||
if (!self->pwm) {
|
||||
mp_raise_RuntimeError(translate("All timers in use"));
|
||||
}
|
||||
|
|
|
@ -44,6 +44,8 @@ typedef struct {
|
|||
uint8_t sample_channel_count;
|
||||
uint8_t bytes_per_sample;
|
||||
|
||||
IRQn_Type pwm_irq;
|
||||
|
||||
bool playing;
|
||||
bool stopping;
|
||||
bool paused;
|
||||
|
|
|
@ -139,11 +139,15 @@ bool convert_frequency(uint32_t frequency, uint16_t *countertop, nrf_pwm_clk_t *
|
|||
return false;
|
||||
}
|
||||
|
||||
// We store these in an array because we cannot compute them.
|
||||
static IRQn_Type pwm_irqs[4] = {PWM0_IRQn, PWM1_IRQn, PWM2_IRQn, PWM3_IRQn};
|
||||
|
||||
NRF_PWM_Type *pwmout_allocate(uint16_t countertop, nrf_pwm_clk_t base_clock,
|
||||
bool variable_frequency, int8_t *channel_out, bool *pwm_already_in_use_out) {
|
||||
bool variable_frequency, int8_t *channel_out, bool *pwm_already_in_use_out,
|
||||
IRQn_Type* irq) {
|
||||
for (size_t pwm_index = 0; pwm_index < MP_ARRAY_SIZE(pwms); pwm_index++) {
|
||||
NRF_PWM_Type *pwm = pwms[pwm_index];
|
||||
bool pwm_already_in_use = pwm->ENABLE & SPIM_ENABLE_ENABLE_Msk;
|
||||
bool pwm_already_in_use = pwm->ENABLE & PWM_ENABLE_ENABLE_Msk;
|
||||
if (pwm_already_in_use) {
|
||||
if (variable_frequency) {
|
||||
// Variable frequency requires exclusive use of a PWM, so try the next one.
|
||||
|
@ -156,20 +160,30 @@ NRF_PWM_Type *pwmout_allocate(uint16_t countertop, nrf_pwm_clk_t base_clock,
|
|||
for (size_t chan = 0; chan < CHANNELS_PER_PWM; chan++) {
|
||||
if (pwm->PSEL.OUT[chan] == 0xFFFFFFFF) {
|
||||
// Channel is free.
|
||||
if(channel_out)
|
||||
if (channel_out) {
|
||||
*channel_out = chan;
|
||||
if(pwm_already_in_use_out)
|
||||
}
|
||||
if (pwm_already_in_use_out) {
|
||||
*pwm_already_in_use_out = pwm_already_in_use;
|
||||
}
|
||||
if (irq) {
|
||||
*irq = pwm_irqs[pwm_index];
|
||||
}
|
||||
return pwm;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// PWM not yet in use, so we can start to use it. Use channel 0.
|
||||
if(channel_out)
|
||||
if (channel_out) {
|
||||
*channel_out = 0;
|
||||
if(pwm_already_in_use_out)
|
||||
}
|
||||
if (pwm_already_in_use_out) {
|
||||
*pwm_already_in_use_out = pwm_already_in_use;
|
||||
}
|
||||
if (irq) {
|
||||
*irq = pwm_irqs[pwm_index];
|
||||
}
|
||||
return pwm;
|
||||
}
|
||||
}
|
||||
|
@ -208,7 +222,7 @@ pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
|
|||
int8_t channel;
|
||||
bool pwm_already_in_use;
|
||||
self->pwm = pwmout_allocate(countertop, base_clock, variable_frequency,
|
||||
&channel, &pwm_already_in_use);
|
||||
&channel, &pwm_already_in_use, NULL);
|
||||
|
||||
if (self->pwm == NULL) {
|
||||
return PWMOUT_ALL_TIMERS_IN_USE;
|
||||
|
|
|
@ -42,7 +42,8 @@ typedef struct {
|
|||
|
||||
void pwmout_reset(void);
|
||||
NRF_PWM_Type *pwmout_allocate(uint16_t countertop, nrf_pwm_clk_t base_clock,
|
||||
bool variable_frequency, int8_t *channel_out, bool *pwm_already_in_use_out);
|
||||
bool variable_frequency, int8_t *channel_out, bool *pwm_already_in_use_out,
|
||||
IRQn_Type *irq);
|
||||
void pwmout_free_channel(NRF_PWM_Type *pwm, int8_t channel);
|
||||
|
||||
#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_PULSEIO_PWMOUT_H
|
||||
|
|
Loading…
Reference in New Issue