From bd08440584b5e090184684248e706a64b5aaed60 Mon Sep 17 00:00:00 2001 From: Thomas Kolb Date: Sun, 18 Jun 2023 16:18:13 +0200 Subject: [PATCH] charge_control: delay overload trigger by a configurable time --- src/charge_control.c | 30 ++++++++++++++++++++++++++---- src/charge_control.h | 1 + src/flash_config.h | 14 ++++++++++++++ utils/config_b26.yaml | 8 ++++++++ utils/config_to_hex.py | 2 ++ 5 files changed, 51 insertions(+), 4 deletions(-) diff --git a/src/charge_control.c b/src/charge_control.c index 117bfd5..b916fbf 100644 --- a/src/charge_control.c +++ b/src/charge_control.c @@ -27,7 +27,8 @@ static const char *DISCHARGE_STATE_TEXT[DISCHARGE_NUM_STATES] = { "WAIT_CHARGEPUMP", "OK", "VOLTAGE_LOW", - "OVERCURRENT" + "OVERCURRENT", + "OVERCURRENT_DELAY" }; static enum ChargeState charge_state; @@ -55,6 +56,7 @@ static fxp_t u_bat_load_on; static fxp_t u_bat_load_off; static fxp_t load_current_limit; +static fxp_t load_current_limit_delay; static fxp_t internal_temperature_limit; static fxp_t internal_temperature_recovery; @@ -294,7 +296,13 @@ static void load_fsm_update(uint64_t uptime_ms, struct MeasurementResult *meas) if((meas->i_load > load_current_limit) && (discharge_time_in_state > FLASH_CONFIG_LOAD_CURRENT_INRUSH_TIME)) { - discharge_state = DISCHARGE_OVERCURRENT; + if(load_current_limit_delay == 0) { + // switch off immediately + power_switch_load_off(); + discharge_state = DISCHARGE_OVERCURRENT; + } else { + discharge_state = DISCHARGE_OVERCURRENT_DELAY; + } } if(meas->avg_u_bat < u_bat_load_off) { @@ -311,17 +319,31 @@ static void load_fsm_update(uint64_t uptime_ms, struct MeasurementResult *meas) // Can only switch on again after a specific amount of time has passed if((meas->avg_u_bat > u_bat_load_on) && (discharge_time_in_state > FLASH_CONFIG_LOAD_ON_DELAY)) { + discharge_state = DISCHARGE_WAIT_CHARGEPUMP; + } + break; + + case DISCHARGE_OVERCURRENT_DELAY: + if(meas->i_load < load_current_limit) { + // current recovered discharge_state = DISCHARGE_OK; + } else if(discharge_time_in_state >= FLASH_CONFIG_OVERLOAD_DELAY_TIME) { + // switch off immediately + power_switch_load_off(); + discharge_state = DISCHARGE_OVERCURRENT; } break; case DISCHARGE_OVERCURRENT: - // Battery voltage is too low, so keep the load switched off + // Current limit reached if(discharge_state_entered) { power_switch_load_off(); } - // no way out except reset + // Overload recovery + if(discharge_time_in_state >= FLASH_CONFIG_OVERLOAD_RETRY_TIME) { + discharge_state = DISCHARGE_WAIT_CHARGEPUMP; + } break; default: diff --git a/src/charge_control.h b/src/charge_control.h index 003b553..8760fcf 100644 --- a/src/charge_control.h +++ b/src/charge_control.h @@ -27,6 +27,7 @@ enum DischargeState DISCHARGE_OK, DISCHARGE_VOLTAGE_LOW, DISCHARGE_OVERCURRENT, + DISCHARGE_OVERCURRENT_DELAY, DISCHARGE_NUM_STATES }; diff --git a/src/flash_config.h b/src/flash_config.h index 5065140..cddf194 100644 --- a/src/flash_config.h +++ b/src/flash_config.h @@ -86,6 +86,10 @@ extern uint8_t __conf_start; * time after load power-on. */ #define FLASH_CONFIG_LOAD_CURRENT_INRUSH_TIME (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0144)) +/* Inrush tolerance time (in ms). Overload protection is not enforced for this + * time after load power-on. */ +#define FLASH_CONFIG_LOAD_CURRENT_INRUSH_TIME (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0144)) + /* Minimum voltage that the charge pump must produce above U_bat before any * power FET is switched on (in mV). */ #define FLASH_CONFIG_MIN_CHARGE_PUMP_EXCESS_VOLTAGE (*(int32_t*)(FLASH_CONFIG_BASE_PTR + 0x0148)) @@ -93,6 +97,14 @@ extern uint8_t __conf_start; /* The minimum time the load must be off before it can be switched on again (in ms). */ #define FLASH_CONFIG_LOAD_ON_DELAY (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x014c)) +/* Overload delay time (in ms). If load current is too high for this duration, + * load is switched permanently off. */ +#define FLASH_CONFIG_OVERLOAD_DELAY_TIME (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0170)) + +/* Overload retry time (in ms). Load is switched on again after this time if + * overload condition has triggered. */ +#define FLASH_CONFIG_OVERLOAD_RETRY_TIME (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0174)) + /* Measurement Averaging: * Alpha is specified in units of 1/1000. 1000 means that only the latest @@ -123,6 +135,8 @@ extern uint8_t __conf_start; /* Deep sleep duration (in seconds). */ #define FLASH_CONFIG_DEEPSLEEP_DURATION (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x016c)) +/* FIXME: next free memory location: 0x178. Update when adding a value! */ + /* Functions */ diff --git a/utils/config_b26.yaml b/utils/config_b26.yaml index aed7811..0a08f38 100644 --- a/utils/config_b26.yaml +++ b/utils/config_b26.yaml @@ -79,6 +79,14 @@ config: # time after load power-on. LOAD_CURRENT_INRUSH_TIME: 10 + # Overload delay time (in ms). If load current is too high for this duration, + # load is switched permanently off. + FLASH_CONFIG_OVERLOAD_DELAY_TIME: 10 + + # Overload retry time (in ms). Load is switched on again after this time if + # overload condition has triggered. + FLASH_CONFIG_OVERLOAD_RETRY_TIME: 1800000 + # Minimum voltage that the charge pump must produce above U_bat before any # power FET is switched on (in mV). MIN_CHARGE_PUMP_EXCESS_VOLTAGE: 10000 diff --git a/utils/config_to_hex.py b/utils/config_to_hex.py index 8891ed7..4996892 100755 --- a/utils/config_to_hex.py +++ b/utils/config_to_hex.py @@ -45,6 +45,8 @@ CONFIG_KEY_TO_OFFSET = { "AVG_ALPHA_TEMP": 0x0164, "DEEPSLEEP_DELAY": 0x0168, "DEEPSLEEP_DURATION": 0x016c, + "FLASH_CONFIG_OVERLOAD_DELAY_TIME": 0x0170, + "FLASH_CONFIG_OVERLOAD_RETRY_TIME": 0x0174 }