电池电量检测算法 - 联芯LC1860 Android平台驱动开发
目录:LC1860_android4.4.4_r2_R50android-4.4.4_r2kernellinux-3.10archarmplat-lcdriverspmiclc1160
文件:lc1160_monitor_battery.c
具体函数如下:
static int capacity_monitor_thread(struct monitor_battery_device_info *di)
{
int curr_capacity = di->capacity;
int charging_disabled = 0;
struct timespec ts;
struct rtc_time tm;
mutex_lock(&battery_mutex);
getnstimeofday(&ts);
rtc_time_to_tm(ts.tv_sec, &tm);
if(di->charger_source > POWER_SUPPLY_TYPE_BATTERY) { -------->检测是否插入充电器。
/* We have to disable charging to read correct voltage*/
if(di->prev_capacity <= 98) { ---------->判断电池电量是否是满格
charging_disabled = 1;
if(di->charger_info->set_charging_enable) {
di->charger_info->set_charging_enable(0); -------> 关掉充电
}
/*voltage setteling time*/
msleep(150); -------> 延迟150mS,让电池电压达到稳定状态,以便让系统检测电量更佳准确。
}
if(di->battery_info->battery_voltage) {
di->bat_voltage_mV = di->battery_info->battery_voltage(); ---------> 检测电池电量
}
/* if we disabled charging to check capacity,
* enable it again after we read the correct voltage */
if ((charging_disabled)
&&(di->charge_status != POWER_SUPPLY_STATUS_NOT_CHARGING)) {
if(di->charger_info->set_charging_enable) {
di->charger_info->set_charging_enable(1); -------->打开充电
}
}
/* if battery temp is over high or
over low we assume it is not charging%*/
monitor_battery_temp_charging(di);
di->voffset = 0;
} else {
if(di->capacity ==-1) {
di->voffset = 60;
} else {
if(di->battery_info->battery_voltage) {
di->bat_voltage_mV = di->battery_info->battery_voltage();
}
di->voffset = 30;
}
}
if(di->battery_info->battery_capacity) {
curr_capacity = di->battery_info->battery_capacity();
}
if(di->battery_info->battery_realsoc) {
di->realsoc = di->battery_info->battery_realsoc();
}
/* Debouncing power on init when voltage change. */
if (di->capacity == -1) {
#ifdef CONFIG_BATINFO_FILE
if(load_batinfo() == 0) {
if((ts.tv_sec - lsec < 24*3600)&&(abs(di->bat_voltage_mV - lvoltage) <250)) {
if((di->bat_present)&&(di->bat_voltage_mV > 3550)) {
curr_capacity = lcapacity;
di->history_capacity = lcapacity;
pr_info("monitor_battery: load_batinfo soc = %dn",curr_capacity);
}
}
}
#endif
di->voffset = 0;
di->capacity = curr_capacity;
di->prev_capacity = curr_capacity;
di->capacity_debounce_count = 0;
di->prev_voltage = di->bat_voltage_mV;
pr_info("monitor_battery: power on soc(volt) = %d(%d mV)n",curr_capacity,di->bat_voltage_mV);
mutex_unlock(&battery_mutex);
return 1;
}
if((di->charger_source != POWER_SUPPLY_TYPE_BATTERY)&&(curr_capacity >= 100)) {
di->charge_status = POWER_SUPPLY_STATUS_FULL;
curr_capacity = 100;
}
if (curr_capacity != di->prev_capacity) {
pr_info("monitor_battery: curr_capacity = %d(%d) " "curr_voltage = %d(%d) " "curr = %d "
"battery_temp = %d " "charge_status = %d(%d-%02d-%02d %02d:%02d:%02d.%09lu UTC)n",
curr_capacity,di->prev_capacity,di->bat_voltage_mV,di->prev_voltage,di->bat_current_mA,
di->bat_temperature,di->charge_status,tm.tm_year + 1900,
tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, ts.tv_nsec);
di->prev_capacity = curr_capacity;
di->capacity = curr_capacity;
di->capacity_debounce_count = 0;
di->prev_voltage = di->bat_voltage_mV;
mutex_unlock(&battery_mutex);
return 1;
}
if (++di->capacity_debounce_count >= 2) {
if(curr_capacity != 100) {
pr_info("monitor_battery: curr_capacity = %d(%d) " "curr_voltage = %d(%d) " "curr = %d "
"battery_temp = %d " "charge_status = %d(%d-%02d-%02d %02d:%02d:%02d.%09lu UTC)n",
curr_capacity,di->prev_capacity,di->bat_voltage_mV,di->prev_voltage,di->bat_current_mA,
di->bat_temperature,di->charge_status,tm.tm_year + 1900,
tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, ts.tv_nsec);
}
di->capacity = curr_capacity;
di->capacity_debounce_count = 0;
mutex_unlock(&battery_mutex);
return 1;
}
mutex_unlock(&battery_mutex);
return 0;
}