From fd99f400b42857b1094811cea76bd3fb841a8286 Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 7 Nov 2022 17:03:04 +1100 Subject: [PATCH] codal_port/microbit_pinmode: Make audio and speech use "audio" pin mode. This distinguishes "music" and "audio" as separate modes as returned by pin.get_mode(), making v2 more compatible with micro:bit v1. Fixes issue #137. Signed-off-by: Damien George --- src/codal_port/microbit_pinaudio.c | 7 +++++-- src/codal_port/microbit_pinmode.c | 14 +++++++------- src/codal_port/modaudio.c | 2 +- src/codal_port/modmicrobit.h | 6 +++++- src/codal_port/modmusic.c | 6 +++--- src/codal_port/modspeech.c | 2 +- 6 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/codal_port/microbit_pinaudio.c b/src/codal_port/microbit_pinaudio.c index 174c1f9..69f67d9 100644 --- a/src/codal_port/microbit_pinaudio.c +++ b/src/codal_port/microbit_pinaudio.c @@ -30,7 +30,7 @@ // The currently selected pin output for the audio. STATIC const microbit_pin_obj_t *audio_routed_pin = NULL; -void microbit_pin_audio_select(mp_const_obj_t select) { +void microbit_pin_audio_select(mp_const_obj_t select, const microbit_pinmode_t *pinmode) { // Work out which pins are requested for the audio output. const microbit_pin_obj_t *pin_selected; if (select == mp_const_none) { @@ -50,9 +50,12 @@ void microbit_pin_audio_select(mp_const_obj_t select) { if (audio_routed_pin == NULL) { microbit_hal_audio_select_pin(-1); } else { - microbit_obj_pin_acquire(audio_routed_pin, microbit_pin_mode_music); + microbit_obj_pin_acquire(audio_routed_pin, pinmode); microbit_hal_audio_select_pin(audio_routed_pin->name); } + } else if (audio_routed_pin != NULL) { + // Update the pin acquisition mode, to make sure pin.get_mode() reflects the current mode. + microbit_pin_set_mode(audio_routed_pin, pinmode); } } diff --git a/src/codal_port/microbit_pinmode.c b/src/codal_port/microbit_pinmode.c index 8f528fa..ceb5a8f 100644 --- a/src/codal_port/microbit_pinmode.c +++ b/src/codal_port/microbit_pinmode.c @@ -39,15 +39,15 @@ const microbit_pinmode_t *microbit_pin_get_mode(const microbit_pin_obj_t *pin) { return µbit_pinmodes[pinmode]; } -static void set_mode(uint32_t pin, const microbit_pinmode_t *mode) { +void microbit_pin_set_mode(const microbit_pin_obj_t *pin, const microbit_pinmode_t *mode) { uint32_t index = mode - µbit_pinmodes[0]; - microbit_pinmode_indices[pin] = index; + microbit_pinmode_indices[pin->number] = index; return; } void microbit_obj_pin_free(const microbit_pin_obj_t *pin) { if (pin != NULL) { - set_mode(pin->number, microbit_pin_mode_unused); + microbit_pin_set_mode(pin, microbit_pin_mode_unused); } } @@ -66,7 +66,7 @@ bool microbit_obj_pin_acquire(const microbit_pin_obj_t *pin, const microbit_pinm if (current_mode != new_mode) { current_mode->release(pin); - set_mode(pin->number, new_mode); + microbit_pin_set_mode(pin, new_mode); return true; } else { return false; @@ -86,7 +86,7 @@ static void analog_release(const microbit_pin_obj_t *pin) { // TODO: pwm_release() } -static void music_release(const microbit_pin_obj_t *pin) { +static void audio_music_release(const microbit_pin_obj_t *pin) { if (microbit_audio_is_playing() || microbit_music_is_playing()) { pinmode_error(pin); } else { @@ -101,8 +101,8 @@ const microbit_pinmode_t microbit_pinmodes[] = { [MODE_WRITE_DIGITAL] = { MP_QSTR_write_digital, noop }, [MODE_DISPLAY] = { MP_QSTR_display, pinmode_error }, [MODE_BUTTON] = { MP_QSTR_button, pinmode_error }, - [MODE_MUSIC] = { MP_QSTR_music, music_release }, - [MODE_AUDIO_PLAY] = { MP_QSTR_audio, noop }, + [MODE_MUSIC] = { MP_QSTR_music, audio_music_release }, + [MODE_AUDIO_PLAY] = { MP_QSTR_audio, audio_music_release }, [MODE_TOUCH] = { MP_QSTR_touch, noop }, [MODE_I2C] = { MP_QSTR_i2c, pinmode_error }, [MODE_SPI] = { MP_QSTR_spi, pinmode_error } diff --git a/src/codal_port/modaudio.c b/src/codal_port/modaudio.c index 2ed5f1b..6a4b6c4 100644 --- a/src/codal_port/modaudio.c +++ b/src/codal_port/modaudio.c @@ -140,7 +140,7 @@ void microbit_audio_play_source(mp_obj_t src, mp_obj_t pin_select, bool wait, ui microbit_audio_stop(); } audio_init(sample_rate); - microbit_pin_audio_select(pin_select); + microbit_pin_audio_select(pin_select, microbit_pin_mode_audio_play); const char *sound_expr_data = NULL; if (mp_obj_is_type(src, µbit_sound_type)) { diff --git a/src/codal_port/modmicrobit.h b/src/codal_port/modmicrobit.h index d3d6d8a..455cae6 100644 --- a/src/codal_port/modmicrobit.h +++ b/src/codal_port/modmicrobit.h @@ -220,11 +220,15 @@ bool microbit_obj_pin_can_be_acquired(const microbit_pin_obj_t *pin); // Not safe to call in an interrupt as it may raise if pin can't be acquired. bool microbit_obj_pin_acquire(const microbit_pin_obj_t *pin, const microbit_pinmode_t *mode); +// Change the mode of a pin. This does not check the existing mode, nor release any +// resources, and should only be used if pin resources are managed by the caller. +void microbit_pin_set_mode(const microbit_pin_obj_t *pin, const microbit_pinmode_t *mode); + const microbit_pinmode_t *microbit_pin_get_mode(const microbit_pin_obj_t *pin); void pinmode_error(const microbit_pin_obj_t *pin); void microbit_pin_audio_speaker_enable(bool enable); -void microbit_pin_audio_select(mp_const_obj_t select); +void microbit_pin_audio_select(mp_const_obj_t select, const microbit_pinmode_t *pinmode); void microbit_pin_audio_free(void); MP_DECLARE_CONST_FUN_OBJ_0(microbit_reset_obj); diff --git a/src/codal_port/modmusic.c b/src/codal_port/modmusic.c index 52f7e8d..d0bbdc8 100644 --- a/src/codal_port/modmusic.c +++ b/src/codal_port/modmusic.c @@ -284,7 +284,7 @@ STATIC mp_obj_t microbit_music_stop(mp_uint_t n_args, const mp_obj_t *args) { pin = args[0]; } // Raise exception if the pin we are trying to stop is not in a compatible mode. - microbit_pin_audio_select(pin); + microbit_pin_audio_select(pin, microbit_pin_mode_music); // Stop any ongoing background music music_data->async_state = ASYNC_MUSIC_STATE_IDLE; @@ -326,7 +326,7 @@ STATIC mp_obj_t microbit_music_play(mp_uint_t n_args, const mp_obj_t *pos_args, music_data->async_state = ASYNC_MUSIC_STATE_IDLE; // get the pin to play on - microbit_pin_audio_select(args[1].u_obj); + microbit_pin_audio_select(args[1].u_obj, microbit_pin_mode_music); // start the tune running in the background music_data->async_wait_ticks = mp_hal_ticks_ms(); @@ -372,7 +372,7 @@ STATIC mp_obj_t microbit_music_pitch(mp_uint_t n_args, const mp_obj_t *pos_args, music_data->async_state = ASYNC_MUSIC_STATE_IDLE; // Update pin modes - microbit_pin_audio_select(args[2].u_obj); + microbit_pin_audio_select(args[2].u_obj, microbit_pin_mode_music); bool wait = args[3].u_bool; music_output_amplitude(MUSIC_OUTPUT_AMPLITUDE_ON); diff --git a/src/codal_port/modspeech.c b/src/codal_port/modspeech.c index b279b8b..4c4bcb2 100644 --- a/src/codal_port/modspeech.c +++ b/src/codal_port/modspeech.c @@ -421,7 +421,7 @@ STATIC mp_obj_t articulate(mp_obj_t phonemes, mp_uint_t n_args, const mp_obj_t * #if USE_DEDICATED_AUDIO_CHANNEL sam_output_reset(NULL); - microbit_pin_audio_select(args[7].u_obj); + microbit_pin_audio_select(args[7].u_obj, microbit_pin_mode_audio_play); microbit_hal_audio_speech_init(sample_rate); #else speech_iterator_t *src = make_speech_iter();