summaryrefslogtreecommitdiff
path: root/quantum
diff options
context:
space:
mode:
Diffstat (limited to 'quantum')
-rw-r--r--quantum/action.c5
-rw-r--r--quantum/audio/driver_chibios_pwm_hardware.c4
-rw-r--r--quantum/backlight/backlight_chibios.c10
-rw-r--r--quantum/eeconfig.c11
-rw-r--r--quantum/keyboard.c13
-rw-r--r--quantum/matrix.c28
-rw-r--r--quantum/mcu_selection.mk32
-rw-r--r--quantum/process_keycode/process_programmable_button.c31
-rw-r--r--quantum/process_keycode/process_programmable_button.h23
-rw-r--r--quantum/process_keycode/process_unicode_common.c47
-rw-r--r--quantum/programmable_button.c37
-rw-r--r--quantum/programmable_button.h30
-rw-r--r--quantum/quantum.c99
-rw-r--r--quantum/quantum.h4
-rw-r--r--quantum/quantum_keycodes.h70
15 files changed, 396 insertions, 48 deletions
diff --git a/quantum/action.c b/quantum/action.c
index be135f18f2..95f39d23d4 100644
--- a/quantum/action.c
+++ b/quantum/action.c
@@ -18,6 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "keycode.h"
#include "keyboard.h"
#include "mousekey.h"
+#include "programmable_button.h"
#include "command.h"
#include "led.h"
#include "action_layer.h"
@@ -988,6 +989,10 @@ void clear_keyboard_but_mods_and_keys() {
mousekey_clear();
mousekey_send();
#endif
+#ifdef PROGRAMMABLE_BUTTON_ENABLE
+ programmable_button_clear();
+ programmable_button_send();
+#endif
}
/** \brief Utilities for actions. (FIXME: Needs better description)
diff --git a/quantum/audio/driver_chibios_pwm_hardware.c b/quantum/audio/driver_chibios_pwm_hardware.c
index 3c7d89b290..cd40019ee7 100644
--- a/quantum/audio/driver_chibios_pwm_hardware.c
+++ b/quantum/audio/driver_chibios_pwm_hardware.c
@@ -109,9 +109,9 @@ void audio_driver_initialize(void) {
// connect the AUDIO_PIN to the PWM hardware
#if defined(USE_GPIOV1) // STM32F103C8
- palSetLineMode(AUDIO_PIN, PAL_MODE_STM32_ALTERNATE_PUSHPULL);
+ palSetLineMode(AUDIO_PIN, PAL_MODE_ALTERNATE_PUSHPULL);
#else // GPIOv2 (or GPIOv3 for f4xx, which is the same/compatible at this command)
- palSetLineMode(AUDIO_PIN, PAL_STM32_MODE_ALTERNATE | PAL_STM32_ALTERNATE(AUDIO_PWM_PAL_MODE));
+ palSetLineMode(AUDIO_PIN, PAL_MODE_ALTERNATE(AUDIO_PWM_PAL_MODE));
#endif
gptStart(&AUDIO_STATE_TIMER, &gptCFG);
diff --git a/quantum/backlight/backlight_chibios.c b/quantum/backlight/backlight_chibios.c
index 4d5a69e14e..7c6edd10d6 100644
--- a/quantum/backlight/backlight_chibios.c
+++ b/quantum/backlight/backlight_chibios.c
@@ -8,9 +8,13 @@
# define BACKLIGHT_LIMIT_VAL 255
#endif
-// GPIOV2 && GPIOV3
#ifndef BACKLIGHT_PAL_MODE
-# define BACKLIGHT_PAL_MODE 2
+# if defined(USE_GPIOV1)
+# define BACKLIGHT_PAL_MODE PAL_MODE_ALTERNATE_PUSHPULL
+# else
+// GPIOV2 && GPIOV3
+# define BACKLIGHT_PAL_MODE 5
+# endif
#endif
// GENERIC
@@ -70,7 +74,7 @@ static uint32_t rescale_limit_val(uint32_t val) {
void backlight_init_ports(void) {
#ifdef USE_GPIOV1
- palSetPadMode(PAL_PORT(BACKLIGHT_PIN), PAL_PAD(BACKLIGHT_PIN), PAL_MODE_STM32_ALTERNATE_PUSHPULL);
+ palSetPadMode(PAL_PORT(BACKLIGHT_PIN), PAL_PAD(BACKLIGHT_PIN), BACKLIGHT_PAL_MODE);
#else
palSetPadMode(PAL_PORT(BACKLIGHT_PIN), PAL_PAD(BACKLIGHT_PIN), PAL_MODE_ALTERNATE(BACKLIGHT_PAL_MODE));
#endif
diff --git a/quantum/eeconfig.c b/quantum/eeconfig.c
index 92f0ac4439..4c2ad2490c 100644
--- a/quantum/eeconfig.c
+++ b/quantum/eeconfig.c
@@ -4,11 +4,6 @@
#include "eeconfig.h"
#include "action_layer.h"
-#ifdef STM32_EEPROM_ENABLE
-# include <hal.h>
-# include "eeprom_stm32.h"
-#endif
-
#if defined(EEPROM_DRIVER)
# include "eeprom_driver.h"
#endif
@@ -43,9 +38,6 @@ __attribute__((weak)) void eeconfig_init_kb(void) {
* FIXME: needs doc
*/
void eeconfig_init_quantum(void) {
-#ifdef STM32_EEPROM_ENABLE
- EEPROM_Erase();
-#endif
#if defined(EEPROM_DRIVER)
eeprom_driver_erase();
#endif
@@ -111,9 +103,6 @@ void eeconfig_enable(void) { eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_N
* FIXME: needs doc
*/
void eeconfig_disable(void) {
-#ifdef STM32_EEPROM_ENABLE
- EEPROM_Erase();
-#endif
#if defined(EEPROM_DRIVER)
eeprom_driver_erase();
#endif
diff --git a/quantum/keyboard.c b/quantum/keyboard.c
index b98fc64e45..6054faa03b 100644
--- a/quantum/keyboard.c
+++ b/quantum/keyboard.c
@@ -76,6 +76,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifdef JOYSTICK_ENABLE
# include "process_joystick.h"
#endif
+#ifdef PROGRAMMABLE_BUTTON_ENABLE
+# include "programmable_button.h"
+#endif
#ifdef HD44780_ENABLE
# include "hd44780.h"
#endif
@@ -97,9 +100,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifdef DIP_SWITCH_ENABLE
# include "dip_switch.h"
#endif
-#ifdef STM32_EEPROM_ENABLE
-# include "eeprom_stm32.h"
-#endif
#ifdef EEPROM_DRIVER
# include "eeprom_driver.h"
#endif
@@ -246,9 +246,6 @@ void keyboard_setup(void) {
disable_jtag();
#endif
print_set_sendchar(sendchar);
-#ifdef STM32_EEPROM_ENABLE
- EEPROM_Init();
-#endif
#ifdef EEPROM_DRIVER
eeprom_driver_init();
#endif
@@ -548,6 +545,10 @@ MATRIX_LOOP_END:
digitizer_task();
#endif
+#ifdef PROGRAMMABLE_BUTTON_ENABLE
+ programmable_button_send();
+#endif
+
// update LED
if (led_status != host_keyboard_leds()) {
led_status = host_keyboard_leds();
diff --git a/quantum/matrix.c b/quantum/matrix.c
index 33586c431b..4fbcc2419c 100644
--- a/quantum/matrix.c
+++ b/quantum/matrix.c
@@ -288,10 +288,8 @@ void matrix_init(void) {
matrix_init_pins();
// initialize matrix state: all keys off
- for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
- raw_matrix[i] = 0;
- matrix[i] = 0;
- }
+ memset(matrix, 0, sizeof(matrix));
+ memset(raw_matrix, 0, sizeof(raw_matrix));
debounce_init(ROWS_PER_HAND);
@@ -312,24 +310,22 @@ __attribute__((weak)) bool transport_master_if_connected(matrix_row_t master_mat
bool matrix_post_scan(void) {
bool changed = false;
if (is_keyboard_master()) {
+ static bool last_connected = false;
matrix_row_t slave_matrix[ROWS_PER_HAND] = {0};
if (transport_master_if_connected(matrix + thisHand, slave_matrix)) {
- for (int i = 0; i < ROWS_PER_HAND; ++i) {
- if (matrix[thatHand + i] != slave_matrix[i]) {
- matrix[thatHand + i] = slave_matrix[i];
- changed = true;
- }
- }
- } else {
- // reset other half if disconnected
- for (int i = 0; i < ROWS_PER_HAND; ++i) {
- matrix[thatHand + i] = 0;
- slave_matrix[i] = 0;
- }
+ changed = memcmp(matrix + thatHand, slave_matrix, sizeof(slave_matrix)) != 0;
+ last_connected = true;
+ } else if (last_connected) {
+ // reset other half when disconnected
+ memset(slave_matrix, 0, sizeof(slave_matrix));
changed = true;
+
+ last_connected = false;
}
+ if (changed) memcpy(matrix + thatHand, slave_matrix, sizeof(slave_matrix));
+
matrix_scan_quantum();
} else {
transport_slave(matrix + thatHand, matrix + thisHand);
diff --git a/quantum/mcu_selection.mk b/quantum/mcu_selection.mk
index f7eaeec8ac..48c53e4da6 100644
--- a/quantum/mcu_selection.mk
+++ b/quantum/mcu_selection.mk
@@ -273,6 +273,38 @@ ifneq ($(findstring STM32F401, $(MCU)),)
UF2_FAMILY ?= STM32F4
endif
+ifneq ($(findstring STM32F405, $(MCU)),)
+ # Cortex version
+ MCU = cortex-m4
+
+ # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7
+ ARMV = 7
+
+ ## chip/board settings
+ # - the next two should match the directories in
+ # <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES)
+ MCU_FAMILY = STM32
+ MCU_SERIES = STM32F4xx
+
+ # Linker script to use
+ # - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
+ # or <keyboard_dir>/ld/
+ MCU_LDSCRIPT ?= STM32F405xG
+
+ # Startup code to use
+ # - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/
+ MCU_STARTUP ?= stm32f4xx
+
+ # Board: it should exist either in <chibios>/os/hal/boards/,
+ # <keyboard_dir>/boards/, or drivers/boards/
+ BOARD ?= GENERIC_STM32_F405XG
+
+ USE_FPU ?= yes
+
+ # UF2 settings
+ UF2_FAMILY ?= STM32F4
+endif
+
ifneq ($(findstring STM32F407, $(MCU)),)
# Cortex version
MCU = cortex-m4
diff --git a/quantum/process_keycode/process_programmable_button.c b/quantum/process_keycode/process_programmable_button.c
new file mode 100644
index 0000000000..c6e77faacc
--- /dev/null
+++ b/quantum/process_keycode/process_programmable_button.c
@@ -0,0 +1,31 @@
+/*
+Copyright 2021 Thomas Weißschuh <thomas@t-8ch.de>
+
+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 "process_programmable_button.h"
+#include "programmable_button.h"
+
+bool process_programmable_button(uint16_t keycode, keyrecord_t *record) {
+ if (keycode >= PROGRAMMABLE_BUTTON_MIN && keycode <= PROGRAMMABLE_BUTTON_MAX) {
+ uint8_t button = keycode - PROGRAMMABLE_BUTTON_MIN + 1;
+ if (record->event.pressed) {
+ programmable_button_on(button);
+ } else {
+ programmable_button_off(button);
+ }
+ }
+ return true;
+}
diff --git a/quantum/process_keycode/process_programmable_button.h b/quantum/process_keycode/process_programmable_button.h
new file mode 100644
index 0000000000..47c6ce5614
--- /dev/null
+++ b/quantum/process_keycode/process_programmable_button.h
@@ -0,0 +1,23 @@
+/*
+Copyright 2021 Thomas Weißschuh <thomas@t-8ch.de>
+
+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/>.
+*/
+
+#pragma once
+
+#include <stdint.h>
+#include "quantum.h"
+
+bool process_programmable_button(uint16_t keycode, keyrecord_t *record);
diff --git a/quantum/process_keycode/process_unicode_common.c b/quantum/process_keycode/process_unicode_common.c
index 46fcaaa86b..7853c22c5d 100644
--- a/quantum/process_keycode/process_unicode_common.c
+++ b/quantum/process_keycode/process_unicode_common.c
@@ -22,6 +22,7 @@
unicode_config_t unicode_config;
uint8_t unicode_saved_mods;
bool unicode_saved_caps_lock;
+bool unicode_saved_num_lock;
#if UNICODE_SELECTED_MODES != -1
static uint8_t selected[] = {UNICODE_SELECTED_MODES};
@@ -79,13 +80,14 @@ void persist_unicode_input_mode(void) { eeprom_update_byte(EECONFIG_UNICODEMODE,
__attribute__((weak)) void unicode_input_start(void) {
unicode_saved_caps_lock = host_keyboard_led_state().caps_lock;
+ unicode_saved_num_lock = host_keyboard_led_state().num_lock;
// Note the order matters here!
// Need to do this before we mess around with the mods, or else
// UNICODE_KEY_LNX (which is usually Ctrl-Shift-U) might not work
// correctly in the shifted case.
if (unicode_config.input_mode == UC_LNX && unicode_saved_caps_lock) {
- tap_code(KC_CAPS);
+ tap_code(KC_CAPSLOCK);
}
unicode_saved_mods = get_mods(); // Save current mods
@@ -99,8 +101,12 @@ __attribute__((weak)) void unicode_input_start(void) {
tap_code16(UNICODE_KEY_LNX);
break;
case UC_WIN:
+ // For increased reliability, use numpad keys for inputting digits
+ if (!unicode_saved_num_lock) {
+ tap_code(KC_NUMLOCK);
+ }
register_code(KC_LALT);
- tap_code(KC_PPLS);
+ tap_code(KC_KP_PLUS);
break;
case UC_WINC:
tap_code(UNICODE_KEY_WINC);
@@ -117,13 +123,16 @@ __attribute__((weak)) void unicode_input_finish(void) {
unregister_code(UNICODE_KEY_MAC);
break;
case UC_LNX:
- tap_code(KC_SPC);
+ tap_code(KC_SPACE);
if (unicode_saved_caps_lock) {
- tap_code(KC_CAPS);
+ tap_code(KC_CAPSLOCK);
}
break;
case UC_WIN:
unregister_code(KC_LALT);
+ if (!unicode_saved_num_lock) {
+ tap_code(KC_NUMLOCK);
+ }
break;
case UC_WINC:
tap_code(KC_ENTER);
@@ -139,26 +148,44 @@ __attribute__((weak)) void unicode_input_cancel(void) {
unregister_code(UNICODE_KEY_MAC);
break;
case UC_LNX:
- tap_code(KC_ESC);
+ tap_code(KC_ESCAPE);
if (unicode_saved_caps_lock) {
- tap_code(KC_CAPS);
+ tap_code(KC_CAPSLOCK);
}
break;
case UC_WINC:
- tap_code(KC_ESC);
+ tap_code(KC_ESCAPE);
break;
case UC_WIN:
unregister_code(KC_LALT);
+ if (!unicode_saved_num_lock) {
+ tap_code(KC_NUMLOCK);
+ }
break;
}
set_mods(unicode_saved_mods); // Reregister previously set mods
}
+// clang-format off
+
+static void send_nibble_wrapper(uint8_t digit) {
+ if (unicode_config.input_mode == UC_WIN) {
+ uint8_t kc = digit < 10
+ ? KC_KP_1 + (10 + digit - 1) % 10
+ : KC_A + (digit - 10);
+ tap_code(kc);
+ return;
+ }
+ send_nibble(digit);
+}
+
+// clang-format on
+
void register_hex(uint16_t hex) {
for (int i = 3; i >= 0; i--) {
uint8_t digit = ((hex >> (i * 4)) & 0xF);
- send_nibble(digit);
+ send_nibble_wrapper(digit);
}
}
@@ -171,10 +198,10 @@ void register_hex32(uint32_t hex) {
uint8_t digit = ((hex >> (i * 4)) & 0xF);
if (digit == 0) {
if (!onzerostart) {
- send_nibble(digit);
+ send_nibble_wrapper(digit);
}
} else {
- send_nibble(digit);
+ send_nibble_wrapper(digit);
onzerostart = false;
}
}
diff --git a/quantum/programmable_button.c b/quantum/programmable_button.c
new file mode 100644
index 0000000000..be828fd17c
--- /dev/null
+++ b/quantum/programmable_button.c
@@ -0,0 +1,37 @@
+/*
+Copyright 2021 Thomas Weißschuh <thomas@t-8ch.de>
+
+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 "programmable_button.h"
+#include "host.h"
+
+#define REPORT_BIT(index) (((uint32_t)1) << (index - 1))
+
+static uint32_t programmable_button_report = 0;
+
+void programmable_button_clear(void) { programmable_button_report = 0; }
+
+void programmable_button_send(void) { host_programmable_button_send(programmable_button_report); }
+
+void programmable_button_on(uint8_t index) { programmable_button_report |= REPORT_BIT(index); }
+
+void programmable_button_off(uint8_t index) { programmable_button_report &= ~REPORT_BIT(index); }
+
+bool programmable_button_is_on(uint8_t index) { return !!(programmable_button_report & REPORT_BIT(index)); };
+
+uint32_t programmable_button_get_report(void) { return programmable_button_report; };
+
+void programmable_button_set_report(uint32_t report) { programmable_button_report = report; }
diff --git a/quantum/programmable_button.h b/quantum/programmable_button.h
new file mode 100644
index 0000000000..e89b8b9fd6
--- /dev/null
+++ b/quantum/programmable_button.h
@@ -0,0 +1,30 @@
+/*
+Copyright 2021 Thomas Weißschuh <thomas@t-8ch.de>
+
+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/>.
+*/
+
+#pragma once
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "report.h"
+
+void programmable_button_clear(void);
+void programmable_button_send(void);
+void programmable_button_on(uint8_t index);
+void programmable_button_off(uint8_t index);
+bool programmable_button_is_on(uint8_t index);
+uint32_t programmable_button_get_report(void);
+void programmable_button_set_report(uint32_t report);
diff --git a/quantum/quantum.c b/quantum/quantum.c
index e60378afe4..326c8370b1 100644
--- a/quantum/quantum.c
+++ b/quantum/quantum.c
@@ -296,6 +296,9 @@ bool process_record_quantum(keyrecord_t *record) {
#ifdef JOYSTICK_ENABLE
process_joystick(keycode, record) &&
#endif
+#ifdef PROGRAMMABLE_BUTTON_ENABLE
+ process_programmable_button(keycode, record) &&
+#endif
true)) {
return false;
}
@@ -480,3 +483,99 @@ void api_send_unicode(uint32_t unicode) {
__attribute__((weak)) void startup_user() {}
__attribute__((weak)) void shutdown_user() {}
+
+/** \brief Run keyboard level Power down
+ *
+ * FIXME: needs doc
+ */
+__attribute__((weak)) void suspend_power_down_user(void) {}
+/** \brief Run keyboard level Power down
+ *
+ * FIXME: needs doc
+ */
+__attribute__((weak)) void suspend_power_down_kb(void) { suspend_power_down_user(); }
+
+void suspend_power_down_quantum(void) {
+#ifndef NO_SUSPEND_POWER_DOWN
+// Turn off backlight
+# ifdef BACKLIGHT_ENABLE
+ backlight_set(0);
+# endif
+
+# ifdef LED_MATRIX_ENABLE
+ led_matrix_task();
+# endif
+# ifdef RGB_MATRIX_ENABLE
+ rgb_matrix_task();
+# endif
+
+ // Turn off LED indicators
+ uint8_t leds_off = 0;
+# if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE)
+ if (is_backlight_enabled()) {
+ // Don't try to turn off Caps Lock indicator as it is backlight and backlight is already off
+ leds_off |= (1 << USB_LED_CAPS_LOCK);
+ }
+# endif
+ led_set(leds_off);
+
+// Turn off audio
+# ifdef AUDIO_ENABLE
+ stop_all_notes();
+# endif
+
+// Turn off underglow
+# if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
+ rgblight_suspend();
+# endif
+
+# if defined(LED_MATRIX_ENABLE)
+ led_matrix_set_suspend_state(true);
+# endif
+# if defined(RGB_MATRIX_ENABLE)
+ rgb_matrix_set_suspend_state(true);
+# endif
+
+# ifdef OLED_ENABLE
+ oled_off();
+# endif
+# ifdef ST7565_ENABLE
+ st7565_off();
+# endif
+#endif
+}
+
+/** \brief run user level code immediately after wakeup
+ *
+ * FIXME: needs doc
+ */
+__attribute__((weak)) void suspend_wakeup_init_user(void) {}
+
+/** \brief run keyboard level code immediately after wakeup
+ *
+ * FIXME: needs doc
+ */
+__attribute__((weak)) void suspend_wakeup_init_kb(void) { suspend_wakeup_init_user(); }
+
+__attribute__((weak)) void suspend_wakeup_init_quantum(void) {
+// Turn on backlight
+#ifdef BACKLIGHT_ENABLE
+ backlight_init();
+#endif
+
+ // Restore LED indicators
+ led_set(host_keyboard_leds());
+
+// Wake up underglow
+#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
+ rgblight_wakeup();
+#endif
+
+#if defined(LED_MATRIX_ENABLE)
+ led_matrix_set_suspend_state(false);
+#endif
+#if defined(RGB_MATRIX_ENABLE)
+ rgb_matrix_set_suspend_state(false);
+#endif
+ suspend_wakeup_init_kb();
+}
diff --git a/quantum/quantum.h b/quantum/quantum.h
index 86b717e445..5cbe84d0c9 100644
--- a/quantum/quantum.h
+++ b/quantum/quantum.h
@@ -147,6 +147,10 @@ extern layer_state_t layer_state;
# include "process_joystick.h"
#endif
+#ifdef PROGRAMMABLE_BUTTON_ENABLE
+# include "process_programmable_button.h"
+#endif
+
#ifdef GRAVE_ESC_ENABLE
# include "process_grave_esc.h"
#endif
diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h
index ef4b0f457b..2ea81dd4c8 100644
--- a/quantum/quantum_keycodes.h
+++ b/quantum/quantum_keycodes.h
@@ -524,6 +524,40 @@ enum quantum_keycodes {
// Additional magic key
MAGIC_TOGGLE_GUI,
+ // Programmable Button
+ PROGRAMMABLE_BUTTON_1,
+ PROGRAMMABLE_BUTTON_2,
+ PROGRAMMABLE_BUTTON_3,
+ PROGRAMMABLE_BUTTON_4,
+ PROGRAMMABLE_BUTTON_5,
+ PROGRAMMABLE_BUTTON_6,
+ PROGRAMMABLE_BUTTON_7,
+ PROGRAMMABLE_BUTTON_8,
+ PROGRAMMABLE_BUTTON_9,
+ PROGRAMMABLE_BUTTON_10,
+ PROGRAMMABLE_BUTTON_11,
+ PROGRAMMABLE_BUTTON_12,
+ PROGRAMMABLE_BUTTON_13,
+ PROGRAMMABLE_BUTTON_14,
+ PROGRAMMABLE_BUTTON_15,
+ PROGRAMMABLE_BUTTON_16,
+ PROGRAMMABLE_BUTTON_17,
+ PROGRAMMABLE_BUTTON_18,
+ PROGRAMMABLE_BUTTON_19,
+ PROGRAMMABLE_BUTTON_20,
+ PROGRAMMABLE_BUTTON_21,
+ PROGRAMMABLE_BUTTON_22,
+ PROGRAMMABLE_BUTTON_23,
+ PROGRAMMABLE_BUTTON_24,
+ PROGRAMMABLE_BUTTON_25,
+ PROGRAMMABLE_BUTTON_26,
+ PROGRAMMABLE_BUTTON_27,
+ PROGRAMMABLE_BUTTON_28,
+ PROGRAMMABLE_BUTTON_29,
+ PROGRAMMABLE_BUTTON_30,
+ PROGRAMMABLE_BUTTON_31,
+ PROGRAMMABLE_BUTTON_32,
+
// Start of custom keycode range for keyboards and keymaps - always leave at the end
SAFE_RANGE
};
@@ -854,3 +888,39 @@ enum quantum_keycodes {
#define OS_TOGG ONESHOT_TOGGLE
#define OS_ON ONESHOT_ENABLE
#define OS_OFF ONESHOT_DISABLE
+
+// Programmable Button aliases
+#define PB_1 PROGRAMMABLE_BUTTON_1
+#define PB_2 PROGRAMMABLE_BUTTON_2
+#define PB_3 PROGRAMMABLE_BUTTON_3
+#define PB_4 PROGRAMMABLE_BUTTON_4
+#define PB_5 PROGRAMMABLE_BUTTON_5
+#define PB_6 PROGRAMMABLE_BUTTON_6
+#define PB_7 PROGRAMMABLE_BUTTON_7
+#define PB_8 PROGRAMMABLE_BUTTON_8
+#define PB_9 PROGRAMMABLE_BUTTON_9
+#define PB_10 PROGRAMMABLE_BUTTON_10
+#define PB_11 PROGRAMMABLE_BUTTON_11
+#define PB_12 PROGRAMMABLE_BUTTON_12
+#define PB_13 PROGRAMMABLE_BUTTON_13
+#define PB_14 PROGRAMMABLE_BUTTON_14
+#define PB_15 PROGRAMMABLE_BUTTON_15
+#define PB_16 PROGRAMMABLE_BUTTON_16
+#define PB_17 PROGRAMMABLE_BUTTON_17
+#define PB_18 PROGRAMMABLE_BUTTON_18
+#define PB_19 PROGRAMMABLE_BUTTON_19
+#define PB_20 PROGRAMMABLE_BUTTON_20
+#define PB_21 PROGRAMMABLE_BUTTON_21
+#define PB_22 PROGRAMMABLE_BUTTON_22
+#define PB_23 PROGRAMMABLE_BUTTON_23
+#define PB_24 PROGRAMMABLE_BUTTON_24
+#define PB_25 PROGRAMMABLE_BUTTON_25
+#define PB_26 PROGRAMMABLE_BUTTON_26
+#define PB_27 PROGRAMMABLE_BUTTON_27
+#define PB_28 PROGRAMMABLE_BUTTON_28
+#define PB_29 PROGRAMMABLE_BUTTON_29
+#define PB_30 PROGRAMMABLE_BUTTON_30
+#define PB_31 PROGRAMMABLE_BUTTON_31
+#define PB_32 PROGRAMMABLE_BUTTON_32
+#define PROGRAMMABLE_BUTTON_MIN PROGRAMMABLE_BUTTON_1
+#define PROGRAMMABLE_BUTTON_MAX PROGRAMMABLE_BUTTON_32