充电
kernel-3.18/drivers/misc/mediatek/include/mt-plat/mt6735/include/mach/mt_charging.h
#define AC_CHARGER_CURRENTCHARGE_CURRENT_800_00_MA //先跑这个
kernel-3.18/arch/arm64/boot/dts/mt6735.dtsi //好像不是用这个啊,被重赋值了,是alps/kernel-3.18/arch/arm64/boot/dts/xxx_public_3565u.dts
ac_charger_current = <80000 >;/* Unit: 0.01 mA */ //再通过dt跑这个,没这个dt就直接用上面那macro了
/kernel-3.18/drivers/power/mediatek/battery_common.c
__batt_init_cust_data_from_cust_header();
#if defined(BATTERY_DTS_SUPPORT) && defined(CONFIG_OF)
__batt_init_cust_data_from_dt();
#endif
什么是 wake charge state ???
流程分析
battery_probe
batt_init_cust_data();//这里从dts读参数
kthread_run(bat_thread_kthread, NULL, "bat_thread_kthread");
charger_hv_detect_sw_workaround_init();//?
bat_thread_kthread{
while (1) {
BAT_thread();//
wait_event(bat_thread_wq, (bat_thread_timeout == KAL_TRUE));//等PMIC设置bat_thread_timeout
}
}
BAT_thread{
mt_battery_charger_detect_check();//[BAT_thread]Cable in, CHR_Type_num=4
mt_battery_GetBatteryData //这个比较重要,会获取各个参数,电池电压,充电电流,电池温度,等
mt_battery_thermal_check();//热敏电阻温度
mt_battery_notify_check();//
mt_battery_charging_algorithm
BAT_ConstantCurrentModeAction//case CHR_CC: 恒流充电
pchr_turn_on_charging //这里设置充电电流
select_charging_current()
battery_charging_control(CHARGING_CMD_SET_CV_VOLTAGE, &cv_voltage);// == charging_set_cv_voltage 设置 0x0E寄存器 CTRL_VBAT
charging_full_check()//什么时候判断为full??
battery_charging_control(CHARGING_CMD_GET_CHARGING_STATUS, &status);
ncp1854_read_interface((unsigned char) (NCP1854_CON0)...)//0号寄存器返回值6 == chargeDone,5=charging
/*这个寄存器什么时候置6 ? 看着好像是RO的
* 电压升高到某个值(Vrechg),同时电流降低到某个值(Ieoc)
* Vrechg 和 Vchg相关(97% ?), Vchg通过VBAT_SET bits CTRL_VBAT[5:0] //现在是0x2A 4.35v
* Ieoc通过IBAT_SET - bits IEOC[2:0] 100~275 默认 150mA
*/
/////////// DPP是什么
/*
* 充电电流 IBAT_SET bit ICHG[3:0] and ICHG_HIGH
* Iinlim
* Iinlim_set Iinlim_TA
* Input Voltage Based Automatic Charge Current -- ILIM! = 0 && ILIM2 = 1 (CTRL2 AICL_EN)
* 温度也会影响Ichg,junction temperature management
*/
mt_battery_update_status();
mt_kpoc_power_off_check();
}
do_jeita_state_machine //没用jeita ¥¥¥¥¥¥
select_jeita_cv //根据温度选择充电电压
battery_charging_control(CHARGING_CMD_SET_CV_VOLTAGE, &cv_voltage);
pmic_thread_kthread //pmic中断 mediatek, pmic-eint === GPIO206 interrupts = <206 IRQ_TYPE_LEVEL_HIGH>;//但是在excel里,GPIO最大只有203 ???,dws EINT那一栏有206,而且配置好了
while(1){
pmic_wrap_eint_clr(0x0);
}
CHARGER_UNKNOWN = 0,
STANDARD_HOST,1/* USB : 450mA */
CHARGING_HOST,2
NONSTANDARD_CHARGER,3/* AC : 450mA~1A */
STANDARD_CHARGER,4/* AC : ~1A */
APPLE_2_1A_CHARGER,5/* 2.1A apple charger */
APPLE_1_0A_CHARGER,6/* 1A apple charger */
APPLE_0_5A_CHARGER,7/* 0.5A apple charger */
WIRELESS_CHARGER,
标准充电(AC_CHARGER_CURRENT)pmic_thread][BAT_thread]Cable in, CHR_Type_num=4 //D+D- 短接 800ma
(NONSTANDARD_CHARGER)390ma
(USB_CHARGER_CURRENT)
battery_charging_control = chr_control_interface;//charging_funccharging_hw_ncp1854.c
static unsigned int (*const charging_func[CHARGING_CMD_NUMBER]) (void *data) = {
charging_hw_init, //0
charging_dump_register,
charging_enable, //2
charging_set_cv_voltage,
charging_get_current, //4
charging_set_current,
charging_set_input_current, //6
charging_get_charging_status,
charging_reset_watch_dog_timer, //8
charging_set_hv_threshold,
charging_get_hv_status, //10
charging_get_battery_status,
charging_get_charger_det_status, //12
charging_get_charger_type,
charging_get_is_pcm_timer_trigger,//14
charging_set_platform_reset,
charging_get_platform_boot_mode,//16
charging_set_power_off,
charging_get_power_source, //18
charging_get_csdac_full_flag,
charging_set_ta_current_pattern,//20
charging_set_error_state,
charging_diso_init, //22
charging_get_diso_state
};
battery_meter_ctrl(BATTERY_METER_CMD_HW_FG_INIT, NULL); -------->>>>> //battery_meter_hal.c
bm_func[BATTERY_METER_CMD_HW_FG_INIT] = fgauge_initialization;
bm_func[BATTERY_METER_CMD_GET_HW_FG_CURRENT] = fgauge_read_current;
bm_func[BATTERY_METER_CMD_GET_HW_FG_CURRENT_SIGN] = fgauge_read_current_sign;
bm_func[BATTERY_METER_CMD_GET_HW_FG_CAR] = fgauge_read_columb;
bm_func[BATTERY_METER_CMD_HW_RESET] = fgauge_hw_reset;
bm_func[BATTERY_METER_CMD_GET_ADC_V_BAT_SENSE] = read_adc_v_bat_sense;
bm_func[BATTERY_METER_CMD_GET_ADC_V_I_SENSE] = read_adc_v_i_sense;
bm_func[BATTERY_METER_CMD_GET_ADC_V_BAT_TEMP] = read_adc_v_bat_temp;
bm_func[BATTERY_METER_CMD_GET_ADC_V_CHARGER] = read_adc_v_charger;
bm_func[BATTERY_METER_CMD_GET_HW_OCV] = read_hw_ocv;
bm_func[BATTERY_METER_CMD_DUMP_REGISTER] = dump_register_fgadc;
bm_func[BATTERY_METER_CMD_SET_COLUMB_INTERRUPT] = fgauge_set_columb_interrupt;
bm_func[BATTERY_METER_CMD_GET_BATTERY_PLUG_STATUS] = read_battery_plug_out_status;
bm_func[BATTERY_METER_CMD_GET_HW_FG_CAR_ACT] = fgauge_read_columb_accurate;
[ 13.083713] (2)[168:bat_thread_kthr]
AvgVbat=(4161,4123), //电池电压bat_vol = battery_meter_get_battery_voltage(KAL_TRUE); 前值是后值的算后均值。BMT_status.bat_vol = mt_battery_average_method(BATTERY_AVG_VOLT, &batteryVoltageBuffer[0], bat_vol,&bat_sum, batteryIndex);
AvgI=(0,0), //充电电流ICharging = battery_meter_get_charging_current();
VChr=66,//充电电压
AvgT=(43,43),//电池温度
SOC=(97,97), //电量百分比
UI_SOC=97,
ZCV=4741 //ZCV ???
bcct:0:0
I:50000
[oam_run_inf] 3787(补偿ocv), 3780, 3715(vol_bat), 7422(oam_i_1), 6701(oam_i_2), 97(), 97(), 1715(), 1548(), 4010(Qmax), 33(), 62(oam_d0)
/*第一个参数就是oam补偿后的电压,根据这个电压查zvc表得到的电量百分比
* 第二个参数
* 第三个参数 是pmic读到的电压(vol_bat)
*
* 倒数第三个 gFG_BATT_CAPACITY_aging
*
*/
[oam_result_inf] 66(oam_d_1), 65(oam_d_2), 62(oam_d_3), 62(oam_d_4), 62(oam_d_5), 38(soc)
配置电池曲线
/kernel-3.18/drivers/misc/mediatek/include/mt-plat/mt6735/include/mach/mt_battery_meter.h
/kernel-3.18/arch/arm64/boot/dts/m6010_public_3565u.dts
OCV //空载电压值
VC //负载电压
#define BAT_NTC_10 1 //热敏电阻 10k
#define BAT_NTC_47 0 //47k
/* Qmax for 0mA */
q_max_pos_50 = <3239 >;//放电容量
q_max_pos_25 = <3230 >;
q_max_pos_0 = <3445 >;
q_max_neg_10 = <3429 >; //负10度容量3429
batt_temperature_table //?什么和温度关系?
battery_profile_t1 // 百分比与电压关系
r_profile_t // 电池内阻与电池电压关系
OCV -- 电池开路电压
VC -- 电池负载电压
R(battery) -- 电池内阻 = (OVC-VC)/(加负载时的电流) //mtk推荐仪器电流400mA,这个应该是他们的电路对应的电流
R(x1000) -- R(battery)x1000,内阻乘1000
如果没有仪器,测试方法如下:
1、先确定放电容量(电池深度?)Cmax。
2、计算每一百分比对应的电量 Cmax*1%
3、充电到对应电量,测量电池开路电压OVC,负载电压VC,电池内阻R(battery)
4、循环执行步骤2,3,直到测量完100%电量
BATSENSE --
alps/kernel-3.18/drivers/misc/mediatek/include/mt-plat/mt6735/include/mach/mt_battery_meter_table.h
#define RBAT_PULL_UP_R 16900 //温度检测上拉电阻
#define RBAT_PULL_UP_VOLT 1800 //参考电压
BATTERY_PROFILE_STRUCT
/kernel-3.18/drivers/power/mediatek/battery_meter.c
__batt_meter_init_cust_data_from_cust_header(); //也是先跑.h头文件的,然后再dt
#if defined(BATTERY_DTS_SUPPORT) && defined(CONFIG_OF)
__batt_meter_init_cust_data_from_dt();
#endi
http://www.cnblogs.com/reality-soul/articles/4786989.html //这里写的很详细
电池状态相关流程 -- 内核到framework间通信
dod_init
get_rtc_spare_fg_value();//这个会从rtc读上次关机电量百分比
battery_meter_get_battery_percentage
oam_run();//sw_fg
oam_r_2 //查表电池内阻
oam_v_ocv_2 = fgauge_read_v_by_d(oam_d_2);
oam_i_2 = (((oam_v_ocv_2 - vol_bat) * 1000) * 10) / oam_r_2;//
oam_v_ocv_1 = vol_bat + mtk_imp_tracking(vol_bat, oam_i_2, 5);//vol_bat-PMIC测量的电压
oam_d_3 = fgauge_read_d_by_v(oam_v_ocv_1);
if(oam_d_3 > oam_d_5)
oam_d_5 = oam_d_5 -1;
#if (OAM_D5 == 1)
return 100 - oam_d_5;
#else
return 100 - oam_d_2;
battery_meter_initial
fgauge_initialization
fgauge_construct_battery_profile_init
BAT_thread
mt_battery_update_status()
usb_update(&usb_main);
ac_update(&ac_main);
wireless_update(&wireless_main);
battery_update(&battery_main);
----->>>
power_supply_changed
schedule_work(&psy->changed_work) == power_supply_changed_work
power_supply_update_leds(psy);
kobject_uevent(&psy->dev->kobj, KOBJ_CHANGE);//obj ==
healthd_register_event(uevent_fd, uevent_event)
uevent_event
healthd_battery_update//healthd.cpp
BatteryMonitor::update //BatteryMonitor.cpp
props.batteryLevel = getIntField(mHealthdConfig->batteryCapacityPath);//电量百分比
props.batteryVoltage = getIntField(mHealthdConfig->batteryVoltagePath);//电池电压
... //分别对应 /sys/class/power_supply/battery 下面的节点
healthd_mode_ops->battery_update
battery_update == healthd_mode_android_battery_update //healthd_mode_android.cpp
gBatteryPropertiesRegistrar->notifyListeners
system/core/healthd/BatteryPropertiesRegistrar.cpp
BatteryPropertiesRegistrar::registerListener
== batteryPropertiesRegistrar.registerListener(new BatteryListener());//BatteryService.java
BatteryListener extends IBatteryPropertiesListener.Stub
this.update
processValuesLocked
sendIntentLocked
ACTION_BATTERY_CHANGED
问题
1、用直流电源5v充电,充电电流300ma,目标1A以上
D+ / D- 没有短接,不是标准TA线,所以按照非正常线进行充电。
2、关机前ui_soc == 57,关机重启,ui_soc == 93
前 [ 2761.942707] (3)[168:bat_thread_kthr]AvgVbat=(4179,4212),AvgI=(493,454),VChr=4901,AvgT=(44,46),SOC=(46,46),UI_SOC=57,ZCV=4428 bcct:0:0 I:50000
后 [ 52.360351] (0)[168:bat_thread_kthr]AvgVbat=(4118,4180),AvgI=(491,424),VChr=4901,AvgT=(43,46),SOC=(91,91),UI_SOC=93,ZCV=4705 bcct:0:0 I:50000
检查几个变量,电压没变,温度没变ZVC 和 soc变了,没更新zvc导致的?
解决 hw_fg --> sw_fg
3、驱动获取的电压值,和万用表测试的值有差异---充不满,达不到4.35v
因为FUll的条件是 Vbat > Vrechg && Ibat < Ieoc, 而Vrechg = Vchg*97%, Vchg = 4.35v,所以,在Vbat达到4.35之前就满足
full的条件了,自然冲不到4.35v
Vchg Vbat
4.35 --> 4.2
4.40 --> 4.32
4.425 --> 4.5
4、电量不准
g_vol_bat_hw_ocv --这个比较接近实际电压
[ 23.166687] (1)[169:bat_thread_kthr][oam_run] 13636,12653,75,68,21,21,4097,19,98,4083,98,3959,4080,21 //倒数第二个是g_vol_bat_hw_ocv(这个是开机第一次的电压值),倒数第三个vol_bat
battery_meter_ctrl(BATTERY_METER_CMD_GET_ADC_V_BAT_SENSE, &vol_bat); //PMIC_IMM_GetOneChannelValue(MT6328_AUX_BATSNS_AP,) // PMIC 读出来的
fgauge_read_capacity_by_v(gFG_voltage)) //用电压和容量对应表算出电池容量
调battery_profile_t2电压值
0 4347 --> 0 4405
1 4325 --> 1 4400
2 4310 --> 2 4350
5、重启后,多3个点的电量
开机后第一次上传电量流程
cust_poweron_delta_capacity_tolrance
cust_poweron_low_capacity_tolrance
6、充电电流达不到设置的值
2000mA只有800~900mA
7、连接TA重启,不充电
log:
[ 616.606001] (0)[167:bat_thread_kthr][BATTERY] Batt temp check : fail
[ 616.606009] (0)[167:bat_thread_kthr]charging_reset_watch_dog_timer
[ 616.606016] (0)[167:bat_thread_kthr]--------------------------------------------------
[ 616.606521] (0)[167:bat_thread_kthr][ncp1854_config_interface] Reg[2]=0x16
[ 616.606885] (0)[167:bat_thread_kthr][ncp18546_config_interface] Write Reg[2]=0x16
[ 616.606893] (0)[167:bat_thread_kthr][mt_battery_charging_algorithm] 0x1005
[ 616.606893]
[ 616.606903] (0)[167:bat_thread_kthr][BATTERY] BAD Battery status... Charging Stop !!
BAT_thread()
mt_battery_CheckBatteryStatus
if (mt_battery_CheckBatteryTemp() != PMU_STATUS_OK) { //读电池温度
BMT_status.bat_charging_state = CHR_ERROR;
}
原因:
为了方便调试,板子上电池id焊接了10k电阻,与电池内部电阻并联==5k,根据5k对应45度,充会电温度上升一点就过高了