battery_adc.c 1.4 KB

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