diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index bc00cd19e..dccf03d5f 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -83,6 +83,7 @@ void increase_tempo(uint8_t tempo_change); void decrease_tempo(uint8_t tempo_change); void audio_init(void); +void audio_startup(void); #ifdef PWM_AUDIO void play_sample(uint8_t* s, uint16_t l, bool r); diff --git a/quantum/audio/audio_avr.c b/quantum/audio/audio_avr.c index 5a96bf643..1bac43bb4 100644 --- a/quantum/audio/audio_avr.c +++ b/quantum/audio/audio_avr.c @@ -227,7 +227,9 @@ void audio_init() { audio_initialized = true; } +} +void audio_startup() { if (audio_config.enable) { PLAY_SONG(startup_song); } diff --git a/quantum/audio/audio_chibios.c b/quantum/audio/audio_chibios.c index 1863ae140..dddb8f135 100644 --- a/quantum/audio/audio_chibios.c +++ b/quantum/audio/audio_chibios.c @@ -281,6 +281,12 @@ void audio_init() { dacStart(&DACD1, &dac1cfg1); dacStart(&DACD2, &dac1cfg2); + /* + * Start the note timer + */ + gptStart(&GPTD8, &gpt8cfg1); + gptStartContinuous(&GPTD8, 2U); + /* * Starting GPT6/7 driver, it is used for triggering the DAC. */ @@ -295,10 +301,12 @@ void audio_init() { audio_initialized = true; + stop_all_notes(); +} + +void audio_startup() { if (audio_config.enable) { PLAY_SONG(startup_song); - } else { - stop_all_notes(); } } @@ -638,6 +646,9 @@ bool is_playing_notes(void) { return playing_notes; } bool is_audio_on(void) { return (audio_config.enable != 0); } void audio_toggle(void) { + if (audio_config.enable) { + stop_all_notes(); + } audio_config.enable ^= 1; eeconfig_update_audio(audio_config.raw); if (audio_config.enable) { diff --git a/quantum/audio/audio_pwm.c b/quantum/audio/audio_pwm.c index 545aef6dd..d93ac4bb4 100644 --- a/quantum/audio/audio_pwm.c +++ b/quantum/audio/audio_pwm.c @@ -29,6 +29,11 @@ #define CPU_PRESCALER 8 +#ifndef STARTUP_SONG +# define STARTUP_SONG SONG(STARTUP_SOUND) +#endif +float startup_song[][2] = STARTUP_SONG; + // Timer Abstractions // TIMSK3 - Timer/Counter #3 Interrupt Mask Register @@ -155,6 +160,12 @@ void audio_init() { audio_initialized = true; } +void audio_startup() { + if (audio_config.enable) { + PLAY_SONG(startup_song); + } +} + void stop_all_notes() { if (!audio_initialized) { audio_init(); diff --git a/quantum/quantum.c b/quantum/quantum.c index 22aa52838..5e0cde8a2 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -656,6 +656,26 @@ void matrix_init_quantum() { } void matrix_scan_quantum() { +#if defined(AUDIO_ENABLE) + // There are some tasks that need to be run a little bit + // after keyboard startup, or else they will not work correctly + // because of interaction with the USB device state, which + // may still be in flux... + // + // At the moment the only feature that needs this is the + // startup song. + static bool delayed_tasks_run = false; + static uint16_t delayed_task_timer = 0; + if (!delayed_tasks_run) { + if (!delayed_task_timer) { + delayed_task_timer = timer_read(); + } else if (timer_elapsed(delayed_task_timer) > 300) { + audio_startup(); + delayed_tasks_run = true; + } + } +#endif + #if defined(AUDIO_ENABLE) && !defined(NO_MUSIC_MODE) matrix_scan_music(); #endif diff --git a/tmk_core/common/avr/suspend.c b/tmk_core/common/avr/suspend.c index 86c3df040..9db0e0064 100644 --- a/tmk_core/common/avr/suspend.c +++ b/tmk_core/common/avr/suspend.c @@ -97,8 +97,7 @@ static void power_down(uint8_t wdto) { led_set(leds_off); # ifdef AUDIO_ENABLE - // This sometimes disables the start-up noise, so it's been disabled - // stop_all_notes(); + stop_all_notes(); # endif /* AUDIO_ENABLE */ # if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) rgblight_suspend(); @@ -157,6 +156,7 @@ __attribute__((weak)) void suspend_wakeup_init_user(void) {} * FIXME: needs doc */ __attribute__((weak)) void suspend_wakeup_init_kb(void) { suspend_wakeup_init_user(); } + /** \brief run immediately after wakeup * * FIXME: needs doc diff --git a/tmk_core/common/chibios/suspend.c b/tmk_core/common/chibios/suspend.c index 796056019..49e20641f 100644 --- a/tmk_core/common/chibios/suspend.c +++ b/tmk_core/common/chibios/suspend.c @@ -12,6 +12,10 @@ #include "led.h" #include "wait.h" +#ifdef AUDIO_ENABLE +# include "audio.h" +#endif /* AUDIO_ENABLE */ + #ifdef BACKLIGHT_ENABLE # include "backlight.h" #endif @@ -65,6 +69,9 @@ void suspend_power_down(void) { #if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) rgblight_suspend(); #endif +#ifdef AUDIO_ENABLE + stop_all_notes(); +#endif /* AUDIO_ENABLE */ suspend_power_down_kb(); // on AVR, this enables the watchdog for 15ms (max), and goes to