[Audio] Add support for audio shutdown pin (#22731)
Co-authored-by: Ryan <fauxpark@gmail.com>
This commit is contained in:
		
							parent
							
								
									045e5c9729
								
							
						
					
					
						commit
						83e6ddbbb4
					
				| @ -19,6 +19,8 @@ | ||||
|     // Audio | ||||
|     "AUDIO_DEFAULT_ON": {"info_key": "audio.default.on", "value_type": "bool"}, | ||||
|     "AUDIO_DEFAULT_CLICKY_ON": {"info_key": "audio.default.clicky", "value_type": "bool"}, | ||||
|     "AUDIO_POWER_CONTROL_PIN": {"info_key": "audio.power_control.pin"}, | ||||
|     "AUDIO_POWER_CONTROL_PIN_ON_STATE": {"info_key": "audio.power_control.on_state", "value_type": "int" }, | ||||
|     "AUDIO_VOICES": {"info_key": "audio.voices", "value_type": "flag"}, | ||||
|     "SENDSTRING_BELL": {"info_key": "audio.macro_beep", "value_type": "flag"}, | ||||
| 
 | ||||
|  | ||||
| @ -135,6 +135,14 @@ | ||||
|                 }, | ||||
|                 "macro_beep": {"type": "boolean"}, | ||||
|                 "pins": {"$ref": "qmk.definitions.v1#/mcu_pin_array"}, | ||||
|                 "power_control": { | ||||
|                     "type": "object", | ||||
|                     "additionalProperties": false, | ||||
|                     "properties": { | ||||
|                         "on_state": {"$ref": "qmk.definitions.v1#/bit"}, | ||||
|                         "pin": {"$ref": "qmk.definitions.v1#/mcu_pin"} | ||||
|                     } | ||||
|                 }, | ||||
|                 "voices": {"type": "boolean"} | ||||
|             } | ||||
|         }, | ||||
|  | ||||
| @ -172,12 +172,14 @@ The available keycodes for audio are: | ||||
| ## Audio Config | ||||
| 
 | ||||
