Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> 高通QCOM 8610平台電量計算

高通QCOM 8610平台電量計算

編輯:關於android開發

高通QCOM 8610平台電量計算


一: SOC(荷電狀態)計算方法

公式:

SOC = RUC / (FCC-UUC)

名詞:

 

術語

全稱

注釋

FCC

Full-Charge Capacity

滿電荷電量

UC

Remaining Capacity

RC 剩余電量

CC

Coulumb Counter

電量計

UUC

Unusable Capacity

不可用電量

RUC

Remaining Usable Capacity

RUC=RC-CC-UUC,剩余可用電量

OCV

Open Circuit Voltage

開路電壓,電池在開路狀態下的端電壓稱為開路電壓

SoC

State of Charge

電量百分比

PC

Percentage Charge

剩余電荷占FCC百分比

 

二:各參數計算方法:

 

1.FCC:根據電池溫度temp通過查找表(lut)來計算

 

static int calculate_fcc(struct qpnp_bms_chip *chip, int batt_temp) 
{ 
	int fcc_uah; 
	 
	if (chip->adjusted_fcc_temp_lut == NULL) { // log顯示,沒有對溫度lut進行修正; 
		/* interpolate_fcc returns a mv value. */ 
		fcc_uah = interpolate_fcc(chip->fcc_temp_lut, 
		batt_temp) * 1000;  // 不修正直接返回對應溫度的FCC值 
		printk("fcc = %d uAh\n", fcc_uah); 
		return fcc_uah; 
	} else { 
		return 1000 * interpolate_fcc(chip->adjusted_fcc_temp_lut, 
		batt_temp); 
	} 
} 

 

2. RC: 依賴ocv,通過ocv計算;單位uAh

 

/* calculate remaining charge at the time of ocv */ 
static int calculate_ocv_charge(struct qpnp_bms_chip *chip, 
		struct raw_soc_params *raw, 
		int fcc_uah) 
{ 
	int  ocv_uv, pc; 
	// RAW - 存在pm?PM裡讀出來的未經修正的原始數據? 
	// read_soc_params_raw -> qpnp_read_wrapper(chip, (u8 *)&raw->last_good_ocv_raw, 
	// chip->base + BMS1_OCV_FOR_SOC_DATA0, 2); 
	ocv_uv = raw->last_good_ocv_uv; // 1. 上次關機時存儲的ocv;2. 電池新插入時會更新該值;3. 模擬電池新插入,手動更新:chip->insertion_ocv_uv;最終會更新raw->last_good_ocv_uv; 
	pc = calculate_pc(chip, ocv_uv, chip->last_ocv_temp); // 上次ocv占FCC的百分比,受溫度影響 
	printk("ocv_uv = %d pc = %d\n", ocv_uv, pc); 
	return (fcc_uah * pc) / 100; 
} 
 
static int calculate_pc(struct qpnp_bms_chip *chip, int ocv_uv, 
		int batt_temp) 
{ 
	int pc; 
	 
	pc = interpolate_pc(chip->pc_temp_ocv_lut, 
	batt_temp / 10, ocv_uv / 1000); // 根據lut查找百分比 
	printk("pc = %u %% for ocv = %d uv batt_temp = %d\n", 
	pc, ocv_uv, batt_temp); 
	/* Multiply the initial FCC value by the scale factor. */ 
	return pc; 
} 

 

有時開機時的ocv和關機時的ocv(raw->last_good_ocv_raw?)差距太大就明顯影響百分比計算了;

所以就需要做修正了;

 

3、CC:將bms電量計讀值轉換成uAh,coulomb counter有兩種,shadow型不知道具體含義,不知是否和80x86裡的影子寄存器是否為相同設計?:

 

