mcu_ab568x/app/platform/bsp/bsp_vbat.c
2025-05-30 18:03:10 +08:00

296 lines
9.0 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "include.h"
#include "app_variable.h"
#if VBAT_DETECT_EN
#define VBG_VOLTAGE sys_trim.vbg_volt
#define VBAT2_COEF sys_trim.vbat_coef
#define TRACE_EN 0
#if TRACE_EN
#define TRACE(...) printf(__VA_ARGS__)
#else
#define TRACE(...)
#endif
static vbat_cb_t vbat_cb;
AT(.com_rodata.bat)
const char bat_str[] = "VBAT: %d.%03dV\n";
AT(.com_text.port.vbat)
u16 bsp_vbat_get_voltage(u32 rst_flag)
{
u32 vbat;
u32 vbat2 = saradc_get_value10(VBAT2_ADCCH);
vbat = saradc_vbat_get_calc_value(vbat2, adc_cb.bg, adc_cb.vrtc_val, adc_cb.vrtc_first);
if (rst_flag) {
adc_cb.vbat_bak = 0;
adc_cb.vbat_val = vbat;
adc_cb.vbat_total = adc_cb.vbat_val << 5;
}
//不同方案可能采用不同 vbat 滤波算法, 在方案对应的plugin.c中处理
plugin_vbat_filter(&vbat);
//默认的取平均值算法.
adc_cb.vbat_total = adc_cb.vbat_total - adc_cb.vbat_val + vbat;
adc_cb.vbat_val = adc_cb.vbat_total >> 5; //平均值
if (adc_cb.vbat_val > adc_cb.vbat_bak) {
vbat = adc_cb.vbat_val - adc_cb.vbat_bak;
} else {
vbat = adc_cb.vbat_bak - adc_cb.vbat_val;
}
if (vbat >= 2) { //偏差大于一定值则更新
adc_cb.vbat_bak = adc_cb.vbat_val;
}
// printf(bat_str, adc_cb.vbat_val/1000, adc_cb.vbat_val%1000);
return adc_cb.vbat_bak;
}
void bsp_vbat_voltage_init(void)
{
sys_cb.vbat = bsp_vbat_get_voltage(1);
// printf("!!!bsp_vbat_voltage_init sys_cb.vbat=%d\n", sys_cb.vbat);
}
int bsp_vbat_get_lpwr_status(void)
{
if(CHARGE_DC_IN()){
return 0;
}
if(sys_cb.charge_sta > 0)
{
return 0;
}
if ((sys_cb.vbat <= LPWR_OFF_VBAT)&&(bsp_vbat_percent_get() <= 3 )) {
if (LPWR_OFF_VBAT) {
if (!sys_cb.lpwr_cnt) {
sys_cb.lpwr_cnt = 1;
// printf("!!!sys_cb.vbat=%d\n", sys_cb.vbat);
} else if (sys_cb.lpwr_cnt >= 10) {
return 2; //VBAT低电关机
}
}
return 0; //VBAT低电不关机
} else {
sys_cb.lpwr_cnt = 0;
if ((sys_cb.vbat < LPWR_WARNING_VBAT)&&(bsp_vbat_percent_get() <= 24 )) {
return 1; //VBAT低电提醒状态
} else {
}
return 0;
}
sys_cb.lpwr_cnt = 0;
return 0;
}
// static int printf_sec = 0;
void bsp_vbat_lpwr_process(void)
{
int vbat_sta = bsp_vbat_get_lpwr_status();
if (vbat_sta == 2) { //达到低电关机状态
if (func_cb.sta != FUN_POWER_OFF_LOGO) {
printf("now is a vaba_sta low power enter to power off !!!\n");
if (sys_cb.gui_sleep_sta) {
sys_cb.wkp_flag = true;
}
func_switch_to_assign_screen(FUN_POWER_OFF_LOGO, true); // 低电,进入关机或省电模式
}
return;
} else if (vbat_sta == 1) { //低电提醒状态
//低电提示音播放
sys_cb.vbat_nor_cnt = 0;
if (sys_cb.lpwr_warning_cnt > LPWR_WARNING_PERIOD) {
sys_cb.lpwr_warning_cnt = 0;
if(func_cb.sta != FUNC_CHARGE)
{
if (sys_cb.gui_sleep_sta) {
sys_cb.wkp_flag = true;
}
sys_cb.motor_flag = 1;
set_func_motor(80, 10, 0, 1);
func_popup_new(POPUP_ID_LOW_POWER_REMIND);
}
if (sys_cb.lpwr_warning_times) { //低电语音提示次数
sys_cb.lowbat_flag = 1;
plugin_lowbat_vol_reduce(); //低电降低音乐音量
if (sys_cb.lpwr_warning_times != 0xff) {
sys_cb.lpwr_warning_times--;
}
}
}
} else {
if ((sys_cb.lowbat_flag) && (sys_cb.vbat > 3800)) {
sys_cb.vbat_nor_cnt++;
if (sys_cb.vbat_nor_cnt > 40) {
sys_cb.lowbat_flag = 0;
sys_cb.lpwr_warning_times = LPWR_WARING_TIMES;
plugin_lowbat_vol_recover(); //离开低电, 恢复音乐音量
}
}
}
}
/* 中性32M方屏的电流曲线 */
#if (GUI_SCREEN_WIDTH == 240 && GUI_SCREEN_HEIGHT == 296 && FLASH_SIZE == FSIZE_4M)
/**
* 电池电量对应百分百表
不同电池修改这张表格表格默认的是4.2v的电池
*/
static const u16 vbat_percent_table[11] = {
// 0% 10% 20% 30% 40% 50% 60% 70% 80% 90% 100%
3480, 3580, 3640, 3690, 3760, 3790, 3820, 3860, 3950, 4050, 4180
};//优化了100%~70%之间的电压值,使这段区间更加耐用;拉宽40%~60%之间的电压值避免40%的电量很快掉到30%以下不能OTA
#else
/**
* 电池电量对应百分百表
不同电池修改这张表格表格默认的是4.2v的电池
*/
static const u16 vbat_percent_table[11] = {
// 0% 10% 20% 30% 40% 50% 60% 70% 80% 90% 100%
3480, 3580, 3640, 3690, 3720, 3750, 3780, 3820, 3900, 3980, 4100
};
#endif
/**
* 电池电量标定回到充电和放电都在这里处理了10s一次回调
*/
static u16 vbat_percent_convert(u16 adc_value)
{
u16 pervent = 0;
u8 i = 0;
if(adc_value >= vbat_percent_table[10]){
return 100;
}
if(adc_value <= vbat_percent_table[0]){
return 0;
}
for(i=0; i<=10; i++){
if(adc_value < vbat_percent_table[i]){
break;
}
}
pervent = (adc_value - vbat_percent_table[i-1]) * 10 / (vbat_percent_table[i] - vbat_percent_table[i-1]) + (i-1)*10;
//pervent = (i-1) * 10;
return pervent;
}
/**
* 电池电量标定回调执行充电和放电都在这里处理了10s执行一次修改在bsp_vbat_percent_init函数
*/
static void vbat_percent_process(co_timer_t *timer, void *param)
{
if(vbat_cb.vbat_adc_last == 0){
sys_cb.vbat_percent = vbat_percent_convert(adc_cb.vbat_val);
vbat_cb.vbat_adc_last = adc_cb.vbat_val;
vbat_cb.vbat_adc_curr = adc_cb.vbat_val;
return;
}
sys_cb.vbat = bsp_vbat_get_voltage(0);
vbat_cb.vbat_adc_curr = adc_cb.vbat_val;
if(CHARGE_DC_IN()){ //充电状态
if(bsp_charge_sta_get() == 2){ //硬件判断充满状态
if(adc_cb.vbat_val < vbat_percent_table[10]){ //如果硬件已经满了,对于个别一些烂电池可能始终没无法达到预设电压, 也认为其满了
vbat_cb.vbat_adc_curr = vbat_percent_table[10];
}
}
if(vbat_cb.vbat_adc_last < vbat_cb.vbat_adc_curr){
vbat_cb.vbat_adc_last += VBAT_PERCENT_STEP*4;
}
}else{
if(vbat_cb.vbat_adc_last > vbat_cb.vbat_adc_curr){
if(vbat_cb.vbat_adc_last - vbat_cb.vbat_adc_curr > 50)
{
vbat_cb.vbat_adc_last = vbat_cb.vbat_adc_curr;
}
vbat_cb.vbat_adc_last -= VBAT_PERCENT_STEP;
if (bsp_system_is_sleep()) {
sys_cb.vbat_percent = vbat_percent_convert(vbat_cb.vbat_adc_last);
}
}
}
if (!bsp_system_is_sleep()) {
sys_cb.vbat_percent = vbat_percent_convert(vbat_cb.vbat_adc_last);
}
TRACE("bsp_system_is_sleep():%d,vbat_adc_last:%d vbat_adc_curr:%d vbat_percent:%d\n",bsp_system_is_sleep(), vbat_cb.vbat_adc_last, vbat_cb.vbat_adc_curr, sys_cb.vbat_percent);
}
/**
* 电池百分比标定初始化
*/
void bsp_vbat_percent_init(void)
{
static co_timer_t vbat_timer;
memset(&vbat_cb, 0, sizeof(vbat_cb_t));
vbat_percent_process(NULL, NULL);
co_timer_set(&vbat_timer, 5000, TIMER_REPEAT, LEVEL_LOW_PRI, vbat_percent_process, NULL);
co_timer_set_sleep(&vbat_timer, true);
}
/**
* 获取电池电量百分比
* 返回: 0~100
*/
u16 bsp_vbat_percent_get(void)
{
return sys_cb.vbat_percent;
}
//ui使用这套
u8 tjd_charging_show_bat_ui_level(void)
{
u8 percent = bsp_vbat_percent_get();
u8 level;
if (percent < 10) {//空电量
level = 0*10;//0-10
} else if (percent < 20) {//1格
level = 1*10;//10+
} else if (percent < 30) {//2格
level = 2*10;//20+
} else if (percent < 40) {//3格
level = 3*10;//30+
} else if (percent < 50) {//4格
level = 4*10;//40+
} else if (percent < 60) {//5格
level = 5*10;//50
} else if (percent < 70) {//6格
level = 6*10;//60+
} else if (percent < 90) {//7格
level = 7*10;//70+
} else if (percent < 90) {//8格
level = 8*10;//80
} else if(percent < 99) {//9格
level = 9*10;
} else {
level = 10*10;
}
/*
if (get_charge_full_flag()) {
level = 10*10;
}
*/
return level/10;
}
#endif //VBAT_DETECT_EN