在MT6572上面遇到电池电量显示与实际电压不符的情况,因为之前都没有接触过这方面的内容,只能慢慢分析。经过两天一晚上的学习与分析,发现是客户提供的ZCV放电曲线有误,这熬了我多少时间啊!!坑!!!
下面顺便整理下流程(fgauge方式):
代码主要是在mediatek\kernel\drivers\power\battery_meter.c
\mediatek\kernel\drivers\power\battery_common.c
\mediatek\custom\mt6582\kernel\battery\battery\cust_battery_meter_table.h【电池曲线里面就会有百分比与电池电压对应关系】。
\mediatek\custom\mt6582\kernel\battery\battery\cust_charging.h
\mediatek\kernel\drivers\power\switch_charging.c
从开机的时候,系统就会把“battery_meter”这个模块加载进去,然后每隔一段时间读取一下电池的电压,温度等等信息,然后计算出百分比。
那么问题来了,它是怎么通过函数获取百分比的呢?
首先看battery_common.c 文件里面的battery_resume()函数,系统设定了一个定线程BAT_thread(),每隔一段时间就会唤醒电池检测系统,BAT_thread()--->>battery_meter_initial()[battery_meter.c]---->>table_init()&oam_init()---->>fgauge_get_profile(TEMPERATURE_T),然后根据检测出来的电池温度选择对应的电池曲线battery_profile_tX[0]。百分比是这样计算的,假如现在读取到的电池电压是3.750V,电池温度是25°,那它就会与battery_profile_t2[0]里面的3750附近做对比,获得对应的百分比78,因为这个电池曲线ZCV是放电曲线,所以显示的百分比应该是Percent=100-78=22。所以3.750V对应的百分比就是22%,然后通过上层UI显示出来。
在ZCV曲线里面,还有一栏是电池内阻R。在cust_battery_meter_table.h里面就是r_profile_tX[0],那这个有什么用呢?
我们先来看一条公式:oam_v_ocv_1 = vol_bat + 补偿电压(IR)。
我们在手机端读取的电池电压是vol_bat ,实际电池电压是oam_v_ocv_1 ,两者之间由于电池特性或者充电线会有一些差异,这时候就会需要一个补偿电压来让手机端显示百分比更准确,这就是R的作用。
最后还发现一个问题:在我这边充电一切正常,到客户那边充电时间比我的多出两个小时!!
这是为什么呢?
下载的同一个软件,按道理说不会出现充电时间相差如此大的情况,后来测试电流发现,我这边是750mA左右,客户那边是450左右,到这里,大概知道是什么问题~~
哈哈~~肯定是充电器坏了!!好高兴!!
后来客户说用是的出货的1A充电器充的,呃~~~
查找相关文档,才知道原来充电器也分国标和非国标两种。
国标充电器是在充电头将两根数据线短接,这样就是系统检测到的充电器就是国标的,就会在switch_charging.c文件里面select_charging_curret()函数根据检测到的充电器(国标或非国标)选择充电电流:
else if (BMT_status.charger_type == NONSTANDARD_CHARGER)
{
g_temp_input_CC_value = NON_STD_AC_CHARGER_CURRENT;
g_temp_CC_value = NON_STD_AC_CHARGER_CURRENT;
}
else if (BMT_status.charger_type == STANDARD_CHARGER)
{
g_temp_input_CC_value = AC_CHARGER_CURRENT;
g_temp_CC_value = AC_CHARGER_CURRENT;
}
充电电流在cust_charging.h文件里面定义:
#define AC_CHARGER_CURRENT CHARGE_CURRENT_850_00_MA
#define NON_STD_AC_CHARGER_CURRENT CHARGE_CURRENT_500_00_MA
如果充电头的两根数据线没有短接,那么手机将会认为是非国标充电器,就会用到CHARGE_CURRENT_500_00_MA充电电流。