diff --git a/ports/atmel-samd/common-hal/analogio/AnalogOut.c b/ports/atmel-samd/common-hal/analogio/AnalogOut.c index 38064ec67d3a2..2fc1629c55635 100644 --- a/ports/atmel-samd/common-hal/analogio/AnalogOut.c +++ b/ports/atmel-samd/common-hal/analogio/AnalogOut.c @@ -155,11 +155,7 @@ void common_hal_analogio_analogout_set_value(analogio_analogout_obj_t *self, } void analogout_reset(void) { - // audioout_reset also resets the DAC, and does a smooth ramp down to avoid clicks - // if it was enabled, so do that instead if AudioOut is enabled. - #if CIRCUITPY_AUDIOIO - audioout_reset(); - #elif HAVE_ANALOGOUT + #if HAVE_ANALOGOUT #ifdef SAMD21 while (DAC->STATUS.reg & DAC_STATUS_SYNCBUSY) { } diff --git a/ports/atmel-samd/common-hal/audioio/AudioOut.c b/ports/atmel-samd/common-hal/audioio/AudioOut.c index c4e26c0f7d422..0f1884a9002d9 100644 --- a/ports/atmel-samd/common-hal/audioio/AudioOut.c +++ b/ports/atmel-samd/common-hal/audioio/AudioOut.c @@ -96,26 +96,6 @@ static void ramp_value(uint16_t start, uint16_t end) { } #endif -void audioout_reset(void) { - #if defined(SAMD21) && !defined(PIN_PA02) - return; - #endif - #ifdef SAMD21 - while (DAC->STATUS.reg & DAC_STATUS_SYNCBUSY) { - } - #endif - #ifdef SAM_D5X_E5X - while (DAC->SYNCBUSY.reg & DAC_SYNCBUSY_SWRST) { - } - #endif - if (DAC->CTRLA.bit.ENABLE) { - ramp_value(0x8000, 0); - } - DAC->CTRLA.reg |= DAC_CTRLA_SWRST; - - // TODO(tannewt): Turn off the DAC clocks to save power. -} - // Caller validates that pins are free. void common_hal_audioio_audioout_construct(audioio_audioout_obj_t *self, const mcu_pin_obj_t *left_channel, const mcu_pin_obj_t *right_channel, uint16_t quiescent_value) { @@ -231,22 +211,16 @@ void common_hal_audioio_audioout_construct(audioio_audioout_obj_t *self, } #endif + // Use a timer to coordinate when DAC conversions occur. - Tc *t = NULL; - uint8_t tc_index = TC_INST_NUM; - for (uint8_t i = TC_INST_NUM; i > 0; i--) { - if (tc_insts[i - 1]->COUNT16.CTRLA.bit.ENABLE == 0) { - t = tc_insts[i - 1]; - tc_index = i - 1; - break; - } - } - if (t == NULL) { + uint8_t tc_index = find_free_timer(); + if (tc_index == 0xFF) { common_hal_audioio_audioout_deinit(self); mp_raise_RuntimeError(MP_ERROR_TEXT("All timers in use")); return; } self->tc_index = tc_index; + Tc *t = tc_insts[tc_index]; // Use the 48MHz clocks on both the SAMD21 and 51 because we will be going much slower. uint8_t tc_gclk = 0; @@ -322,10 +296,6 @@ void common_hal_audioio_audioout_deinit(audioio_audioout_obj_t *self) { common_hal_audioio_audioout_stop(self); } - // Ramp the DAC down. - ramp_value(self->quiescent_value, 0); - - DAC->CTRLA.bit.ENABLE = 0; #ifdef SAMD21 while (DAC->STATUS.bit.SYNCBUSY == 1) { } @@ -335,6 +305,15 @@ void common_hal_audioio_audioout_deinit(audioio_audioout_obj_t *self) { } #endif + // Ramp the DAC down. + ramp_value(self->quiescent_value, 0); + + DAC->CTRLA.reg |= DAC_CTRLA_SWRST; + + // TODO(tannewt): Turn off the DAC clocks to save power. + + DAC->CTRLA.bit.ENABLE = 0; + disable_event_channel(self->tc_to_dac_event_channel); tc_set_enable(tc_insts[self->tc_index], false); diff --git a/ports/atmel-samd/common-hal/audioio/AudioOut.h b/ports/atmel-samd/common-hal/audioio/AudioOut.h index 956839969ff5f..207344c04e5e9 100644 --- a/ports/atmel-samd/common-hal/audioio/AudioOut.h +++ b/ports/atmel-samd/common-hal/audioio/AudioOut.h @@ -47,8 +47,6 @@ typedef struct { uint16_t quiescent_value; } audioio_audioout_obj_t; -void audioout_reset(void); - void audioout_background(void); #endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_AUDIOIO_AUDIOOUT_H diff --git a/ports/atmel-samd/supervisor/port.c b/ports/atmel-samd/supervisor/port.c index 6233fac53d695..42445030b28cd 100644 --- a/ports/atmel-samd/supervisor/port.c +++ b/ports/atmel-samd/supervisor/port.c @@ -386,7 +386,6 @@ void reset_port(void) { #if CIRCUITPY_AUDIOIO audio_dma_reset(); - audioout_reset(); #endif #if CIRCUITPY_AUDIOBUSIO diff --git a/ports/mimxrt10xx/supervisor/port.c b/ports/mimxrt10xx/supervisor/port.c index 628a2fdb842e9..7c7fec3a00135 100644 --- a/ports/mimxrt10xx/supervisor/port.c +++ b/ports/mimxrt10xx/supervisor/port.c @@ -453,8 +453,8 @@ void reset_port(void) { #if CIRCUITPY_AUDIOIO audio_dma_reset(); - audioout_reset(); #endif + #if CIRCUITPY_AUDIOBUSIO i2s_reset(); #endif diff --git a/shared-bindings/audioio/AudioOut.c b/shared-bindings/audioio/AudioOut.c index 4c7231c0ce1c8..a9676859c4ee2 100644 --- a/shared-bindings/audioio/AudioOut.c +++ b/shared-bindings/audioio/AudioOut.c @@ -110,7 +110,8 @@ STATIC mp_obj_t audioio_audioout_make_new(const mp_obj_type_t *type, size_t n_ar validate_obj_is_free_pin_or_none(args[ARG_right_channel].u_obj, MP_QSTR_right_channel); // create AudioOut object from the given pin - audioio_audioout_obj_t *self = mp_obj_malloc(audioio_audioout_obj_t, &audioio_audioout_type); + audioio_audioout_obj_t *self = m_new_obj_with_finaliser(audioio_audioout_obj_t); + self->base.type = &audioio_audioout_type; common_hal_audioio_audioout_construct(self, left_channel_pin, right_channel_pin, args[ARG_quiescent_value].u_int); return MP_OBJ_FROM_PTR(self); @@ -244,6 +245,7 @@ MP_PROPERTY_GETTER(audioio_audioout_paused_obj, STATIC const mp_rom_map_elem_t audioio_audioout_locals_dict_table[] = { // Methods + { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&audioio_audioout_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audioio_audioout_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&audioio_audioout___exit___obj) },