diff options
| author | Joel Challis <git@zvecr.com> | 2025-08-17 01:14:48 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-17 01:14:48 +0100 |
| commit | cc696a2ae838a9639335ca8eb3cb3b794c06bc33 (patch) | |
| tree | 901b54bda536acb5503c6cf924b0f30bca1a174e | |
| parent | f29d8117bf877a4df1f88f40e0131f4465748540 (diff) | |
Refactor battery driver (#25550)
26 files changed, 287 insertions, 73 deletions
diff --git a/builddefs/build_test.mk b/builddefs/build_test.mk index 0c5c98e2a3..ccdad1b4e7 100644 --- a/builddefs/build_test.mk +++ b/builddefs/build_test.mk | |||
| @@ -62,6 +62,7 @@ include $(BUILDDEFS_PATH)/common_features.mk | |||
| 62 | include $(BUILDDEFS_PATH)/generic_features.mk | 62 | include $(BUILDDEFS_PATH)/generic_features.mk |
| 63 | include $(PLATFORM_PATH)/common.mk | 63 | include $(PLATFORM_PATH)/common.mk |
| 64 | include $(TMK_PATH)/protocol.mk | 64 | include $(TMK_PATH)/protocol.mk |
| 65 | include $(QUANTUM_PATH)/battery/tests/rules.mk | ||
| 65 | include $(QUANTUM_PATH)/debounce/tests/rules.mk | 66 | include $(QUANTUM_PATH)/debounce/tests/rules.mk |
| 66 | include $(QUANTUM_PATH)/encoder/tests/rules.mk | 67 | include $(QUANTUM_PATH)/encoder/tests/rules.mk |
| 67 | include $(QUANTUM_PATH)/os_detection/tests/rules.mk | 68 | include $(QUANTUM_PATH)/os_detection/tests/rules.mk |
diff --git a/builddefs/common_features.mk b/builddefs/common_features.mk index c122afcff9..1da13997b5 100644 --- a/builddefs/common_features.mk +++ b/builddefs/common_features.mk | |||
| @@ -945,21 +945,25 @@ ifeq ($(strip $(DIP_SWITCH_ENABLE)), yes) | |||
| 945 | endif | 945 | endif |
| 946 | endif | 946 | endif |
| 947 | 947 | ||
| 948 | ifeq ($(strip $(BATTERY_ENABLE)), yes) | ||
| 949 | BATTERY_DRIVER_REQUIRED := yes | ||
| 950 | endif | ||
| 951 | |||
| 948 | VALID_BATTERY_DRIVER_TYPES := adc custom vendor | 952 | VALID_BATTERY_DRIVER_TYPES := adc custom vendor |
| 949 | 953 | ||
| 950 | BATTERY_DRIVER ?= adc | 954 | BATTERY_DRIVER ?= none |
| 951 | ifeq ($(strip $(BATTERY_DRIVER_REQUIRED)), yes) | 955 | ifeq ($(strip $(BATTERY_DRIVER_REQUIRED)), yes) |
| 952 | ifeq ($(filter $(BATTERY_DRIVER),$(VALID_BATTERY_DRIVER_TYPES)),) | 956 | ifeq ($(filter $(BATTERY_DRIVER),$(VALID_BATTERY_DRIVER_TYPES)),) |
| 953 | $(call CATASTROPHIC_ERROR,Invalid BATTERY_DRIVER,BATTERY_DRIVER="$(BATTERY_DRIVER)" is not a valid battery driver) | 957 | $(call CATASTROPHIC_ERROR,Invalid BATTERY_DRIVER,BATTERY_DRIVER="$(BATTERY_DRIVER)" is not a valid battery driver) |
| 954 | endif | 958 | endif |
| 955 | 959 | ||
| 956 | OPT_DEFS += -DBATTERY_DRIVER | 960 | OPT_DEFS += -DBATTERY_DRIVER_$(strip $(shell echo $(BATTERY_DRIVER) | tr '[:lower:]' '[:upper:]')) |
| 957 | OPT_DEFS += -DBATTERY_$(strip $(shell echo $(BATTERY_DRIVER) | tr '[:lower:]' '[:upper:]')) | ||
| 958 | 961 | ||
| 959 | COMMON_VPATH += $(DRIVER_PATH)/battery | 962 | COMMON_VPATH += $(DRIVER_PATH)/battery |
| 960 | 963 | ||
| 961 | SRC += battery.c | 964 | ifneq ($(strip $(BATTERY_DRIVER)), custom) |
| 962 | SRC += battery_$(strip $(BATTERY_DRIVER)).c | 965 | SRC += battery_$(strip $(BATTERY_DRIVER)).c |
| 966 | endif | ||
| 963 | 967 | ||
| 964 | # add extra deps | 968 | # add extra deps |
| 965 | ifeq ($(strip $(BATTERY_DRIVER)), adc) | 969 | ifeq ($(strip $(BATTERY_DRIVER)), adc) |
diff --git a/builddefs/generic_features.mk b/builddefs/generic_features.mk index c826514431..6d394977bd 100644 --- a/builddefs/generic_features.mk +++ b/builddefs/generic_features.mk | |||
| @@ -21,6 +21,7 @@ SPACE_CADET_ENABLE ?= yes | |||
| 21 | GENERIC_FEATURES = \ | 21 | GENERIC_FEATURES = \ |
| 22 | AUTO_SHIFT \ | 22 | AUTO_SHIFT \ |
| 23 | AUTOCORRECT \ | 23 | AUTOCORRECT \ |
| 24 | BATTERY \ | ||
| 24 | BOOTMAGIC \ | 25 | BOOTMAGIC \ |
| 25 | CAPS_WORD \ | 26 | CAPS_WORD \ |
| 26 | COMBO \ | 27 | COMBO \ |
diff --git a/builddefs/testlist.mk b/builddefs/testlist.mk index 74a794adcd..2e81fe576b 100644 --- a/builddefs/testlist.mk +++ b/builddefs/testlist.mk | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | TEST_LIST = $(sort $(patsubst %/test.mk,%, $(shell find $(ROOT_DIR)tests -type f -name test.mk))) | 1 | TEST_LIST = $(sort $(patsubst %/test.mk,%, $(shell find $(ROOT_DIR)tests -type f -name test.mk))) |
| 2 | FULL_TESTS := $(notdir $(TEST_LIST)) | 2 | FULL_TESTS := $(notdir $(TEST_LIST)) |
| 3 | 3 | ||
| 4 | include $(QUANTUM_PATH)/battery/tests/testlist.mk | ||
| 4 | include $(QUANTUM_PATH)/debounce/tests/testlist.mk | 5 | include $(QUANTUM_PATH)/debounce/tests/testlist.mk |
| 5 | include $(QUANTUM_PATH)/encoder/tests/testlist.mk | 6 | include $(QUANTUM_PATH)/encoder/tests/testlist.mk |
| 6 | include $(QUANTUM_PATH)/os_detection/tests/testlist.mk | 7 | include $(QUANTUM_PATH)/os_detection/tests/testlist.mk |
diff --git a/data/mappings/info_config.hjson b/data/mappings/info_config.hjson index a160e490c7..4c53aa4339 100644 --- a/data/mappings/info_config.hjson +++ b/data/mappings/info_config.hjson | |||
| @@ -43,6 +43,14 @@ | |||
| 43 | "BOOTMAGIC_ROW": {"info_key": "bootmagic.matrix.0", "value_type": "int"}, | 43 | "BOOTMAGIC_ROW": {"info_key": "bootmagic.matrix.0", "value_type": "int"}, |
| 44 | "BOOTMAGIC_ROW_RIGHT": {"info_key": "split.bootmagic.matrix.0", "value_type": "int"}, | 44 | "BOOTMAGIC_ROW_RIGHT": {"info_key": "split.bootmagic.matrix.0", "value_type": "int"}, |
| 45 | 45 | ||
| 46 | // Battery | ||
| 47 | "BATTERY_SAMPLE_INTERVAL": {"info_key": "battery.sample_interval", "value_type": "int"}, | ||
| 48 | "BATTERY_ADC_PIN": {"info_key": "battery.adc.pin"}, | ||
| 49 | "BATTERY_ADC_REF_VOLTAGE_MV": {"info_key": "battery.adc.reference_voltage", "value_type": "int"}, | ||
| 50 | "BATTERY_ADC_VOLTAGE_DIVIDER_R1": {"info_key": "battery.adc.divider_r1", "value_type": "int"}, | ||
| 51 | "BATTERY_ADC_VOLTAGE_DIVIDER_R2": {"info_key": "battery.adc.divider_r2", "value_type": "int"}, | ||
| 52 | "BATTERY_ADC_RESOLUTION": {"info_key": "battery.adc.resolution", "value_type": "int"}, | ||
| 53 | |||
| 46 | // Caps Word | 54 | // Caps Word |
| 47 | "BOTH_SHIFTS_TURNS_ON_CAPS_WORD": {"info_key": "caps_word.both_shifts_turns_on", "value_type": "flag"}, | 55 | "BOTH_SHIFTS_TURNS_ON_CAPS_WORD": {"info_key": "caps_word.both_shifts_turns_on", "value_type": "flag"}, |
| 48 | "CAPS_WORD_IDLE_TIMEOUT": {"info_key": "caps_word.idle_timeout", "value_type": "int"}, | 56 | "CAPS_WORD_IDLE_TIMEOUT": {"info_key": "caps_word.idle_timeout", "value_type": "int"}, |
diff --git a/data/mappings/info_rules.hjson b/data/mappings/info_rules.hjson index d43d83c3ea..5ecd5c12b3 100644 --- a/data/mappings/info_rules.hjson +++ b/data/mappings/info_rules.hjson | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | 13 | ||
| 14 | "AUDIO_DRIVER": {"info_key": "audio.driver"}, | 14 | "AUDIO_DRIVER": {"info_key": "audio.driver"}, |
| 15 | "BACKLIGHT_DRIVER": {"info_key": "backlight.driver"}, | 15 | "BACKLIGHT_DRIVER": {"info_key": "backlight.driver"}, |
| 16 | "BATTERY_DRIVER": {"info_key": "battery.driver"}, | ||
| 16 | "BLUETOOTH_DRIVER": {"info_key": "bluetooth.driver"}, | 17 | "BLUETOOTH_DRIVER": {"info_key": "bluetooth.driver"}, |
| 17 | "BOARD": {"info_key": "board"}, | 18 | "BOARD": {"info_key": "board"}, |
| 18 | "BOOTLOADER": {"info_key": "bootloader", "warn_duplicate": false}, | 19 | "BOOTLOADER": {"info_key": "bootloader", "warn_duplicate": false}, |
diff --git a/data/schemas/keyboard.jsonschema b/data/schemas/keyboard.jsonschema index 3775b66c1a..93b1c82b1c 100644 --- a/data/schemas/keyboard.jsonschema +++ b/data/schemas/keyboard.jsonschema | |||
| @@ -188,6 +188,28 @@ | |||
| 188 | "as_caps_lock": {"type": "boolean"} | 188 | "as_caps_lock": {"type": "boolean"} |
| 189 | } | 189 | } |
| 190 | }, | 190 | }, |
| 191 | "battery": { | ||
| 192 | "type": "object", | ||
| 193 | "additionalProperties": false, | ||
| 194 | "properties": { | ||
| 195 | "driver": { | ||
| 196 | "type": "string", | ||
| 197 | "enum": ["adc", "custom", "vendor"] | ||
| 198 | }, | ||
| 199 | "adc": { | ||
| 200 | "type": "object", | ||
| 201 | "additionalProperties": false, | ||
| 202 | "properties": { | ||
| 203 | "pin": {"$ref": "./definitions.jsonschema#/mcu_pin"}, | ||
| 204 | "reference_voltage": {"type": "integer"}, | ||
| 205 | "divider_r1": {"type": "integer"}, | ||
| 206 | "divider_r2": {"type": "integer"}, | ||
| 207 | "resolution": {"type": "integer"} | ||
| 208 | } | ||
| 209 | }, | ||
| 210 | "sample_interval": {"type": "integer"} | ||
| 211 | } | ||
| 212 | }, | ||
| 191 | "bluetooth": { | 213 | "bluetooth": { |
| 192 | "type": "object", | 214 | "type": "object", |
| 193 | "additionalProperties": false, | 215 | "additionalProperties": false, |
diff --git a/docs/_sidebar.json b/docs/_sidebar.json index ee4709a650..eec345b788 100644 --- a/docs/_sidebar.json +++ b/docs/_sidebar.json | |||
| @@ -175,6 +175,7 @@ | |||
| 175 | ] | 175 | ] |
| 176 | }, | 176 | }, |
| 177 | { "text": "Audio", "link": "/features/audio" }, | 177 | { "text": "Audio", "link": "/features/audio" }, |
| 178 | { "text": "Battery", "link": "/features/battery" }, | ||
| 178 | { "text": "Bootmagic", "link": "/features/bootmagic" }, | 179 | { "text": "Bootmagic", "link": "/features/bootmagic" }, |
| 179 | { "text": "Converters", "link": "/feature_converters" }, | 180 | { "text": "Converters", "link": "/feature_converters" }, |
| 180 | { "text": "Custom Matrix", "link": "/custom_matrix" }, | 181 | { "text": "Custom Matrix", "link": "/custom_matrix" }, |
diff --git a/docs/drivers/battery.md b/docs/drivers/battery.md index e482ffc8b6..ae07668cc0 100644 --- a/docs/drivers/battery.md +++ b/docs/drivers/battery.md | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | # Battery Driver | 1 | # Battery Driver |
| 2 | 2 | ||
| 3 | This driver provides support for sampling battery level. | 3 | This driver provides support for directly sampling battery level. |
| 4 | 4 | ||
| 5 | ## Usage | 5 | ## Usage |
| 6 | 6 | ||
| @@ -10,21 +10,17 @@ To use this driver, add the following to your `rules.mk`: | |||
| 10 | BATTERY_DRIVER_REQUIRED = yes | 10 | BATTERY_DRIVER_REQUIRED = yes |
| 11 | ``` | 11 | ``` |
| 12 | 12 | ||
| 13 | ## Basic Configuration {#basic-configuration} | 13 | ::::info Note |
| 14 | 14 | This is already configured for you if you are using the [Battery](../features/battery) feature. | |
| 15 | Add the following to your `config.h`: | 15 | :::: |
| 16 | |||
| 17 | |Define |Default |Description | | ||
| 18 | |--------------------------|--------|--------------------------------------------------| | ||
| 19 | |`BATTERY_SAMPLE_INTERVAL` |`30000` |The time between battery samples in milliseconds. | | ||
| 20 | 16 | ||
| 21 | ## Driver Configuration {#driver-configuration} | 17 | ## Driver Configuration {#driver-configuration} |
| 22 | 18 | ||
| 23 | Driver selection can be configured in `rules.mk` as `BATTERY_DRIVER`. Valid values are `adc` (default), `vendor`, or `custom`. See below for information on individual drivers. | 19 | Driver selection can be configured in `rules.mk` as `BATTERY_DRIVER`. Valid values are `adc`, `vendor`, or `custom`. See below for information on individual drivers. |
| 24 | 20 | ||
| 25 | ### ADC Driver {#adc-driver} | 21 | ### ADC Driver {#adc-driver} |
| 26 | 22 | ||
| 27 | This is the default battery driver. The default configuration assumes the battery is connected to a ADC capable pin through a voltage divider. | 23 | The default configuration assumes the battery is connected to a ADC capable pin through a voltage divider. |
| 28 | 24 | ||
| 29 | ```make | 25 | ```make |
| 30 | BATTERY_DRIVER = adc | 26 | BATTERY_DRIVER = adc |
| @@ -32,42 +28,25 @@ BATTERY_DRIVER = adc | |||
| 32 | 28 | ||
| 33 | The following `#define`s apply only to the `adc` driver: | 29 | The following `#define`s apply only to the `adc` driver: |
| 34 | 30 | ||
| 35 | |Define |Default |Description | | 31 | |Define |Default |Description | |
| 36 | |-----------------------------|--------------|--------------------------------------------------------------| | 32 | |---------------------------------|--------------|--------------------------------------------------------------| |
| 37 | |`BATTERY_PIN` |*Not defined* |The GPIO pin connected to the voltage divider. | | 33 | |`BATTERY_ADC_PIN` |*Not defined* |The GPIO pin connected to the voltage divider. | |
| 38 | |`BATTERY_REF_VOLTAGE_MV` |`3300` |The ADC reverence voltage, in millivolts. | | 34 | |`BATTERY_ADC_REF_VOLTAGE_MV` |`3300` |The ADC reverence voltage, in millivolts. | |
| 39 | |`BATTERY_VOLTAGE_DIVIDER_R1` |`100` |The voltage divider resistance, in kOhm. Set to 0 to disable. | | 35 | |`BATTERY_ADC_VOLTAGE_DIVIDER_R1` |`100` |The voltage divider resistance, in kOhm. Set to 0 to disable. | |
| 40 | |`BATTERY_VOLTAGE_DIVIDER_R2` |`100` |The voltage divider resistance, in kOhm. Set to 0 to disable. | | 36 | |`BATTERY_ADC_VOLTAGE_DIVIDER_R2` |`100` |The voltage divider resistance, in kOhm. Set to 0 to disable. | |
| 41 | |`BATTERY_ADC_RESOLUTION` |`10` |The ADC resolution configured for the ADC Driver. | | 37 | |`BATTERY_ADC_RESOLUTION` |`10` |The ADC resolution configured for the ADC Driver. | |
| 42 | |||
| 43 | ## Functions | ||
| 44 | |||
| 45 | ### `uint8_t battery_get_percent(void)` {#api-battery-get-percent} | ||
| 46 | |||
| 47 | Sample battery level. | ||
| 48 | |||
| 49 | #### Return Value {#api-battery-get-percent-return} | ||
| 50 | |||
| 51 | The battery percentage, in the range 0-100. | ||
| 52 | 38 | ||
| 53 | ## Callbacks | 39 | ### Custom Driver {#custom-driver} |
| 54 | 40 | ||
| 55 | ### `void battery_percent_changed_user(uint8_t level)` {#api-battery-percent-changed-user} | 41 | A custom driver is expected to implement the following interface: |
| 56 | 42 | ||
| 57 | User hook called when battery level changed. | 43 | ```c |
| 44 | void battery_driver_init(void) { | ||
| 45 | // Perform any initialisation here | ||
| 46 | } | ||
| 58 | 47 | ||
| 59 | ### Arguments {#api-battery-percent-changed-user-arguments} | 48 | uint8_t battery_driver_sample_percent(void) { |
| 60 | 49 | // Read and return current state here | |
| 61 | - `uint8_t level` | 50 | return value; |
| 62 | The battery percentage, in the range 0-100. | 51 | } |
| 63 | 52 | ``` | |
| 64 | --- | ||
| 65 | |||
| 66 | ### `void battery_percent_changed_kb(uint8_t level)` {#api-battery-percent-changed-kb} | ||
| 67 | |||
| 68 | Keyboard hook called when battery level changed. | ||
| 69 | |||
| 70 | ### Arguments {#api-battery-percent-changed-kb-arguments} | ||
| 71 | |||
| 72 | - `uint8_t level` | ||
| 73 | The battery percentage, in the range 0-100. | ||
diff --git a/docs/features/battery.md b/docs/features/battery.md new file mode 100644 index 0000000000..f5c725efb9 --- /dev/null +++ b/docs/features/battery.md | |||
| @@ -0,0 +1,55 @@ | |||
| 1 | # Battery | ||
| 2 | |||
| 3 | This feature provides the high level abstraction for sampling battery level. | ||
| 4 | |||
| 5 | ## Usage | ||
| 6 | |||
| 7 | To use this driver, add the following to your `rules.mk`: | ||
| 8 | |||
| 9 | ```make | ||
| 10 | BATTERY_ENABLE = yes | ||
| 11 | ``` | ||
| 12 | |||
| 13 | ## Basic Configuration {#basic-configuration} | ||
| 14 | |||
| 15 | Add the following to your `config.h`: | ||
| 16 | |||
| 17 | |Define |Default |Description | | ||
| 18 | |--------------------------|--------|--------------------------------------------------| | ||
| 19 | |`BATTERY_SAMPLE_INTERVAL` |`30000` |The time between battery samples in milliseconds. | | ||
| 20 | |||
| 21 | ## Driver Configuration {#driver-configuration} | ||
| 22 | |||
| 23 | See the [Battery Driver](../drivers/battery) documentation for more information. | ||
| 24 | |||
| 25 | ## Functions | ||
| 26 | |||
| 27 | ### `uint8_t battery_get_percent(void)` {#api-battery-get-percent} | ||
| 28 | |||
| 29 | Sample battery level. | ||
| 30 | |||
| 31 | #### Return Value {#api-battery-get-percent-return} | ||
| 32 | |||
| 33 | The battery percentage, in the range 0-100. | ||
| 34 | |||
| 35 | ## Callbacks | ||
| 36 | |||
| 37 | ### `void battery_percent_changed_user(uint8_t level)` {#api-battery-percent-changed-user} | ||
| 38 | |||
| 39 | User hook called when battery level changed. | ||
| 40 | |||
| 41 | ### Arguments {#api-battery-percent-changed-user-arguments} | ||
| 42 | |||
| 43 | - `uint8_t level` | ||
| 44 | The battery percentage, in the range 0-100. | ||
| 45 | |||
| 46 | --- | ||
| 47 | |||
| 48 | ### `void battery_percent_changed_kb(uint8_t level)` {#api-battery-percent-changed-kb} | ||
| 49 | |||
| 50 | Keyboard hook called when battery level changed. | ||
| 51 | |||
| 52 | ### Arguments {#api-battery-percent-changed-kb-arguments} | ||
| 53 | |||
| 54 | - `uint8_t level` | ||
| 55 | The battery percentage, in the range 0-100. | ||
diff --git a/docs/reference_info_json.md b/docs/reference_info_json.md index cf22317613..84377ef36c 100644 --- a/docs/reference_info_json.md +++ b/docs/reference_info_json.md | |||
| @@ -179,6 +179,32 @@ Configures the [Backlight](features/backlight) feature. | |||
| 179 | * `pins` <Badge type="info">Array: Pin</Badge> | 179 | * `pins` <Badge type="info">Array: Pin</Badge> |
| 180 | * A list of GPIO pins connected to the backlight LEDs (`software` and `timer` drivers only). | 180 | * A list of GPIO pins connected to the backlight LEDs (`software` and `timer` drivers only). |
| 181 | 181 | ||
| 182 | ## Battery | ||
| 183 | |||
| 184 | Configures the [Battery](features/battery) feature. | ||
| 185 | |||
| 186 | * `battery` | ||
| 187 | * `adc` | ||
| 188 | * `pin` <Badge type="info">Pin</Badge> <Badge>Required</Badge> | ||
| 189 | * The GPIO pin connected to the voltage divider. | ||
| 190 | * `reference_voltage` <Badge type="info">Number</Badge> | ||
| 191 | * The ADC reverence voltage, in millivolts. | ||
| 192 | * Default: `3300` | ||
| 193 | * `divider_r1` <Badge type="info">Number</Badge> | ||
| 194 | * The voltage divider resistance, in kOhm. Set to 0 to disable. | ||
| 195 | * Default: `100` | ||
| 196 | * `divider_r2` <Badge type="info">Number</Badge> | ||
| 197 | * The voltage divider resistance, in kOhm. Set to 0 to disable. | ||
| 198 | * Default: `100` | ||
| 199 | * `resolution` <Badge type="info">Number</Badge> | ||
| 200 | * The ADC resolution configured for the ADC Driver. | ||
| 201 | * Default: `10` | ||
| 202 | * `driver` <Badge type="info">String</Badge> <Badge>Required</Badge> | ||
| 203 | * The driver to use. Must be one of `adc`, `custom`, `vendor`. | ||
| 204 | * `sample_interval` <Badge type="info">Number</Badge> | ||
| 205 | * The delay between sampling the battery in milliseconds. | ||
| 206 | * Default: `30000` (30 s) | ||
| 207 | |||
| 182 | ## Wireless/Bluetooth {#bluetooth} | 208 | ## Wireless/Bluetooth {#bluetooth} |
| 183 | 209 | ||
| 184 | Configures the [Wireless](features/wireless) feature. | 210 | Configures the [Wireless](features/wireless) feature. |
diff --git a/drivers/battery/battery_adc.c b/drivers/battery/battery_adc.c index cf0e69cb48..145265b5db 100644 --- a/drivers/battery/battery_adc.c +++ b/drivers/battery/battery_adc.c | |||
| @@ -1,23 +1,24 @@ | |||
| 1 | // Copyright 2025 QMK | 1 | // Copyright 2025 QMK |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "battery_driver.h" | ||
| 4 | #include "analog.h" | 5 | #include "analog.h" |
| 5 | #include "gpio.h" | 6 | #include "gpio.h" |
| 6 | 7 | ||
| 7 | #ifndef BATTERY_PIN | 8 | #ifndef BATTERY_ADC_PIN |
| 8 | # error("BATTERY_PIN not configured!") | 9 | # error("BATTERY_ADC_PIN not configured!") |
| 9 | #endif | 10 | #endif |
| 10 | 11 | ||
| 11 | #ifndef BATTERY_REF_VOLTAGE_MV | 12 | #ifndef BATTERY_ADC_REF_VOLTAGE_MV |
| 12 | # define BATTERY_REF_VOLTAGE_MV 3300 | 13 | # define BATTERY_ADC_REF_VOLTAGE_MV 3300 |
| 13 | #endif | 14 | #endif |
| 14 | 15 | ||
| 15 | #ifndef BATTERY_VOLTAGE_DIVIDER_R1 | 16 | #ifndef BATTERY_ADC_VOLTAGE_DIVIDER_R1 |
| 16 | # define BATTERY_VOLTAGE_DIVIDER_R1 100 | 17 | # define BATTERY_VOLTAGE_DIVIDER_R1 100 |
| 17 | #endif | 18 | #endif |
| 18 | 19 | ||
| 19 | #ifndef BATTERY_VOLTAGE_DIVIDER_R2 | 20 | #ifndef BATTERY_ADC_VOLTAGE_DIVIDER_R2 |
| 20 | # define BATTERY_VOLTAGE_DIVIDER_R2 100 | 21 | # define BATTERY_ADC_VOLTAGE_DIVIDER_R2 100 |
| 21 | #endif | 22 | #endif |
| 22 | 23 | ||
| 23 | // TODO: infer from adc config? | 24 | // TODO: infer from adc config? |
| @@ -26,16 +27,16 @@ | |||
| 26 | #endif | 27 | #endif |
| 27 | 28 | ||
| 28 | void battery_driver_init(void) { | 29 | void battery_driver_init(void) { |
| 29 | gpio_set_pin_input(BATTERY_PIN); | 30 | gpio_set_pin_input(BATTERY_ADC_PIN); |
| 30 | } | 31 | } |
| 31 | 32 | ||
| 32 | uint16_t battery_driver_get_mv(void) { | 33 | uint16_t battery_driver_get_mv(void) { |
| 33 | uint32_t raw = analogReadPin(BATTERY_PIN); | 34 | uint32_t raw = analogReadPin(BATTERY_ADC_PIN); |
| 34 | 35 | ||
| 35 | uint32_t bat_mv = raw * BATTERY_REF_VOLTAGE_MV / (1 << BATTERY_ADC_RESOLUTION); | 36 | uint32_t bat_mv = raw * BATTERY_ADC_REF_VOLTAGE_MV / (1 << BATTERY_ADC_RESOLUTION); |
| 36 | 37 | ||
| 37 | #if BATTERY_VOLTAGE_DIVIDER_R1 > 0 && BATTERY_VOLTAGE_DIVIDER_R2 > 0 | 38 | #if BATTERY_VOLTAGE_DIVIDER_R1 > 0 && BATTERY_ADC_VOLTAGE_DIVIDER_R2 > 0 |
| 38 | bat_mv = bat_mv * (BATTERY_VOLTAGE_DIVIDER_R1 + BATTERY_VOLTAGE_DIVIDER_R2) / BATTERY_VOLTAGE_DIVIDER_R2; | 39 | bat_mv = bat_mv * (BATTERY_VOLTAGE_DIVIDER_R1 + BATTERY_ADC_VOLTAGE_DIVIDER_R2) / BATTERY_ADC_VOLTAGE_DIVIDER_R2; |
| 39 | #endif | 40 | #endif |
| 40 | 41 | ||
| 41 | return bat_mv; | 42 | return bat_mv; |
diff --git a/keyboards/handwired/onekey/keymaps/battery/config.h b/keyboards/handwired/onekey/keymaps/battery/config.h index 8a1c05d436..b93bfe9000 100644 --- a/keyboards/handwired/onekey/keymaps/battery/config.h +++ b/keyboards/handwired/onekey/keymaps/battery/config.h | |||
| @@ -3,4 +3,4 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #define BATTERY_PIN ADC_PIN | 6 | #define BATTERY_ADC_PIN ADC_PIN |
diff --git a/keyboards/handwired/onekey/keymaps/battery/keymap.c b/keyboards/handwired/onekey/keymaps/battery/keymap.c index 74191e83fc..793a6ed87e 100644 --- a/keyboards/handwired/onekey/keymaps/battery/keymap.c +++ b/keyboards/handwired/onekey/keymaps/battery/keymap.c | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include QMK_KEYBOARD_H | 4 | #include QMK_KEYBOARD_H |
| 5 | #include "battery.h" | ||
| 6 | 5 | ||
| 7 | const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | 6 | const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { |
| 8 | LAYOUT_ortho_1x1(KC_A) | 7 | LAYOUT_ortho_1x1(KC_A) |
| @@ -14,8 +13,6 @@ void keyboard_post_init_user(void) { | |||
| 14 | // debug_matrix=false; | 13 | // debug_matrix=false; |
| 15 | // debug_keyboard=true; | 14 | // debug_keyboard=true; |
| 16 | // debug_mouse=false; | 15 | // debug_mouse=false; |
| 17 | |||
| 18 | battery_init(); | ||
| 19 | } | 16 | } |
| 20 | 17 | ||
| 21 | void housekeeping_task_user(void) { | 18 | void housekeeping_task_user(void) { |
diff --git a/keyboards/handwired/onekey/keymaps/battery/keymap.json b/keyboards/handwired/onekey/keymaps/battery/keymap.json index c641dfe773..7232d6d899 100644 --- a/keyboards/handwired/onekey/keymaps/battery/keymap.json +++ b/keyboards/handwired/onekey/keymaps/battery/keymap.json | |||
| @@ -1,6 +1,10 @@ | |||
| 1 | { | 1 | { |
| 2 | "config": { | 2 | "config": { |
| 3 | "battery": { | ||
| 4 | "driver": "adc" | ||
| 5 | }, | ||
| 3 | "features": { | 6 | "features": { |
| 7 | "battery": true, | ||
| 4 | "console": true | 8 | "console": true |
| 5 | } | 9 | } |
| 6 | } | 10 | } |
diff --git a/keyboards/handwired/onekey/keymaps/battery/rules.mk b/keyboards/handwired/onekey/keymaps/battery/rules.mk deleted file mode 100644 index 06908179ae..0000000000 --- a/keyboards/handwired/onekey/keymaps/battery/rules.mk +++ /dev/null | |||
| @@ -1 +0,0 @@ | |||
| 1 | BATTERY_DRIVER_REQUIRED = yes | ||
diff --git a/keyboards/handwired/promethium/config.h b/keyboards/handwired/promethium/config.h index 974a4f951f..c63d3eaead 100644 --- a/keyboards/handwired/promethium/config.h +++ b/keyboards/handwired/promethium/config.h | |||
| @@ -64,8 +64,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| 64 | 64 | ||
| 65 | #define PS2_MOUSE_INIT_DELAY 2000 | 65 | #define PS2_MOUSE_INIT_DELAY 2000 |
| 66 | 66 | ||
| 67 | #define BATTERY_PIN B5 | ||
| 68 | |||
| 69 | #ifndef __ASSEMBLER__ // assembler doesn't like enum in .h file | 67 | #ifndef __ASSEMBLER__ // assembler doesn't like enum in .h file |
| 70 | enum led_sequence { | 68 | enum led_sequence { |
| 71 | LED_IND_LINUX, | 69 | LED_IND_LINUX, |
diff --git a/keyboards/handwired/promethium/keyboard.json b/keyboards/handwired/promethium/keyboard.json index fa72908039..2e47bd186a 100644 --- a/keyboards/handwired/promethium/keyboard.json +++ b/keyboards/handwired/promethium/keyboard.json | |||
| @@ -10,6 +10,12 @@ | |||
| 10 | "ws2812": { | 10 | "ws2812": { |
| 11 | "pin": "B5" | 11 | "pin": "B5" |
| 12 | }, | 12 | }, |
| 13 | "battery": { | ||
| 14 | "driver": "adc", | ||
| 15 | "adc": { | ||
| 16 | "pin": "B5" | ||
| 17 | } | ||
| 18 | }, | ||
| 13 | "bluetooth": { | 19 | "bluetooth": { |
| 14 | "driver": "bluefruit_le" | 20 | "driver": "bluefruit_le" |
| 15 | }, | 21 | }, |
| @@ -22,6 +28,7 @@ | |||
| 22 | "nkro": true, | 28 | "nkro": true, |
| 23 | "ps2_mouse": true, | 29 | "ps2_mouse": true, |
| 24 | "ps2": true, | 30 | "ps2": true, |
| 31 | "battery": true, | ||
| 25 | "bluetooth": true | 32 | "bluetooth": true |
| 26 | }, | 33 | }, |
| 27 | "build": { | 34 | "build": { |
diff --git a/keyboards/handwired/promethium/rules.mk b/keyboards/handwired/promethium/rules.mk index 4012f8ca29..ecadca399c 100644 --- a/keyboards/handwired/promethium/rules.mk +++ b/keyboards/handwired/promethium/rules.mk | |||
| @@ -5,7 +5,6 @@ PS2_DRIVER = interrupt | |||
| 5 | CUSTOM_MATRIX = yes | 5 | CUSTOM_MATRIX = yes |
| 6 | 6 | ||
| 7 | WS2812_DRIVER_REQUIRED = yes | 7 | WS2812_DRIVER_REQUIRED = yes |
| 8 | BATTERY_DRIVER_REQUIRED = yes | ||
| 9 | 8 | ||
| 10 | SRC += rgbsps.c | 9 | SRC += rgbsps.c |
| 11 | SRC += matrix.c | 10 | SRC += matrix.c |
diff --git a/drivers/battery/battery.c b/quantum/battery/battery.c index faf3c5a214..faf3c5a214 100644 --- a/drivers/battery/battery.c +++ b/quantum/battery/battery.c | |||
diff --git a/drivers/battery/battery.h b/quantum/battery/battery.h index 0985723eaa..0985723eaa 100644 --- a/drivers/battery/battery.h +++ b/quantum/battery/battery.h | |||
diff --git a/quantum/battery/tests/battery_tests.cpp b/quantum/battery/tests/battery_tests.cpp new file mode 100644 index 0000000000..ee011be8a8 --- /dev/null +++ b/quantum/battery/tests/battery_tests.cpp | |||
| @@ -0,0 +1,97 @@ | |||
| 1 | // Copyright 2025 QMK | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "gtest/gtest.h" | ||
| 5 | #include "gmock/gmock.h" | ||
| 6 | |||
| 7 | using testing::_; | ||
| 8 | |||
| 9 | class BatteryDriverMock { | ||
| 10 | public: | ||
| 11 | virtual ~BatteryDriverMock() {} | ||
| 12 | |||
| 13 | // mock methods | ||
| 14 | MOCK_METHOD0(battery_driver_init, void(void)); | ||
| 15 | MOCK_METHOD0(battery_driver_sample_percent, uint8_t(void)); | ||
| 16 | MOCK_METHOD1(battery_percent_changed_kb, void(uint8_t)); | ||
| 17 | }; | ||
| 18 | |||
| 19 | class BatteryTest : public ::testing::Test { | ||
| 20 | public: | ||
| 21 | BatteryTest() { | ||
| 22 | _batteryDriverMock.reset(new ::testing::NiceMock<BatteryDriverMock>()); | ||
| 23 | } | ||
| 24 | virtual ~BatteryTest() { | ||
| 25 | _batteryDriverMock.reset(); | ||
| 26 | } | ||
| 27 | |||
| 28 | static std::unique_ptr<BatteryDriverMock> _batteryDriverMock; | ||
| 29 | }; | ||
| 30 | |||
| 31 | std::unique_ptr<BatteryDriverMock> BatteryTest::_batteryDriverMock; | ||
| 32 | |||
| 33 | extern "C" { | ||
| 34 | #include "quantum/battery/battery.h" | ||
| 35 | #include "timer.h" | ||
| 36 | |||
| 37 | void advance_time(uint32_t ms); | ||
| 38 | |||
| 39 | void battery_driver_init(void) { | ||
| 40 | if (BatteryTest::_batteryDriverMock) { | ||
| 41 | BatteryTest::_batteryDriverMock->battery_driver_init(); | ||
| 42 | } | ||
| 43 | } | ||
| 44 | |||
| 45 | uint8_t battery_driver_sample_percent(void) { | ||
| 46 | if (BatteryTest::_batteryDriverMock) { | ||
| 47 | return BatteryTest::_batteryDriverMock->battery_driver_sample_percent(); | ||
| 48 | } | ||
| 49 | return 255; | ||
| 50 | } | ||
| 51 | |||
| 52 | void battery_percent_changed_kb(uint8_t level) { | ||
| 53 | if (BatteryTest::_batteryDriverMock) { | ||
| 54 | BatteryTest::_batteryDriverMock->battery_percent_changed_kb(level); | ||
| 55 | } | ||
| 56 | } | ||
| 57 | } | ||
| 58 | |||
| 59 | TEST_F(BatteryTest, TestInit) { | ||
| 60 | // init driver and initial sample | ||
| 61 | EXPECT_CALL(*_batteryDriverMock, battery_driver_init()).Times(1); | ||
| 62 | EXPECT_CALL(*_batteryDriverMock, battery_driver_sample_percent()).Times(1); | ||
| 63 | |||
| 64 | battery_init(); | ||
| 65 | } | ||
| 66 | |||
| 67 | TEST_F(BatteryTest, TestSampleCached) { | ||
| 68 | // sample before timeout | ||
| 69 | EXPECT_CALL(*_batteryDriverMock, battery_driver_sample_percent()).Times(0); | ||
| 70 | |||
| 71 | advance_time(1); | ||
| 72 | battery_task(); | ||
| 73 | } | ||
| 74 | |||
| 75 | TEST_F(BatteryTest, TestSampleNotCached) { | ||
| 76 | // sample after timeout | ||
| 77 | EXPECT_CALL(*_batteryDriverMock, battery_driver_sample_percent()).Times(1); | ||
| 78 | |||
| 79 | advance_time(60000); | ||
| 80 | battery_task(); | ||
| 81 | } | ||
| 82 | |||
| 83 | TEST_F(BatteryTest, TestGet) { | ||
| 84 | // sample does not directly sample | ||
| 85 | EXPECT_CALL(*_batteryDriverMock, battery_driver_sample_percent()).Times(0); | ||
| 86 | |||
| 87 | battery_get_percent(); | ||
| 88 | } | ||
| 89 | |||
| 90 | TEST_F(BatteryTest, TestChanged) { | ||
| 91 | // callbacks on value changed | ||
| 92 | EXPECT_CALL(*_batteryDriverMock, battery_percent_changed_kb(_)).Times(1); | ||
| 93 | |||
| 94 | battery_task(); | ||
| 95 | advance_time(60000); | ||
| 96 | battery_task(); | ||
| 97 | } | ||
diff --git a/quantum/battery/tests/rules.mk b/quantum/battery/tests/rules.mk new file mode 100644 index 0000000000..86980f1020 --- /dev/null +++ b/quantum/battery/tests/rules.mk | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | VPATH += $(DRIVER_PATH)/battery | ||
| 2 | |||
| 3 | battery_SRC := \ | ||
| 4 | $(PLATFORM_PATH)/timer.c \ | ||
| 5 | $(PLATFORM_PATH)/$(PLATFORM_KEY)/timer.c \ | ||
| 6 | $(QUANTUM_PATH)/battery/battery.c \ | ||
| 7 | $(QUANTUM_PATH)/battery/tests/battery_tests.cpp \ | ||
diff --git a/quantum/battery/tests/testlist.mk b/quantum/battery/tests/testlist.mk new file mode 100644 index 0000000000..e91da865a0 --- /dev/null +++ b/quantum/battery/tests/testlist.mk | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | TEST_LIST += \ | ||
| 2 | battery \ | ||
diff --git a/quantum/keyboard.c b/quantum/keyboard.c index bf4890a51d..173c696e2d 100644 --- a/quantum/keyboard.c +++ b/quantum/keyboard.c | |||
| @@ -122,7 +122,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| 122 | #ifdef SPLIT_KEYBOARD | 122 | #ifdef SPLIT_KEYBOARD |
| 123 | # include "split_util.h" | 123 | # include "split_util.h" |
| 124 | #endif | 124 | #endif |
| 125 | #ifdef BATTERY_DRIVER | 125 | #ifdef BATTERY_ENABLE |
| 126 | # include "battery.h" | 126 | # include "battery.h" |
| 127 | #endif | 127 | #endif |
| 128 | #ifdef BLUETOOTH_ENABLE | 128 | #ifdef BLUETOOTH_ENABLE |
| @@ -532,7 +532,7 @@ void keyboard_init(void) { | |||
| 532 | // init after split init | 532 | // init after split init |
| 533 | pointing_device_init(); | 533 | pointing_device_init(); |
| 534 | #endif | 534 | #endif |
| 535 | #ifdef BATTERY_DRIVER | 535 | #ifdef BATTERY_ENABLE |
| 536 | battery_init(); | 536 | battery_init(); |
| 537 | #endif | 537 | #endif |
| 538 | #ifdef BLUETOOTH_ENABLE | 538 | #ifdef BLUETOOTH_ENABLE |
| @@ -779,7 +779,7 @@ void keyboard_task(void) { | |||
| 779 | joystick_task(); | 779 | joystick_task(); |
| 780 | #endif | 780 | #endif |
| 781 | 781 | ||
| 782 | #ifdef BATTERY_DRIVER | 782 | #ifdef BATTERY_ENABLE |
| 783 | battery_task(); | 783 | battery_task(); |
| 784 | #endif | 784 | #endif |
| 785 | 785 | ||
diff --git a/quantum/quantum.h b/quantum/quantum.h index 0036cd784b..176c8a292d 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h | |||
| @@ -63,6 +63,10 @@ | |||
| 63 | # include "bootmagic.h" | 63 | # include "bootmagic.h" |
| 64 | #endif | 64 | #endif |
| 65 | 65 | ||
| 66 | #ifdef BATTERY_ENABLE | ||
| 67 | # include "battery.h" | ||
| 68 | #endif | ||
| 69 | |||
| 66 | #ifdef DEFERRED_EXEC_ENABLE | 70 | #ifdef DEFERRED_EXEC_ENABLE |
| 67 | # include "deferred_exec.h" | 71 | # include "deferred_exec.h" |
| 68 | #endif | 72 | #endif |
