M data/mappings/info_config.hjson => data/mappings/info_config.hjson +2 -0
@@ 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"},
M data/schemas/keyboard.jsonschema => data/schemas/keyboard.jsonschema +8 -0
@@ 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"}
}
},
M docs/feature_audio.md => docs/feature_audio.md +25 -23
@@ 171,29 171,31 @@ 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. |
-|`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) |
-|`AG_SWAP_SONG` | `AG_SWAP_SOUND` |Plays when you press AG_SWAP (process_magic.c) |
-|`CG_NORM_SONG` | `AG_NORM_SOUND` |Plays when you press CG_NORM (process_magic.c) |
-|`CG_SWAP_SONG` | `AG_SWAP_SOUND` |Plays when you press CG_SWAP (process_magic.c) |
-|`MUSIC_ON_SONG` | `MUSIC_ON_SOUND` |Plays when music mode is activated (process_music.c) |
-|`MUSIC_OFF_SONG` | `MUSIC_OFF_SOUND` |Plays when music mode is deactivated (process_music.c) |
-|`MIDI_ON_SONG` | `MUSIC_ON_SOUND` |Plays when midi mode is activated (process_music.c) |
-|`MIDI_OFF_SONG` | `MUSIC_OFF_SOUND` |Plays when midi mode is deactivated (process_music.c) |
-|`CHROMATIC_SONG` | `CHROMATIC_SOUND` |Plays when the chromatic music mode is selected (process_music.c) |
-|`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) |
-|`SENDSTRING_BELL` | *Not defined* |Plays chime when the "enter" ("\a") character is sent (send_string.c) |
+| 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) |
+|`AG_SWAP_SONG` | `AG_SWAP_SOUND` |Plays when you press AG_SWAP (process_magic.c) |
+|`CG_NORM_SONG` | `AG_NORM_SOUND` |Plays when you press CG_NORM (process_magic.c) |
+|`CG_SWAP_SONG` | `AG_SWAP_SOUND` |Plays when you press CG_SWAP (process_magic.c) |
+|`MUSIC_ON_SONG` | `MUSIC_ON_SOUND` |Plays when music mode is activated (process_music.c) |
+|`MUSIC_OFF_SONG` | `MUSIC_OFF_SOUND` |Plays when music mode is deactivated (process_music.c) |
+|`MIDI_ON_SONG` | `MUSIC_ON_SOUND` |Plays when midi mode is activated (process_music.c) |
+|`MIDI_OFF_SONG` | `MUSIC_OFF_SOUND` |Plays when midi mode is deactivated (process_music.c) |
+|`CHROMATIC_SONG` | `CHROMATIC_SOUND` |Plays when the chromatic music mode is selected (process_music.c) |
+|`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). |
+|`SENDSTRING_BELL` | *Not defined* |Plays chime when the "enter" ("\a") character is sent (send_string.c) |
## Tempo
the 'speed' at which SONGs are played is dictated by the set Tempo, which is measured in beats-per-minute. Note lengths are defined relative to that.
M docs/reference_info_json.md => docs/reference_info_json.md +7 -0
@@ 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.
M keyboards/adafruit/macropad/config.h => keyboards/adafruit/macropad/config.h +0 -2
@@ 48,5 48,3 @@
#define AUDIO_PWM_CHANNEL RP2040_PWM_CHANNEL_A
#define AUDIO_INIT_DELAY
#define AUDIO_CLICKY
-
-#define SPEAKER_SHUTDOWN GP14
M keyboards/adafruit/macropad/info.json => keyboards/adafruit/macropad/info.json +5 -0
@@ 8,6 8,11 @@
"pid": "0x0108",
"device_version": "0.0.1"
},
+ "audio": {
+ "power_control": {
+ "pin": "GP14"
+ }
+ },
"encoder": {
"rotary": [
{"pin_a": "GP18", "pin_b": "GP17"}
D keyboards/adafruit/macropad/macropad.c => keyboards/adafruit/macropad/macropad.c +0 -42
@@ 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
M platforms/avr/drivers/audio_pwm_hardware.c => platforms/avr/drivers/audio_pwm_hardware.c +3 -3
@@ 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) {
M platforms/chibios/drivers/audio_dac_additive.c => platforms/chibios/drivers/audio_dac_additive.c +3 -3
@@ 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++) {
M platforms/chibios/drivers/audio_dac_basic.c => platforms/chibios/drivers/audio_dac_basic.c +3 -3
@@ 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);
}
M platforms/chibios/drivers/audio_pwm_hardware.c => platforms/chibios/drivers/audio_pwm_hardware.c +3 -3
@@ 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);
}
M platforms/chibios/drivers/audio_pwm_software.c => platforms/chibios/drivers/audio_pwm_software.c +3 -3
@@ 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);
}
M platforms/test/drivers/audio_pwm_hardware.c => platforms/test/drivers/audio_pwm_hardware.c +3 -3
@@ 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() {}
M quantum/audio/audio.c => quantum/audio/audio.c +27 -0
@@ 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);
}
M quantum/audio/audio.h => quantum/audio/audio.h +3 -3
@@ 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