diff --git a/.clangd b/.clangd
index 6133ae7229d..63dadd7e7c1 100644
--- a/.clangd
+++ b/.clangd
@@ -1,4 +1,4 @@
CompileFlags:
Add: [-Wno-unknown-attributes, -Wno-maybe-uninitialized, -Wno-unknown-warning-option]
- Remove: [-W*, -mmcu=*, -mcpu=*, -mfpu=*, -mfloat-abi=*, -mno-unaligned-access, -mno-thumb-interwork, -mcall-prologues]
+ Remove: [-W*, -mmcu=*, -mcpu=*, -mfpu=*, -mfloat-abi=*, -mno-unaligned-access, -mno-thumb-interwork, -mcall-prologues, -D__has_include*]
Compiler: clang
diff --git a/builddefs/common_features.mk b/builddefs/common_features.mk
index ec52ad08a5b..b37f26f3d8c 100644
--- a/builddefs/common_features.mk
+++ b/builddefs/common_features.mk
@@ -175,80 +175,82 @@ endif
VALID_EEPROM_DRIVER_TYPES := vendor custom transient i2c spi wear_leveling legacy_stm32_flash
EEPROM_DRIVER ?= vendor
-ifeq ($(filter $(EEPROM_DRIVER),$(VALID_EEPROM_DRIVER_TYPES)),)
+ifneq ($(strip $(EEPROM_DRIVER)),none)
+ ifeq ($(filter $(EEPROM_DRIVER),$(VALID_EEPROM_DRIVER_TYPES)),)
$(call CATASTROPHIC_ERROR,Invalid EEPROM_DRIVER,EEPROM_DRIVER="$(EEPROM_DRIVER)" is not a valid EEPROM driver)
-else
- OPT_DEFS += -DEEPROM_ENABLE
- COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/eeprom
- COMMON_VPATH += $(DRIVER_PATH)/eeprom
- COMMON_VPATH += $(PLATFORM_COMMON_DIR)
- ifeq ($(strip $(EEPROM_DRIVER)), custom)
- # Custom EEPROM implementation -- only needs to implement init/erase/read_block/write_block
- OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_CUSTOM
- SRC += eeprom_driver.c
- else ifeq ($(strip $(EEPROM_DRIVER)), wear_leveling)
- # Wear-leveling EEPROM implementation
- OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_WEAR_LEVELING
- SRC += eeprom_driver.c eeprom_wear_leveling.c
- else ifeq ($(strip $(EEPROM_DRIVER)), i2c)
- # External I2C EEPROM implementation
- OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_I2C
- I2C_DRIVER_REQUIRED = yes
- SRC += eeprom_driver.c eeprom_i2c.c
- else ifeq ($(strip $(EEPROM_DRIVER)), spi)
- # External SPI EEPROM implementation
- OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_SPI
- SPI_DRIVER_REQUIRED = yes
- SRC += eeprom_driver.c eeprom_spi.c
- else ifeq ($(strip $(EEPROM_DRIVER)), legacy_stm32_flash)
- # STM32 Emulated EEPROM, backed by MCU flash (soon to be deprecated)
- OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_LEGACY_EMULATED_FLASH
- COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/flash
- COMMON_VPATH += $(DRIVER_PATH)/flash
- SRC += eeprom_driver.c eeprom_legacy_emulated_flash.c legacy_flash_ops.c
- else ifeq ($(strip $(EEPROM_DRIVER)), transient)
- # Transient EEPROM implementation -- no data storage but provides runtime area for it
- OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_TRANSIENT
- SRC += eeprom_driver.c eeprom_transient.c
- else ifeq ($(strip $(EEPROM_DRIVER)), vendor)
- # Vendor-implemented EEPROM
- OPT_DEFS += -DEEPROM_VENDOR
- ifeq ($(PLATFORM),AVR)
- # Automatically provided by avr-libc, nothing required
- else ifeq ($(PLATFORM),CHIBIOS)
- ifneq ($(filter %_STM32F072xB %_STM32F042x6, $(MCU_SERIES)_$(MCU_LDSCRIPT)),)
- # STM32 Emulated EEPROM, backed by MCU flash (soon to be deprecated)
- OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_LEGACY_EMULATED_FLASH
- COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/flash
- COMMON_VPATH += $(DRIVER_PATH)/flash
- SRC += eeprom_driver.c eeprom_legacy_emulated_flash.c legacy_flash_ops.c
- else ifneq ($(filter $(MCU_SERIES),STM32F1xx STM32F3xx STM32F4xx STM32L4xx STM32G4xx WB32F3G71xx WB32FQ95xx AT32F415 GD32VF103),)
- # Wear-leveling EEPROM implementation, backed by MCU flash
- OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_WEAR_LEVELING
- SRC += eeprom_driver.c eeprom_wear_leveling.c
- WEAR_LEVELING_DRIVER ?= embedded_flash
- else ifneq ($(filter $(MCU_SERIES),STM32L0xx STM32L1xx),)
- # True EEPROM on STM32L0xx, L1xx
- OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_STM32_L0_L1
- SRC += eeprom_driver.c eeprom_stm32_L0_L1.c
- else ifneq ($(filter $(MCU_SERIES),RP2040),)
- # Wear-leveling EEPROM implementation, backed by RP2040 flash
- OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_WEAR_LEVELING
- SRC += eeprom_driver.c eeprom_wear_leveling.c
- WEAR_LEVELING_DRIVER ?= rp2040_flash
- else ifneq ($(filter $(MCU_SERIES),KL2x K20x),)
- # Teensy EEPROM implementations
- OPT_DEFS += -DEEPROM_KINETIS_FLEXRAM
- SRC += eeprom_kinetis_flexram.c
- else
- # Fall back to transient, i.e. non-persistent
- OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_TRANSIENT
- SRC += eeprom_driver.c eeprom_transient.c
+ else
+ OPT_DEFS += -DEEPROM_ENABLE
+ COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/eeprom
+ COMMON_VPATH += $(DRIVER_PATH)/eeprom
+ COMMON_VPATH += $(PLATFORM_COMMON_DIR)
+ ifeq ($(strip $(EEPROM_DRIVER)), custom)
+ # Custom EEPROM implementation -- only needs to implement init/erase/read_block/write_block
+ OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_CUSTOM
+ SRC += eeprom_driver.c
+ else ifeq ($(strip $(EEPROM_DRIVER)), wear_leveling)
+ # Wear-leveling EEPROM implementation
+ OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_WEAR_LEVELING
+ SRC += eeprom_driver.c eeprom_wear_leveling.c
+ else ifeq ($(strip $(EEPROM_DRIVER)), i2c)
+ # External I2C EEPROM implementation
+ OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_I2C
+ I2C_DRIVER_REQUIRED = yes
+ SRC += eeprom_driver.c eeprom_i2c.c
+ else ifeq ($(strip $(EEPROM_DRIVER)), spi)
+ # External SPI EEPROM implementation
+ OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_SPI
+ SPI_DRIVER_REQUIRED = yes
+ SRC += eeprom_driver.c eeprom_spi.c
+ else ifeq ($(strip $(EEPROM_DRIVER)), legacy_stm32_flash)
+ # STM32 Emulated EEPROM, backed by MCU flash (soon to be deprecated)
+ OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_LEGACY_EMULATED_FLASH
+ COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/flash
+ COMMON_VPATH += $(DRIVER_PATH)/flash
+ SRC += eeprom_driver.c eeprom_legacy_emulated_flash.c legacy_flash_ops.c
+ else ifeq ($(strip $(EEPROM_DRIVER)), transient)
+ # Transient EEPROM implementation -- no data storage but provides runtime area for it
+ OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_TRANSIENT
+ SRC += eeprom_driver.c eeprom_transient.c
+ else ifeq ($(strip $(EEPROM_DRIVER)), vendor)
+ # Vendor-implemented EEPROM
+ OPT_DEFS += -DEEPROM_VENDOR
+ ifeq ($(PLATFORM),AVR)
+ # Automatically provided by avr-libc, nothing required
+ else ifeq ($(PLATFORM),CHIBIOS)
+ ifneq ($(filter %_STM32F072xB %_STM32F042x6, $(MCU_SERIES)_$(MCU_LDSCRIPT)),)
+ # STM32 Emulated EEPROM, backed by MCU flash (soon to be deprecated)
+ OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_LEGACY_EMULATED_FLASH
+ COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/flash
+ COMMON_VPATH += $(DRIVER_PATH)/flash
+ SRC += eeprom_driver.c eeprom_legacy_emulated_flash.c legacy_flash_ops.c
+ else ifneq ($(filter $(MCU_SERIES),STM32F1xx STM32F3xx STM32F4xx STM32L4xx STM32G4xx WB32F3G71xx WB32FQ95xx AT32F415 GD32VF103),)
+ # Wear-leveling EEPROM implementation, backed by MCU flash
+ OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_WEAR_LEVELING
+ SRC += eeprom_driver.c eeprom_wear_leveling.c
+ WEAR_LEVELING_DRIVER ?= embedded_flash
+ else ifneq ($(filter $(MCU_SERIES),STM32L0xx STM32L1xx),)
+ # True EEPROM on STM32L0xx, L1xx
+ OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_STM32_L0_L1
+ SRC += eeprom_driver.c eeprom_stm32_L0_L1.c
+ else ifneq ($(filter $(MCU_SERIES),RP2040),)
+ # Wear-leveling EEPROM implementation, backed by RP2040 flash
+ OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_WEAR_LEVELING
+ SRC += eeprom_driver.c eeprom_wear_leveling.c
+ WEAR_LEVELING_DRIVER ?= rp2040_flash
+ else ifneq ($(filter $(MCU_SERIES),KL2x K20x),)
+ # Teensy EEPROM implementations
+ OPT_DEFS += -DEEPROM_KINETIS_FLEXRAM
+ SRC += eeprom_kinetis_flexram.c
+ else
+ # Fall back to transient, i.e. non-persistent
+ OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_TRANSIENT
+ SRC += eeprom_driver.c eeprom_transient.c
+ endif
+ else ifeq ($(PLATFORM),TEST)
+ # Test harness "EEPROM"
+ OPT_DEFS += -DEEPROM_TEST_HARNESS
+ SRC += eeprom.c
endif
- else ifeq ($(PLATFORM),TEST)
- # Test harness "EEPROM"
- OPT_DEFS += -DEEPROM_TEST_HARNESS
- SRC += eeprom.c
endif
endif
endif
@@ -910,12 +912,11 @@ ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
OPT_DEFS += -DBLUETOOTH_ENABLE
OPT_DEFS += -DBLUETOOTH_$(strip $(shell echo $(BLUETOOTH_DRIVER) | tr '[:lower:]' '[:upper:]'))
NO_USB_STARTUP_CHECK := yes
+ CONNECTION_ENABLE := yes
COMMON_VPATH += $(DRIVER_PATH)/bluetooth
- SRC += outputselect.c process_connection.c
ifeq ($(strip $(BLUETOOTH_DRIVER)), bluefruit_le)
SPI_DRIVER_REQUIRED = yes
- ANALOG_DRIVER_REQUIRED = yes
SRC += $(DRIVER_PATH)/bluetooth/bluetooth.c
SRC += $(DRIVER_PATH)/bluetooth/bluefruit_le.cpp
endif
diff --git a/builddefs/generic_features.mk b/builddefs/generic_features.mk
index d39727f23bf..c8265144314 100644
--- a/builddefs/generic_features.mk
+++ b/builddefs/generic_features.mk
@@ -25,6 +25,7 @@ GENERIC_FEATURES = \
CAPS_WORD \
COMBO \
COMMAND \
+ CONNECTION \
CRC \
DEFERRED_EXEC \
DIGITIZER \
diff --git a/data/schemas/keyboard.jsonschema b/data/schemas/keyboard.jsonschema
index 2314c72bdb9..4e8bae1084f 100644
--- a/data/schemas/keyboard.jsonschema
+++ b/data/schemas/keyboard.jsonschema
@@ -319,7 +319,7 @@
"properties": {
"driver": {
"type": "string",
- "enum": ["custom", "embedded_flash", "legacy", "rp2040_flash", "spi_flash"]
+ "enum": ["none", "custom", "embedded_flash", "legacy", "rp2040_flash", "spi_flash"]
},
"backing_size": {"$ref": "qmk.definitions.v1#/unsigned_int"},
"logical_size": {"$ref": "qmk.definitions.v1#/unsigned_int"}
diff --git a/docs/config_options.md b/docs/config_options.md
index 90a708dd99c..e75a5b2f7ec 100644
--- a/docs/config_options.md
+++ b/docs/config_options.md
@@ -401,6 +401,7 @@ This is a [make](https://www.gnu.org/software/make/manual/make.html) file that i
* `atmel-dfu`
* `lufa-dfu`
* `qmk-dfu`
+ * `qmk-hid`
* `halfkay`
* `caterina`
* `bootloadhid`
diff --git a/drivers/bluetooth/bluefruit_le.cpp b/drivers/bluetooth/bluefruit_le.cpp
index 218eca21953..5fdd104dcfb 100644
--- a/drivers/bluetooth/bluefruit_le.cpp
+++ b/drivers/bluetooth/bluefruit_le.cpp
@@ -32,13 +32,8 @@
# define BLUEFRUIT_LE_SCK_DIVISOR 2 // 4MHz SCK/8MHz CPU, calculated for Feather 32U4 BLE
#endif
-#define SAMPLE_BATTERY
#define ConnectionUpdateInterval 1000 /* milliseconds */
-#ifndef BATTERY_LEVEL_PIN
-# define BATTERY_LEVEL_PIN B5
-#endif
-
static struct {
bool is_connected;
bool initialized;
@@ -48,10 +43,6 @@ static struct {
#define UsingEvents 2
bool event_flags;
-#ifdef SAMPLE_BATTERY
- uint16_t last_battery_update;
- uint32_t vbat;
-#endif
uint16_t last_connection_update;
} state;
@@ -549,14 +540,6 @@ void bluefruit_le_task(void) {
set_connected(atoi(resbuf));
}
}
-
-#ifdef SAMPLE_BATTERY
- if (timer_elapsed(state.last_battery_update) > BatteryUpdateInterval && resp_buf.empty()) {
- state.last_battery_update = timer_read();
-
- state.vbat = analogReadPin(BATTERY_LEVEL_PIN);
- }
-#endif
}
static bool process_queue_item(struct queue_item *item, uint16_t timeout) {
@@ -655,10 +638,6 @@ void bluefruit_le_send_mouse(report_mouse_t *report) {
}
}
-uint32_t bluefruit_le_read_battery_voltage(void) {
- return state.vbat;
-}
-
bool bluefruit_le_set_mode_leds(bool on) {
if (!state.configured) {
return false;
diff --git a/drivers/bluetooth/bluefruit_le.h b/drivers/bluetooth/bluefruit_le.h
index a3de03c35c3..5efe92b6e0b 100644
--- a/drivers/bluetooth/bluefruit_le.h
+++ b/drivers/bluetooth/bluefruit_le.h
@@ -45,10 +45,6 @@ extern void bluefruit_le_send_consumer(uint16_t usage);
* change. */
extern void bluefruit_le_send_mouse(report_mouse_t *report);
-/* Compute battery voltage by reading an analog pin.
- * Returns the integer number of millivolts */
-extern uint32_t bluefruit_le_read_battery_voltage(void);
-
extern bool bluefruit_le_set_mode_leds(bool on);
extern bool bluefruit_le_set_power_level(int8_t level);
diff --git a/drivers/bluetooth/outputselect.c b/drivers/bluetooth/outputselect.c
deleted file mode 100644
index b986ba274e9..00000000000
--- a/drivers/bluetooth/outputselect.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
-Copyright 2017 Priyadi Iman Nurcahyo
-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 .
-*/
-
-#include "outputselect.h"
-#include "usb_util.h"
-
-#ifdef BLUETOOTH_BLUEFRUIT_LE
-# include "bluefruit_le.h"
-#endif
-
-uint8_t desired_output = OUTPUT_DEFAULT;
-
-/** \brief Set Output
- *
- * FIXME: Needs doc
- */
-void set_output(uint8_t output) {
- set_output_user(output);
- desired_output = output;
-}
-
-/** \brief Set Output User
- *
- * FIXME: Needs doc
- */
-__attribute__((weak)) void set_output_user(uint8_t output) {}
-
-/** \brief Auto Detect Output
- *
- * FIXME: Needs doc
- */
-uint8_t auto_detect_output(void) {
- if (usb_connected_state()) {
- return OUTPUT_USB;
- }
-
-#ifdef BLUETOOTH_BLUEFRUIT_LE
- if (bluefruit_le_is_connected()) {
- return OUTPUT_BLUETOOTH;
- }
-#endif
-
-#ifdef BLUETOOTH_ENABLE
- return OUTPUT_BLUETOOTH; // should check if BT is connected here
-#endif
-
- return OUTPUT_NONE;
-}
-
-/** \brief Where To Send
- *
- * FIXME: Needs doc
- */
-uint8_t where_to_send(void) {
- if (desired_output == OUTPUT_AUTO) {
- return auto_detect_output();
- }
- return desired_output;
-}
diff --git a/drivers/bluetooth/outputselect.h b/drivers/bluetooth/outputselect.h
index c4548e1122a..25f063bbff0 100644
--- a/drivers/bluetooth/outputselect.h
+++ b/drivers/bluetooth/outputselect.h
@@ -14,21 +14,17 @@ along with this program. If not, see .
#pragma once
-#include
+#include "connection.h"
-enum outputs {
- OUTPUT_AUTO,
+// DEPRECATED - DO NOT USE
- OUTPUT_NONE,
- OUTPUT_USB,
- OUTPUT_BLUETOOTH
-};
+#define OUTPUT_AUTO CONNECTION_HOST_AUTO
+#define OUTPUT_NONE CONNECTION_HOST_NONE
+#define OUTPUT_USB CONNECTION_HOST_USB
+#define OUTPUT_BLUETOOTH CONNECTION_HOST_BLUETOOTH
-#ifndef OUTPUT_DEFAULT
-# define OUTPUT_DEFAULT OUTPUT_AUTO
-#endif
+#define set_output connection_set_host_noeeprom
+#define where_to_send connection_get_host
+#define auto_detect_output connection_auto_detect_host
-void set_output(uint8_t output);
-void set_output_user(uint8_t output);
-uint8_t auto_detect_output(void);
-uint8_t where_to_send(void);
+void set_output_user(uint8_t output);
diff --git a/keyboards/anavi/macropad8/keyboard.json b/keyboards/anavi/macropad8/keyboard.json
index d70d3fa0475..50381ce8a87 100644
--- a/keyboards/anavi/macropad8/keyboard.json
+++ b/keyboards/anavi/macropad8/keyboard.json
@@ -23,7 +23,6 @@
"rainbow_swirl": true,
"snake": true,
"knight": true,
- "christmas": true,
"static_gradient": true,
"rgb_test": true,
"alternating": true,
diff --git a/keyboards/handwired/footy/config.h b/keyboards/handwired/footy/config.h
new file mode 100644
index 00000000000..5a081f79d69
--- /dev/null
+++ b/keyboards/handwired/footy/config.h
@@ -0,0 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#pragma once
+
+#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET
+#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_TIMEOUT 500U
diff --git a/keyboards/handwired/footy/keyboard.json b/keyboards/handwired/footy/keyboard.json
new file mode 100644
index 00000000000..eef8c250386
--- /dev/null
+++ b/keyboards/handwired/footy/keyboard.json
@@ -0,0 +1,35 @@
+{
+ "manufacturer": "CJ Pais",
+ "keyboard_name": "Footy",
+ "maintainer": "cjpais",
+ "bootloader": "rp2040",
+ "diode_direction": "COL2ROW",
+ "features": {
+ "bootmagic": true,
+ "extrakey": true,
+ "mousekey": true
+ },
+ "bootmagic": {
+ "matrix": [0, 1]
+ },
+ "matrix_pins": {
+ "cols": ["GP11", "GP10", "GP15"],
+ "rows": ["GP14"]
+ },
+ "processor": "RP2040",
+ "url": "https://workshop.cjpais.com/projects/footy",
+ "usb": {
+ "device_version": "1.0.0",
+ "pid": "0x0001",
+ "vid": "0x636A"
+ },
+ "layouts": {
+ "LAYOUT": {
+ "layout": [
+ {"matrix": [0, 0], "x": 0, "y": 0},
+ {"matrix": [0, 1], "x": 1, "y": 0},
+ {"matrix": [0, 2], "x": 2, "y": 0}
+ ]
+ }
+ }
+}
diff --git a/keyboards/handwired/footy/keymaps/default/keymap.json b/keyboards/handwired/footy/keymaps/default/keymap.json
new file mode 100644
index 00000000000..99804041d85
--- /dev/null
+++ b/keyboards/handwired/footy/keymaps/default/keymap.json
@@ -0,0 +1,10 @@
+{
+ "keyboard": "handwired/footy",
+ "keymap": "default",
+ "layout": "LAYOUT",
+ "layers": [
+ [
+ "KC_A", "KC_B", "KC_C"
+ ]
+ ]
+}
diff --git a/keyboards/handwired/footy/keymaps/handy/keymap.json b/keyboards/handwired/footy/keymaps/handy/keymap.json
new file mode 100644
index 00000000000..e2a2db6d10b
--- /dev/null
+++ b/keyboards/handwired/footy/keymaps/handy/keymap.json
@@ -0,0 +1,15 @@
+{
+ "keyboard": "handwired/footy",
+ "keymap": "handy",
+ "layout": "LAYOUT",
+ "layers": [
+ [
+ "KC_NO", "MT(MOD_RCTL | MOD_RGUI, KC_NO)", "KC_NO"
+ ]
+ ],
+ "config": {
+ "tapping": {
+ "term": 50
+ }
+ }
+}
diff --git a/keyboards/handwired/footy/keymaps/superwhisper/keymap.json b/keyboards/handwired/footy/keymaps/superwhisper/keymap.json
new file mode 100644
index 00000000000..0cfa41f502e
--- /dev/null
+++ b/keyboards/handwired/footy/keymaps/superwhisper/keymap.json
@@ -0,0 +1,15 @@
+{
+ "keyboard": "handwired/footy",
+ "keymap": "superwhisper",
+ "layout": "LAYOUT",
+ "layers": [
+ [
+ "KC_NO", "LOPT(KC_SPACE)", "KC_NO"
+ ]
+ ],
+ "config": {
+ "tapping": {
+ "term": 50
+ }
+ }
+}
diff --git a/keyboards/handwired/footy/readme.md b/keyboards/handwired/footy/readme.md
new file mode 100644
index 00000000000..6d02fad95cc
--- /dev/null
+++ b/keyboards/handwired/footy/readme.md
@@ -0,0 +1,42 @@
+# Footy
+
+
+
+*Footy is a foot pedal intended to be used with a speech to text application like 'handy' or superwhisper. Initially developed as an assistive technology device for those with limited typing abilities.*
+
+* Keyboard Maintainer: [CJ Pais](https://github.com/cjpais)
+* Hardware Supported: [Keebio Stampy](https://keeb.io/products/stampy-rp2040-usb-c-controller-board-for-handwiring)
+* Hardware Availability: [3D printed case](https://makerworld.com/en/models/1185240-footy)
+
+Make example for this keyboard (after setting up your build environment):
+
+ make handwired/footy:default
+
+Flashing example for this keyboard (enter the bootloader first):
+
+ make handwired/footy:default:flash
+
+or drag and drop .uf2 file on the removable storage
+
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
+
+## Bootloader
+
+Enter the bootloader:
+
+* **Physical reset button**: Briefly double press the button on the back of the PCB
+
+## Keymaps
+
+Right now there are two primary keymaps, one for 'handy' and one for 'superwhisper'.
+
+Handy's default keymap is for the center switch to be RCTRL + RGUI.
+
+Superwhisper's default keymap is for the center switch to be LOPT + SPACE.
+
+You can build either of these firmware images by running the following commands:
+
+```
+make handwired/footy:handy
+make handwired/footy:superwhisper
+```
\ No newline at end of file
diff --git a/keyboards/handwired/promethium/config.h b/keyboards/handwired/promethium/config.h
index 806726b5eba..974a4f951fd 100644
--- a/keyboards/handwired/promethium/config.h
+++ b/keyboards/handwired/promethium/config.h
@@ -63,9 +63,8 @@ along with this program. If not, see .
//#define NO_ACTION_ONESHOT
#define PS2_MOUSE_INIT_DELAY 2000
-#define BATTERY_POLL 30000
-#define MAX_VOLTAGE 4.2
-#define MIN_VOLTAGE 3.2
+
+#define BATTERY_PIN B5
#ifndef __ASSEMBLER__ // assembler doesn't like enum in .h file
enum led_sequence {
diff --git a/keyboards/handwired/promethium/promethium.c b/keyboards/handwired/promethium/promethium.c
index 63139ac09db..c94a27a4deb 100644
--- a/keyboards/handwired/promethium/promethium.c
+++ b/keyboards/handwired/promethium/promethium.c
@@ -1,16 +1,15 @@
-#include "promethium.h"
-#include "analog.h"
+#include "keyboard.h"
#include "timer.h"
-#include "matrix.h"
-#include "bluefruit_le.h"
+#include "battery.h"
-// cubic fit {3.3, 0}, {3.5, 2.9}, {3.6, 5}, {3.7, 8.6}, {3.8, 36}, {3.9, 62}, {4.0, 73}, {4.05, 83}, {4.1, 89}, {4.15, 94}, {4.2, 100}
+#ifndef BATTERY_POLL
+# define BATTERY_POLL 30000
+#endif
uint8_t battery_level(void) {
- float voltage = bluefruit_le_read_battery_voltage() * 2 * 3.3 / 1024;
- if (voltage < MIN_VOLTAGE) return 0;
- if (voltage > MAX_VOLTAGE) return 255;
- return (voltage - MIN_VOLTAGE) / (MAX_VOLTAGE - MIN_VOLTAGE) * 255;
+ // maintain legacy behaviour and scale 0-100 percent to 0-255
+ uint16_t percent = battery_get_percent();
+ return (percent * 255) / 100;
}
__attribute__ ((weak))
diff --git a/keyboards/handwired/promethium/rules.mk b/keyboards/handwired/promethium/rules.mk
index 7f208800663..4012f8ca29c 100644
--- a/keyboards/handwired/promethium/rules.mk
+++ b/keyboards/handwired/promethium/rules.mk
@@ -5,7 +5,7 @@ PS2_DRIVER = interrupt
CUSTOM_MATRIX = yes
WS2812_DRIVER_REQUIRED = yes
-ANALOG_DRIVER_REQUIRED = yes
+BATTERY_DRIVER_REQUIRED = yes
SRC += rgbsps.c
SRC += matrix.c
diff --git a/keyboards/matrix/falcon/config.h b/keyboards/matrix/falcon/config.h
index 9065dd0770a..66787658fd1 100644
--- a/keyboards/matrix/falcon/config.h
+++ b/keyboards/matrix/falcon/config.h
@@ -29,4 +29,3 @@
//pin setting
#define LED_POWER_PIN D5
#define CHG_EN_PIN E6
-#define BATTERY_LEVEL_PIN F0
diff --git a/keyboards/tokyokeyboard/alix40/config.h b/keyboards/tokyokeyboard/alix40/config.h
deleted file mode 100644
index 51d446c6d2a..00000000000
--- a/keyboards/tokyokeyboard/alix40/config.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
-Copyright 2021 quadcube
-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 .
-*/
-
-#pragma once
-
-/* Bluetooth */
-#define BATTERY_LEVEL_PIN B6
diff --git a/keyboards/ymdk/id75/f103/keyboard.json b/keyboards/ymdk/id75/f103/keyboard.json
index 5b1974b3f22..07088ee7ccb 100644
--- a/keyboards/ymdk/id75/f103/keyboard.json
+++ b/keyboards/ymdk/id75/f103/keyboard.json
@@ -1,5 +1,4 @@
{
- "manufacturer": "YMDK",
"bootloader": "uf2boot",
"matrix_pins": {
"cols": ["A10", "A9", "A8", "B15", "B14", "B13", "B12", "A5", "A6", "A4", "A3", "A2", "A1", "A0", "A15"],
diff --git a/keyboards/ymdk/id75/info.json b/keyboards/ymdk/id75/info.json
index bbe4d1c73ee..e409743abbb 100644
--- a/keyboards/ymdk/id75/info.json
+++ b/keyboards/ymdk/id75/info.json
@@ -1,6 +1,8 @@
{
+ "manufacturer": "YMDK",
"keyboard_name": "Idobao x YMDK ID75",
"maintainer": "qmk",
+ "bootloader_instructions": "Press the button on the back of the PCB twice in quick succession.",
"diode_direction": "ROW2COL",
"features": {
"bootmagic": true,
diff --git a/keyboards/ymdk/id75/readme.md b/keyboards/ymdk/id75/readme.md
index 4f7e779458b..f94d4c14cf5 100644
--- a/keyboards/ymdk/id75/readme.md
+++ b/keyboards/ymdk/id75/readme.md
@@ -8,15 +8,18 @@ A 75-key, 5-row ortholinear keyboard with per-key and underglow RGB LEDs.
* Hardware Supported: [Idobao x YMDK ID75](https://www.aliexpress.com/item/3256804537842097.html). **This is not the same PCB as `idobao/id75` or `ymdk/ymd75`.**
This keyboard has had multiple PCB revisions, some of which may not work with the firmware in this repository. **Check your PCB before flashing.**
* `f103`: (Geehy APM32F103CBT6, uf2boot)
+ * `rp2040`: (RP2040, rp2040)
* Hardware Availability: [YMDK](https://ymdkey.com/products/id75-75-keys-ortholinear-layout-qmk-anodized-aluminum-case-plate-hot-swappable-hot-swap-type-c-pcb-mechanical-keyboard-kit), [AliExpress (YMDK Store)](https://www.aliexpress.com/item/2255800125183974.html), [Amazon](https://www.amazon.com/Ortholinear-Anodized-Aluminum-hot-swappable-Mechanical/dp/B07ZQ8CD88)
Make example for this keyboard (after setting up your build environment):
make ymdk/id75/f103:default
+ make ymdk/id75/rp2040:default
Flashing example for this keyboard:
make ymdk/id75/f103:default:flash
+ make ymdk/id75/rp2040:default:flash
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
@@ -30,3 +33,4 @@ Enter the bootloader in 3 ways:
After entering the bootloader through one of the three methods above, the keyboard will appear as a USB mass storage device. If the CLI is unable to find this device, the compiled `.uf2` file can be manually copied to it. The keyboard will reboot on completion with the new firmware loaded.
- `f103`: The volume name is `MT.KEY`.
+- `rp2040`: The volume name is `RPI-RP2`.
diff --git a/keyboards/ymdk/id75/rp2040/config.h b/keyboards/ymdk/id75/rp2040/config.h
new file mode 100644
index 00000000000..b7a25de1603
--- /dev/null
+++ b/keyboards/ymdk/id75/rp2040/config.h
@@ -0,0 +1,20 @@
+/* Copyright 2021 Mike Tsao
+ *
+ * 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 .
+ */
+
+#pragma once
+
+#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET
+#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_TIMEOUT 500U
diff --git a/keyboards/ymdk/id75/rp2040/keyboard.json b/keyboards/ymdk/id75/rp2040/keyboard.json
new file mode 100644
index 00000000000..f153203cd04
--- /dev/null
+++ b/keyboards/ymdk/id75/rp2040/keyboard.json
@@ -0,0 +1,12 @@
+{
+ "bootloader": "rp2040",
+ "matrix_pins": {
+ "cols": ["GP26", "GP27", "GP4", "GP5", "GP1", "GP23", "GP22", "GP21", "GP28", "GP3", "GP7", "GP12", "GP13", "GP14", "GP15"],
+ "rows": ["GP8", "GP6", "GP19", "GP20", "GP18"]
+ },
+ "processor": "RP2040",
+ "ws2812": {
+ "driver": "vendor",
+ "pin": "GP2"
+ }
+}
diff --git a/lib/pico-sdk b/lib/pico-sdk
index a3398d8d3a7..d0c5cac430c 160000
--- a/lib/pico-sdk
+++ b/lib/pico-sdk
@@ -1 +1 @@
-Subproject commit a3398d8d3a772f37fef44a74743a1de69770e9c2
+Subproject commit d0c5cac430cc955b65efa0e899748853d9a80928
diff --git a/lib/python/qmk/cli/doctor/check.py b/lib/python/qmk/cli/doctor/check.py
index 2804a1d7df1..51b0f0c80a7 100644
--- a/lib/python/qmk/cli/doctor/check.py
+++ b/lib/python/qmk/cli/doctor/check.py
@@ -54,10 +54,13 @@ def _check_arm_gcc_installation():
"""Returns OK if the arm-none-eabi-gcc is fully installed and can produce binaries.
"""
with TemporaryDirectory() as temp_dir:
- temp_file = Path(temp_dir) / 'test.elf'
+ temp_in = Path(temp_dir) / 'test.c'
+ temp_out = Path(temp_dir) / 'test.elf'
- args = ['arm-none-eabi-gcc', '-mcpu=cortex-m0', '-mthumb', '-mno-thumb-interwork', '--specs=nosys.specs', '--specs=nano.specs', '-x', 'c', '-o', str(temp_file), '-']
- result = cli.run(args, stdin=None, stdout=None, stderr=None, input='#include \nint main() { return __NEWLIB__ * __NEWLIB_MINOR__ * __NEWLIB_PATCHLEVEL__; }')
+ temp_in.write_text('#include \nint main() { return __NEWLIB__ * __NEWLIB_MINOR__ * __NEWLIB_PATCHLEVEL__; }', encoding='utf-8')
+
+ args = ['arm-none-eabi-gcc', '-mcpu=cortex-m0', '-mthumb', '-mno-thumb-interwork', '--specs=nosys.specs', '--specs=nano.specs', '-x', 'c', '-o', str(temp_out), str(temp_in)]
+ result = cli.run(args, stdout=None, stderr=None)
if result.returncode == 0:
cli.log.info('Successfully compiled using arm-none-eabi-gcc')
else:
@@ -65,8 +68,8 @@ def _check_arm_gcc_installation():
cli.log.error(f'Command: {" ".join(args)}')
return CheckStatus.ERROR
- args = ['arm-none-eabi-size', str(temp_file)]
- result = cli.run(args, stdin=None, stdout=None, stderr=None)
+ args = ['arm-none-eabi-size', str(temp_out)]
+ result = cli.run(args, stdout=None, stderr=None)
if result.returncode == 0:
cli.log.info('Successfully tested arm-none-eabi-binutils using arm-none-eabi-size')
else:
@@ -91,10 +94,13 @@ def _check_avr_gcc_installation():
"""Returns OK if the avr-gcc is fully installed and can produce binaries.
"""
with TemporaryDirectory() as temp_dir:
- temp_file = Path(temp_dir) / 'test.elf'
+ temp_in = Path(temp_dir) / 'test.c'
+ temp_out = Path(temp_dir) / 'test.elf'
- args = ['avr-gcc', '-mmcu=atmega32u4', '-x', 'c', '-o', str(temp_file), '-']
- result = cli.run(args, stdin=None, stdout=None, stderr=None, input='int main() { return 0; }')
+ temp_in.write_text('int main() { return 0; }', encoding='utf-8')
+
+ args = ['avr-gcc', '-mmcu=atmega32u4', '-x', 'c', '-o', str(temp_out), str(temp_in)]
+ result = cli.run(args, stdout=None, stderr=None)
if result.returncode == 0:
cli.log.info('Successfully compiled using avr-gcc')
else:
@@ -102,8 +108,8 @@ def _check_avr_gcc_installation():
cli.log.error(f'Command: {" ".join(args)}')
return CheckStatus.ERROR
- args = ['avr-size', str(temp_file)]
- result = cli.run(args, stdin=None, stdout=None, stderr=None)
+ args = ['avr-size', str(temp_out)]
+ result = cli.run(args, stdout=None, stderr=None)
if result.returncode == 0:
cli.log.info('Successfully tested avr-binutils using avr-size')
else:
diff --git a/lib/python/qmk/cli/lint.py b/lib/python/qmk/cli/lint.py
index bc14b61e8b4..e2c76e4465f 100644
--- a/lib/python/qmk/cli/lint.py
+++ b/lib/python/qmk/cli/lint.py
@@ -171,6 +171,14 @@ def _handle_invalid_features(kb, info):
return ok
+def _handle_invalid_config(kb, info):
+ """Check for invalid keyboard level config
+ """
+ if info.get('url') == "":
+ cli.log.warning(f'{kb}: Invalid keyboard level config detected - Optional field "url" should not be empty.')
+ return True
+
+
def _chibios_conf_includenext_check(target):
"""Check the ChibiOS conf.h for the correct inclusion of the next conf.h
"""
@@ -255,6 +263,9 @@ def keyboard_check(kb): # noqa C901
if not _handle_invalid_features(kb, kb_info):
ok = False
+ if not _handle_invalid_config(kb, kb_info):
+ ok = False
+
invalid_files = git_get_ignored_files(f'keyboards/{kb}/')
for file in invalid_files:
if 'keymap' in file:
diff --git a/quantum/connection/connection.c b/quantum/connection/connection.c
new file mode 100644
index 00000000000..c7f3c4b4246
--- /dev/null
+++ b/quantum/connection/connection.c
@@ -0,0 +1,147 @@
+// Copyright 2025 QMK
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include "connection.h"
+#include "eeconfig.h"
+#include "usb_util.h"
+#include "util.h"
+
+// ======== DEPRECATED DEFINES - DO NOT USE ========
+#ifdef OUTPUT_DEFAULT
+# undef CONNECTION_HOST_DEFAULT
+# define CONNECTION_HOST_DEFAULT OUTPUT_DEFAULT
+#endif
+
+__attribute__((weak)) void set_output_user(uint8_t output) {}
+// ========
+
+#ifdef BLUETOOTH_ENABLE
+# ifdef BLUETOOTH_BLUEFRUIT_LE
+# include "bluefruit_le.h"
+# define bluetooth_is_connected() bluefruit_le_is_connected()
+# else
+// TODO: drivers should check if BT is connected here
+# define bluetooth_is_connected() true
+# endif
+#endif
+
+#define CONNECTION_HOST_INVALID 0xFF
+
+#ifndef CONNECTION_HOST_DEFAULT
+# define CONNECTION_HOST_DEFAULT CONNECTION_HOST_AUTO
+#endif
+
+static const connection_host_t host_candidates[] = {
+ CONNECTION_HOST_AUTO,
+ CONNECTION_HOST_USB,
+#ifdef BLUETOOTH_ENABLE
+ CONNECTION_HOST_BLUETOOTH,
+#endif
+#if 0
+ CONNECTION_HOST_2P4GHZ,
+#endif
+};
+
+#define HOST_CANDIDATES_COUNT ARRAY_SIZE(host_candidates)
+
+static connection_config_t config = {.desired_host = CONNECTION_HOST_INVALID};
+
+void eeconfig_update_connection_default(void) {
+ config.desired_host = CONNECTION_HOST_DEFAULT;
+
+ eeconfig_update_connection(&config);
+}
+
+void connection_init(void) {
+ eeconfig_read_connection(&config);
+ if (config.desired_host == CONNECTION_HOST_INVALID) {
+ eeconfig_update_connection_default();
+ }
+}
+
+__attribute__((weak)) void connection_host_changed_user(connection_host_t host) {}
+__attribute__((weak)) void connection_host_changed_kb(connection_host_t host) {}
+
+static void handle_host_changed(void) {
+ connection_host_changed_user(config.desired_host);
+ connection_host_changed_kb(config.desired_host);
+
+ // TODO: Remove deprecated callback
+ set_output_user(config.desired_host);
+}
+
+void connection_set_host_noeeprom(connection_host_t host) {
+ if (config.desired_host == host) {
+ return;
+ }
+
+ config.desired_host = host;
+
+ handle_host_changed();
+}
+
+void connection_set_host(connection_host_t host) {
+ connection_set_host_noeeprom(host);
+
+ eeconfig_update_connection(&config);
+}
+
+void connection_next_host_noeeprom(void) {
+ uint8_t next = 0;
+ for (uint8_t i = 0; i < HOST_CANDIDATES_COUNT; i++) {
+ if (host_candidates[i] == config.desired_host) {
+ next = i == HOST_CANDIDATES_COUNT - 1 ? 0 : i + 1;
+ break;
+ }
+ }
+
+ connection_set_host_noeeprom(host_candidates[next]);
+}
+
+void connection_next_host(void) {
+ connection_next_host_noeeprom();
+
+ eeconfig_update_connection(&config);
+}
+
+void connection_prev_host_noeeprom(void) {
+ uint8_t next = 0;
+ for (uint8_t i = 0; i < HOST_CANDIDATES_COUNT; i++) {
+ if (host_candidates[i] == config.desired_host) {
+ next = i == 0 ? HOST_CANDIDATES_COUNT - 1 : i - 1;
+ break;
+ }
+ }
+
+ connection_set_host_noeeprom(host_candidates[next]);
+}
+
+void connection_prev_host(void) {
+ connection_prev_host_noeeprom();
+
+ eeconfig_update_connection(&config);
+}
+
+connection_host_t connection_get_host_raw(void) {
+ return config.desired_host;
+}
+
+connection_host_t connection_auto_detect_host(void) {
+ if (usb_connected_state()) {
+ return CONNECTION_HOST_USB;
+ }
+
+#ifdef BLUETOOTH_ENABLE
+ if (bluetooth_is_connected()) {
+ return CONNECTION_HOST_BLUETOOTH;
+ }
+#endif
+
+ return CONNECTION_HOST_NONE;
+}
+
+connection_host_t connection_get_host(void) {
+ if (config.desired_host == CONNECTION_HOST_AUTO) {
+ return connection_auto_detect_host();
+ }
+ return config.desired_host;
+}
diff --git a/quantum/connection/connection.h b/quantum/connection/connection.h
new file mode 100644
index 00000000000..e403141faed
--- /dev/null
+++ b/quantum/connection/connection.h
@@ -0,0 +1,110 @@
+// Copyright 2025 QMK
+// SPDX-License-Identifier: GPL-2.0-or-later
+#pragma once
+
+#include
+#include "util.h"
+
+/**
+ * \enum connection_host_t
+ *
+ * An enumeration of the possible hosts.
+ */
+typedef enum connection_host_t {
+ CONNECTION_HOST_AUTO,
+
+ CONNECTION_HOST_NONE,
+ CONNECTION_HOST_USB,
+ CONNECTION_HOST_BLUETOOTH,
+ CONNECTION_HOST_2P4GHZ
+} connection_host_t;
+
+/**
+ * \union connection_config_t
+ *
+ * Configuration structure for the connection subsystem.
+ */
+typedef union connection_config_t {
+ uint8_t raw;
+ connection_host_t desired_host : 8;
+} PACKED connection_config_t;
+
+_Static_assert(sizeof(connection_config_t) == sizeof(uint8_t), "Connection EECONFIG out of spec.");
+
+/**
+ * \brief Initialize the subsystem.
+ *
+ * This function must be called only once, before any of the below functions can be called.
+ */
+void connection_init(void);
+
+/**
+ * \brief Get currently configured host. Does not resolve 'CONNECTION_HOST_AUTO'.
+ *
+ * \return 'connection_host_t' of the configured host.
+ */
+connection_host_t connection_get_host_raw(void);
+
+/**
+ * \brief Get current active host.
+ *
+ * \return 'connection_host_t' of the configured host.
+ */
+connection_host_t connection_auto_detect_host(void);
+
+/**
+ * \brief Get currently configured host. Resolves 'CONNECTION_HOST_AUTO' using 'connection_auto_detect_host()'.
+ *
+ * \return 'connection_host_t' of the configured host.
+ */
+connection_host_t connection_get_host(void);
+
+/**
+ * \brief Get current host. New state is not written to EEPROM.
+ *
+ * \param host The host to configure.
+ */
+void connection_set_host_noeeprom(connection_host_t host);
+
+/**
+ * \brief Get current host.
+ *
+ * \param host The host to configure.
+ */
+void connection_set_host(connection_host_t host);
+
+/**
+ * \brief Move to the next potential host. New state is not written to EEPROM.
+ *
+ */
+void connection_next_host_noeeprom(void);
+
+/**
+ * \brief Move to the next potential host.
+ *
+ */
+void connection_next_host(void);
+
+/**
+ * \brief Move to the previous potential host. New state is not written to EEPROM.
+ *
+ */
+void connection_prev_host_noeeprom(void);
+
+/**
+ * \brief Move to the previous potential host.
+ *
+ */
+void connection_prev_host(void);
+
+/**
+ * \brief user hook called when changing configured host
+ *
+ */
+void connection_host_changed_user(connection_host_t host);
+
+/**
+ * \brief keyboard hook called when changing configured host
+ *
+ */
+void connection_host_changed_kb(connection_host_t host);
diff --git a/quantum/dynamic_keymap.c b/quantum/dynamic_keymap.c
index bc5473a3d98..a5954119ad8 100644
--- a/quantum/dynamic_keymap.c
+++ b/quantum/dynamic_keymap.c
@@ -18,7 +18,6 @@
#include "dynamic_keymap.h"
#include "keymap_introspection.h"
#include "action.h"
-#include "eeprom.h"
#include "send_string.h"
#include "keycodes.h"
#include "nvm_eeconfig.h"
diff --git a/quantum/eeconfig.c b/quantum/eeconfig.c
index 7f559181e1f..9b7b6f6bc27 100644
--- a/quantum/eeconfig.c
+++ b/quantum/eeconfig.c
@@ -2,16 +2,11 @@
#include
#include
#include "debug.h"
-#include "eeprom.h"
#include "eeconfig.h"
#include "action_layer.h"
#include "nvm_eeconfig.h"
#include "keycode_config.h"
-#ifdef EEPROM_DRIVER
-# include "eeprom_driver.h"
-#endif // EEPROM_DRIVER
-
#ifdef BACKLIGHT_ENABLE
# include "backlight.h"
#endif // BACKLIGHT_ENABLE
@@ -40,6 +35,10 @@
# include "haptic.h"
#endif // HAPTIC_ENABLE
+#ifdef CONNECTION_ENABLE
+# include "connection.h"
+#endif // CONNECTION_ENABLE
+
#ifdef VIA_ENABLE
bool via_eeprom_is_valid(void);
void via_eeprom_set_valid(bool valid);
@@ -105,8 +104,8 @@ void eeconfig_init_quantum(void) {
#endif // AUDIO_ENABLE
#ifdef RGBLIGHT_ENABLE
- rgblight_config_t rgblight_config = {0};
- eeconfig_update_rgblight(&rgblight_config);
+ extern void eeconfig_update_rgblight_default(void);
+ eeconfig_update_rgblight_default();
#endif // RGBLIGHT_ENABLE
#ifdef UNICODE_COMMON_ENABLE
@@ -119,13 +118,13 @@ void eeconfig_init_quantum(void) {
#endif // STENO_ENABLE
#ifdef RGB_MATRIX_ENABLE
- rgb_config_t rgb_matrix_config = {0};
- eeconfig_update_rgb_matrix(&rgb_matrix_config);
+ extern void eeconfig_update_rgb_matrix_default(void);
+ eeconfig_update_rgb_matrix_default();
#endif
#ifdef LED_MATRIX_ENABLE
- led_eeconfig_t led_matrix_config = {0};
- eeconfig_update_led_matrix(&led_matrix_config);
+ extern void eeconfig_update_led_matrix_default(void);
+ eeconfig_update_led_matrix_default();
#endif // LED_MATRIX_ENABLE
#ifdef HAPTIC_ENABLE
@@ -134,6 +133,11 @@ void eeconfig_init_quantum(void) {
haptic_reset();
#endif // HAPTIC_ENABLE
+#ifdef CONNECTION_ENABLE
+ extern void eeconfig_update_connection_default(void);
+ eeconfig_update_connection_default();
+#endif // CONNECTION_ENABLE
+
#if (EECONFIG_KB_DATA_SIZE) > 0
eeconfig_init_kb_datablock();
#endif // (EECONFIG_KB_DATA_SIZE) > 0
@@ -153,6 +157,15 @@ void eeconfig_init_quantum(void) {
#endif
eeconfig_init_kb();
+
+#ifdef RGB_MATRIX_ENABLE
+ extern void eeconfig_force_flush_rgb_matrix(void);
+ eeconfig_force_flush_rgb_matrix();
+#endif // RGB_MATRIX_ENABLE
+#ifdef LED_MATRIX_ENABLE
+ extern void eeconfig_force_flush_led_matrix(void);
+ eeconfig_force_flush_led_matrix();
+#endif // LED_MATRIX_ENABLE
}
void eeconfig_init(void) {
@@ -306,6 +319,15 @@ void eeconfig_update_haptic(const haptic_config_t *haptic_config) {
}
#endif // HAPTIC_ENABLE
+#ifdef CONNECTION_ENABLE
+void eeconfig_read_connection(connection_config_t *config) {
+ nvm_eeconfig_read_connection(config);
+}
+void eeconfig_update_connection(const connection_config_t *config) {
+ nvm_eeconfig_update_connection(config);
+}
+#endif // CONNECTION_ENABLE
+
bool eeconfig_read_handedness(void) {
return nvm_eeconfig_read_handedness();
}
diff --git a/quantum/eeconfig.h b/quantum/eeconfig.h
index 4044f1c2947..d4d8d957bed 100644
--- a/quantum/eeconfig.h
+++ b/quantum/eeconfig.h
@@ -131,6 +131,12 @@ void eeconfig_read_haptic(haptic_config_t *haptic_confi
void eeconfig_update_haptic(const haptic_config_t *haptic_config) __attribute__((nonnull));
#endif
+#ifdef CONNECTION_ENABLE
+typedef union connection_config_t connection_config_t;
+void eeconfig_read_connection(connection_config_t *config);
+void eeconfig_update_connection(const connection_config_t *config);
+#endif
+
bool eeconfig_read_handedness(void);
void eeconfig_update_handedness(bool val);
diff --git a/quantum/keyboard.c b/quantum/keyboard.c
index 0671b0461f8..be51190a87d 100644
--- a/quantum/keyboard.c
+++ b/quantum/keyboard.c
@@ -146,6 +146,9 @@ along with this program. If not, see .
#ifdef LAYER_LOCK_ENABLE
# include "layer_lock.h"
#endif
+#ifdef CONNECTION_ENABLE
+# include "connection.h"
+#endif
static uint32_t last_input_modification_time = 0;
uint32_t last_input_activity_time(void) {
@@ -465,6 +468,9 @@ void keyboard_init(void) {
#endif
matrix_init();
quantum_init();
+#ifdef CONNECTION_ENABLE
+ connection_init();
+#endif
led_init_ports();
#ifdef BACKLIGHT_ENABLE
backlight_init_ports();
diff --git a/quantum/led_matrix/led_matrix.c b/quantum/led_matrix/led_matrix.c
index 2e107a66e96..f9d76e27761 100644
--- a/quantum/led_matrix/led_matrix.c
+++ b/quantum/led_matrix/led_matrix.c
@@ -19,7 +19,6 @@
#include "led_matrix.h"
#include "progmem.h"
-#include "eeprom.h"
#include "eeconfig.h"
#include "keyboard.h"
#include "sync_timer.h"
diff --git a/quantum/nvm/eeprom/nvm_eeconfig.c b/quantum/nvm/eeprom/nvm_eeconfig.c
index c24c16d9531..6d8be1a05cc 100644
--- a/quantum/nvm/eeprom/nvm_eeconfig.c
+++ b/quantum/nvm/eeprom/nvm_eeconfig.c
@@ -41,6 +41,10 @@
# include "haptic.h"
#endif
+#ifdef CONNECTION_ENABLE
+# include "connection.h"
+#endif
+
void nvm_eeconfig_erase(void) {
#ifdef EEPROM_DRIVER
eeprom_driver_format(false);
@@ -196,6 +200,15 @@ void nvm_eeconfig_update_haptic(const haptic_config_t *haptic_config) {
}
#endif // HAPTIC_ENABLE
+#ifdef CONNECTION_ENABLE
+void nvm_eeconfig_read_connection(connection_config_t *config) {
+ config->raw = eeprom_read_byte(EECONFIG_CONNECTION);
+}
+void nvm_eeconfig_update_connection(const connection_config_t *config) {
+ eeprom_update_byte(EECONFIG_CONNECTION, config->raw);
+}
+#endif // CONNECTION_ENABLE
+
bool nvm_eeconfig_read_handedness(void) {
return !!eeprom_read_byte(EECONFIG_HANDEDNESS);
}
diff --git a/quantum/nvm/eeprom/nvm_eeprom_eeconfig_internal.h b/quantum/nvm/eeprom/nvm_eeprom_eeconfig_internal.h
index 6e145e02b22..5236c617b32 100644
--- a/quantum/nvm/eeprom/nvm_eeprom_eeconfig_internal.h
+++ b/quantum/nvm/eeprom/nvm_eeprom_eeconfig_internal.h
@@ -27,6 +27,7 @@ typedef struct PACKED {
};
uint32_t haptic;
uint8_t rgblight_ext;
+ uint8_t connection;
uint32_t keymap_hash;
} eeprom_core_t;
@@ -47,6 +48,7 @@ typedef struct PACKED {
#define EECONFIG_RGB_MATRIX (uint64_t *)(offsetof(eeprom_core_t, rgb_matrix))
#define EECONFIG_HAPTIC (uint32_t *)(offsetof(eeprom_core_t, haptic))
#define EECONFIG_RGBLIGHT_EXTENDED (uint8_t *)(offsetof(eeprom_core_t, rgblight_ext))
+#define EECONFIG_CONNECTION (uint8_t *)(offsetof(eeprom_core_t, connection))
#define EECONFIG_KEYMAP_HASH (uint32_t *)(offsetof(eeprom_core_t, keymap_hash))
// Size of EEPROM being used for core data storage
diff --git a/quantum/nvm/nvm_eeconfig.h b/quantum/nvm/nvm_eeconfig.h
index 2df3ad1abd3..5658694fb4f 100644
--- a/quantum/nvm/nvm_eeconfig.h
+++ b/quantum/nvm/nvm_eeconfig.h
@@ -87,6 +87,12 @@ void nvm_eeconfig_read_haptic(haptic_config_t *haptic_c
void nvm_eeconfig_update_haptic(const haptic_config_t *haptic_config);
#endif // HAPTIC_ENABLE
+#ifdef CONNECTION_ENABLE
+typedef union connection_config_t connection_config_t;
+void nvm_eeconfig_read_connection(connection_config_t *config);
+void nvm_eeconfig_update_connection(const connection_config_t *config);
+#endif // CONNECTION_ENABLE
+
bool nvm_eeconfig_read_handedness(void);
void nvm_eeconfig_update_handedness(bool val);
diff --git a/quantum/process_keycode/process_connection.c b/quantum/process_keycode/process_connection.c
index b0e230d680a..501529ede7e 100644
--- a/quantum/process_keycode/process_connection.c
+++ b/quantum/process_keycode/process_connection.c
@@ -1,24 +1,34 @@
// Copyright 2024 Nick Brassel (@tzarc)
// SPDX-License-Identifier: GPL-2.0-or-later
-#include "outputselect.h"
+#include "connection.h"
#include "process_connection.h"
bool process_connection(uint16_t keycode, keyrecord_t *record) {
if (record->event.pressed) {
switch (keycode) {
case QK_OUTPUT_NEXT:
- set_output(OUTPUT_AUTO); // This should cycle through the outputs going forward. Ensure `docs/keycodes.md`, `docs/features/bluetooth.md` are updated when it does.
+ connection_next_host();
return false;
- case QK_OUTPUT_USB:
- set_output(OUTPUT_USB);
- return false;
- case QK_OUTPUT_BLUETOOTH:
- set_output(OUTPUT_BLUETOOTH);
+ case QK_OUTPUT_PREV:
+ connection_prev_host();
return false;
- case QK_OUTPUT_PREV:
+ case QK_OUTPUT_AUTO:
+ connection_set_host(CONNECTION_HOST_AUTO);
+ return false;
case QK_OUTPUT_NONE:
+ connection_set_host(CONNECTION_HOST_NONE);
+ return false;
+ case QK_OUTPUT_USB:
+ connection_set_host(CONNECTION_HOST_USB);
+ return false;
+ case QK_OUTPUT_BLUETOOTH:
+ connection_set_host(CONNECTION_HOST_BLUETOOTH);
+ return false;
case QK_OUTPUT_2P4GHZ:
+ connection_set_host(CONNECTION_HOST_2P4GHZ);
+ return false;
+
case QK_BLUETOOTH_PROFILE_NEXT:
case QK_BLUETOOTH_PROFILE_PREV:
case QK_BLUETOOTH_UNPAIR:
diff --git a/quantum/quantum.c b/quantum/quantum.c
index c789fdb69da..bbc7f980c56 100644
--- a/quantum/quantum.c
+++ b/quantum/quantum.c
@@ -20,7 +20,7 @@
# include "process_backlight.h"
#endif
-#ifdef BLUETOOTH_ENABLE
+#ifdef CONNECTION_ENABLE
# include "process_connection.h"
#endif
@@ -436,7 +436,7 @@ bool process_record_quantum(keyrecord_t *record) {
#ifdef LAYER_LOCK_ENABLE
process_layer_lock(keycode, record) &&
#endif
-#ifdef BLUETOOTH_ENABLE
+#ifdef CONNECTION_ENABLE
process_connection(keycode, record) &&
#endif
true)) {
diff --git a/quantum/rgb_matrix/rgb_matrix.c b/quantum/rgb_matrix/rgb_matrix.c
index a18105c9b35..3fc9085f06c 100644
--- a/quantum/rgb_matrix/rgb_matrix.c
+++ b/quantum/rgb_matrix/rgb_matrix.c
@@ -18,7 +18,6 @@
#include "rgb_matrix.h"
#include "progmem.h"
-#include "eeprom.h"
#include "eeconfig.h"
#include "keyboard.h"
#include "sync_timer.h"
diff --git a/quantum/unicode/unicode.c b/quantum/unicode/unicode.c
index b0729335f07..dff1d43fb41 100644
--- a/quantum/unicode/unicode.c
+++ b/quantum/unicode/unicode.c
@@ -16,7 +16,6 @@
#include "unicode.h"
-#include "eeprom.h"
#include "eeconfig.h"
#include "action.h"
#include "action_util.h"
diff --git a/quantum/via.c b/quantum/via.c
index c746d9a6082..3682b4ab2b2 100644
--- a/quantum/via.c
+++ b/quantum/via.c
@@ -26,7 +26,6 @@
#include "raw_hid.h"
#include "dynamic_keymap.h"
-#include "eeprom.h"
#include "eeconfig.h"
#include "matrix.h"
#include "timer.h"
diff --git a/tmk_core/protocol/chibios/chibios.c b/tmk_core/protocol/chibios/chibios.c
index cf948154f9b..d752f3746b0 100644
--- a/tmk_core/protocol/chibios/chibios.c
+++ b/tmk_core/protocol/chibios/chibios.c
@@ -134,8 +134,6 @@ void protocol_setup(void) {
// chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);
}
-static host_driver_t *driver = NULL;
-
void protocol_pre_init(void) {
/* Init USB */
usb_event_queue_init();
@@ -146,18 +144,11 @@ void protocol_pre_init(void) {
#endif
/* Wait until USB is active */
- while (true) {
-#if defined(USB_WAIT_FOR_ENUMERATION)
- if (USB_DRIVER.state == USB_ACTIVE) {
- driver = &chibios_driver;
- break;
- }
-#else
- driver = &chibios_driver;
- break;
-#endif
+#ifdef USB_WAIT_FOR_ENUMERATION
+ while (USB_DRIVER.state != USB_ACTIVE) {
wait_ms(50);
}
+#endif
/* Do need to wait here!
* Otherwise the next print might start a transfer on console EP
@@ -170,7 +161,7 @@ void protocol_pre_init(void) {
}
void protocol_post_init(void) {
- host_set_driver(driver);
+ host_set_driver(&chibios_driver);
}
void protocol_pre_task(void) {
diff --git a/tmk_core/protocol/host.c b/tmk_core/protocol/host.c
index df805c827c2..453952049fe 100644
--- a/tmk_core/protocol/host.c
+++ b/tmk_core/protocol/host.c
@@ -31,8 +31,11 @@ along with this program. If not, see .
#endif
#ifdef BLUETOOTH_ENABLE
+# ifndef CONNECTION_ENABLE
+# error CONNECTION_ENABLE required and not enabled
+# endif
+# include "connection.h"
# include "bluetooth.h"
-# include "outputselect.h"
#endif
#ifdef NKRO_ENABLE
@@ -74,7 +77,7 @@ led_t host_keyboard_led_state(void) {
/* send report */
void host_keyboard_send(report_keyboard_t *report) {
#ifdef BLUETOOTH_ENABLE
- if (where_to_send() == OUTPUT_BLUETOOTH) {
+ if (connection_get_host() == CONNECTION_HOST_BLUETOOTH) {
bluetooth_send_keyboard(report);
return;
}
@@ -111,7 +114,7 @@ void host_nkro_send(report_nkro_t *report) {
void host_mouse_send(report_mouse_t *report) {
#ifdef BLUETOOTH_ENABLE
- if (where_to_send() == OUTPUT_BLUETOOTH) {
+ if (connection_get_host() == CONNECTION_HOST_BLUETOOTH) {
bluetooth_send_mouse(report);
return;
}
@@ -147,7 +150,7 @@ void host_consumer_send(uint16_t usage) {
last_consumer_usage = usage;
#ifdef BLUETOOTH_ENABLE
- if (where_to_send() == OUTPUT_BLUETOOTH) {
+ if (connection_get_host() == CONNECTION_HOST_BLUETOOTH) {
bluetooth_send_consumer(usage);
return;
}