/* Coulomb counter data */ 
#define BMS1_CC_DATA0 0x8A 
/* Shadow Coulomb counter data */ 
#define BMS1_SW_CC_DATA0 0xA8 
/** 
 * calculate_cc() - converts a hardware coulomb counter reading into uah 
 * @chip: the bms chip pointer 
 * @cc: the cc reading from bms h/w 
 * @cc_type: calcualte cc from regular or shadow coulomb counter 
 * @clear_cc: whether this function should clear the hardware counter 
 * after reading 
 * 
 * Converts the 64 bit hardware coulomb counter into microamp-hour by taking 
 * into account hardware resolution and adc errors. 
 * 
 * Return: the coulomb counter based charge in uAh (micro-amp hour) 
 */ 
static int calculate_cc(struct qpnp_bms_chip *chip, int64_t cc, 
		int cc_type, int clear_cc) 
{ 
	struct qpnp_iadc_calib calibration; 
	struct qpnp_vadc_result result; 
	int64_t cc_voltage_uv, cc_pvh, cc_uah, *software_counter; 
	int rc; 
	 
	// chip->software_shdw_cc_uah == 0; chip->software_cc_uah == 0; 
	software_counter = cc_type == SHDW_CC ? 
	&chip->software_shdw_cc_uah : &chip->software_cc_uah; 
	rc = qpnp_vadc_read(chip->vadc_dev, DIE_TEMP, &result); 
	if (rc) { 
		pr_err("could not read pmic die temperature: %d\n", rc); 
		return *software_counter; 
	} 
	 
	qpnp_iadc_get_gain_and_offset(chip->iadc_dev, &calibration); // 獲得平台相關的增益修正參數,msm8610,msm8912; 
	printk("%scc = %lld, die_temp = %lld\n", 
	cc_type == SHDW_CC ? "shdw_" : "", 
	cc, result.physical); 
	cc_voltage_uv = cc_reading_to_uv(cc); 
	cc_voltage_uv = cc_adjust_for_gain(cc_voltage_uv, 
	calibration.gain_raw 
	- calibration.offset_raw); 
	cc_pvh = cc_uv_to_pvh(cc_voltage_uv);  // 為減小cc的精度損失; 
	cc_uah = div_s64(cc_pvh, chip->r_sense_uohm); // i = u / r;算出cc電流 
	rc = qpnp_iadc_comp_result(chip->iadc_dev, &cc_uah); // 根據QPNP不同版本ID,比如PM8110:QPNP_IADC_REV_ID_8110_1_0,做增益補償 
	if (rc) 
	printk("error compensation failed: %d\n", rc); 
	if (clear_cc == RESET) {  //1. calculate_state_of_charge -> calculate_soc_params中有RESET調用;
							// 2. load_shutdown_data(probe獲取上次關機時的一些參數,比如ocv) -> recalculate_raw_soc -> recalculate_soc ->calculate_soc_params有調用(先cc、後shadow_cc);
							// 3. calculate_soc_work(calculate_soc_work會延時調用自身) -> recalculate_soc -> calculate_state_of_charge -> calculate_soc_params; 
							// 4. recalculate_work(電池充電高壓、檢查電池狀態、電池插入檢查、ocv阈值中斷、sw_cc中斷、高溫死機中斷都會重新sched_work) -> recalculate_soc; 
		printk("software_%scc = %lld, added cc_uah = %lld\n", 
		cc_type == SHDW_CC ? "sw_" : "", 
		*software_counter, cc_uah); 
		*software_counter += cc_uah; 
		reset_cc(chip, cc_type == SHDW_CC ? CLEAR_SHDW_CC : CLEAR_CC); 
		return (int)*software_counter; 
	} else { 
		printk("software_%scc = %lld, cc_uah = %lld, total = %lld\n", 
		cc_type == SHDW_CC ? "shdw_" : "", 
		*software_counter, cc_uah, 
		*software_counter + cc_uah); 
		return *software_counter + cc_uah; 
	} 
} 

 

對於影子寄存器(Shadow Register):

