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

156 lines
4.8 KiB
C

#include "include.h"
#if VBAT_DETECT_EN
#define VBG_VOLTAGE sys_trim.vbg_volt
#define VBAT2_COEF sys_trim.vbat_coef
//AT(.com_rodata.bat)
//const char bat_str[] = "VBAT: %d.%03dV\n";
AT(.com_text.port.vbat)
u16 bsp_vbat_get_voltage(void)
{
static u16 vbat_bak = 0;
u32 vbat2_val, vbat;
u32 vbat2 = saradc_get_value10(VBAT2_ADCCH);
vbat2_val = vbat2 * VBG_VOLTAGE * adc_cb.vrtc_val / (adc_cb.bg * adc_cb.vrtc_first);
vbat = vbat2_val * VBAT2_COEF / 1000;
//不同方案可能采用不同 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 > vbat_bak) {
vbat = adc_cb.vbat_val - vbat_bak;
} else {
vbat = vbat_bak - adc_cb.vbat_val;
}
if (vbat >= 2) { //偏差大于一定值则更新
vbat_bak = adc_cb.vbat_val;
// printf(bat_str, adc_cb.vbat_val/1000, adc_cb.vbat_val%1000);
}
//printf(bat_str, adc_cb.vbat_val/1000, adc_cb.vbat_val%1000);
return vbat_bak;
}
void bsp_vbat_voltage_init(void)
{
u32 vbat2_val;
u32 vbat2 = saradc_get_value10(VBAT2_ADCCH);
vbat2_val = vbat2 * VBG_VOLTAGE * adc_cb.vrtc_val / (adc_cb.bg * adc_cb.vrtc_first);
adc_cb.vbat_val = vbat2_val * VBAT2_COEF / 1000;
adc_cb.vbat_total = adc_cb.vbat_val << 5;
sys_cb.vbat = bsp_vbat_get_voltage();
sys_cb.vbat_percent = 0xff;
}
int bsp_vbat_get_lpwr_status(void)
{
if (sys_cb.vbat <= LPWR_OFF_VBAT) {
if (LPWR_OFF_VBAT) {
if (!sys_cb.lpwr_cnt) {
sys_cb.lpwr_cnt = 1;
} 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) {
return 1; //VBAT低电提醒状态
} else {
}
return 0;
}
sys_cb.lpwr_cnt = 0;
return 0;
}
void bsp_vbat_lpwr_process(void)
{
int vbat_sta = bsp_vbat_get_lpwr_status();
if (vbat_sta == 2) { //达到低电关机状态
func_cb.sta = FUNC_PWROFF; //低电,进入关机或省电模式
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 (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(); //离开低电, 恢复音乐音量
}
}
}
}
void bat_percent_update_callback(void)
{
#if (USE_APP_TYPE == USE_AB_APP)
bool charge_now = sys_cb.charge_sta == 1 ? true : false;
if(ble_is_connect()) {
ble_uplode_battery(sys_cb.vbat_percent, charge_now);
}
#endif
}
void bat_percent_update(void)
{
u8 bat_level = 0;
u16 full_vbat = 4150; //满电电压
u16 pwroff_vbat = LPWR_OFF_VBAT; //关机电压
u16 vbat_percent = sys_cb.vbat_percent;
//calc bat percent
if (sys_cb.vbat > pwroff_vbat) {
bat_level = ((sys_cb.vbat - pwroff_vbat) * 100) / (full_vbat - pwroff_vbat);
}
if (bat_level > 100){
bat_level = 100;
}
//update check
if (sys_cb.vbat_percent == 0xff) {
sys_cb.vbat_percent = bat_level;
} else {
if (sys_cb.charge_sta) { //充电中
if (bat_level > sys_cb.vbat_percent) {
sys_cb.vbat_percent = bat_level;
}
} else {
if (bat_level < sys_cb.vbat_percent) {
sys_cb.vbat_percent = bat_level;
}
}
}
if (sys_cb.vbat_percent != vbat_percent) {
bat_percent_update_callback();
}
// printf("%d %d\n", full_vbat, bat_level);
// printf("bat:%d%% , vbat:%d, %d, %d\n", sys_cb.vbat_percent, sys_cb.vbat, ((sys_cb.vbat - 3400) * 100), (full_vbat - 3400));
}
#endif //VBAT_DETECT_EN