MTK电量统计与充电模式分析

1.初始化电量,关机后插入充电器(sw fg)
bat_thread_kthread
    BAT_thread
        battery_meter_initial();
            table_init(); 主要是根据温度得到内阻R的表和OCV表        
    oam_init();
                battery_charging_control(CHARGING_CMD_ENABLE, &charging_enable); //停止充电
                ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_OCV, &gFG_voltage); //HW_OCV
        ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_ADC_V_BAT_SENSE, &g_booting_vbat); //VBAT电压
                gFG_capacity_by_v = fgauge_read_capacity_by_v(gFG_voltage); //以这个为主
        vbat_capacity = fgauge_read_capacity_by_v(g_booting_vbat);
       ¥第一个判断
                if (bat_is_charger_exist() == KAL_TRUE) //充电器存在
                    if (((gFG_capacity_by_v == 100) && (vbat_capacity < CUST_POWERON_MAX_VBAT_TOLRANCE(90))) //(HW_OCV_C == 100 && VBAT_C < 90)
                        || (abs(gFG_capacity_by_v - vbat_capacity) > CUST_POWERON_DELTA_VBAT_TOLRANCE))  //HW_OCV_C - VBAT_C +-30, 绝对值
                            gFG_voltage = g_booting_vbat;  //使用VABT电压
    gFG_capacity_by_v = vbat_capacity; //使用VBAT的容量
                     }
                }
            gFG_capacity_by_v_init = gFG_capacity_by_v; //第一个判断得到的电池容量

            dod_init
                gFG_capacity_by_sw_ocv = gFG_capacity_by_v; //第一个判断得到的电池容量
                battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_OCV, &gFG_voltage); //HW_OCV
                gFG_capacity_by_v = fgauge_read_capacity_by_v(gFG_voltage); //第二次得到HW_OCV容量

       ¥第二个判断
                if ((abs(gFG_capacity_by_v_init - gFG_capacity_by_v) > 5) && (bat_is_charger_exist() == KAL_TRUE)) { 
    gFG_capacity_by_v = gFG_capacity_by_v_init; //第一次判断得到的容量比第二次HW_OCV绝对值大5,则使用第一次
        }
                
                g_rtc_fg_soc = get_rtc_spare_fg_value(); //得到rtc电量

        ¥第三个判断
                if (((g_rtc_fg_soc != 0)  && (((abs(g_rtc_fg_soc - gFG_capacity_by_v)) <= CUST_POWERON_DELTA_CAPACITY_TOLRANCE)
|| (abs(gFG_capacity_by_v_init - g_rtc_fg_soc) < abs(gFG_capacity_by_v - gFG_capacity_by_v_init))))
|| ((g_rtc_fg_soc != 0)
&& (g_boot_reason == BR_WDT_BY_PASS_PWK || g_boot_reason == BR_WDT
|| g_boot_reason == BR_TOOL_BY_PASS_PWK || g_boot_reason == BR_2SEC_REBOOT
|| g_boot_mode == RECOVERY_BOOT)))
                    gFG_capacity_by_v = g_rtc_fg_soc;

                       BgFG_capacity_by_v_init - g_rtc_fg_soc  < gFG_capacity_by_v - gFG_capacity_by_v_init ) //abs(第一次判断得到的容量 - rtc) < abs (第二次判断得到的容量 - 第一次判断得到的容量)。
        化简:   A ((g_rtc_fg_soc != 0)  && (((abs(g_rtc_fg_soc - gFG_capacity_by_v)) <= CUST_POWERON_DELTA_CAPACITY_TOLRANCE)
|| (abs(gFG_capacity_by_v_init - g_rtc_fg_soc) < abs(gFG_capacity_by_v - gFG_capacity_by_v_init))))
                     ( g_rtc_fg_soc 不等于0)  &&  g_rtc_fg_soc - gFG_capacity_by_v //绝对值小于20  ||   B)
                      
                    C((g_rtc_fg_soc != 0)  && (g_boot_reason == BR_WDT_BY_PASS_PWK || g_boot_reason == BR_WDT
|| g_boot_reason == BR_TOOL_BY_PASS_PWK || g_boot_reason == BR_2SEC_REBOOT
|| g_boot_mode == RECOVERY_BOOT))
         总判断 =  A || C 成立,就使用rtc电量 ,这里我们这样调节CUST_POWERON_DELTA_CAPACITY_TOLRANCE, g_rtc_fg_soc 

        if (gFG_capacity_by_v == 0 && bat_is_charger_exist() == KAL_TRUE) { //开机后电量不可能为0
gFG_capacity_by_v = 1; 




二.运行时电量计算,第一次开机,或者关机充电也需要进入(D5算法基本不需要容量,只是逼近ocv)
    mt_battery_GetBatteryData();
        bat_vol = battery_meter_get_battery_voltage(KAL_TRUE);
         battery_meter_get_battery_percentage 
            oam_run();
                battery_meter_ctrl(BATTERY_METER_CMD_GET_ADC_V_BAT_SENSE, &vol_bat);
                oam_i_1 = (((oam_v_ocv_1 - vol_bat) * 1000) * 10) / oam_r_1; /* 0.1mA */
        oam_i_2 = (((oam_v_ocv_2 - vol_bat) * 1000) * 10) / oam_r_2; /* 0.1mA */  这都是battery_meter_initial初始化得到的值
                oam_d_1 = oam_d0 + (oam_car_1 * 100 / 10) / gFG_BATT_CAPACITY_aging; //这就是得到的初始化电量
                oam_v_ocv_1 = vol_bat + mtk_imp_tracking(vol_bat, oam_i_2, 5); //得到内阻的补偿
                    mtk_imp_tracking
                        ret_compensate_value =  ((ori_current) * (gFG_resistance_bat + R_FG_VALUE + FG_METER_RESISTANCE)) / 1000;  //两个重要参数
               oam_d_3 = fgauge_read_d_by_v(oam_v_ocv_1); //得到容量
                ........经错一系列的计算逼近得到oam_d_5
        SOC =  100 - oam_d_5
        BMT_status.SOC = SOC; //赋值电量
        



三.更新电量
    mt_battery_update_status();
        battery_update(&battery_main);
            if ((BMT_status.charger_exist == KAL_TRUE) && (BMT_status.bat_charging_state != CHR_ERROR)) 
                mt_battery_100Percent_tracking_check //显示充电到100%的条件
                if (BMT_status.bat_full == KAL_TRUE) //这个为KAL_TRUE,四.检查充电状态这里改变这个状态
                    /* increase UI percentage every xxs */
if (timer_counter >= (cust_sync_time / BAT_TASK_PERIOD)) {  //大于等于1就可以了
timer_counter = 1;
BMT_status.UI_SOC++;
} else {
timer_counter++;
return resetBatteryMeter;
}
                set_rtc_spare_fg_value(BMT_status.UI_SOC); //设置RTC,不小于1
                mt_battery_update_EM //更新上层读取的文件节点,有的已经在前面更新了
                    bat_data->BAT_CAPACITY = BMT_status.UI_SOC; //电量
                power_supply_changed(bat_psy); //更新sysfs内容,供上层读取



四.检查充电状态
    if (BMT_status.charger_exist == KAL_TRUE)
        mt_battery_charging_algorithm(); //Switch_charging.c (kernel-3.10\drivers\power\mediatek)
            case CHR_CC:
BAT_ConstantCurrentModeAction(); //恒流充电状态下
                    if (charging_full_check() == KAL_TRUE) {   //这里是检查bq24296是否是充满状态,如果是
        BMT_status.bat_charging_state = CHR_BATFULL; 
        BMT_status.bat_full = KAL_TRUE;
        g_charging_full_reset_bat_meter = KAL_TRUE;

        charging_full_check
            battery_charging_control(CHARGING_CMD_GET_CHARGING_STATUS, &status);
                ret_val = bq24296_get_chrg_stat();
                if(ret_val == 0x3) //如果等于3就是充满了
                    *(kal_uint32 *)data = KAL_TRUE;




五.检测充电模式
mt_battery_charger_detect_check
    if (upmu_is_chr_det() == KAL_TRUE)  //如果charge存在,主要是查看pmic的寄存器
        mt_charger_type_detection();
            battery_charging_control(CHARGING_CMD_GET_CHARGER_TYPE, &CHR_Type_num);
                charging_get_charger_type //Charging_hw_fan5405.c (kernel-3.10\drivers\misc\mediatek\power\mt6735)
                    /********* Step initial  ***************/  
            hw_bc11_init(); //单独分析1, BC11协议初始化
                    if(1 == hw_bc11_DCD())  //单独分析2,检测是否是标准充电器
                        /********* Step A1 ***************/
if(1 == hw_bc11_stepA1())  //单独分析3,检测是不是苹果充电器,苹果充电器,D+,和D-不是短接
*(CHARGER_TYPE*)(data) = APPLE_2_1A_CHARGER;,//苹果2.A充电器
                esle
                        *(CHARGER_TYPE*)(data) = NONSTANDARD_CHARGER; //不标准充电器
          else
                /********* Step A2 ***************/
if(1 == hw_bc11_stepA2()) //单独分析4,标准充电器就是D+,D-短接,用到BC1.X标准,附件有
                        /********* Step B2 ***************/
if(1 == hw_bc11_stepB2()) //单独分析5
*(CHARGER_TYPE*)(data) = STANDARD_CHARGER;
                        else
                                 *(CHARGER_TYPE*)(data) = CHARGING_HOST;
                else
                        *(CHARGER_TYPE*)(data) = STANDARD_HOST;
      hw_bc11_done //结束检测
          Charger_Detect_Release(); 、、

相应的寄存器描述
    
    


单独分析1
    hw_bc11_init(); //BC1.1协议初始化
        Charger_Detect_Init
            //turn on USB reference clock.
            usb_enable_clock(true);
            //wait 50 usec.
            udelay(50);
            /* RG_USB20_BC11_SW_EN = 1'b1 */
            USBPHY_SET8(0x1a, 0x80);
     //RG_bc11_BIAS_EN=1 //进行一些寄存器的设置,初始化状态
    bc11_set_register_value(PMIC_RG_BC11_BIAS_EN,1);
    //RG_bc11_VSRC_EN[1:0]=00
    bc11_set_register_value(PMIC_RG_BC11_VSRC_EN,0);
    //RG_bc11_VREF_VTH = [1:0]=00
    bc11_set_register_value(PMIC_RG_BC11_VREF_VTH,0);
    //RG_bc11_CMP_EN[1.0] = 00
    bc11_set_register_value(PMIC_RG_BC11_CMP_EN,0);
    //RG_bc11_IPU_EN[1.0] = 00
    bc11_set_register_value(PMIC_RG_BC11_IPU_EN,0);
    //RG_bc11_IPD_EN[1.0] = 00
    bc11_set_register_value(PMIC_RG_BC11_IPD_EN,0);
    //bc11_RST=1
    bc11_set_register_value(PMIC_RG_BC11_RST,1);
    //bc11_BB_CTRL=1
    bc11_set_register_value(PMIC_RG_BC11_BB_CTRL,1);


单独分析2
hw_bc11_DCD
     //RG_bc11_IPU_EN[1.0] = 10,,
    bc11_set_register_value(PMIC_RG_BC11_IPU_EN,0x2);  
    //RG_bc11_IPD_EN[1.0] = 01,,
    bc11_set_register_value(PMIC_RG_BC11_IPD_EN,0x1);
    //RG_bc11_VREF_VTH = [1:0]=01,,
    bc11_set_register_value(PMIC_RG_BC11_VREF_VTH,0x1);
    //RG_bc11_CMP_EN[1.0] = 10
    bc11_set_register_value(PMIC_RG_BC11_CMP_EN,0x2);
    wChargerAvail = bc11_get_register_value(PMIC_RGS_BC11_CMP_OUT);,得到结果


单独分析3
    //RG_bc11_IPD_EN[1.0] = 01
   bc11_set_register_value(PMIC_RG_BC11_IPD_EN,0x1);
   //RG_bc11_VREF_VTH = [1:0]=00
   bc11_set_register_value(PMIC_RG_BC11_VREF_VTH,0x0);
   //RG_bc11_CMP_EN[1.0] = 01
   bc11_set_register_value(PMIC_RG_BC11_CMP_EN,0x1);
    wChargerAvail = bc11_get_register_value(PMIC_RGS_BC11_CMP_OUT); //获取结果


单独分析4
hw_bc11_stepA2
    //RG_bc11_VSRC_EN[1.0] = 10 
   bc11_set_register_value(PMIC_RG_BC11_VSRC_EN,0x2);
   //RG_bc11_IPD_EN[1:0] = 01
   bc11_set_register_value(PMIC_RG_BC11_IPD_EN,0x1);
   //RG_bc11_VREF_VTH = [1:0]=00
   bc11_set_register_value(PMIC_RG_BC11_VREF_VTH,0x0);
   //RG_bc11_CMP_EN[1.0] = 01
   bc11_set_register_value(PMIC_RG_BC11_CMP_EN,0x1);
   wChargerAvail = bc11_get_register_value(PMIC_RGS_BC11_CMP_OUT); //得到结果


单独分析5
hw_bc11_stepB2
     //RG_bc11_IPU_EN[1:0]=10
   bc11_set_register_value(PMIC_RG_BC11_IPU_EN,0x2); 
   //RG_bc11_VREF_VTH = [1:0]=01
   bc11_set_register_value(PMIC_RG_BC11_VREF_VTH,0x1);
   //RG_bc11_CMP_EN[1.0] = 01
   bc11_set_register_value(PMIC_RG_BC11_CMP_EN,0x1);
   wChargerAvail = bc11_get_register_value(PMIC_RGS_BC11_CMP_OUT);




六.CK3_01插入usb测试
1.插入usb,台式电脑
Charger_Detect_Init
    hw_bc11_DCD() 
    hw_bc11_stepA2() 
    step A2 : Standard USB Host!
    hw_bc11_done()
    所以这里是STANDARD_HOST类型
    [BAT_thread]Cable in, CHR_Type_num=1

    充电的电流就是:
        g_temp_input_CC_value = USB_CHARGER_CURRENT;  //500ma
        g_temp_CC_value = USB_CHARGER_CURRENT;

2.插入标准充电器
Charger_Detect_Init
    hw_bc11_init()
    hw_bc11_DCD()
    hw_bc11_stepA2()
    hw_bc11_stepB2()
    step B2 : STANDARD CHARGER!
    hw_bc11_done()
    [BAT_thread]Cable in, CHR_Type_num=4

 充电的电流就是    
    g_temp_input_CC_value = AC_CHARGER_CURRENT; //2A
    g_temp_CC_value = AC_CHARGER_CURRENT;
    

七.充电协议BC1.2

MTK Fuel Gauge算法分析








    
        
    









Attachment List

     

    posted @ 2020-11-25 16:00  luoyuna  阅读(2322)  评论(0编辑  收藏  举报