fix(battery): detect TP4056 charging and full states on new board
This commit is contained in:
@@ -403,22 +403,25 @@ void platform_power_release_deep_sleep_holds(void);
|
||||
esp_err_t platform_power_enter_deep_sleep(int charger_gpio, int button_gpio);
|
||||
|
||||
/* platform 只报告原始充电和电压质量,电量等级/SOC 语义由 domain 层计算。 */
|
||||
typedef enum {
|
||||
PLATFORM_BATTERY_CHARGE_UNKNOWN = 0,
|
||||
PLATFORM_BATTERY_CHARGE_NOT_CHARGING,
|
||||
PLATFORM_BATTERY_CHARGE_CHARGING,
|
||||
} platform_battery_charge_state_t;
|
||||
/* 板级数字输入原始电平;电平组合含义及去抖由 domain 唯一解释。 */
|
||||
typedef struct {
|
||||
int charge_level;
|
||||
int full_level;
|
||||
bool valid;
|
||||
} platform_battery_charge_inputs_t;
|
||||
|
||||
/** 读取两路原始电平;无 ADC 访问,互斥等待最多100ms。 */
|
||||
esp_err_t platform_battery_read_charge_inputs(platform_battery_charge_inputs_t *out_inputs);
|
||||
|
||||
typedef struct {
|
||||
int adc_voltage_mv;
|
||||
int voltage_mv;
|
||||
platform_battery_charge_state_t charge_state;
|
||||
bool voltage_valid;
|
||||
bool high_load_active;
|
||||
bool cooldown_active;
|
||||
} platform_battery_sample_t;
|
||||
|
||||
/** 幂等初始化电池 ADC 和 TP4057 状态输入。 / Idempotently initialize battery sensing. */
|
||||
/** 幂等初始化电池 ADC 和 TP4056 两路状态输入。 / Idempotently initialize battery sensing. */
|
||||
esp_err_t platform_battery_init(void);
|
||||
|
||||
/**
|
||||
|
||||
@@ -41,6 +41,7 @@ static adc_oneshot_unit_handle_t s_adc_handle;
|
||||
static adc_cali_handle_t s_cali_handle;
|
||||
static adc_channel_t s_adc_channel;
|
||||
static bool s_initialized;
|
||||
static bool s_inputs_initialized;
|
||||
static StaticSemaphore_t s_adc_lock_buffer;
|
||||
static SemaphoreHandle_t s_adc_lock;
|
||||
static portMUX_TYPE s_adc_lock_init_guard = portMUX_INITIALIZER_UNLOCKED;
|
||||
@@ -123,6 +124,53 @@ static esp_err_t create_calibration(adc_unit_t unit, adc_channel_t channel)
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/* 调用者持有 ADC/输入互斥锁;数字输入可独立初始化,不依赖 ADC 校准成功。 */
|
||||
static esp_err_t configure_charge_inputs_locked(void)
|
||||
{
|
||||
if (s_inputs_initialized) {
|
||||
return ESP_OK;
|
||||
}
|
||||
if (!GPIO_IS_VALID_GPIO(CONFIG_TQ_BATTERY_CHARGE_GPIO) ||
|
||||
!GPIO_IS_VALID_GPIO(CONFIG_TQ_BATTERY_FULL_GPIO) ||
|
||||
CONFIG_TQ_BATTERY_CHARGE_GPIO == CONFIG_TQ_BATTERY_FULL_GPIO ||
|
||||
CONFIG_TQ_BATTERY_ADC_GPIO == CONFIG_TQ_BATTERY_CHARGE_GPIO ||
|
||||
CONFIG_TQ_BATTERY_ADC_GPIO == CONFIG_TQ_BATTERY_FULL_GPIO) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
gpio_config_t config = {
|
||||
.pin_bit_mask = gpio_mask(CONFIG_TQ_BATTERY_CHARGE_GPIO) |
|
||||
gpio_mask(CONFIG_TQ_BATTERY_FULL_GPIO),
|
||||
.mode = GPIO_MODE_INPUT,
|
||||
.pull_up_en = GPIO_PULLUP_ENABLE,
|
||||
.pull_down_en = GPIO_PULLDOWN_DISABLE,
|
||||
.intr_type = GPIO_INTR_DISABLE,
|
||||
};
|
||||
esp_err_t err = gpio_config(&config);
|
||||
if (err == ESP_OK) {
|
||||
s_inputs_initialized = true;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t platform_battery_read_charge_inputs(platform_battery_charge_inputs_t *out_inputs)
|
||||
{
|
||||
if (out_inputs == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
memset(out_inputs, 0, sizeof(*out_inputs));
|
||||
if (!lock_adc()) {
|
||||
return ESP_ERR_TIMEOUT;
|
||||
}
|
||||
esp_err_t err = configure_charge_inputs_locked();
|
||||
if (err == ESP_OK) {
|
||||
out_inputs->charge_level = gpio_get_level(CONFIG_TQ_BATTERY_CHARGE_GPIO);
|
||||
out_inputs->full_level = gpio_get_level(CONFIG_TQ_BATTERY_FULL_GPIO);
|
||||
out_inputs->valid = true;
|
||||
}
|
||||
unlock_adc();
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t platform_battery_init(void)
|
||||
{
|
||||
if (!lock_adc()) {
|
||||
@@ -133,24 +181,10 @@ esp_err_t platform_battery_init(void)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
if (CONFIG_TQ_BATTERY_CHARGE_GPIO >= GPIO_NUM_MAX) {
|
||||
esp_err_t input_err = configure_charge_inputs_locked();
|
||||
if (input_err != ESP_OK) {
|
||||
unlock_adc();
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (CONFIG_TQ_BATTERY_CHARGE_GPIO >= 0) {
|
||||
gpio_config_t charge_config = {
|
||||
.pin_bit_mask = gpio_mask(CONFIG_TQ_BATTERY_CHARGE_GPIO),
|
||||
.mode = GPIO_MODE_INPUT,
|
||||
.pull_up_en = GPIO_PULLUP_ENABLE,
|
||||
.pull_down_en = GPIO_PULLDOWN_DISABLE,
|
||||
.intr_type = GPIO_INTR_DISABLE,
|
||||
};
|
||||
esp_err_t gpio_err = gpio_config(&charge_config);
|
||||
if (gpio_err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Configure charger status GPIO failed: %s", esp_err_to_name(gpio_err));
|
||||
unlock_adc();
|
||||
return gpio_err;
|
||||
}
|
||||
return input_err;
|
||||
}
|
||||
|
||||
adc_unit_t unit = ADC_UNIT_1;
|
||||
@@ -295,14 +329,6 @@ esp_err_t platform_battery_read_sample(platform_battery_sample_t *out_sample)
|
||||
out_sample->voltage_mv <= BATTERY_VALID_MAX_MV;
|
||||
snapshot_load_state(&out_sample->high_load_active, &out_sample->cooldown_active);
|
||||
|
||||
if (CONFIG_TQ_BATTERY_CHARGE_GPIO < 0) {
|
||||
out_sample->charge_state = PLATFORM_BATTERY_CHARGE_UNKNOWN;
|
||||
} else {
|
||||
int level = gpio_get_level((gpio_num_t)CONFIG_TQ_BATTERY_CHARGE_GPIO);
|
||||
out_sample->charge_state = level == CONFIG_TQ_BATTERY_CHARGE_ACTIVE_LEVEL
|
||||
? PLATFORM_BATTERY_CHARGE_CHARGING
|
||||
: PLATFORM_BATTERY_CHARGE_NOT_CHARGING;
|
||||
}
|
||||
unlock_adc();
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -341,6 +367,14 @@ void platform_battery_load_end(platform_battery_load_source_t source)
|
||||
|
||||
#else
|
||||
|
||||
esp_err_t platform_battery_read_charge_inputs(platform_battery_charge_inputs_t *out_inputs)
|
||||
{
|
||||
if (out_inputs != NULL) {
|
||||
memset(out_inputs, 0, sizeof(*out_inputs));
|
||||
}
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
esp_err_t platform_battery_init(void)
|
||||
{
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
|
||||
Reference in New Issue
Block a user