diff options
Diffstat (limited to 'quantum')
| -rw-r--r-- | quantum/battery/battery.c | 41 | ||||
| -rw-r--r-- | quantum/battery/battery.h | 46 | ||||
| -rw-r--r-- | quantum/battery/tests/battery_tests.cpp | 97 | ||||
| -rw-r--r-- | quantum/battery/tests/rules.mk | 7 | ||||
| -rw-r--r-- | quantum/battery/tests/testlist.mk | 2 | ||||
| -rw-r--r-- | quantum/keyboard.c | 6 | ||||
| -rw-r--r-- | quantum/quantum.h | 4 |
7 files changed, 200 insertions, 3 deletions
diff --git a/quantum/battery/battery.c b/quantum/battery/battery.c new file mode 100644 index 0000000000..faf3c5a214 --- /dev/null +++ b/quantum/battery/battery.c @@ -0,0 +1,41 @@ +// Copyright 2025 QMK +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "battery_driver.h" +#include "battery.h" +#include "timer.h" + +#ifndef BATTERY_SAMPLE_INTERVAL +# define BATTERY_SAMPLE_INTERVAL 30000 +#endif + +static uint8_t last_bat_level = 100; + +void battery_init(void) { + battery_driver_init(); + + last_bat_level = battery_driver_sample_percent(); +} + +__attribute__((weak)) void battery_percent_changed_user(uint8_t level) {} +__attribute__((weak)) void battery_percent_changed_kb(uint8_t level) {} + +static void handle_percent_changed(void) { + battery_percent_changed_user(last_bat_level); + battery_percent_changed_kb(last_bat_level); +} + +void battery_task(void) { + static uint32_t bat_timer = 0; + if (timer_elapsed32(bat_timer) > BATTERY_SAMPLE_INTERVAL) { + last_bat_level = battery_driver_sample_percent(); + + handle_percent_changed(); + + bat_timer = timer_read32(); + } +} + +uint8_t battery_get_percent(void) { + return last_bat_level; +} diff --git a/quantum/battery/battery.h b/quantum/battery/battery.h new file mode 100644 index 0000000000..0985723eaa --- /dev/null +++ b/quantum/battery/battery.h @@ -0,0 +1,46 @@ +// Copyright 2025 QMK +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include <stdint.h> + +/** + * \file + * + * \defgroup battery Battery API + * + * \brief API to query battery status. + * \{ + */ + +/** + * \brief Initialize the battery driver. + */ +void battery_init(void); + +/** + * \brief Perform housekeeping tasks. + */ +void battery_task(void); + +/** + * \brief Sample battery level. + * + * \return The battery percentage, in the range 0-100. + */ +uint8_t battery_get_percent(void); + +/** + * \brief user hook called when battery level changed. + * + */ +void battery_percent_changed_user(uint8_t level); + +/** + * \brief keyboard hook called when battery level changed. + * + */ +void battery_percent_changed_kb(uint8_t level); + +/** \} */ 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 @@ +// Copyright 2025 QMK +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "gtest/gtest.h" +#include "gmock/gmock.h" + +using testing::_; + +class BatteryDriverMock { + public: + virtual ~BatteryDriverMock() {} + + // mock methods + MOCK_METHOD0(battery_driver_init, void(void)); + MOCK_METHOD0(battery_driver_sample_percent, uint8_t(void)); + MOCK_METHOD1(battery_percent_changed_kb, void(uint8_t)); +}; + +class BatteryTest : public ::testing::Test { + public: + BatteryTest() { + _batteryDriverMock.reset(new ::testing::NiceMock<BatteryDriverMock>()); + } + virtual ~BatteryTest() { + _batteryDriverMock.reset(); + } + + static std::unique_ptr<BatteryDriverMock> _batteryDriverMock; +}; + +std::unique_ptr<BatteryDriverMock> BatteryTest::_batteryDriverMock; + +extern "C" { +#include "quantum/battery/battery.h" +#include "timer.h" + +void advance_time(uint32_t ms); + +void battery_driver_init(void) { + if (BatteryTest::_batteryDriverMock) { + BatteryTest::_batteryDriverMock->battery_driver_init(); + } +} + +uint8_t battery_driver_sample_percent(void) { + if (BatteryTest::_batteryDriverMock) { + return BatteryTest::_batteryDriverMock->battery_driver_sample_percent(); + } + return 255; +} + +void battery_percent_changed_kb(uint8_t level) { + if (BatteryTest::_batteryDriverMock) { + BatteryTest::_batteryDriverMock->battery_percent_changed_kb(level); + } +} +} + +TEST_F(BatteryTest, TestInit) { + // init driver and initial sample + EXPECT_CALL(*_batteryDriverMock, battery_driver_init()).Times(1); + EXPECT_CALL(*_batteryDriverMock, battery_driver_sample_percent()).Times(1); + + battery_init(); +} + +TEST_F(BatteryTest, TestSampleCached) { + // sample before timeout + EXPECT_CALL(*_batteryDriverMock, battery_driver_sample_percent()).Times(0); + + advance_time(1); + battery_task(); +} + +TEST_F(BatteryTest, TestSampleNotCached) { + // sample after timeout + EXPECT_CALL(*_batteryDriverMock, battery_driver_sample_percent()).Times(1); + + advance_time(60000); + battery_task(); +} + +TEST_F(BatteryTest, TestGet) { + // sample does not directly sample + EXPECT_CALL(*_batteryDriverMock, battery_driver_sample_percent()).Times(0); + + battery_get_percent(); +} + +TEST_F(BatteryTest, TestChanged) { + // callbacks on value changed + EXPECT_CALL(*_batteryDriverMock, battery_percent_changed_kb(_)).Times(1); + + battery_task(); + advance_time(60000); + battery_task(); +} 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 @@ +VPATH += $(DRIVER_PATH)/battery + +battery_SRC := \ + $(PLATFORM_PATH)/timer.c \ + $(PLATFORM_PATH)/$(PLATFORM_KEY)/timer.c \ + $(QUANTUM_PATH)/battery/battery.c \ + $(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 @@ +TEST_LIST += \ + 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/>. #ifdef SPLIT_KEYBOARD # include "split_util.h" #endif -#ifdef BATTERY_DRIVER +#ifdef BATTERY_ENABLE # include "battery.h" #endif #ifdef BLUETOOTH_ENABLE @@ -532,7 +532,7 @@ void keyboard_init(void) { // init after split init pointing_device_init(); #endif -#ifdef BATTERY_DRIVER +#ifdef BATTERY_ENABLE battery_init(); #endif #ifdef BLUETOOTH_ENABLE @@ -779,7 +779,7 @@ void keyboard_task(void) { joystick_task(); #endif -#ifdef BATTERY_DRIVER +#ifdef BATTERY_ENABLE battery_task(); #endif 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 @@ # include "bootmagic.h" #endif +#ifdef BATTERY_ENABLE +# include "battery.h" +#endif + #ifdef DEFERRED_EXEC_ENABLE # include "deferred_exec.h" #endif |