mt6735电池状态监测
来源:互联网 发布:stc单片机isp原理 编辑:程序博客网 时间:2024/04/30 03:17
这里分析下mt6735平台下的电池驱动,使用的bq24296芯片(开关模式的充电方式)。
kernel-3.18/drivers/power/mediatek/battery_common.c
static int battery_probe(struct platform_device *dev){struct class_device *class_dev = NULL;int ret = 0;battery_log(BAT_LOG_CRTI, "******** battery driver probe!! ********\n");/* Integrate with NVRAM */ret = alloc_chrdev_region(&adc_cali_devno, 0, 1, ADC_CALI_DEVNAME);if (ret)battery_log(BAT_LOG_CRTI, "Error: Can't Get Major number for adc_cali\n");adc_cali_cdev = cdev_alloc();adc_cali_cdev->owner = THIS_MODULE;adc_cali_cdev->ops = &adc_cali_fops;ret = cdev_add(adc_cali_cdev, adc_cali_devno, 1);if (ret)battery_log(BAT_LOG_CRTI, "adc_cali Error: cdev_add\n");adc_cali_major = MAJOR(adc_cali_devno);adc_cali_class = class_create(THIS_MODULE, ADC_CALI_DEVNAME);class_dev = (struct class_device *)device_create(adc_cali_class, NULL, adc_cali_devno, NULL, ADC_CALI_DEVNAME);battery_log(BAT_LOG_CRTI, "[BAT_probe] adc_cali prepare : done !!\n ");get_charging_control();batt_init_cust_data();battery_charging_control(CHARGING_CMD_GET_PLATFORM_BOOT_MODE, &g_platform_boot_mode);battery_log(BAT_LOG_CRTI, "[BAT_probe] g_platform_boot_mode = %d\n ", g_platform_boot_mode);wake_lock_init(&battery_fg_lock, WAKE_LOCK_SUSPEND, "battery fg wakelock");wake_lock_init(&battery_suspend_lock, WAKE_LOCK_SUSPEND, "battery suspend wakelock");#if defined(CONFIG_MTK_PUMP_EXPRESS_SUPPORT)wake_lock_init(&TA_charger_suspend_lock, WAKE_LOCK_SUSPEND, "TA charger suspend wakelock");#endifmtk_pep_init();mtk_pep20_init();/* Integrate with Android Battery Service */ret = power_supply_register(&(dev->dev), &ac_main.psy);if (ret) {battery_log(BAT_LOG_CRTI, "[BAT_probe] power_supply_register AC Fail !!\n");return ret;}battery_log(BAT_LOG_CRTI, "[BAT_probe] power_supply_register AC Success !!\n");ret = power_supply_register(&(dev->dev), &usb_main.psy);if (ret) {battery_log(BAT_LOG_CRTI, "[BAT_probe] power_supply_register USB Fail !!\n");return ret;}battery_log(BAT_LOG_CRTI, "[BAT_probe] power_supply_register USB Success !!\n");ret = power_supply_register(&(dev->dev), &wireless_main.psy);if (ret) {battery_log(BAT_LOG_CRTI, "[BAT_probe] power_supply_register WIRELESS Fail !!\n");return ret;}battery_log(BAT_LOG_CRTI, "[BAT_probe] power_supply_register WIRELESS Success !!\n");ret = power_supply_register(&(dev->dev), &battery_main.psy);if (ret) {battery_log(BAT_LOG_CRTI, "[BAT_probe] power_supply_register Battery Fail !!\n");return ret;}battery_log(BAT_LOG_CRTI, "[BAT_probe] power_supply_register Battery Success !!\n");#if !defined(CONFIG_POWER_EXT)#ifdef CONFIG_MTK_POWER_EXT_DETECTif (KAL_TRUE == bat_is_ext_power()) {battery_main.BAT_STATUS = POWER_SUPPLY_STATUS_FULL;battery_main.BAT_HEALTH = POWER_SUPPLY_HEALTH_GOOD;battery_main.BAT_PRESENT = 1;battery_main.BAT_TECHNOLOGY = POWER_SUPPLY_TECHNOLOGY_LION;battery_main.BAT_CAPACITY = 100;battery_main.BAT_batt_vol = 4200;battery_main.BAT_batt_temp = 220;g_bat_init_flag = KAL_TRUE;return 0;}#endif/* For EM */{int ret_device_file = 0;ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Charger_Voltage);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_0_Slope);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_1_Slope);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_2_Slope);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_3_Slope);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_4_Slope);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_5_Slope);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_6_Slope);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_7_Slope);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_8_Slope);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_9_Slope);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_10_Slope);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_11_Slope);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_12_Slope);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_13_Slope);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_0_Offset);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_1_Offset);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_2_Offset);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_3_Offset);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_4_Offset);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_5_Offset);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_6_Offset);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_7_Offset);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_8_Offset);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_9_Offset);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_10_Offset);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_11_Offset);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_12_Offset);ret_device_file = device_create_file(&(dev->dev), &dev_attr_ADC_Channel_13_Offset);ret_device_file =device_create_file(&(dev->dev), &dev_attr_ADC_Channel_Is_Calibration);ret_device_file = device_create_file(&(dev->dev), &dev_attr_Power_On_Voltage);ret_device_file = device_create_file(&(dev->dev), &dev_attr_Power_Off_Voltage);ret_device_file = device_create_file(&(dev->dev), &dev_attr_Charger_TopOff_Value);ret_device_file =device_create_file(&(dev->dev), &dev_attr_FG_Battery_CurrentConsumption);ret_device_file = device_create_file(&(dev->dev), &dev_attr_FG_SW_CoulombCounter);ret_device_file = device_create_file(&(dev->dev), &dev_attr_Charging_CallState);ret_device_file = device_create_file(&(dev->dev), &dev_attr_V_0Percent_Tracking);ret_device_file = device_create_file(&(dev->dev), &dev_attr_Charger_Type);ret_device_file = device_create_file(&(dev->dev), &dev_attr_Pump_Express);}/* battery_meter_initial(); //move to mt_battery_GetBatteryData() to decrease booting time *//* Initialization BMT Struct */BMT_status.bat_exist = KAL_TRUE;/* phone must have battery */BMT_status.charger_exist = KAL_FALSE;/* for default, no charger */BMT_status.bat_vol = 0;BMT_status.ICharging = 0;BMT_status.temperature = 0;BMT_status.charger_vol = 0;BMT_status.total_charging_time = 0;BMT_status.PRE_charging_time = 0;BMT_status.CC_charging_time = 0;BMT_status.TOPOFF_charging_time = 0;BMT_status.POSTFULL_charging_time = 0;BMT_status.SOC = 0;BMT_status.UI_SOC = 0;BMT_status.bat_charging_state = CHR_PRE;BMT_status.bat_in_recharging_state = KAL_FALSE;BMT_status.bat_full = KAL_FALSE;BMT_status.nPercent_ZCV = 0;BMT_status.nPrecent_UI_SOC_check_point = battery_meter_get_battery_nPercent_UI_SOC();#if defined(CONFIG_MTK_DUAL_INPUT_CHARGER_SUPPORT)dual_input_init();#endif/* battery kernel thread for 10s check and charger in/out event *//* Replace GPT timer by hrtime */battery_kthread_hrtimer_init();kthread_run(bat_thread_kthread, NULL, "bat_thread_kthread");battery_log(BAT_LOG_CRTI, "[battery_probe] bat_thread_kthread Done\n");charger_hv_detect_sw_workaround_init();/*LOG System Set */init_proc_log();#else/* keep HW alive *//* charger_hv_detect_sw_workaround_init(); */#endifg_bat_init_flag = KAL_TRUE;#if defined(CONFIG_MTK_DUAL_INPUT_CHARGER_SUPPORT)if ((g_vcdt_irq_delay_flag == KAL_TRUE) || (upmu_is_chr_det() == KAL_TRUE))do_chrdet_int_task();#endifreturn 0;}
get_charging_control();//获取bq24296的接口
batt_init_cust_data();//获取dts中配置的电池数据
battery_kthread_hrtimer_init();//初始化高精度定时器,每10s唤醒bat_thread_kthread
kthread_run(bat_thread_kthread, NULL, "bat_thread_kthread");//创建内核线程
ret = power_supply_register(&(dev->dev), &battery_main.psy);//注册电池电源
get_charging_control();指针数组初始化
typedef signed int(*CHARGING_CONTROL) (CHARGING_CTRL_CMD cmd, void *data);CHARGING_CONTROL battery_charging_control;static void get_charging_control(void){battery_charging_control = chr_control_interface;}signed int chr_control_interface(CHARGING_CTRL_CMD cmd, void *data){ static signed int init = -1; if (init == -1) { init = 0; charging_func[CHARGING_CMD_INIT] = charging_hw_init; charging_func[CHARGING_CMD_DUMP_REGISTER] = charging_dump_register; charging_func[CHARGING_CMD_ENABLE] = charging_enable; charging_func[CHARGING_CMD_SET_CV_VOLTAGE] = charging_set_cv_voltage; charging_func[CHARGING_CMD_GET_CURRENT] = charging_get_current; charging_func[CHARGING_CMD_SET_CURRENT] = charging_set_current; charging_func[CHARGING_CMD_SET_INPUT_CURRENT] = charging_set_input_current; charging_func[CHARGING_CMD_GET_CHARGING_STATUS] = charging_get_charging_status; charging_func[CHARGING_CMD_RESET_WATCH_DOG_TIMER] = charging_reset_watch_dog_timer; charging_func[CHARGING_CMD_SET_HV_THRESHOLD] = charging_set_hv_threshold; charging_func[CHARGING_CMD_GET_HV_STATUS] = charging_get_hv_status; charging_func[CHARGING_CMD_GET_BATTERY_STATUS] = charging_get_battery_status; charging_func[CHARGING_CMD_GET_CHARGER_DET_STATUS] = charging_get_charger_det_status; charging_func[CHARGING_CMD_GET_CHARGER_TYPE] = charging_get_charger_type; charging_func[CHARGING_CMD_SET_PLATFORM_RESET] = charging_set_platform_reset; charging_func[CHARGING_CMD_GET_PLATFORM_BOOT_MODE] = charging_get_platform_boot_mode; charging_func[CHARGING_CMD_SET_POWER_OFF] = charging_set_power_off; charging_func[CHARGING_CMD_SET_TA_CURRENT_PATTERN] = charging_set_ta_current_pattern; charging_func[CHARGING_CMD_SET_ERROR_STATE] = charging_set_error_state; charging_func[CHARGING_CMD_DISO_INIT] = charging_diso_init; charging_func[CHARGING_CMD_GET_DISO_STATE] = charging_get_diso_state; charging_func[CHARGING_CMD_SET_VBUS_OVP_EN] = charging_set_vbus_ovp_en; charging_func[CHARGING_CMD_SET_VINDPM] = charging_set_vindpm; } if (cmd < CHARGING_CMD_NUMBER) { if (charging_func[cmd] != NULL) return charging_func[cmd](data); } pr_debug("[%s]UNSUPPORT Function: %d\n", __func__, cmd); return STATUS_UNSUPPORTED;}
power_supply_register(&(dev->dev), &battery_main.psy);
上层要获取电池属性,相当于直接获取全局结构体battery_data的值。
struct battery_data { struct power_supply psy; int BAT_STATUS; int BAT_HEALTH; int BAT_PRESENT; int BAT_TECHNOLOGY; int BAT_CAPACITY; /* Add for Battery Service */ int BAT_batt_vol; int BAT_batt_temp; /* Add for EM */ int BAT_TemperatureR; int BAT_TempBattVoltage; int BAT_InstatVolt; int BAT_BatteryAverageCurrent; int BAT_BatterySenseVoltage; int BAT_ISenseVoltage; int BAT_ChargerVoltage; /* Dual battery */ int status_smb; int capacity_smb; int present_smb; int adjust_power;};static enum power_supply_property battery_props[] = { POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_HEALTH, POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_TECHNOLOGY, POWER_SUPPLY_PROP_CAPACITY, /* Add for Battery Service */ POWER_SUPPLY_PROP_batt_vol, POWER_SUPPLY_PROP_batt_temp, /* Add for EM */ POWER_SUPPLY_PROP_TemperatureR, POWER_SUPPLY_PROP_TempBattVoltage, POWER_SUPPLY_PROP_InstatVolt, POWER_SUPPLY_PROP_BatteryAverageCurrent, POWER_SUPPLY_PROP_BatterySenseVoltage, POWER_SUPPLY_PROP_ISenseVoltage, POWER_SUPPLY_PROP_ChargerVoltage, /* Dual battery */ POWER_SUPPLY_PROP_status_smb, POWER_SUPPLY_PROP_capacity_smb, POWER_SUPPLY_PROP_present_smb, /* ADB CMD Discharging */ POWER_SUPPLY_PROP_adjust_power,}; static int battery_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val){ int ret = 0; struct battery_data *data = container_of(psy, struct battery_data, psy); switch (psp) { case POWER_SUPPLY_PROP_STATUS: val->intval = data->BAT_STATUS; break; case POWER_SUPPLY_PROP_HEALTH: val->intval = data->BAT_HEALTH; break; case POWER_SUPPLY_PROP_PRESENT: val->intval = data->BAT_PRESENT; break; case POWER_SUPPLY_PROP_TECHNOLOGY: val->intval = data->BAT_TECHNOLOGY; break; case POWER_SUPPLY_PROP_CAPACITY: val->intval = data->BAT_CAPACITY; break; case POWER_SUPPLY_PROP_batt_vol: val->intval = data->BAT_batt_vol; break; case POWER_SUPPLY_PROP_batt_temp: val->intval = data->BAT_batt_temp; break; case POWER_SUPPLY_PROP_TemperatureR: val->intval = data->BAT_TemperatureR; break; case POWER_SUPPLY_PROP_TempBattVoltage: val->intval = data->BAT_TempBattVoltage; break; case POWER_SUPPLY_PROP_InstatVolt: val->intval = data->BAT_InstatVolt; break; case POWER_SUPPLY_PROP_BatteryAverageCurrent: val->intval = data->BAT_BatteryAverageCurrent; break; case POWER_SUPPLY_PROP_BatterySenseVoltage: val->intval = data->BAT_BatterySenseVoltage; break; case POWER_SUPPLY_PROP_ISenseVoltage: val->intval = data->BAT_ISenseVoltage; break; case POWER_SUPPLY_PROP_ChargerVoltage: val->intval = data->BAT_ChargerVoltage; break; /* Dual battery */ case POWER_SUPPLY_PROP_status_smb: val->intval = data->status_smb; break; case POWER_SUPPLY_PROP_capacity_smb: val->intval = data->capacity_smb; break; case POWER_SUPPLY_PROP_present_smb: val->intval = data->present_smb; break; case POWER_SUPPLY_PROP_adjust_power: val->intval = data->adjust_power; break; default: ret = -EINVAL; break; } return ret;}/* battery_data initialization */static struct battery_data battery_main = {.psy = {.name = "battery",.type = POWER_SUPPLY_TYPE_BATTERY,.properties = battery_props,.num_properties = ARRAY_SIZE(battery_props),.get_property = battery_get_property,},/* CC: modify to have a full power supply status */#if defined(CONFIG_POWER_EXT).BAT_STATUS = POWER_SUPPLY_STATUS_FULL,.BAT_HEALTH = POWER_SUPPLY_HEALTH_GOOD,.BAT_PRESENT = 1,.BAT_TECHNOLOGY = POWER_SUPPLY_TECHNOLOGY_LION,.BAT_CAPACITY = 100,.BAT_batt_vol = 4200,.BAT_batt_temp = 22,/* Dual battery */.status_smb = POWER_SUPPLY_STATUS_NOT_CHARGING,.capacity_smb = 50,.present_smb = 0,/* ADB CMD discharging */.adjust_power = -1,#else.BAT_STATUS = POWER_SUPPLY_STATUS_NOT_CHARGING,.BAT_HEALTH = POWER_SUPPLY_HEALTH_GOOD,.BAT_PRESENT = 1,.BAT_TECHNOLOGY = POWER_SUPPLY_TECHNOLOGY_LION,#if defined(PUMP_EXPRESS_SERIES).BAT_CAPACITY = -1,#else.BAT_CAPACITY = 50,#endif.BAT_batt_vol = 0,.BAT_batt_temp = 0,/* Dual battery */.status_smb = POWER_SUPPLY_STATUS_NOT_CHARGING,.capacity_smb = 50,.present_smb = 0,/* ADB CMD discharging */.adjust_power = -1,#endif};
下面看下电池线程函数
void BAT_thread(void){ static kal_bool battery_meter_initilized = KAL_FALSE; static int first_time_update; if (battery_meter_initilized == KAL_FALSE) { battery_meter_initial(); /* move from battery_probe() to decrease booting time */ BMT_status.nPercent_ZCV = battery_meter_get_battery_nPercent_zcv(); battery_meter_initilized = KAL_TRUE; } mt_battery_charger_detect_check(); if (fg_battery_shutdown) return; mt_battery_GetBatteryData(); if (fg_battery_shutdown) return; if (BMT_status.charger_exist == KAL_TRUE) check_battery_exist(); mt_battery_thermal_check(); mt_battery_notify_check(); if (first_time_update == 0) { mt_battery_update_status(); if (BMT_status.charger_exist == KAL_TRUE) { mt_battery_CheckBatteryStatus(); mt_battery_charging_algorithm(); } first_time_update = 1; } else { if (BMT_status.charger_exist == KAL_TRUE && !fg_battery_shutdown) { mt_battery_CheckBatteryStatus(); mt_battery_charging_algorithm(); } mt_battery_update_status(); } mt_kpoc_power_off_check();}int bat_thread_kthread(void *x){ktime_t ktime = ktime_set(3, 0);/* 10s, 10* 1000 ms *//* Run on a process content */while (!fg_battery_shutdown) {mutex_lock(&bat_mutex);if (((chargin_hw_init_done == KAL_TRUE) && (battery_suspended == KAL_FALSE)) || ((chargin_hw_init_done == KAL_TRUE) && (fg_wake_up_bat == KAL_TRUE)))BAT_thread();mutex_unlock(&bat_mutex);#ifdef FG_BAT_INTif (fg_wake_up_bat == KAL_TRUE) {wake_unlock(&battery_fg_lock);fg_wake_up_bat = KAL_FALSE;battery_log(BAT_LOG_CRTI, "unlock battery_fg_lock\n");}#endif/* #ifdef FG_BAT_INT */battery_log(BAT_LOG_FULL, "wait event\n");wait_event(bat_thread_wq, (bat_thread_timeout == KAL_TRUE));bat_thread_timeout = KAL_FALSE;hrtimer_start(&battery_kthread_timer, ktime, HRTIMER_MODE_REL);/* 10s, 10* 1000 ms */if (!fg_battery_shutdown)ktime = ktime_set(BAT_TASK_PERIOD, 0);if (chr_wake_up_bat == KAL_TRUE && g_smartbook_update != 1) {/* for charger plug in/ out */#if defined(CONFIG_MTK_DUAL_INPUT_CHARGER_SUPPORT)if (DISO_data.chr_get_diso_state) {DISO_data.chr_get_diso_state = KAL_FALSE;battery_charging_control(CHARGING_CMD_GET_DISO_STATE, &DISO_data);}#endifg_smartbook_update = 0;battery_meter_reset();chr_wake_up_bat = KAL_FALSE;battery_log(BAT_LOG_CRTI, "[BATTERY] Charger plug in/out, Call battery_meter_reset. (%d)\n", BMT_status.UI_SOC);}}mutex_lock(&bat_mutex);fg_bat_thread = KAL_TRUE;mutex_unlock(&bat_mutex);return 0;}
mt_battery_charger_detect_check//检测充电器的类型
mt_battery_GetBatteryData()//获取电池数据
mt_battery_thermal_check()/电池温度检查
mt_battery_notify_check();//电池其他参数检查
mt_battery_charging_algorithm();充电算法(充电硬件初始化,选择充电电流)
mt_battery_update_status()//更新电池数据
mt_battery_GetBatteryData
void mt_battery_GetBatteryData(void){unsigned int bat_vol, charger_vol, Vsense, ZCV;signed int ICharging, temperature, temperatureR, temperatureV, SOC;static signed int bat_sum, icharging_sum, temperature_sum;static signed int batteryVoltageBuffer[BATTERY_AVERAGE_SIZE];static signed int batteryCurrentBuffer[BATTERY_AVERAGE_SIZE];static signed int batteryTempBuffer[BATTERY_AVERAGE_SIZE];static unsigned char batteryIndex;static signed int previous_SOC = -1;kal_bool current_sign;bat_vol = battery_meter_get_battery_voltage(KAL_TRUE);Vsense = battery_meter_get_VSense();if (upmu_is_chr_det() == KAL_TRUE)ICharging = battery_meter_get_charging_current();elseICharging = 0;charger_vol = battery_meter_get_charger_voltage();temperature = battery_meter_get_battery_temperature();temperatureV = battery_meter_get_tempV();temperatureR = battery_meter_get_tempR(temperatureV);if (bat_meter_timeout == KAL_TRUE || bat_spm_timeout == TRUE || fg_wake_up_bat == KAL_TRUE) {SOC = battery_meter_get_battery_percentage();/* if (bat_spm_timeout == true) *//* BMT_status.UI_SOC = battery_meter_get_battery_percentage(); */bat_meter_timeout = KAL_FALSE;bat_spm_timeout = FALSE;} else {if (previous_SOC == -1)SOC = battery_meter_get_battery_percentage();elseSOC = previous_SOC;}ZCV = battery_meter_get_battery_zcv();BMT_status.ICharging = mt_battery_average_method(BATTERY_AVG_CURRENT, &batteryCurrentBuffer[0], ICharging, &icharging_sum, batteryIndex);if (previous_SOC == -1 && bat_vol <= batt_cust_data.v_0percent_tracking) {battery_log(BAT_LOG_CRTI, "battery voltage too low, use ZCV to init average data.\n");BMT_status.bat_vol = mt_battery_average_method(BATTERY_AVG_VOLT, &batteryVoltageBuffer[0], ZCV, &bat_sum, batteryIndex);} else {BMT_status.bat_vol = mt_battery_average_method(BATTERY_AVG_VOLT, &batteryVoltageBuffer[0], bat_vol, &bat_sum, batteryIndex);}if (battery_cmd_thermal_test_mode == 1) {battery_log(BAT_LOG_CRTI, "test mode , battery temperature is fixed.\n");} else {BMT_status.temperature = mt_battery_average_method(BATTERY_AVG_TEMP, &batteryTempBuffer[0], temperature, &temperature_sum, batteryIndex);}BMT_status.Vsense = Vsense;BMT_status.charger_vol = charger_vol;BMT_status.temperatureV = temperatureV;BMT_status.temperatureR = temperatureR;BMT_status.SOC = SOC;BMT_status.ZCV = ZCV;BMT_status.IBattery = battery_meter_get_battery_current();current_sign = battery_meter_get_battery_current_sign();BMT_status.IBattery *= (current_sign ? 1 : (-1));if (BMT_status.charger_exist == KAL_FALSE) {if (BMT_status.SOC > previous_SOC && previous_SOC >= 0)BMT_status.SOC = previous_SOC;}previous_SOC = BMT_status.SOC;batteryIndex++;if (batteryIndex >= BATTERY_AVERAGE_SIZE)batteryIndex = 0;if (g_battery_soc_ready == KAL_FALSE)g_battery_soc_ready = KAL_TRUE;battery_log(BAT_LOG_CRTI,"AvgVbat=(%d,%d),AvgI=(%d,%d),VChr=%d,AvgT=(%d,%d),SOC=(%d,%d),UI_SOC=%d,ZCV=%d,CHR_Type=%d bcct:%d:%d I:%d Ibat:%d\n", BMT_status.bat_vol, bat_vol, BMT_status.ICharging, ICharging, BMT_status.charger_vol, BMT_status.temperature, temperature, previous_SOC, BMT_status.SOC, BMT_status.UI_SOC, BMT_status.ZCV, BMT_status.charger_type, g_bcct_flag, get_usb_current_unlimited(), get_bat_charging_current_level(), BMT_status.IBattery / 10);battery_log(BAT_LOG_CRTI, "v=%d,i=%d,t=%d,soc=%d,bcct:%d:%d I:%d Ibat:%d\n", bat_vol, ICharging, temperature, BMT_status.UI_SOC, g_bcct_flag, get_usb_current_unlimited(), get_bat_charging_current_level(), BMT_status.IBattery / 10);}battery_meter_get_battery_percentage //获取电池电量(方式1通过开路电压与容量的关系 方式2根据开路电压算出初始电量,然后通过库伦积分算出消耗的电量)
BMT_status.bat_vol, bat_vol, //该段时间的平均电池电压 //电池电压(直接读寄存器)
BMT_status.ICharging //电流(平台硬件差异这里是0,这里通过的是库仑计获取电流)
BMT_status.charger_vol //充电器电压 根据pmic6328vcdt脚获取到的电压,根据分压原理算出vbus的电压 其中vcdt还有一个功能,
作为充电器的中断检测,来判断充电器的插拔
BMT_status.temperature, temperature, //电池温度
BMT_status.SOC, BMT_status.UI_SOC //电池容量 电池ui容量
BMT_status.ZCV//电路开路电压
BMT_status.charger_type//充电器类型
g_bcct_flag//充电是否被限流(高温或者其他情况)
get_bat_charging_current_level(), //获取充电电流等级(bq24296对应的值)
mt_battery_update_status//更新全局结构体battery_data的值,上层便能及时获取到电池的数据
static void mt_battery_update_status(void){#if defined(CONFIG_POWER_EXT)battery_log(BAT_LOG_CRTI, "[BATTERY] CONFIG_POWER_EXT, no update Android.\n");#else{if (skip_battery_update == KAL_FALSE) {battery_log(BAT_LOG_FULL, "mt_battery_update_status.\n");usb_update(&usb_main);ac_update(&ac_main);wireless_update(&wireless_main);battery_update(&battery_main);} else {battery_log(BAT_LOG_CRTI, "skip mt_battery_update_status.\n");skip_battery_update = KAL_FALSE;}}#endif}static void battery_update(struct battery_data *bat_data){ struct power_supply *bat_psy = &bat_data->psy; kal_bool resetBatteryMeter = KAL_FALSE; static unsigned int update_cnt = 3; static unsigned int pre_uisoc; static unsigned int pre_chr_state; bat_data->BAT_TECHNOLOGY = POWER_SUPPLY_TECHNOLOGY_LION; bat_data->BAT_HEALTH = POWER_SUPPLY_HEALTH_GOOD; bat_data->BAT_batt_vol = BMT_status.bat_vol; bat_data->BAT_batt_temp = BMT_status.temperature * 10; bat_data->BAT_PRESENT = BMT_status.bat_exist; if ((BMT_status.charger_exist == KAL_TRUE) && (BMT_status.bat_charging_state != CHR_ERROR)) { if (BMT_status.bat_exist) { /* charging */ if (BMT_status.bat_vol <= batt_cust_data.v_0percent_tracking) resetBatteryMeter = mt_battery_0Percent_tracking_check(); else resetBatteryMeter = mt_battery_100Percent_tracking_check(); bat_data->BAT_STATUS = POWER_SUPPLY_STATUS_CHARGING; } else { /* No Battery, Only Charger */ bat_data->BAT_STATUS = POWER_SUPPLY_STATUS_UNKNOWN; BMT_status.UI_SOC = 0; } } else { /* Only Battery */ bat_data->BAT_STATUS = POWER_SUPPLY_STATUS_NOT_CHARGING; if (BMT_status.bat_vol <= batt_cust_data.v_0percent_tracking) resetBatteryMeter = mt_battery_0Percent_tracking_check(); else resetBatteryMeter = mt_battery_nPercent_tracking_check(); } if (resetBatteryMeter == KAL_TRUE) { battery_meter_reset(); } else { if (BMT_status.bat_full == KAL_TRUE && is_uisoc_ever_100 == KAL_TRUE) { BMT_status.UI_SOC = 100; battery_log(BAT_LOG_CRTI, "[recharging] UI_SOC=%d, SOC=%d\n", BMT_status.UI_SOC, BMT_status.SOC); } else { mt_battery_Sync_UI_Percentage_to_Real(); } } battery_log(BAT_LOG_CRTI, "UI_SOC=(%d), resetBatteryMeter=(%d)\n", BMT_status.UI_SOC, resetBatteryMeter); /* set RTC SOC to 1 to avoid SOC jump in charger boot.*/ if (BMT_status.UI_SOC <= 1) set_rtc_spare_fg_value(1); else set_rtc_spare_fg_value(BMT_status.UI_SOC); mt_battery_update_EM(bat_data); if (cmd_discharging == 1) bat_data->BAT_STATUS = POWER_SUPPLY_STATUS_CMD_DISCHARGING; if (adjust_power != -1) { bat_data->adjust_power = adjust_power; battery_log(BAT_LOG_CRTI, "adjust_power=(%d)\n", adjust_power); }#ifdef DLPT_POWER_OFF_EN /*extern int dlpt_check_power_off(void);*/ if (bat_data->BAT_CAPACITY <= DLPT_POWER_OFF_THD) { static signed char cnt; battery_log(BAT_LOG_CRTI, "[DLPT_POWER_OFF_EN] run\n"); if (dlpt_check_power_off() == 1) { bat_data->BAT_CAPACITY = 0; cnt++; battery_log(BAT_LOG_CRTI, "[DLPT_POWER_OFF_EN] SOC=%d to power off\n", bat_data->BAT_CAPACITY); if (cnt >= 2) kernel_restart("DLPT reboot system"); } else cnt = 0; } else { battery_log(BAT_LOG_CRTI, "[DLPT_POWER_OFF_EN] disable(%d)\n", bat_data->BAT_CAPACITY); }#endif if (update_cnt >= 3) { /* Update per 60 seconds */ power_supply_changed(bat_psy); pre_uisoc = BMT_status.UI_SOC; update_cnt = 0; pre_chr_state = BMT_status.bat_charging_state; if (cable_in_uevent == 1) cable_in_uevent = 0; } else if ((pre_uisoc != BMT_status.UI_SOC) || (BMT_status.UI_SOC == 0)) { /* Update when soc change */ power_supply_changed(bat_psy); pre_uisoc = BMT_status.UI_SOC; update_cnt = 0; } else if ((BMT_status.charger_exist == KAL_TRUE) && ((pre_chr_state != BMT_status.bat_charging_state) || (BMT_status.bat_charging_state == CHR_ERROR))) { /* Update when changer status change */ power_supply_changed(bat_psy); pre_chr_state = BMT_status.bat_charging_state; update_cnt = 0; } else if (cable_in_uevent == 1) { /*To prevent interrupt-trigger update from being filtered*/ power_supply_changed(bat_psy); cable_in_uevent = 0; } else { /* No update */ update_cnt++; }}mt_battery_0Percent_tracking_check//低于关机电压监测,让ui电池容量减少到0,这时framework层会让系统关机
mt_battery_nPercent_tracking_check//n可自行定制,库仑积分计算的电量跟ocv(开路电压)计算的电量进行同步,保证电量计算的可靠性。
mt_battery_Sync_UI_Percentage_to_Real();//同步ui显示的电量百分比
- mt6735电池状态监测
- MT6735 - battery相关笔记 (充电、电池状态、zvc、driver与service通信)
- android监测电池的电量与充电状态
- 【Android Training - Performance】优化电池续航能力[Lesson 1 - 监测设备的电量与充电状态]
- 【Android Training - Performance】优化电池续航能力[Lesson 3 - 判断并监测网络连接状态]
- Android 的电池消耗优化 II-监测电量等级和充电状态
- android监测电池的电量
- Android官方开发文档Training系列课程中文版:电池续航时间优化之监测电池电量及充电状态
- android 设置电池状态
- 如何检测电池状态
- android 电池状态获取
- 获得电池充电状态
- WINCE 电池状态(C#)
- iOS 获取电池状态
- WINCE 电池状态(C#)
- Android电池状态监听
- iOS_电池状态
- IOS 电池状态监控
- 深入理解Java常用类-----时间日期
- SSL/TLS Handshake 握手 连接
- eclipse下taglib标准标签库问题Can not find the tag library descriptor for "http://java.sun.com/jsp/jstl/core"
- software architecture 看到这篇文章不错
- 全方位玩转Windows 10 Bash 子系统Ubuntu
- mt6735电池状态监测
- JSON Web Tokens介绍
- 七夕节
- 【剑指offer-解题系列(38)】数字在排序数组中出现的次数
- (POJ 1990)MooFest 树状数组 求一个数和他前面的所有数的值的差值之和
- \r与\n
- Spring的bean管理(注解创建对象)
- [一天几个linux命令] umask
- 数据结构之队列