623 lines
19 KiB
C
623 lines
19 KiB
C
#include "soc.h"
|
|
#include "system/includes.h"
|
|
#include "app_power_manage.h"
|
|
#include "app_main.h"
|
|
#include "app_config.h"
|
|
#include "app_action.h"
|
|
#include "asm/charge.h"
|
|
#include "ui_manage.h"
|
|
#include "tone_player.h"
|
|
#include "btstack/avctp_user.h"
|
|
#include "user_cfg.h"
|
|
#include "bt.h"
|
|
#include "asm/charge.h"
|
|
#include "ui/ui_api.h"
|
|
#include "../../include/key_event_deal.h"
|
|
#include "smartbox_user_app.h"
|
|
#include "gpadc.h"
|
|
#include "smartbox_info_manager.h"
|
|
|
|
|
|
#define LOG_TAG_CONST APP_CHGBOX
|
|
#define LOG_TAG "[SOC]"
|
|
#define LOG_ERROR_ENABLE
|
|
#define LOG_DEBUG_ENABLE
|
|
#define LOG_INFO_ENABLE
|
|
/* #define LOG_DUMP_ENABLE */
|
|
#define LOG_CLI_ENABLE
|
|
#include "debug.h"
|
|
|
|
|
|
#define CHARGE_QUXIAN_TEST 0
|
|
#define LOW_POWER_READREAD 0//比记忆低重新校准
|
|
#define DISP_TEST_SOC_UI_FIRST 0//校准显示UI
|
|
|
|
#define SOC_SIMULATE 0//仿真测试
|
|
#if (defined CUSTOM_BATTERY_CURVE_MANAGEMENT) && CUSTOM_BATTERY_CURVE_MANAGEMENT
|
|
|
|
|
|
// 低电参数
|
|
#define LOW_POW_STORAGE_MODE 0//1 // 低电是否直接进仓储模式
|
|
#define LOWPOWER_V 3.550 //低电提示电压
|
|
#define POWEROFF_V 3.500 //低电关机电压
|
|
#define POWEROFF_V_OFFSET 0.1 //开机滞回电压差,避免低电反复开机
|
|
// #define POWEROFF_SOC 0.01 //低电百分比关机
|
|
#define POWERSHUTDOWN_V 3.400 //严重低电关机电压
|
|
#define LOWPOWER_CNT 3 //关机计数3*8S关机
|
|
|
|
|
|
// 充电曲线
|
|
#define CHARGE_PA_END_V 4.1//0.1//4.300 //恒流结束电压(估计)
|
|
#define CHARGE_PA_START_V (LOWPOWER_V+0.1)//3.5//0.0//3.500 //恒流开始电压(估计)
|
|
#define CHARGE_PA_END_SOC 0.8//0.0//0.8 //恒流结束百分比(估计)
|
|
#define CHARGE_PA_START_SOC 0.0//0.0 //恒流开始百分比(估计)
|
|
#define CHARGE_PV_TIME (1*25*60*1000)//(1.0*60*60*1000) //恒压充电时间(估计)
|
|
|
|
#if (CHARGE_PV_TIME == 0)
|
|
#define CHARGE_PA_START_A 250 // 恒压充电开始电流
|
|
#define CHARGE_PA_END_A 20 //50 // 恒压充电满电电流
|
|
#endif
|
|
|
|
// 滤波参数
|
|
#define CHR_SPEED 0.003 //充电电量追赶速度
|
|
#define DIS_SPEED 0.001 //放电电量追赶速度
|
|
#define DIS_K 0.2 //放电滤波系数,越大越快
|
|
#define CHANGE_FIL_TIME 10000 //切换过滤不靠谱时间
|
|
#define SOC_CICLE_TIME 8000 //电量循环读取时间
|
|
|
|
|
|
// #define ERROR_SOC 1.0//0.3 //放电差异太大需要重新读
|
|
// #define ZERO_RE_READ 0//1 //放电状态下 电量0 % 是否重新读,关闭比较保险
|
|
// #define CHARG_ZERO_RE_READ 0//1//0// //第一次充电是否重读电量,982给过来的信息概率不准不建议开启
|
|
//
|
|
|
|
// 校准
|
|
// #define charge_first_work_charge_out_trim_vbat 1//0//1
|
|
// #define NO_CHARGE_CNT 2//5//5次采样后才认为稳定
|
|
// #define FIRST_START_INFO /看VM序号实际配置
|
|
// #define ALL_USR_CFG 34//看VM序号实际配置
|
|
|
|
// 放电曲线
|
|
// #define NEW_NUM_POINTS 3//11 // 实际应用的电池曲线(放电)
|
|
static float cap_ocv[][2] = {
|
|
{1.00, 4.1},//100% //建议满电稍低一点,避免出现满电拔掉充电立即掉电的情况 {0.10, LOWPOWER_V},//10%
|
|
{0.00, POWEROFF_V},//0%
|
|
};
|
|
|
|
void earphone_controller_in_poweroff_battery_capacity();
|
|
|
|
#define NEW_NUM_POINTS (ARRAY_SIZE(cap_ocv))
|
|
#if (CHARGE_PV_TIME)
|
|
int get_vbat_a_from_f98 = 0;
|
|
#else
|
|
extern int get_vbat_a_from_f98;
|
|
#endif
|
|
|
|
#if CHARGE_QUXIAN_TEST
|
|
static float vbat_val_test = 4.200;
|
|
|
|
static void change_vbat_val_test(void)
|
|
{
|
|
vbat_val_test -= 0.001;
|
|
r_printf("%s, test val:%f\n", __func__, vbat_val_test);
|
|
}
|
|
#endif /* CHARGE_QUXIAN_TEST */
|
|
|
|
|
|
static void trig_vcb(void (*func)(void))
|
|
{
|
|
log_info("os:%s func:%p", os_current_task(), func);
|
|
func();
|
|
}
|
|
|
|
int send_to_trig_vcb(void (*func)(void), char *taskname)
|
|
{
|
|
if (0) {
|
|
return 0;
|
|
}
|
|
log_info("send_to_trig_ui_vcb:%p", func);
|
|
int argv[3];
|
|
|
|
argv[0] = (int)trig_vcb;
|
|
argv[1] = 1;
|
|
argv[2] = (int)func;
|
|
|
|
int ret = os_taskq_post_type(taskname, Q_CALLBACK, 3, argv);
|
|
if (ret) {
|
|
printf("post ret:%d \n", ret);
|
|
}
|
|
return 0;
|
|
}
|
|
int now_soc_trim_info;
|
|
|
|
// 获取上电信息
|
|
u8 get_first_start_info()
|
|
{
|
|
int reset_sour = 0;
|
|
int vmret = syscfg_read(FIRST_START_INFO, &reset_sour, sizeof(reset_sour));
|
|
if (vmret == sizeof(reset_sour)) {
|
|
g_printf("write_first_start_info 读VM成功: %d", reset_sour);
|
|
}
|
|
now_soc_trim_info = reset_sour;
|
|
return reset_sour;
|
|
}
|
|
|
|
static u8 get_chr_cap(float ocv, float *soc)
|
|
{
|
|
if (ocv < CHARGE_PA_START_V) {
|
|
printf("%s %d", __func__, __LINE__);
|
|
*soc = CHARGE_PA_START_SOC;
|
|
} else if (ocv >= CHARGE_PA_END_V) {
|
|
#if(CHARGE_PV_TIME)
|
|
*soc += (float)SOC_CICLE_TIME / (float)CHARGE_PV_TIME * (1.0 - CHARGE_PA_END_SOC);
|
|
if (*soc > 1.0) {
|
|
*soc = 1.0;
|
|
}
|
|
printf("%s %d", __func__, __LINE__);
|
|
return 1;
|
|
#else
|
|
*soc = CHARGE_PA_END_SOC + (CHARGE_PA_START_A - get_vbat_a_from_f98) * (1.0 - CHARGE_PA_END_SOC) / (CHARGE_PA_START_A - CHARGE_PA_END_A);
|
|
printf("%s %d", __func__, __LINE__);
|
|
return 0;
|
|
#endif
|
|
} else {
|
|
printf("%s %d", __func__, __LINE__);
|
|
*soc = CHARGE_PA_START_SOC + (CHARGE_PA_END_SOC - CHARGE_PA_START_SOC) * (ocv - CHARGE_PA_START_V) / (CHARGE_PA_END_V - CHARGE_PA_START_V);
|
|
}
|
|
printf("%s %d", __func__, __LINE__);
|
|
return 0 ;
|
|
}
|
|
|
|
static float get_ocv(float cap)
|
|
{
|
|
if (cap >= cap_ocv[0][0]) {
|
|
return cap_ocv[0][1];
|
|
} else if (cap <= cap_ocv[NEW_NUM_POINTS - 1][0]) {
|
|
return cap_ocv[NEW_NUM_POINTS - 1][1];
|
|
} else {
|
|
for (int i = 0; i < NEW_NUM_POINTS - 1; i++) {
|
|
if (cap <= cap_ocv[i][0] && cap >= cap_ocv[i + 1][0]) {
|
|
float ocv = cap_ocv[i][1] + (cap - cap_ocv[i][0]) * (cap_ocv[i + 1][1] - cap_ocv[i][1]) / (cap_ocv[i + 1][0] - cap_ocv[i][0]);
|
|
return ocv;
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static float get_cap(float ocv)
|
|
{
|
|
|
|
printf("%f %f %f %f", cap_ocv[0][1], cap_ocv[0][0], cap_ocv[NEW_NUM_POINTS - 1][1], cap_ocv[NEW_NUM_POINTS - 1][0]);
|
|
if (ocv >= cap_ocv[0][1]) {
|
|
return cap_ocv[0][0];
|
|
} else if (ocv <= cap_ocv[NEW_NUM_POINTS - 1][1]) {
|
|
return cap_ocv[NEW_NUM_POINTS - 1][0];
|
|
} else {
|
|
for (int i = 0; i < NEW_NUM_POINTS - 1; i++) {
|
|
if (ocv <= cap_ocv[i][1] && ocv >= cap_ocv[i + 1][1]) {
|
|
float cap = cap_ocv[i][0] + (ocv - cap_ocv[i][1]) * (cap_ocv[i + 1][0] - cap_ocv[i][0]) / (cap_ocv[i + 1][1] - cap_ocv[i][1]);
|
|
return cap;
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
static int vm_vbat_value = 0;
|
|
static void write_vm_vbat_value(int vm_value)
|
|
{
|
|
if (vm_value < -1) {
|
|
vm_value = -1;
|
|
} else if (vm_value > 100) {
|
|
vm_value = -1;
|
|
}
|
|
printf("%s %d", __func__, vm_value);
|
|
syscfg_write(VM_BAT_PRESENT, &vm_value, sizeof(vm_value));
|
|
}
|
|
|
|
static int read_vm_vbat_value()
|
|
{
|
|
int vm_value = -1;
|
|
int ret = syscfg_read(VM_BAT_PRESENT, &vm_value, sizeof(vm_value));
|
|
if (ret > 0) {
|
|
if (vm_value < 0) {
|
|
vm_value = -1;
|
|
} else if (vm_value > 100) {
|
|
vm_value = -1;
|
|
}
|
|
|
|
printf(">>>>>>>>> VM init val is %d", vm_vbat_value);
|
|
} else {
|
|
vm_value = -1;
|
|
}
|
|
|
|
// vm_vbat_value = vm_value;
|
|
return vm_value;
|
|
}
|
|
|
|
u8 check_bat_vm_is_vaild()
|
|
{
|
|
if (-1 == read_vm_vbat_value()) {
|
|
return 0;
|
|
} else {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
static float disp_soc;
|
|
static void soc_calculate_loop(void *p);
|
|
static void low_enter_poweroff();
|
|
static void force_poweroff(void *p);
|
|
// #include "lvgl.h"
|
|
|
|
int get_curr_soc()
|
|
{
|
|
return sbox_battery_box_get();
|
|
}
|
|
|
|
|
|
static u8 reread = 0;
|
|
|
|
|
|
static int soc_trim_id = 0;
|
|
|
|
static int app_is_sleep = 0;
|
|
static u16 app_sleep_check_timer = 0;
|
|
void app_sleep_check()
|
|
{
|
|
int value = 1;
|
|
/* struct lp_target *p; */
|
|
// list_for_each_lp_target(p){
|
|
// value = 1 & (p->is_idle());
|
|
// putchar('*');
|
|
// }
|
|
int lcd_sleep_flag = true;
|
|
|
|
#ifdef CONFIG_UI_STYLE_JL_CSC_PUBLIC_MODLS_ENABLE
|
|
lcd_sleep_flag = lcd_sleep_status();
|
|
#endif
|
|
|
|
if (value && lcd_sleep_flag && (sbox_ble_connect_flag_get() == 0) && !sbox_box_charging_get()) {
|
|
++app_is_sleep;
|
|
putchar('o');
|
|
if (app_is_sleep > TCFG_AUTO_POWER_OFF_TIME) {
|
|
putchar('P');
|
|
// app_chargebox_api_shutdown();
|
|
// power_event_to_user(POWER_EVENT_POWER_LOW);
|
|
// set_sys_soft_shutdown_flag(1);
|
|
// app_chargebox_api_shutdown();
|
|
sys_timer_del(app_sleep_check_timer);
|
|
// soft_poweroff_mode(1); ///强制关机
|
|
sys_enter_soft_poweroff(POWEROFF_NORMAL);
|
|
}
|
|
} else {
|
|
// putchar('@');
|
|
app_is_sleep = 0;
|
|
}
|
|
}
|
|
|
|
void soc_check_init()
|
|
{
|
|
r_printf("soc_check_init reset ok");
|
|
#if CHARGE_QUXIAN_TEST
|
|
sys_timer_add(NULL, change_vbat_val_test, 2000);
|
|
#endif /* CHARGE_QUXIAN_TEST */
|
|
get_first_start_info();
|
|
// 读取各个电量信息
|
|
#if CHARGE_QUXIAN_TEST
|
|
float current_707_vbat = vbat_val_test;//(float)(adc_get_voltage(AD_CH_PMU_VBAT) * 4)/1000.0;
|
|
r_printf("current_707_vbat init:%f\n", (float)(adc_get_voltage(AD_CH_PMU_VBAT) * 4) / 1000.0);
|
|
#else
|
|
float current_707_vbat = (float)(adc_get_voltage(AD_CH_PMU_VBAT) * 4) / 1000.0;
|
|
#endif /* CHARGE_QUXIAN_TEST */
|
|
float current_982_vbat = current_707_vbat;//(float)(adc_get_value_f98())/1000.0;
|
|
u8 charging = (sbox_box_charging_get() /*|| (nocharge_cnt<NO_CHARGE_CNT)*/);
|
|
|
|
// 读取VM的电量
|
|
vm_vbat_value = read_vm_vbat_value();
|
|
r_printf("init vm_vbat_value %d", vm_vbat_value);
|
|
|
|
// 无效电量,看时机校准
|
|
if (vm_vbat_value == -1) {
|
|
r_printf("init vm_vbat_value invail");
|
|
} else {
|
|
// 初始电量
|
|
disp_soc = (float)vm_vbat_value / 100.0;
|
|
r_printf("init disp_soc:%f", disp_soc);
|
|
|
|
r_printf("arry : %d", NEW_NUM_POINTS);
|
|
#if LOW_POWER_READREAD
|
|
|
|
|
|
// 非充电状态,比记忆低,重新读取
|
|
if (!charging && (get_cap(current_707_vbat) < disp_soc - 0.1)) {
|
|
g_printf(">>>>no charge vbat low low :%f, %f", disp_soc, get_cap(current_707_vbat));
|
|
disp_soc = get_cap(current_707_vbat);
|
|
}
|
|
#endif
|
|
// 范围控制
|
|
disp_soc = SOC_CLAMP(-1.0, disp_soc, 101.0);
|
|
vm_vbat_value = (int)(disp_soc * 100.0);
|
|
if (vm_vbat_value < 1) {
|
|
vm_vbat_value += 1;
|
|
}
|
|
vm_vbat_value = SOC_CLAMP(0, vm_vbat_value, 100);
|
|
sbox_battery_box_set(vm_vbat_value);
|
|
write_vm_vbat_value(sbox_battery_box_get());
|
|
}
|
|
|
|
g_printf(">>>>set_soc_first_work c %d init %d mapsoc:%f 701:%f 982:%f", charging, sbox_battery_box_get(), disp_soc, current_707_vbat, current_982_vbat);
|
|
|
|
#if SOC_SIMULATE
|
|
if (!soc_trim_id) {
|
|
soc_trim_id = sys_timer_add(NULL, soc_calculate_loop, 10);
|
|
}
|
|
#else
|
|
if (!soc_trim_id) {
|
|
soc_trim_id = sys_timer_add(NULL, soc_calculate_loop, (vm_vbat_value == -1) ? 500 : SOC_CICLE_TIME);
|
|
}
|
|
#endif
|
|
|
|
if (app_sleep_check_timer == 0) {
|
|
app_sleep_check_timer = sys_timer_add(NULL, app_sleep_check, 60000);//检查是否进入低功耗
|
|
}
|
|
|
|
}
|
|
|
|
float current_701_vbat;
|
|
float current_982_vbat;
|
|
float map_soc;
|
|
static int last_change_time = 0;
|
|
|
|
static void soc_calculate_loop(void *p)
|
|
{
|
|
r_printf("Entering soc_calculate_loop\n");
|
|
|
|
// 读取各个电量信息
|
|
#if CHARGE_QUXIAN_TEST
|
|
current_701_vbat = vbat_val_test;
|
|
r_printf("Testing mode: current_701_vbat: %f\n", (float)(adc_get_voltage(AD_CH_PMU_VBAT) * 4) / 1000.0);
|
|
#else
|
|
current_701_vbat = (float)(adc_get_voltage(AD_CH_PMU_VBAT) * 4) / 1000.0;
|
|
r_printf("Normal mode: current_701_vbat: %f\n", current_701_vbat);
|
|
#endif /* CHARGE_QUXIAN_TEST */
|
|
|
|
current_982_vbat = current_701_vbat;
|
|
u8 charging = sbox_box_charging_get();
|
|
|
|
r_printf("Charging status: %d\n", charging);
|
|
|
|
if (current_701_vbat < 2.0) {
|
|
r_printf("Error: 701 VBAT below threshold\n");
|
|
return;
|
|
}
|
|
|
|
if (charging && current_982_vbat < 2.0) {
|
|
r_printf("Error: 982 VBAT below threshold while charging\n");
|
|
return;
|
|
}
|
|
|
|
// 严重低电
|
|
if (!charging && (current_701_vbat < POWERSHUTDOWN_V)) {
|
|
earphone_controller_in_poweroff_battery_capacity();
|
|
g_printf("Critical low battery: %f\n", current_701_vbat);
|
|
vm_vbat_value = 0;
|
|
sbox_battery_box_set(vm_vbat_value);
|
|
write_vm_vbat_value(vm_vbat_value);
|
|
force_poweroff(NULL);
|
|
return;
|
|
}
|
|
|
|
// 记录变化时间点
|
|
static s8 state = -1;
|
|
if (state != charging || last_change_time == 0) {
|
|
last_change_time = jiffies_msec();
|
|
state = charging;
|
|
r_printf("State change detected: charging = %d, time = %d\n", charging, last_change_time);
|
|
}
|
|
|
|
#if DISP_TEST_SOC_UI_FIRST
|
|
if (vm_vbat_value == -1) {
|
|
static u8 firstsoc_disp = 1;
|
|
if (firstsoc_disp) {
|
|
firstsoc_disp = 0;
|
|
send_to_trig_vcb(soc_disp, "ui");
|
|
r_printf("First SOC display triggered\n");
|
|
}
|
|
}
|
|
#endif
|
|
|
|
// 过滤不靠谱时间
|
|
r_printf("Current time: %d, Last change time: %d\n", jiffies_msec(), last_change_time);
|
|
if (jiffies_msec() - last_change_time < CHANGE_FIL_TIME) {
|
|
r_printf("Time filter active, skipping calculation\n");
|
|
return;
|
|
}
|
|
r_printf("Passed time filter\n");
|
|
|
|
// 无效电量,需要重新校准
|
|
if (vm_vbat_value == -1) {
|
|
r_printf("Invalid battery value detected, starting recalibration\n");
|
|
|
|
if (!charging) {
|
|
r_printf("Device is not charging, proceeding with recalibration\n");
|
|
|
|
// 修改定时器
|
|
sys_timer_modify(soc_trim_id, SOC_CICLE_TIME);
|
|
r_printf("Timer modified with SOC_CICLE_TIME: %d\n", SOC_CICLE_TIME);
|
|
|
|
// 获取当前电量
|
|
disp_soc = get_cap(current_701_vbat);
|
|
r_printf("Calculated SOC from voltage: %f\n", disp_soc);
|
|
|
|
// 限制 SOC 范围
|
|
disp_soc = SOC_CLAMP(-1.0, disp_soc, 101.0);
|
|
r_printf("Clamped SOC: %f\n", disp_soc);
|
|
|
|
// 转换为整数
|
|
vm_vbat_value = (int)(disp_soc * 100.0);
|
|
r_printf("Converted SOC to integer value: %d\n", vm_vbat_value);
|
|
|
|
// 确保电量值不低于 1
|
|
if (vm_vbat_value < 1) {
|
|
vm_vbat_value += 1;
|
|
r_printf("Adjusted SOC to minimum threshold: %d\n", vm_vbat_value);
|
|
}
|
|
|
|
// 再次限制范围
|
|
vm_vbat_value = SOC_CLAMP(0, vm_vbat_value, 100);
|
|
r_printf("Final clamped SOC value: %d\n", vm_vbat_value);
|
|
|
|
// 更新电池信息
|
|
sbox_battery_box_set(vm_vbat_value);
|
|
write_vm_vbat_value(vm_vbat_value);
|
|
r_printf("Recalibrated SOC saved: %d\n", vm_vbat_value);
|
|
} else {
|
|
r_printf("Device is charging, skipping recalibration\n");
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
// 低电关机
|
|
static int low_cnt = 0;
|
|
if (!charging && (current_701_vbat < POWEROFF_V)) {
|
|
g_printf("Low battery detected: %f\n", current_701_vbat);
|
|
low_cnt++;
|
|
}
|
|
if (charging) {
|
|
low_cnt = 0;
|
|
}
|
|
if (low_cnt > LOWPOWER_CNT) {
|
|
g_printf("Low power shutdown triggered\n");
|
|
vm_vbat_value = 0;
|
|
sbox_battery_box_set(vm_vbat_value);
|
|
write_vm_vbat_value(vm_vbat_value);
|
|
low_enter_poweroff();
|
|
return;
|
|
}
|
|
|
|
// 计算电量
|
|
r_printf("Calculating SOC\n");
|
|
if (charging) {
|
|
map_soc = disp_soc;
|
|
u8 ret = get_chr_cap(current_982_vbat, &map_soc);
|
|
if (ret) {
|
|
disp_soc = map_soc;
|
|
r_printf("Charging: SOC updated to %f\n", disp_soc);
|
|
}
|
|
} else {
|
|
map_soc = get_cap(current_701_vbat);
|
|
r_printf("Discharging: Calculated SOC = %f\n", map_soc);
|
|
}
|
|
|
|
// 追赶
|
|
r_printf("Adjusting SOC\n");
|
|
if (map_soc > disp_soc && charging) {
|
|
if (disp_soc < 0.01) {
|
|
disp_soc += 0.02;
|
|
}
|
|
disp_soc += CHR_SPEED;
|
|
r_printf("Charging: SOC increased to %f\n", disp_soc);
|
|
}
|
|
if (map_soc < disp_soc && !charging) {
|
|
disp_soc -= (disp_soc - map_soc) < DIS_SPEED ? DIS_SPEED : (disp_soc - map_soc) * DIS_K;
|
|
r_printf("Discharging: SOC decreased to %f\n", disp_soc);
|
|
}
|
|
|
|
// 转化整形
|
|
r_printf("Clamping SOC\n");
|
|
disp_soc = SOC_CLAMP(-1.0, disp_soc, 101.0);
|
|
vm_vbat_value = (int)(disp_soc * 100.0);
|
|
if (vm_vbat_value < 1) {
|
|
vm_vbat_value += 1;
|
|
}
|
|
vm_vbat_value = SOC_CLAMP(0, vm_vbat_value, 100);
|
|
sbox_battery_box_set(vm_vbat_value);
|
|
|
|
// 电量变化保存
|
|
static u8 lastboxbat = -3;
|
|
if (lastboxbat != sbox_battery_box_get()) {
|
|
lastboxbat = sbox_battery_box_get();
|
|
write_vm_vbat_value(lastboxbat);
|
|
UI_MSG_POST("batcharge:process=%4", lastboxbat);
|
|
r_printf("Battery value saved: %d\n", lastboxbat);
|
|
}
|
|
|
|
r_printf("Charge: %d, SOC: %.2f, 701: %.2f, Map: %.2f, 982: %.2f\n",
|
|
charging, disp_soc * 100.0, current_701_vbat, map_soc, current_982_vbat);
|
|
|
|
r_printf("Exiting soc_calculate_loop\n");
|
|
}
|
|
|
|
|
|
|
|
|
|
// 开机前电压判断
|
|
void usr_check_power_on_voltage(void)
|
|
{
|
|
float current_vbat;
|
|
current_vbat = (float)(adc_get_voltage(AD_CH_PMU_VBAT) * 4) / 1000.0;
|
|
g_printf("usr_check_power_on_voltage current_vbat %f ", current_vbat);
|
|
if (current_vbat <= POWEROFF_V + POWEROFF_V_OFFSET) {
|
|
extern void sbox_storage_mode_enter();
|
|
sbox_storage_mode_enter();
|
|
}
|
|
}
|
|
|
|
static void force_poweroff(void *p)
|
|
{
|
|
g_printf("%s %d", __func__, __LINE__);
|
|
sbox_battery_box_set(0);
|
|
write_vm_vbat_value(0);
|
|
|
|
#if LOW_POW_STORAGE_MODE
|
|
extern void sbox_storage_mode_enter();
|
|
sbox_storage_mode_enter();
|
|
#else
|
|
// soft_poweroff_mode(1); ///强制关机
|
|
sys_enter_soft_poweroff(0);
|
|
#endif
|
|
}
|
|
|
|
static void low_enter_poweroff()
|
|
{
|
|
g_printf("%s %d", __func__, __LINE__);
|
|
sbox_battery_box_set(0);
|
|
write_vm_vbat_value(0);
|
|
// ui_poweroff_enter();
|
|
sys_timer_add(NULL, force_poweroff, 5000);
|
|
}
|
|
|
|
// 升级代码、上电复位、清
|
|
void write_first_start_info(int reset_sour)
|
|
{
|
|
|
|
y_printf("write_first_start_info : %d", reset_sour);
|
|
|
|
// if(reset_sour == 200){
|
|
// // 设置成无效状态
|
|
// // box_info.box_bat = vm_vbat_value = -1;
|
|
// // write_vm_vbat_value(box_info.box_bat);
|
|
// // sys_timer_modify(soc_trim_id, 100);
|
|
// }
|
|
|
|
int ret = 0;
|
|
int retry = 10;
|
|
do {
|
|
ret = syscfg_write(FIRST_START_INFO, &reset_sour, sizeof(reset_sour));
|
|
y_printf("retry:%d", retry);
|
|
os_time_dly(1);
|
|
} while (ret <= 0 && retry);
|
|
now_soc_trim_info = reset_sour;
|
|
}
|
|
|
|
#endif //#if (defined CUSTOM_BATTERY_CURVE_MANAGEMENT) && CUSTOM_BATTERY_CURVE_MANAGEMENT
|
|
|