diff options
Diffstat (limited to 'drivers/battery/battery_adc.c')
-rw-r--r-- | drivers/battery/battery_adc.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/drivers/battery/battery_adc.c b/drivers/battery/battery_adc.c new file mode 100644 index 0000000000..cf0e69cb48 --- /dev/null +++ b/drivers/battery/battery_adc.c @@ -0,0 +1,55 @@ +// Copyright 2025 QMK +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "analog.h" +#include "gpio.h" + +#ifndef BATTERY_PIN +# error("BATTERY_PIN not configured!") +#endif + +#ifndef BATTERY_REF_VOLTAGE_MV +# define BATTERY_REF_VOLTAGE_MV 3300 +#endif + +#ifndef BATTERY_VOLTAGE_DIVIDER_R1 +# define BATTERY_VOLTAGE_DIVIDER_R1 100 +#endif + +#ifndef BATTERY_VOLTAGE_DIVIDER_R2 +# define BATTERY_VOLTAGE_DIVIDER_R2 100 +#endif + +// TODO: infer from adc config? +#ifndef BATTERY_ADC_RESOLUTION +# define BATTERY_ADC_RESOLUTION 10 +#endif + +void battery_driver_init(void) { + gpio_set_pin_input(BATTERY_PIN); +} + +uint16_t battery_driver_get_mv(void) { + uint32_t raw = analogReadPin(BATTERY_PIN); + + uint32_t bat_mv = raw * BATTERY_REF_VOLTAGE_MV / (1 << BATTERY_ADC_RESOLUTION); + +#if BATTERY_VOLTAGE_DIVIDER_R1 > 0 && BATTERY_VOLTAGE_DIVIDER_R2 > 0 + bat_mv = bat_mv * (BATTERY_VOLTAGE_DIVIDER_R1 + BATTERY_VOLTAGE_DIVIDER_R2) / BATTERY_VOLTAGE_DIVIDER_R2; +#endif + + return bat_mv; +} + +uint8_t battery_driver_sample_percent(void) { + uint16_t bat_mv = battery_driver_get_mv(); + + // https://github.com/zmkfirmware/zmk/blob/3f7c9d7cc4f46617faad288421025ea2a6b0bd28/app/module/drivers/sensor/battery/battery_common.c#L33 + if (bat_mv >= 4200) { + return 100; + } else if (bat_mv <= 3450) { + return 0; + } + + return bat_mv * 2 / 15 - 459; +} |