"It depends on the context. Even my friend named something as shadow register in his security
architecture. Usually shadow somthing means a backup. Whenever a misprediction or a wrong path
execution is detected, the shadows one can be used to restore the correct status in architecture."

“即對用戶不可見的,有時候叫投影寄存器,比如linux中,ES,CS,SS等段寄存器存放的是段選擇子,每個都有對應的影子寄存器用來存放段描述符,cpu會根據段寄存器內容自動裝載對應的影子寄存器,所以訪問同一個段的時候不用總是訪問內存來讀段描述符來確定段基址。”

 

4.UUC:不可使用電量,受溫度影響;

 

static int calculate_termination_uuc(struct qpnp_bms_chip *chip, 
		struct soc_params *params, 
		int batt_temp, int uuc_iavg_ma, 
		int *ret_pc_unusable) 
{ 
	int unusable_uv, pc_unusable, uuc_uah; 
	int i = 0; 
	int ocv_mv; 
	int batt_temp_degc = batt_temp / 10; 
	int rbatt_mohm; 
	int delta_uv; 
	int prev_delta_uv = 0; 
	int prev_rbatt_mohm = 0; 
	int uuc_rbatt_mohm; 
 
	for (i = 0; i <= 100; i++) { 
		ocv_mv = interpolate_ocv(chip->pc_temp_ocv_lut, // 根據temp通過lut獲得ocv, 
		batt_temp_degc, i); 
		rbatt_mohm = get_rbatt(chip, i, batt_temp); // batt_temp用於獲得對應溫度下的比例因子來得到對應溫度下的rbatt; 
		unusable_uv = (rbatt_mohm * uuc_iavg_ma) 
		+ (chip->v_cutoff_uv);  // UUC = cutoff_uv + rbatt * iavg; 
		delta_uv = ocv_mv * 1000 - unusable_uv; 
		 
		if (delta_uv > 0) 
		break; 
		 
		prev_delta_uv = delta_uv; 
		prev_rbatt_mohm = rbatt_mohm; 
	} 
	 
	uuc_rbatt_mohm = linear_interpolate(rbatt_mohm, delta_uv, // 用插值法修正uuc_rbatt_mohm 
	prev_rbatt_mohm, prev_delta_uv, 
	0); 
	 
	unusable_uv = (uuc_rbatt_mohm * uuc_iavg_ma) + (chip->v_cutoff_uv); // 更新uuv 
	 
	pc_unusable = calculate_pc(chip, unusable_uv, batt_temp); // 利用uuv和temp獲得不可使用的電量占FCC的百分比; 
	uuc_uah = (params->fcc_uah * pc_unusable) / 100; // 獲得UUC 
	printk("For uuc_iavg_ma = %d, unusable_rbatt = %d unusable_uv = %d unusable_pc = %d rbatt_pc = %d uuc = %d\n", 
	uuc_iavg_ma, 
	uuc_rbatt_mohm, unusable_uv, 
	pc_unusable, i, uuc_uah); 
	*ret_pc_unusable = pc_unusable; 
	return uuc_uah; 
} 

 

以上只是獲得bms對應參數的函數調用,高通還添加了針對soc和ocv的校正方法;

 

三、調用流程

recalculate_soc ->qpnp_vadc_read ->read_soc_params_raw ->calculate_state_of_charge(adjust_soc對soc進行修正):

1.rc = qpnp_vadc_read(chip->vadc_dev, LR_MUX1_BATT_THERM, &result);
 

通過熱敏電阻獲得電池的溫度batt_temp = (int)result.physical;後面計算FCC時需要;

 

2.read_soc_params_raw(chip, &raw, batt_temp);

“Add functions necessary for driver initialization and

exported CHARGE_FULL_DESIGN and CURRENT_NOW properties in the

bms power supply.“

“power: qpnp-bms: remember the temperature when ocv was taken

The code looks up the percent charge based on ocv at the

