一,插入充电器检测。由于使用两节锂电池串联,电压达到8.4v,充电检测是由电阻分压后接在VCHG引脚。遇到的的问题是,由于电池内阻小,将此处VCHG的电压拉低,不能达到PMIC默认AC插入的电压4.3V(PMIC默认4.3v,达到此电压,硬件置位,中断通知),所以AC_flag一直不变。解决方法是,在检测函数内,判断VCHG电压,大于一定值,就默认插入充电器。不过此处是10s循环运行该函数,插入充电器,状态指示反应有点慢。
AP7350_MDK_kernel\AP7350_MDK-kernel\kernel-3.10\drivers\power\mediatek\battery_common.c
修改内容:
1,battery_common.c 第347行
原函数
int get_charger_detect_status(void)
{
kal_bool chr_status;
battery_charging_control(CHARGING_CMD_GET_CHARGER_DET_STATUS, &chr_status);
return chr_status;
}
修改为
int get_charger_detect_status(void)
{
kal_bool chr_status;
//battery_charging_control(CHARGING_CMD_GET_CHARGER_DET_STATUS, &chr_status);
//return chr_status;
kal_uint32 charger_vol;
charger_vol = battery_meter_get_charger_voltage();
if(charger_vol > 3000)
{
chr_status = KAL_TRUE;
}else
{
chr_status = KAL_FALSE;
}
return chr_status;
}
二,充电估算方法变更。
mt6735的电量估算有三种方法电压查表法,硬件电量计法,软件电量计法。由于核心板AP7350供电是有DCDC降压提供,电流不经过核心板,所以此处采用电压查表法。
AP7350_MDK_kernel\AP7350_MDK-kernel\kernel-3.10\drivers\misc\mediatek\mach\mt6735\ap7350_65u_l1\power\cust_battery_meter.h
原程序
//#define SOC_BY_AUXADC
#define SOC_BY_HW_FG
#define HW_FG_FORCE_USE_SW_OCV
//#define SOC_BY_SW_FG
改为
#define SOC_BY_AUXADC
//#define SOC_BY_HW_FG
//#define HW_FG_FORCE_USE_SW_OCV
//#define SOC_BY_SW_FG
并将#define IS_BATTERY_REMOVE_BY_PMIC一并注释掉,不然会报错。
实际发现,这里改不改,好像不起作用,原因是使用硬件电量计法中会检测电流,如果电流小于1mA,就默认使用电压查表法。但最好还是改了吧,万一干扰有个微小电流,别引起什么问题。另外后来发现,两种方法在充电时是有区别的。
三,电池电压测量。
原来的程序是通过mt6328的ch0通道检测的电池电压,由于我们这里的核心板AP7350供电是有DCDC降压提供的,所以这里检测到的电压是不变的。我们这里使用电阻分压,利用ADC1_LCD_ID口来检测电压,检测电路如下:
ADC1_LCD_ID引脚是mt6735的AD的12通道,程序中须修改battery_meter_get_battery_voltage(),这个函数,更改ad采样通道。
原函数
kal_int32 battery_meter_get_battery_voltage(kal_bool update)
{
int ret = 0;
int val = 5;
static int pre_val = -1;
if (update == KAL_TRUE || pre_val == -1) {
val = 5; /* set avg times */
ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_ADC_V_BAT_SENSE, &val);
pre_val = val;
} else {
val = pre_val;
}
g_sw_vbat_temp = val;
#ifdef MTK_BATTERY_LIFETIME_DATA_SUPPORT
if (g_sw_vbat_temp > gFG_max_voltage) {
gFG_max_voltage = g_sw_vbat_temp;
}
if (g_sw_vbat_temp < gFG_min_voltage) {
gFG_min_voltage = g_sw_vbat_temp;
}
#endif
return val;
}
修改后
kal_int32 battery_meter_get_battery_voltage(kal_bool update)
{
int ret = 0;
int val = 5;
static int pre_val = -1;
int adcdata[4];
int rawdata = 0;
if (update == KAL_TRUE || pre_val == -1) {
val = 5; // set avg times
//ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_ADC_V_BAT_SENSE, &val);
IMM_GetOneChannelValue(12,adcdata,&rawdata);
val = (rawdata*1500*291)/4096/102; //(rawdata/4096)*1500*(29100/5100)/2 //mv
pre_val = val;
} else {
val = pre_val;
}
g_sw_vbat_temp = val;
#ifdef MTK_BATTERY_LIFETIME_DATA_SUPPORT
if (g_sw_vbat_temp > gFG_max_voltage) {
gFG_max_voltage = g_sw_vbat_temp;
}
if (g_sw_vbat_temp < gFG_min_voltage) {
gFG_min_voltage = g_sw_vbat_temp;
}
#endif
return val;
}
并注意在该文件中引入外部函数,不然会报错。
extern int IMM_GetOneChannelValue(int dwChannel, int data[4], int* rawdata);//zyd
四,修改ZCV表。
根据电池放电时间与电压的关系,重新构建ZCV表。分析程序发现,温度曲线实际只按照了25℃的表,所以这里只改25度是的ZCV表,参考:
{0 , 4280},
{1 , 4200},
{3 , 4150},
{4 , 4130},
{5 , 4110},
{7 , 4090},
{8 , 4080},
{9 , 4070},
{11 , 4052},
{12 , 4044},
{13 , 4036},
{15 , 4020},
{16 , 4012},
{17 , 4004},
{19 , 3988},
{20 , 3980},
{21 , 3970},
{23 , 3950},
{24 , 3940},
{25 , 3930},
{27 , 3910},
{28 , 3900},
{29 , 3890},
{31 , 3872},
{32 , 3864},
{34 , 3848},
{35 , 3840},
{36 , 3832},
{38 , 3816},
{39 , 3808},
{40 , 3800},
{42 , 3789},
{43 , 3784},
{44 , 3779},
{46 , 3769},
{47 , 3765},
{48 , 3761},
{50 , 3755},
{51 , 3751},
{52 , 3747},
{54 , 3739},
{55 , 3735},
{56 , 3731},
{58 , 3723},
{59 , 3719},
{60 , 3715},
{62 , 3707},
{63 , 3703},
{64 , 3699},
{66 , 3691},
{67 , 3687},
{68 , 3683},
{70 , 3675},
{71 , 3671},
{72 , 3667},
{74 , 3659},
{75 , 3655},
{76 , 3651},
{78 , 3643},
{79 , 3639},
{80 , 3635},
{82 , 3625},
{83 , 3620},
{84 , 3615},
{86 , 3605},
{87 , 3600},
{88 , 3595},
{90 , 3585},
{91 , 3575},
{92 , 3565},
{94 , 3535},
{95 , 3520},
{97 , 3480},
{98 , 3460},
{99 , 3440},
{100 , 3400},
{100 , 3350},
{100 , 3300},
{100 , 3250},
{100 , 3200},
{100 , 3150},
{100 , 3100},
{100 , 3050},
{100 , 3000},
{100 , 3023},
{100 , 3005},
{100 , 2998},
{100 , 2992},
{100 , 2981},
{100 , 2973},
{100 , 2974},
{100 , 2975},
{100 , 2960},
{100 , 2950},
{100 , 2949},
{100 , 2947},
{100 , 2944},
{100 , 2939},
{100 , 2936},
{100 , 2931}
五,充电控制。
以上步骤改完,放电测试,电量百分比显示能达到预期效果,但是当充电时,电压突然太高,电量会猛地上升,影响使用体验。经过讨论决定,在UI层去掉百分比,只使用图标显示。另外充电时根据电压对电量进行分段,即充电时让UI_SOC根据充电电压重新设置,不让其突然提升。修改记录:
AP7350_MDK_kernel\AP7350_MDK-kernel\kernel-3.10\drivers\power\mediatek\battery_common.c中原函数
static void mt_battery_Sync_UI_Percentage_to_Real(void)
{
static kal_uint32 timer_counter;
if ((BMT_status.UI_SOC > BMT_status.SOC) && ((BMT_status.UI_SOC != 1))) {
#if !defined (SYNC_UI_SOC_IMM)
/* reduce after xxs */
if(chr_wake_up_bat==KAL_FALSE)
{
if (timer_counter == (SYNC_TO_REAL_TRACKING_TIME / BAT_TASK_PERIOD))
{
BMT_status.UI_SOC--;
timer_counter = 0;
}
#ifdef FG_BAT_INT
else if(fg_wake_up_bat==KAL_TRUE)
{
BMT_status.UI_SOC--;
}
#endif //#ifdef FG_BAT_INT
else
{
timer_counter++;
}
}
else
{
battery_log(BAT_LOG_CRTI, "[Sync_Real] chr_wake_up_bat=1 , do not update UI_SOC\n");
}
#else
BMT_status.UI_SOC--;
#endif
battery_log(BAT_LOG_CRTI, "[Sync_Real] UI_SOC=%d, SOC=%d, counter = %d\n",
BMT_status.UI_SOC, BMT_status.SOC, timer_counter);
} else {
timer_counter = 0;
#if !defined(CUST_CAPACITY_OCV2CV_TRANSFORM)
BMT_status.UI_SOC = BMT_status.SOC;
#else
if (BMT_status.UI_SOC == -1)
BMT_status.UI_SOC = BMT_status.SOC;
else if (BMT_status.charger_exist && BMT_status.bat_charging_state != CHR_ERROR) {
if (BMT_status.UI_SOC < BMT_status.SOC
&& (BMT_status.SOC - BMT_status.UI_SOC > 1))
BMT_status.UI_SOC++;
else
BMT_status.UI_SOC = BMT_status.SOC;
}
#endif
}
if (BMT_status.UI_SOC <= 0) {
BMT_status.UI_SOC = 1;
battery_log(BAT_LOG_CRTI, "[Battery]UI_SOC get 0 first (%d)\r\n",
BMT_status.UI_SOC);
}
}
修改为:
static void mt_battery_Sync_UI_Percentage_to_Real(void)
{
static kal_uint32 timer_counter;
kal_uint32 charger_vol0;
if ((BMT_status.UI_SOC > BMT_status.SOC) && ((BMT_status.UI_SOC != 1))) {
#if !defined (SYNC_UI_SOC_IMM)
/* reduce after xxs */
if(chr_wake_up_bat==KAL_FALSE)
{
if (timer_counter == (SYNC_TO_REAL_TRACKING_TIME / BAT_TASK_PERIOD))
{
BMT_status.UI_SOC--;
timer_counter = 0;
}
#ifdef FG_BAT_INT
else if(fg_wake_up_bat==KAL_TRUE)
{
BMT_status.UI_SOC--;
}
#endif //#ifdef FG_BAT_INT
else
{
timer_counter++;
}
}
else
{
battery_log(BAT_LOG_CRTI, "[Sync_Real] chr_wake_up_bat=1 , do not update UI_SOC\n");
}
#else
BMT_status.UI_SOC--;
#endif
battery_log(BAT_LOG_CRTI, "[Sync_Real] UI_SOC=%d, SOC=%d, counter = %d\n",
BMT_status.UI_SOC, BMT_status.SOC, timer_counter);
} else {
timer_counter = 0;
if (BMT_status.UI_SOC <= 0) {
BMT_status.UI_SOC = 1;
battery_log(BAT_LOG_CRTI, "[Battery]UI_SOC get 0 first (%d)\r\n",
BMT_status.UI_SOC);
}
//#if
if (BMT_status.charger_exist && BMT_status.bat_charging_state != CHR_ERROR) {
//if (BMT_status.UI_SOC < BMT_status.SOC)
//{
charger_vol0 = battery_meter_get_battery_voltage(KAL_TRUE);
if(charger_vol0 >= 4300)
{
BMT_status.UI_SOC = BMT_status.SOC;
}else if(charger_vol0 >= 4250)
{
BMT_status.UI_SOC=90;
}else if(charger_vol0 >= 4200)
{
BMT_status.UI_SOC=80;
}else if(charger_vol0 >= 4150)
{
BMT_status.UI_SOC=70;
}else if(charger_vol0 >= 4100)
{
BMT_status.UI_SOC=60;
}else if(charger_vol0 >= 4050)
{
BMT_status.UI_SOC=50;
}else if(charger_vol0 >= 4000)
{
BMT_status.UI_SOC=40;
}else if(charger_vol0 >= 3950)
{
BMT_status.UI_SOC=30;
}else if(charger_vol0 >= 3900)
{
BMT_status.UI_SOC=20;
}else if(charger_vol0 >= 3800)
{
BMT_status.UI_SOC=10;
}else
{
BMT_status.UI_SOC = BMT_status.SOC;
}
//}
}else
{
BMT_status.UI_SOC = BMT_status.SOC;
}
//#endif
}
}
六,经过测试,充放电基本达到预期目的。
版权声明:本文为CSDN博主「zhengyad123」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_38012497/article/details/121266424
暂无评论