高压电池根据电压显示百分比

原文网址(转载请注明出处):

链接:http://t.csdnimg.cn/gcmBA

源码基于:Android Q

1.查看硬件设计

在这里插入图片描述

我们可以看到VBAT-LEVEL管教直接接到芯片管脚上的。

2.DTS配置

电源PMIC DT配置如下:

#sl8541e-1h10wifi5g_32b-overlay.dts
&pmic_fgu {
	monitored-battery = <&bat>;
	sprd,calib-resistance-real = <10000>;
	sprd,calib-resistance-spec = <20000>;
	io-channels =  <&pmic_adc 0>, <&pmic_adc 3>, <&pmic_adc 14>, <&pmic_adc 4>;
	io-channel-names = "adc-batt-id", "bat-temp", "charge-vol", "chg-temp";
};

pmic_fgu是展锐提供的电量计芯片,主要是通过其ADC进行信息采集。根据硬件描述如上的adc管脚就是"chg-temp"这个配置。

2. 获取设备电压值

根据之前的描述,我们知道电量的获取主要是在sc27xx_fuel_gauge.c文件实现的。电压获取如下所示:


```cpp
bsp/kernel/kernel4.14/drivers/power/supply/sc27xx_fuel_gauge.c

static int sc27xx_fgu_get_vbat_vol(struct sc27xx_fgu_data *data, int *val)
{
	int ret, vol;

	ret = regmap_read(data->regmap, data->base + SC27XX_FGU_VOLTAGE, &vol);
	if (ret)
		return ret;

	/*
	 * It is ADC values reading from registers which need to convert to
	 * corresponding voltage values.
	 */
	*val = sc27xx_fgu_adc_to_voltage(data, vol);

	return 0;
}

我们可以参考上面的函数,去找到电压获取方式的调用代码。

3.高压电池设计

由于是高压电池,需要对比电量百分比,我们可以重新添加一个方法,让电压和电量百分比有个对应关系:

   //bsp/kernel/kernel4.14/drivers/power/supply/sc27xx_fuel_gauge.c	
	   case POWER_SUPPLY_PROP_CAPACITY:
		if (val->intval == CM_BOOT_CAPACITY) {
			val->intval = data->boot_cap;
			break;
		}

		// ret = sc27xx_fgu_get_capacity(data, &value, chg_sts); //注销之前的函数
		ret = sc27xx_fgu_get_vbat_for_percent(data, &value, chg_sts);
		if (ret)
			goto error;
		SPRD_FGU_DEBUG("POWER_SUPPLY_PROP_CAPACITY value:%d", value);
		val->intval = value;
		break;

重新修改自己的百分比获取函数,因为没有电量计,只能根据电压值进行简单的百分比换算,如下:

//bsp/kernel/kernel4.14/drivers/power/supply/sc27xx_fuel_gauge.c
static int sc27xx_fgu_get_vbat_for_percent(struct sc27xx_fgu_data *data, int *val, int chg_sts)
{
	int ret, vol, temp, voltage;
	uint32_t i;
	// int vat[21] = {4330, 4249, 4189, 4133, 4081, 4034, 3991, 3953, 3910, 3866, 3836, 3813, 3795, 3782, 3774, 3765, 3750, 3726, 3687, 3658, 3400}; // 根据DTS配置文件写的

	int vat[21] = {4330, 4249, 4189, 4133, 4081, 4034, 3991, 3953, 3910, 3866, 3836, 3813, 3795, 3782, 3774, 3765, 3750, 3726, 3687, 930, 925}; // adc4
	int percent[21] = {100, 95, 90, 85, 80, 75, 70, 65, 60, 55, 50, 45, 40, 35, 30, 25, 20, 15, 10, 5, 30};
	ret = regmap_read(data->regmap, data->base + SC27XX_FGU_VOLTAGE, &vol);
	if (ret)
		return ret;

	/*
	 * It is ADC values reading from registers which need to convert to
	 * corresponding voltage values.
	 */
	// *val = sc27xx_fgu_adc_to_voltage(data, vol);

	// adc4
	if (IS_ERR(data->chg_temp_cha))
	{
	}
	else
	{
		ret = iio_read_channel_processed(data->chg_temp_cha, val);
		SPRD_FGU_DEBUG(" sc27xx_fgu_get_vbat_for_percent val : %d \n", *val);
	}
	// adc4

	voltage = *val;

	//adc 4
	// if (chg_sts == POWER_SUPPLY_STATUS_CHARGING) { // 插上usb 电压会增高
	// 	voltage = voltage - 60;
	// }
	// adc 4

	if (voltage >= 4330) {
		return percent[0];
	}

	for (i = 0; i < 21; i++)
	{
		if ((voltage < vat[i]) && (voltage >= vat[i + 1]))
		{
			temp = percent[i + 1];
		}
	}
	*val = temp;
	SPRD_FGU_DEBUG("%s line:%d  val = %d  temp = %d\n", __func__, __LINE__, voltage, temp);
	return 0;
}

ret = iio_read_channel_processed(data->chg_temp_cha, val);此函数是获取adc电压值的关键函数。
adc4 是128管脚,配的adc4, 是测试128管脚的,要用原本的需要把添加了adc4 的代码注释掉,把原本的打开。
因为插入USB会让电压升高60左右,我们需要判断插入状态,如果插入了USB,就减去USB带来的偏移量。

4.电量数据上报

bsp/kernel/kernel4.14/drivers/power/supply/charger-manager.c

	case POWER_SUPPLY_PROP_CAPACITY:
		if (!is_batt_present(cm)) {
			/* There is no battery. Assume 100% */
			val->intval = 100;
			break;
		}

		if (cm->desc->cap_debug != -1)
			val->intval = cm->desc->cap_debug;
		else {
			/* Raise cap a bit, by *101/98, the affect is real 97% raised to 100%*/
			cap_new  = cm->desc->cap;
			// cap_new = DIV_ROUND_CLOSEST(cap_new * 101, 960);  注释原本的计算方式
			dev_info(cm->dev, "capacity orig: %d, new: %d\n", cm->desc->cap, cap_new);

			if (cap_new > 100)
				cap_new = 100;

			if (cm->desc->cap <= 0) {
				get_batt_vol_now(cm, &batt_uV);
				if (batt_uV >= CUTOFF_VOLTAGE_UV) {
					cap_new = 1;
					dev_info(cm->dev, "## force report soc 1, vbat %d\n", batt_uV);
				}
			}
			val->intval = cap_new;
		}

		break;
	...

	if (fuel_cap != cm->desc->cap) {
		/*if (DIV_ROUND_CLOSEST(fuel_cap, 10) != DIV_ROUND_CLOSEST(cm->desc->cap, 10)) {
			cm->desc->cap = fuel_cap;
			cm->desc->update_capacity_time = cur_time.tv_sec;
			power_supply_changed(cm->charger_psy);
		}*/

		/*power_supply_changed use ui_cap update strategy*/
		if (DIV_ROUND_CLOSEST(fuel_cap * 101, 960)
			!= DIV_ROUND_CLOSEST(cm->desc->cap * 101, 960)) {
			cm->desc->cap = fuel_cap;
			cm->desc->update_capacity_time = cur_time.tv_sec;
			power_supply_changed(cm->charger_psy);
		}

		ret = get_batt_cap(cm, &fuel_cap); // 获取电量
		cm->desc->cap = fuel_cap;// 赋值
		dev_info(cm->dev, " fuel_cap= %d", fuel_cap);
		set_batt_cap(cm, cm->desc->cap);
	}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lion_heart001

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值