current temperature. The ocv could have been recorded earlier

under different temperature conditions. Looking it up at the

current temperature is wrong.

 

Hence remember the temperature when the ocv was first seen. And

use that to lookup the ocv values.“

 

“power: qpnp-bms: estimate OCV when a new battery is inserted

 

When a new battery is inserted, the BMS will continue to use its old

OCV value until a new OCV is taken. This is clearly wrong, as the new

battery can have a completely different state of charge than the old

one.

Fix this by making BMS driver estimate a new OCV based on the close

circuit battery voltage and IR drop across the battery when a battery

insertion is detected.“

 

“power: qpnp-bms: detect warm resets

 

During warm PMIC resets, the BMS will not take a new OCV. This may

cause the SOC upon reboot to be completely wrong if no recent OCVs

have been taken.

 

Fix this by checking for invalid OCVs and warm resets. If either

occur, estimate a new OCV based on vbat and use that instead.“

 

“power: qpnp-bms: fake a high OCV when charging completes

 

When charging is finished and the battery is considered full, the BMS

does not necessarily report 100%. Fix this by faking a high OCV when

the charger notifies BMS of EOC.“

 

“power: qpnp-bms: export shadow coulomb counter value

 

Export the shadow coulomb counter register value to userspace in

order to assist in recording power consumption."

 

3.充電檢測:

static void power_supply_changed_work(struct work_struct *work)// 該工作會定期檢查電源狀態:插入DC充電,並遍歷已注冊supply的pst->external_power_changed,如果有就調用;更新系統LED;最後發送kobject_uevent;

 

external_power_changed:

會檢查1、是否有電池插入;2、電源路徑是否發生變化(BATFET);3、檢查電池狀態:未充電、充電、充電結束,調度recalc_work重新計算SoC;

 

4. 關機保存SOC和iavg:

report_state_of_charge ->report_cc_based_soc ->backup_soc_and_iavg ->qpnp_masked_write_base(chip,chip->soc_storage_addr,

SOC_STORAGE_MASK, (soc + 1) << 1);

 

開始充電、充電結束、計算soc(calculate_state_of_charge)時都會調用report_state_of_charge;

也就是每次新的SOC都會存到bms中;

 

5.開機時probe會加載上次關機時保存的soc:

load_shutdown_data ->read_shutdown_soc ->rc = qpnp_read_wrapper(chip, &stored_soc, chip->soc_storage_addr, 1);

 

6. 當dts中有如下配置會忽略關機時的SoC:

 