| | Settings                         | Default              | Description                                                                                 | | ||||
| |---------------------------------|----------------------|-------------------------------------------------------------------------------| | ||||
| |----------------------------------|----------------------|---------------------------------------------------------------------------------------------| | ||||
| |`AUDIO_PIN`                       | *Not defined*        |Configures the pin that the speaker is connected to.                                         | | ||||
| |`AUDIO_PIN_ALT`                   | *Not defined*        |Configures the pin for a second speaker or second pin connected to one speaker.              | | ||||
| |`AUDIO_PIN_ALT_AS_NEGATIVE`       | *Not defined*        |Enables support for one speaker connected to two pins.                                       | | ||||
| |`AUDIO_INIT_DELAY`                | *Not defined*        |Enables delay during startup song to accomidate for USB startup issues.                      | | ||||
| |`AUDIO_ENABLE_TONE_MULTIPLEXING`  | *Not defined*        |Enables time splicing/multiplexing to create multiple tones simutaneously.                   | | ||||
| |`AUDIO_POWER_CONTROL_PIN`         | *Not defined*        |Enables power control code to enable or cut off power to speaker (such as with PAM8302 amp). | | ||||
| |`AUDIO_POWER_CONTROL_PIN_ON_STATE`| `1`                  |The state of the audio power control pin when audio is "on" - `1` for high, `0` for low.     | | ||||
| |`STARTUP_SONG`                    | `STARTUP_SOUND`      |Plays when the keyboard starts up (audio.c)                                                  | | ||||
| |`GOODBYE_SONG`                    | `GOODBYE_SOUND`      |Plays when you press the QK_BOOT key (quantum.c)                                             | | ||||
| |`AG_NORM_SONG`                    | `AG_NORM_SOUND`      |Plays when you press AG_NORM (process_magic.c)                                               | | ||||
| @ -192,7 +194,7 @@ The available keycodes for audio are: | ||||
| |`GUITAR_SONG`                     | `GUITAR_SOUND`       |Plays when the guitar music mode is selected (process_music.c)                               | | ||||
| |`VIOLIN_SONG`                     | `VIOLIN_SOUND`       |Plays when the violin music mode is selected (process_music.c)                               | | ||||
| |`MAJOR_SONG`                      | `MAJOR_SOUND`        |Plays when the major music mode is selected (process_music.c)                                | | ||||
| |`DEFAULT_LAYER_SONGS`            | *Not defined*        |Plays song when switched default layers with [`set_single_persistent_default_layer(layer)`](ref_functions.md#setting-the-persistent-default-layer)(quantum.c)       | | ||||
| |`DEFAULT_LAYER_SONGS`             | *Not defined*        |Plays song when switched default layers with [`set_single_persistent_default_layer(layer)`](ref_functions.md#setting-the-persistent-default-layer)(quantum.c). | | ||||
| |`SENDSTRING_BELL`                 | *Not defined*        |Plays chime when the "enter" ("\a") character is sent (send_string.c)                        | | ||||
| 
 | ||||
| ## Tempo | ||||
|  | ||||
| @ -123,10 +123,17 @@ Configures the [Audio](feature_audio.md) feature. | ||||
|         * Default: `false` | ||||
|     * `pins` (Required) | ||||
|         * The GPIO pin(s) connected to the speaker(s). | ||||
|     * `power_control` | ||||
|         * `on_state` | ||||
|             * The logical GPIO state required to turn the speaker on. | ||||
|             * Default: `1` (on = high) | ||||
|         * `pin` | ||||
|             * The GPIO pin connected to speaker power circuit. | ||||
|     * `voices` | ||||
|         * Use multiple audio voices. | ||||
|         * Default: `false` | ||||
| 
 | ||||
| 
 | ||||
| ## Backlight :id=backlight | ||||
| 
 | ||||
| Configures the [Backlight](feature_backlight.md) feature. | ||||
|  | ||||
| @ -48,5 +48,3 @@ | ||||
| #define AUDIO_PWM_CHANNEL RP2040_PWM_CHANNEL_A | ||||
| #define AUDIO_INIT_DELAY | ||||
| #define AUDIO_CLICKY | ||||
| 
 | ||||
| #define SPEAKER_SHUTDOWN GP14 | ||||
|  | ||||
| @ -8,6 +8,11 @@ | ||||
|         "pid": "0x0108", | ||||
|         "device_version": "0.0.1" | ||||
|     }, | ||||
|     "audio": { | ||||
|         "power_control": { | ||||
|             "pin": "GP14" | ||||
|         } | ||||
|     }, | ||||
|     "encoder": { | ||||
|         "rotary": [ | ||||
|             {"pin_a": "GP18", "pin_b": "GP17"} | ||||
|  | ||||
| @ -1,42 +0,0 @@ | ||||
| /* Copyright 2022 Jose Pablo Ramirez <jp.ramangulo@gmail.com>
 | ||||
|  * | ||||
|  * This program is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  */ | ||||
| 
 | ||||
| #include "quantum.h" | ||||
| 
 | ||||
| #ifdef AUDIO_ENABLE | ||||
| void keyboard_pre_init_kb(void) { | ||||
|     // ensure pin is set and enabled pre-audio init
 | ||||
|     setPinOutput(SPEAKER_SHUTDOWN); | ||||
|     writePinHigh(SPEAKER_SHUTDOWN); | ||||
|     keyboard_pre_init_user(); | ||||
| } | ||||
| 
 | ||||
| void keyboard_post_init_kb(void) { | ||||
|     // set pin based on active status
 | ||||
|     writePin(SPEAKER_SHUTDOWN, audio_is_on()); | ||||
|     keyboard_post_init_user(); | ||||
| } | ||||
| 
 | ||||
| void audio_on_user(void) { | ||||
|     writePinHigh(SPEAKER_SHUTDOWN); | ||||
| } | ||||
| 
 | ||||
| void audio_off_user(void) { | ||||
|     // needs a delay or it runs right after play note.
 | ||||
|     wait_ms(200); | ||||
|     writePinLow(SPEAKER_SHUTDOWN); | ||||
| } | ||||
| #endif | ||||
| @ -213,7 +213,7 @@ void channel_2_stop(void) { | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| void audio_driver_initialize(void) { | ||||
| void audio_driver_initialize_impl(void) { | ||||
| #ifdef AUDIO1_PIN_SET | ||||
|     channel_1_stop(); | ||||
|     gpio_set_pin_output(AUDIO1_PIN); | ||||
| @ -254,7 +254,7 @@ void audio_driver_initialize(void) { | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void audio_driver_stop(void) { | ||||
| void audio_driver_stop_impl(void) { | ||||
| #ifdef AUDIO1_PIN_SET | ||||
|     channel_1_stop(); | ||||
| #endif | ||||
| @ -264,7 +264,7 @@ void audio_driver_stop(void) { | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void audio_driver_start(void) { | ||||
| void audio_driver_start_impl(void) { | ||||
| #ifdef AUDIO1_PIN_SET | ||||
|     channel_1_start(); | ||||
|     if (playing_note) { | ||||
|  | ||||
| @ -303,7 +303,7 @@ static const DACConfig dac_conf = {.init = AUDIO_DAC_OFF_VALUE, .datamode = DAC_ | ||||
|  */ | ||||
| static const DACConversionGroup dac_conv_cfg = {.num_channels = 1U, .end_cb = dac_end, .error_cb = dac_error, .trigger = DAC_TRG(0b000)}; | ||||
| 
 | ||||
| void audio_driver_initialize(void) { | ||||
| void audio_driver_initialize_impl(void) { | ||||
|     if ((AUDIO_PIN == A4) || (AUDIO_PIN_ALT == A4)) { | ||||
|         palSetLineMode(A4, PAL_MODE_INPUT_ANALOG); | ||||
|         dacStart(&DACD1, &dac_conf); | ||||
| @ -350,11 +350,11 @@ void audio_driver_initialize(void) { | ||||
|     gptStart(&GPTD6, &gpt6cfg1); | ||||
| } | ||||
| 
 | ||||
| void audio_driver_stop(void) { | ||||
| void audio_driver_stop_impl(void) { | ||||
|     state = OUTPUT_SHOULD_STOP; | ||||
| } | ||||
| 
 | ||||
| void audio_driver_start(void) { | ||||
| void audio_driver_start_impl(void) { | ||||
|     gptStartContinuous(&GPTD6, 2U); | ||||
| 
 | ||||
|     for (uint8_t i = 0; i < AUDIO_MAX_SIMULTANEOUS_TONES; i++) { | ||||
|  | ||||
| @ -190,7 +190,7 @@ static void gpt_audio_state_cb(GPTDriver *gptp) { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void audio_driver_initialize(void) { | ||||
| void audio_driver_initialize_impl(void) { | ||||
|     if ((AUDIO_PIN == A4) || (AUDIO_PIN_ALT == A4)) { | ||||
|         palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG); | ||||
|         dacStart(&DACD1, &dac_conf_ch1); | ||||
| @ -223,7 +223,7 @@ void audio_driver_initialize(void) { | ||||
|     gptStart(&AUDIO_STATE_TIMER, &gptStateUpdateCfg); | ||||
| } | ||||
| 
 | ||||
| void audio_driver_stop(void) { | ||||
| void audio_driver_stop_impl(void) { | ||||
|     if ((AUDIO_PIN == A4) || (AUDIO_PIN_ALT == A4)) { | ||||
|         gptStopTimer(&GPTD6); | ||||
| 
 | ||||
| @ -241,7 +241,7 @@ void audio_driver_stop(void) { | ||||
|     gptStopTimer(&AUDIO_STATE_TIMER); | ||||
| } | ||||
| 
 | ||||
| void audio_driver_start(void) { | ||||
| void audio_driver_start_impl(void) { | ||||
|     if ((AUDIO_PIN == A4) || (AUDIO_PIN_ALT == A4)) { | ||||
|         dacStartConversion(&DACD1, &dac_conv_grp_ch1, (dacsample_t *)dac_buffer_1, AUDIO_DAC_BUFFER_SIZE); | ||||
|     } | ||||
|  | ||||
| @ -87,7 +87,7 @@ static void audio_callback(virtual_timer_t *vtp, void *p) { | ||||
|     chSysUnlockFromISR(); | ||||
| } | ||||
| 
 | ||||
| void audio_driver_initialize(void) { | ||||
| void audio_driver_initialize_impl(void) { | ||||
|     pwmStart(&AUDIO_PWM_DRIVER, &pwmCFG); | ||||
| 
 | ||||
|     // connect the AUDIO_PIN to the PWM hardware
 | ||||
| @ -100,7 +100,7 @@ void audio_driver_initialize(void) { | ||||
|     chVTObjectInit(&audio_vt); | ||||
| } | ||||
| 
 | ||||
| void audio_driver_start(void) { | ||||
| void audio_driver_start_impl(void) { | ||||
|     channel_1_stop(); | ||||
|     channel_1_start(); | ||||
| 
 | ||||
| @ -115,7 +115,7 @@ void audio_driver_start(void) { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void audio_driver_stop(void) { | ||||
| void audio_driver_stop_impl(void) { | ||||
|     channel_1_stop(); | ||||
|     chVTReset(&audio_vt); | ||||
| } | ||||
|  | ||||
| @ -121,7 +121,7 @@ GPTConfig   gptCFG = { | ||||
|     .callback  = gpt_callback, | ||||
| }; | ||||
| 
 | ||||
| void audio_driver_initialize(void) { | ||||
| void audio_driver_initialize_impl(void) { | ||||
|     pwmStart(&AUDIO_PWM_DRIVER, &pwmCFG); | ||||
| 
 | ||||
|     palSetLineMode(AUDIO_PIN, PAL_MODE_OUTPUT_PUSHPULL); | ||||
| @ -138,7 +138,7 @@ void audio_driver_initialize(void) { | ||||
|     gptStart(&AUDIO_STATE_TIMER, &gptCFG); | ||||
| } | ||||
| 
 | ||||
| void audio_driver_start(void) { | ||||
| void audio_driver_start_impl(void) { | ||||
|     channel_1_stop(); | ||||
|     channel_1_start(); | ||||
| 
 | ||||
| @ -147,7 +147,7 @@ void audio_driver_start(void) { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void audio_driver_stop(void) { | ||||
| void audio_driver_stop_impl(void) { | ||||
|     channel_1_stop(); | ||||
|     gptStopTimer(&AUDIO_STATE_TIMER); | ||||
| } | ||||
|  | ||||
| @ -15,6 +15,6 @@ | ||||
| 
 | ||||
| #include "audio.h" | ||||
| 
 | ||||
| void audio_driver_initialize(void) {} | ||||
| void audio_driver_start() {} | ||||
| void audio_driver_stop() {} | ||||
| void audio_driver_initialize_impl(void) {} | ||||
| void audio_driver_start_impl() {} | ||||
| void audio_driver_stop_impl() {} | ||||
|  | ||||
| @ -20,6 +20,7 @@ | ||||
| #include "debug.h" | ||||
| #include "wait.h" | ||||
| #include "util.h" | ||||
| #include "gpio.h" | ||||
| 
 | ||||
| /* audio system:
 | ||||
|  * | ||||
| @ -121,6 +122,32 @@ static bool    audio_initialized    = false; | ||||
| static bool    audio_driver_stopped = true; | ||||
| audio_config_t audio_config; | ||||
| 
 | ||||
| #ifndef AUDIO_POWER_CONTROL_PIN_ON_STATE | ||||
| #    define AUDIO_POWER_CONTROL_PIN_ON_STATE 1 | ||||
| #endif | ||||
| 
 | ||||
| void audio_driver_initialize(void) { | ||||
| #ifdef AUDIO_POWER_CONTROL_PIN | ||||
|     gpio_set_pin_output_push_pull(AUDIO_POWER_CONTROL_PIN); | ||||
|     gpio_write_pin(AUDIO_POWER_CONTROL_PIN, !AUDIO_POWER_CONTROL_PIN_ON_STATE); | ||||
| #endif | ||||
|     audio_driver_initialize_impl(); | ||||
| } | ||||
| 
 | ||||
| void audio_driver_stop(void) { | ||||
|     audio_driver_stop_impl(); | ||||
| #ifdef AUDIO_POWER_CONTROL_PIN | ||||
|     gpio_write_pin(AUDIO_POWER_CONTROL_PIN, !AUDIO_POWER_CONTROL_PIN_ON_STATE); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void audio_driver_start(void) { | ||||
| #ifdef AUDIO_POWER_CONTROL_PIN | ||||
|     gpio_write_pin(AUDIO_POWER_CONTROL_PIN, AUDIO_POWER_CONTROL_PIN_ON_STATE); | ||||
| #endif | ||||
|     audio_driver_start_impl(); | ||||
| } | ||||
| 
 | ||||
| void eeconfig_update_audio_current(void) { | ||||
|     eeconfig_update_audio(audio_config.raw); | ||||
| } | ||||
|  | ||||
| @ -215,9 +215,9 @@ void audio_startup(void); | ||||
| // hardware interface
 | ||||
| 
 | ||||
| // implementation in the driver_avr/arm_* respective parts
 | ||||
| void audio_driver_initialize(void); | ||||
| void audio_driver_start(void); | ||||
| void audio_driver_stop(void); | ||||
| void audio_driver_initialize_impl(void); | ||||
| void audio_driver_start_impl(void); | ||||
| void audio_driver_stop_impl(void); | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief get the number of currently active tones | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user