battery_adc.c (1448B)
1 // Copyright 2025 QMK 2 // SPDX-License-Identifier: GPL-2.0-or-later 3 4 #include "battery_driver.h" 5 #include "analog.h" 6 #include "gpio.h" 7 8 #ifndef BATTERY_ADC_PIN 9 # error("BATTERY_ADC_PIN not configured!") 10 #endif 11 12 #ifndef BATTERY_ADC_REF_VOLTAGE_MV 13 # define BATTERY_ADC_REF_VOLTAGE_MV 3300 14 #endif 15 16 #ifndef BATTERY_ADC_VOLTAGE_DIVIDER_R1 17 # define BATTERY_VOLTAGE_DIVIDER_R1 100 18 #endif 19 20 #ifndef BATTERY_ADC_VOLTAGE_DIVIDER_R2 21 # define BATTERY_ADC_VOLTAGE_DIVIDER_R2 100 22 #endif 23 24 // TODO: infer from adc config? 25 #ifndef BATTERY_ADC_RESOLUTION 26 # define BATTERY_ADC_RESOLUTION 10 27 #endif 28 29 void battery_driver_init(void) { 30 gpio_set_pin_input(BATTERY_ADC_PIN); 31 } 32 33 uint16_t battery_driver_get_mv(void) { 34 uint32_t raw = analogReadPin(BATTERY_ADC_PIN); 35 36 uint32_t bat_mv = raw * BATTERY_ADC_REF_VOLTAGE_MV / (1 << BATTERY_ADC_RESOLUTION); 37 38 #if BATTERY_VOLTAGE_DIVIDER_R1 > 0 && BATTERY_ADC_VOLTAGE_DIVIDER_R2 > 0 39 bat_mv = bat_mv * (BATTERY_VOLTAGE_DIVIDER_R1 + BATTERY_ADC_VOLTAGE_DIVIDER_R2) / BATTERY_ADC_VOLTAGE_DIVIDER_R2; 40 #endif 41 42 return bat_mv; 43 } 44 45 uint8_t battery_driver_sample_percent(void) { 46 uint16_t bat_mv = battery_driver_get_mv(); 47 48 // https://github.com/zmkfirmware/zmk/blob/3f7c9d7cc4f46617faad288421025ea2a6b0bd28/app/module/drivers/sensor/battery/battery_common.c#L33 49 if (bat_mv >= 4200) { 50 return 100; 51 } else if (bat_mv <= 3450) { 52 return 0; 53 } 54 55 return bat_mv * 2 / 15 - 459; 56 }