/* Invalidate the shutdown SoC if any of these conditions hold true */ 
if (chip->ignore_shutdown_soc 
	|| invalid_stored_soc 
	|| offmode_battery_replaced 
	|| shutdown_soc_out_of_limit) { 

這意味著開機時不會用上次關機SOC來修正開機時讀到的OCV(PON_OCV_UV)

 

 

四、SOC校准

上面參數或多或少都和ocv有關,ocv的變化有:

1. 開機時和上次關機存儲的ocv有變化;

2. 長時間suspend後的resume會更新ocv;

3. 手動更新ocv;

4. 低電會進入adjust_soc()更新ocv;

 

“在高通8064平台由於電量計對大電流計算不准確,一直亮屏的情況(沒有經歷睡眠喚醒的ocv更新與CC RST)會導致關機電壓到達3.74V。要想解決這個問題必須使得校准SOC可以正常工作。但是當滿電時開機就會記錄ocv的值偏高,導致快要低電時不能很好的校准soc。所以有必要在馬上進入低電(15%)時做一次模擬開機一次(電量計RERST CC=0從soc找出ocv )使得last_ocv_uv降下來,才可以完美發揮adjust_soc的作用,使得關機電壓能一直能到3.4V左右。”

 

當bms計算的SoC在98以上、等於soc_est或者soc_est在adjust-soc-low-threshold以上時不做修正直接返回;

 

static int adjust_soc(struct qpnp_bms_chip *chip, struct soc_params *params, 
int soc, int batt_temp) 
{ 
	int ibat_ua = 0, vbat_uv = 0; 
	int ocv_est_uv = 0, soc_est = 0, pc_est = 0, pc = 0; 
	int delta_ocv_uv = 0; 
	int n = 0; 
	int rc_new_uah = 0; 
	int pc_new = 0; 
	int soc_new = 0; 
	int slope = 0; 
	int rc = 0; 
	int delta_ocv_uv_limit = 0; 
	int correction_limit_uv = 0; 
	 
	rc = get_simultaneous_batt_v_and_i(chip, &ibat_ua, &vbat_uv); 
	if (rc < 0) { 
		pr_err("simultaneous vbat ibat failed err = %d\n", rc); 
		goto out; 
	} 
	 
	very_low_voltage_check(chip, vbat_uv); 
	cv_voltage_check(chip, vbat_uv); 
	 
	delta_ocv_uv_limit = DIV_ROUND_CLOSEST(ibat_ua, 1000); 
	 
	ocv_est_uv = vbat_uv + (ibat_ua * params->rbatt_mohm)/1000; 
	 
	pc_est = calculate_pc(chip, ocv_est_uv, batt_temp); 
	soc_est = div_s64((s64)params->fcc_uah * pc_est - params->uuc_uah*100, 
		(s64)params->fcc_uah - params->uuc_uah); 
	soc_est = bound_soc(soc_est); 
	 
	/* never adjust during bms reset mode */ 
	if (bms_reset) { 
		printk("bms reset mode, SOC adjustment skipped\n"); 
		goto out; 
	} 
	 
	if (is_battery_charging(chip)) { 
		soc = charging_adjustments(chip, params, soc, vbat_uv, ibat_ua, 
			batt_temp); 
		/* Skip adjustments if we are in CV or ibat is negative */ 
		if (chip->soc_at_cv != -EINVAL || ibat_ua < 0) 
		goto out; 
	} 
	 
	/* 
	* do not adjust 
	* if soc_est is same as what bms calculated 
	* OR if soc_est > adjust_soc_low_threshold 
	* OR if soc is above 90 
	* because we might pull it low 
	* and cause a bad user experience 
	*/ 
	if (!wake_lock_active(&chip->low_voltage_wake_lock) && 
		(soc_est == soc 
		|| soc_est > chip->adjust_soc_low_threshold 
		|| soc >= NO_ADJUST_HIGH_SOC_THRESHOLD)) 
		goto out; 
	 
	if (chip->last_soc_est == -EINVAL) 
		chip->last_soc_est = soc; 
	 
	n = min(200, max(1 , soc + soc_est + chip->last_soc_est)); 
	chip->last_soc_est = soc_est; 
	 
	pc = calculate_pc(chip, chip->last_ocv_uv, chip->last_ocv_temp); 
	if (pc > 0) { 
		pc_new = calculate_pc(chip, 
			chip->last_ocv_uv - (++slope * 1000), 
			chip->last_ocv_temp); 
		while (pc_new == pc) { 
			/* start taking 10mV steps */ 
			slope = slope + 10; 
			pc_new = calculate_pc(chip, 
			chip->last_ocv_uv - (slope * 1000), 
			chip->last_ocv_temp); 
		} 
	} else { 
		/* 
		* pc is already at the lowest point, 
		* assume 1 millivolt translates to 1% pc 
		*/ 
		pc = 1; 
		pc_new = 0; 
		slope = 1; 
	} 
	 
	delta_ocv_uv = div_s64((soc - soc_est) * (s64)slope * 1000, n * (pc - pc_new)); 
	 
	if (abs(delta_ocv_uv) > delta_ocv_uv_limit) { 
		printk("limiting delta ocv %d limit = %d\n", delta_ocv_uv, delta_ocv_uv_limit); 
	 
	if (delta_ocv_uv > 0) 
		delta_ocv_uv = delta_ocv_uv_limit; 
		else 
		delta_ocv_uv = -1 * delta_ocv_uv_limit; 
		printk("new delta ocv = %d\n", delta_ocv_uv); 
	} 
	 
	if (wake_lock_active(&chip->low_voltage_wake_lock)) { 
		/* when in the cutoff region, do not correct upwards */ 
		delta_ocv_uv = max(0, delta_ocv_uv); 
		goto skip_limits; 
	} 
	 
	if (chip->last_ocv_uv > chip->flat_ocv_threshold_uv) 
		correction_limit_uv = chip->high_ocv_correction_limit_uv;// 250@dts 
	else 
		correction_limit_uv = chip->low_ocv_correction_limit_uv; // 100@dts 
	 
	if (abs(delta_ocv_uv) > correction_limit_uv) { 
		printk("limiting delta ocv %d limit = %d\n", 
		delta_ocv_uv, correction_limit_uv); 
		if (delta_ocv_uv > 0) 
			delta_ocv_uv = correction_limit_uv; 
		else 
			delta_ocv_uv = -correction_limit_uv; 
		printk("new delta ocv = %d\n", delta_ocv_uv); 
	} 
	 
skip_limits: 
	 
	chip->last_ocv_uv -= delta_ocv_uv; 
	 
	if (chip->last_ocv_uv >= chip->max_voltage_uv) 
		chip->last_ocv_uv = chip->max_voltage_uv; 
	 
	/* calculate the soc based on this new ocv */ 
	pc_new = calculate_pc(chip, chip->last_ocv_uv, chip->last_ocv_temp); 
	rc_new_uah = (params->fcc_uah * pc_new) / 100; 
	soc_new = (rc_new_uah - params->cc_uah - params->uuc_uah)*100 
		/ (params->fcc_uah - params->uuc_uah); 
	soc_new = bound_soc(soc_new); 
	 
	/* 
	* if soc_new is ZERO force it higher so that phone doesnt report soc=0 
	* soc = 0 should happen only when soc_est is above a set value 
	*/ 
	if (soc_new == 0 && soc_est >= chip->hold_soc_est) 
		soc_new = 1; 
	 
	soc = soc_new; 
	 
out: 
	printk("ibat_ua = %d, vbat_uv = %d, ocv_est_uv = %d, pc_est = %d, soc_est = %d, n = %d, delta_ocv_uv = %d, last_ocv_uv = %d, pc_new = %d, soc_new = %d, rbatt = %d, slope = %d\n", 
		 ibat_ua, vbat_uv, ocv_est_uv, pc_est, 
		 soc_est, n, delta_ocv_uv, chip->last_ocv_uv, 
		 pc_new, soc_new, params->rbatt_mohm, slope); 
	 
	return soc; 
} 

參考:

 

http://blog.csdn.net/linux_devices_driver/article/details/20762839

 

附件:運行中log

調用棧:

<6>[ 406.051003] enabled source qpnp_soc_wake

 

<6>[  406.075253] batt_temp phy = 301 meas = 0xc090d488c1a153e4 
 
// 計算CC 
<6>[  406.075351] last_good_ocv_raw= 0x922a, last_good_ocv_uv= 3738332uV 
<6>[  406.075363] cc_raw= 0xffffffffffd631b1 
<6>[  406.075410] tm_sec = 2425, delta_s = 20 
<6>[  406.075423] fcc = 4690000 uAh 
<6>[  406.075434] FCC = 4690000uAh batt_temp = 301 
<6>[  406.075451] pc = 24 % for ocv = 3738332 uv batt_temp = 298 
<6>[  406.075464] ocv_uv = 3738332 pc = 24 
<6>[  406.075474] ocv_charge_uah = 1125600uAh 
<6>[  406.084235] cc = -2739791, die_temp = 37432 
<6>[  406.084249] adjusting_uv = -14864325 
<6>[  406.084262] adjusting by factor: 3291/3061 = 107% 
<6>[  406.084273] result_uv = -15981213 
<6>[  406.084286] software_cc = -16133, added cc_uah = -797 
<6>[  406.084298] resetting cc manually with flags 128 
<6>[  406.093446] shdw_cc = -2738411, die_temp = 37384 
<6>[  406.093459] adjusting_uv = -14856838 
<6>[  406.093471] adjusting by factor: 3291/3061 = 107% 
<6>[  406.093482] result_uv = -15973163 
<6>[  406.093494] software_sw_cc = -16131, added cc_uah = -797 
<6>[  406.093506] resetting cc manually with flags 64 
<6>[  406.093658] cc_uah = -16930uAh raw->cc = ffffffffffd631b1, shdw_cc_uah = -16928uAh raw->shdw_cc = ffffffffffd63715 
<6>[  406.093677] rbatt_mohm = 113 
<6>[  406.093689] delta_cc = -797 iavg_ua = -143460 
 
// 計算UUC:calculate_unusable_charge_uah -> calculate_termination_uuc 
<6>[  406.093701] iavg_samples_ma[0] = 250 
<6>[  406.093711] iavg_samples_ma[1] = 250 
<6>[  406.093721] iavg_samples_ma[2] = 250 
<6>[  406.093731] iavg_samples_ma[3] = 250 
<6>[  406.093741] iavg_samples_ma[4] = 250 
<6>[  406.093751] iavg_samples_ma[5] = 250 
<6>[  406.093761] iavg_samples_ma[6] = 250 
<6>[  406.093771] iavg_samples_ma[7] = 250 
<6>[  406.093781] iavg_samples_ma[8] = 250 
<6>[  406.093791] iavg_samples_ma[9] = 250 
<6>[  406.093801] iavg_samples_ma[10] = 250 
<6>[  406.093811] iavg_samples_ma[11] = 250 
<6>[  406.093821] iavg_samples_ma[12] = 250 
<6>[  406.093831] iavg_samples_ma[13] = 250 
<6>[  406.093841] iavg_samples_ma[14] = 250 
<6>[  406.093851] iavg_samples_ma[15] = 250 
<6>[  406.093869] pc = 0 % for ocv = 3400000 uv batt_temp = 301 
<6>[  406.093886] For uuc_iavg_ma = 250, unusable_rbatt = 0 unusable_uv = 3400000 unusable_pc = 0 rbatt_pc = 0 uuc = 0 
<6>[  406.093901] uuc_iavg_ma = 250 uuc with iavg = 0 
<6>[  406.093913] UUC = 0uAh 
<6>[  406.093935] RUC = 1142530uAh 
<6>[  406.093947] SOC before adjustment = 24 
<6>[  406.098457] pc = 18 % for ocv = 3717671 uv batt_temp = 301 
<6>[  406.098499] CC CHG SOC 24 
<6>[  406.098519] ibat_ua = -169206, vbat_uv = 3736791, ocv_est_uv = 3717671, pc_est = 18, soc_est = 18, n = 0, delta_ocv_uv = 0, last_ocv_uv = 3738332, pc_new = 0, soc_new = 0, rbatt = 113, slope = 0 
<6>[  406.108713] mvolts phy = 3737379 meas = 0x390723 
<6>[  406.108730] not clamping, using soc = 24, vbat = 3737379 and cutoff = 3400000 // 3737379 
<6>[  406.108777] CC based calculated SOC = 24 
<6>[  406.113307] batt_temp phy = 302 meas = 0x12d00000012 
<6>[  406.113391] last_soc = 24, calculated_soc = 24, soc = 24, time since last change = 402 
<6>[  406.113433] Reported SOC = 24 
<6>[  406.113471] disabled source qpnp_soc_wake 

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved