From 17b9261b9c999f7b0a4f399d74431c09f56c0da2 Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 2 Jul 2024 23:06:39 +0100 Subject: [PATCH] Improve BatteryLevel (#179) * improve BatteryLevel change algorithm to be based on charge current when charging and use different voltage levels for charge and discharge. reduce termination current * swap logic and tidy up * base max charge current on input current limit. * ci to cv point based on input current limit scale limits to keep battery level percentage approximately the same for all 3 input current limits and when not connected. --- drivers/tildagon_power/bq25895/bq25895.c | 6 ++- drivers/tildagon_power/mp_power.c | 55 +++++++++++++++++++++++- drivers/tildagon_power/tildagon_power.h | 4 -- 3 files changed, 58 insertions(+), 7 deletions(-) diff --git a/drivers/tildagon_power/bq25895/bq25895.c b/drivers/tildagon_power/bq25895/bq25895.c index 7016625..de15df0 100644 --- a/drivers/tildagon_power/bq25895/bq25895.c +++ b/drivers/tildagon_power/bq25895/bq25895.c @@ -41,13 +41,15 @@ static void write_scaled( bq_state_t* state, scaled_register_t scaledregister, f * @brief initialise the bq25895 * @details reset then setup 500mA Iin limit, boost disabled, charging enabled, * ADC at 1Hz, disable unused features and disable watchdog to reduce interruptions + * charge current limit to be 0.85C for the 1800mAh and 0.77C for 2000mAh batteries + * termination and precharge current to 64mA. min Vbat 3.5V * @param state pmic object */ void bq_init( bq_state_t* state ) { write_bits( state, register_reset, 1 ); - uint8_t write_buffer[3] = { 0x02, 0x60, 0x1A }; - mp_machine_i2c_buf_t buffer = { .len = 3, .buf = write_buffer }; + uint8_t write_buffer[5] = { 0x02, 0x60, 0x1A, 0x18, 0x00 }; + mp_machine_i2c_buf_t buffer = { .len = 5, .buf = write_buffer }; tildagon_mux_i2c_transaction( state->mux_port, ADDRESS, 1, &buffer, WRITE ); write_buffer[0] = 0x07; write_buffer[1] = 0x8C; diff --git a/drivers/tildagon_power/mp_power.c b/drivers/tildagon_power/mp_power.c index b071a2c..6355201 100644 --- a/drivers/tildagon_power/mp_power.c +++ b/drivers/tildagon_power/mp_power.c @@ -4,6 +4,19 @@ #include #include "tildagon_power.h" +/* + minimum input voltage for step down at max (4A) load. + minimum input voltage = ( Rl(DCR) + Rdson ) * max current + output voltage + (0.078ohms * 4.0A) + 3.3V = 3.6V + most users won't use 4A so badge will run lower than this so use 3.5V as minimum. +*/ +#define VBAT_DIS_MAX 4.14F +#define VBAT_DIS_MIN 3.5F +#define VBAT_CHG_MAX 4.2F +#define VBAT_CHG_MIN 3.6F +#define IBAT_TERM 0.064F +#define VBAT_CI_PERCENT 85.0F + static mp_obj_t power_enable5V( mp_obj_t a_obj ) { bool enable = (bool)mp_obj_get_int(a_obj); @@ -56,7 +69,47 @@ static MP_DEFINE_CONST_FUN_OBJ_0( Icharge_obj, power_Icharge); static mp_obj_t power_BatteryLevel( void ) { bq_update_state( &pmic ); - return mp_obj_new_float( ( ( pmic.vbat-VBATMIN ) / ( VBATMAX- VBATMIN ) ) * 100.0F ); + float level = 0.0F; + if( ( ( pmic.status & BQ_CHARGE_STAT_MASK ) == BQ_NOTCHARGING ) + || ( ( pmic.status & BQ_CHARGE_STAT_MASK ) == BQ_TERMINATED ) ) + { + level = ( ( pmic.vbat-VBAT_DIS_MIN ) / ( VBAT_DIS_MAX- VBAT_DIS_MIN ) ) * 100.0F; + } + else + { + float max_current = 1.536F; + float vbat_cv_percent = 20.0F; + float vbat_ci_percent = 100.0F - vbat_cv_percent; + if ( usb_in.fusb.input_current_limit == 1500U ) + { + max_current = 1.3F; + vbat_cv_percent = 17.0F; + vbat_ci_percent = 100.0F - vbat_cv_percent; + } + else if ( usb_in.fusb.input_current_limit == 500 ) + { + max_current = 0.4F; + vbat_cv_percent = 2.0F; + vbat_ci_percent = 100.0F - vbat_cv_percent; + } + if ( pmic.vbat < VBAT_CHG_MAX ) + { + level = ( ( pmic.vbat-VBAT_CHG_MIN ) / ( VBAT_CHG_MAX - VBAT_CHG_MIN ) ) * vbat_ci_percent; + } + else + { + level = 100.0F - ( ( pmic.ichrg / ( max_current - IBAT_TERM ) ) * vbat_cv_percent ); + } + } + if ( level > 100.0F ) + { + level = 100.0F; + } + else if ( level < 0.0F ) + { + level = 0.0F; + } + return mp_obj_new_float(level); } static MP_DEFINE_CONST_FUN_OBJ_0( BatteryLevel_obj, power_BatteryLevel); diff --git a/drivers/tildagon_power/tildagon_power.h b/drivers/tildagon_power/tildagon_power.h index 8df50f5..9d65eb6 100644 --- a/drivers/tildagon_power/tildagon_power.h +++ b/drivers/tildagon_power/tildagon_power.h @@ -9,10 +9,6 @@ #include "fusb302b/fusb302b_pd.h" #include "fusb302b/fusb302b.h" - -#define VBATMAX 4.104F -#define VBATMIN 3.500F - typedef struct { fusb_state_t fusb;