From fd6f9a0a0540c18da019ac11c36134cd2d579aa1 Mon Sep 17 00:00:00 2001 From: Tim Crawford Date: Mon, 24 Aug 2020 06:53:36 -0600 Subject: [PATCH] battery: Implement charging thresholds Battery Charging Start Threshold: - Valid values are [0, 100] - A value of 0 disables the feature, leaving the charger enabled on AC Battery Charging End Threshold: - Valid values are [0,100] - A value of 100 disabled the feature, leaving the charger enabled on AC The stop threshold must be configured for the start threshold to work. --- src/board/system76/common/battery.c | 77 ++++++++++++++++++- .../system76/common/include/board/battery.h | 8 ++ src/board/system76/common/power.c | 7 +- 3 files changed, 89 insertions(+), 3 deletions(-) diff --git a/src/board/system76/common/battery.c b/src/board/system76/common/battery.c index 61fee8e..bf5960b 100644 --- a/src/board/system76/common/battery.c +++ b/src/board/system76/common/battery.c @@ -1,7 +1,6 @@ #include #include #include -#include #define BATTERY_ADDRESS 0x0B #define CHARGER_ADDRESS 0x09 @@ -16,6 +15,52 @@ // IDCHG Amplifier Gain #define SBC_IDCHC_GAIN ((uint16_t)(1 << 3)) +// TODO: Make thresholds configurable +#define BATTERY_START_THRESHOLD 0 +#define BATTERY_END_THRESHOLD 100 + +// Default values to disable battery charging thresholds +#define BATTERY_START_DEFAULT 0 +#define BATTERY_END_DEFAULT 100 + +// Represents a battery percentage level, below which charging will begin. +// Valid values are [0, 100] +// A value of 0 turns off the start threshold control. +static uint8_t battery_start_threshold = BATTERY_START_DEFAULT; + +// Represents a battery percentage level, above which charging will stop. +// Valid values are [0, 100] +// A value of 100 turns off the stop threshold control. +static uint8_t battery_end_threshold = BATTERY_END_DEFAULT; + +uint8_t battery_get_start_threshold(void) { + if (battery_start_threshold > 100) + return BATTERY_START_DEFAULT; + return battery_start_threshold; +} + +bool battery_set_start_threshold(uint8_t value) { + if (value > 100 || value >= battery_end_threshold) + return false; + + battery_start_threshold = value; + return true; +} + +uint8_t battery_get_end_threshold(void) { + if (battery_end_threshold > 100) + return BATTERY_END_DEFAULT; + return battery_end_threshold; +} + +bool battery_set_end_threshold(uint8_t value) { + if (value > 100 || value <= battery_start_threshold) + return false; + + battery_end_threshold = value; + return true; +} + // XXX: Assumption: ac_last is initialized high. static bool charger_enabled = false; @@ -85,6 +130,34 @@ int battery_charger_enable(void) { return 0; } +/** + * Configure the charger based on charging threshold values. + */ +int battery_charger_configure(void) { + static bool should_charge = true; + + if (battery_get_end_threshold() == BATTERY_END_DEFAULT) { + // Stop threshold not configured: Always charge on AC. + should_charge = true; + } + else if (battery_charge >= battery_get_end_threshold()) { + // Stop threshold configured: Stop charging at threshold. + should_charge = false; + } + else if (battery_get_start_threshold() == BATTERY_START_DEFAULT) { + // Start threshold not configured: Always charge up to stop threshold. + should_charge = true; + } + else if (battery_charge <= battery_get_start_threshold()) { + // Start threshold configured: Start charging at threshold. + should_charge = true; + } + + if (should_charge) + return battery_charger_enable(); + return battery_charger_disable(); +} + uint16_t battery_temp = 0; uint16_t battery_voltage = 0; uint16_t battery_current = 0; @@ -123,7 +196,7 @@ void battery_debug(void) { int res = 0; #define command(N, A, V) { \ - DEBUG(#N ": "); \ + DEBUG(" " #N ": "); \ res = smbus_read(A, V, &data); \ if (res < 0) { \ DEBUG("ERROR %04X\n", -res); \ diff --git a/src/board/system76/common/include/board/battery.h b/src/board/system76/common/include/board/battery.h index 4da7a2c..eb3c6c5 100644 --- a/src/board/system76/common/include/board/battery.h +++ b/src/board/system76/common/include/board/battery.h @@ -1,6 +1,7 @@ #ifndef _BOARD_BATTERY_H #define _BOARD_BATTERY_H +#include #include #define BATTERY_INITIALIZED (1U << 7) @@ -15,8 +16,15 @@ extern uint16_t battery_status; extern uint16_t battery_design_capacity; extern uint16_t battery_design_voltage; +uint8_t battery_get_start_threshold(void); +bool battery_set_start_threshold(uint8_t value); + +uint8_t battery_get_end_threshold(void); +bool battery_set_end_threshold(uint8_t value); + int battery_charger_disable(void); int battery_charger_enable(void); +int battery_charger_configure(void); void battery_event(void); void battery_debug(void); diff --git a/src/board/system76/common/power.c b/src/board/system76/common/power.c index 1a02fe1..c939bf5 100644 --- a/src/board/system76/common/power.c +++ b/src/board/system76/common/power.c @@ -357,7 +357,7 @@ void power_event(void) { battery_charger_disable(); } else { DEBUG("plugged in\n"); - battery_charger_enable(); + battery_charger_configure(); } battery_debug(); @@ -377,6 +377,11 @@ void power_event(void) { gpio_set(&AC_PRESENT, !ac_new); + // Configure charger based on charging thresholds when plugged in + if (!ac_new) { + battery_charger_configure(); + } + // Read power switch state static bool ps_last = true; bool ps_new = gpio_get(&PWR_SW_N);