立即注册
查看: 4436|回复: 1

[arm开发问题] MT6735平台FW HG电源算法问题

已绑定手机
发表于 2016-12-10 17:41:35 | 显示全部楼层 |阅读模式 来自 陕西省西安市
目前存在一台机器一个电池,重启电量显示不同的问题(100%的电池关机重启之后显示0%关机)
两台机器一块电池,在两台机器上显示的电量也不相同,有差异

目前分析这个算法的结果如下:
    开机要初始化算法,获取关机之前写入rtc的电量。
    首先执行fgauge_initialization(void)
       这个方法中做了如下工作:
  1. void fgauge_initialization(void)
  2. {
  3. #if defined(CONFIG_POWER_EXT)
  4. #else
  5.         int i = 0;
  6.         kal_uint32 ret = 0;

  7.         /* gFG_BATT_CAPACITY_init_high_current = fgauge_get_Q_max_high_current(25); */
  8.         /* gFG_BATT_CAPACITY_aging = fgauge_get_Q_max(25); */

  9.         /* 1. HW initialization */
  10.         ret = Battery_meter_ctrl(BATTERY_METER_CMD_HW_FG_INIT, NULL);     这块不懂在初始化什么,主要是配置MT6328里面的一些寄存器

  11.         /* 2. SW algorithm initialization */
  12.         ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_OCV, &gFG_voltage);     //adc采样获得ocv电压

  13.         ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CURRENT, &gFG_current);   //这个应该是读取电流信息
  14.         i = 0;
  15.         while (gFG_current == 0) {
  16.                 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CURRENT, &gFG_current);
  17.                 if (i > 10) {
  18.                         bm_print(BM_LOG_CRTI, "[fgauge_initialization] gFG_current == 0\n");
  19.                         break;
  20.                 }
  21.                 i++;
  22.         }

  23.         ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CAR, &gFG_columb); //读取库仑计流量,充电为正,放电为负
  24.         #if !defined(CUST_CAPACITY_OCV2CV_TRANSFORM)
  25.         fgauge_construct_battery_profile_init();  //这个主要是修改四种温度(-10,0,25,50)温度下电池曲线的tables长度
  26.         #endif
  27.         gFG_temp = force_get_tbat(KAL_FALSE);   //获取当前温度
  28.         gFG_capacity = fgauge_read_capacity(0);   //根据当前温度构建一份当前温度下的电池曲线,并更具Vbat电压插值得到当前的电量和用电深度

  29.         gFG_capacity_by_c_init = gFG_capacity;
  30.         gFG_capacity_by_c = gFG_capacity;
  31.         gFG_capacity_by_v = gFG_capacity;

  32.         gFG_DOD0 = 100 - gFG_capacity;//初始化用电深度
  33.         bm_print(BM_LOG_CRTI, "[fgauge_initialization] gFG_DOD0 =%d %d \n",gFG_DOD0,gFG_capacity);

  34.         gFG_BATT_CAPACITY = fgauge_get_Q_max(gFG_temp);//获取当前温度下的电池容量

  35.         gFG_BATT_CAPACITY_init_high_current = fgauge_get_Q_max_high_current(gFG_temp);
  36.         gFG_BATT_CAPACITY_aging = fgauge_get_Q_max(gFG_temp);

  37.         ret = battery_meter_ctrl(BATTERY_METER_CMD_DUMP_REGISTER, NULL);

  38.         bm_print(BM_LOG_CRTI, "[fgauge_initialization] Done HW_OCV:%d FG_Current:%d FG_CAR:%d tmp=%d capacity=%d Qmax=%d\n",
  39.                 gFG_voltage,gFG_current,gFG_columb,gFG_temp,gFG_capacity,gFG_BATT_CAPACITY);

  40. #if defined(FG_BAT_INT)
  41.         pmic_register_interrupt_callback(41,fg_bat_int_handler);
  42.         pmic_register_interrupt_callback(40,fg_bat_int_handler);
  43. #endif
  44. #endif
  45. }
  46. #endif
复制代码
第二步执行fgauge_algo_run_init(void)初始化一些信息
  1. void fgauge_algo_run_init(void)
  2. {
  3.         int i = 0;
  4.         int ret = 0;

  5. #ifdef INIT_SOC_BY_SW_SOC
  6.         kal_bool charging_enable = KAL_FALSE;
  7. #if defined (CONFIG_MTK_kernel_POWER_OFF_CHARGING) && !defined(SWCHR_POWER_PATH)
  8.         if(LOW_POWER_OFF_CHARGING_BOOT != g_boot_mode)
  9. #endif
  10.                 /*stop charging for vbat measurement*/
  11.                 battery_charging_control(CHARGING_CMD_ENABLE,&charging_enable);
  12.        
  13.         msleep(50);
  14. #endif
  15. /* 1. Get Raw Data */
  16.         gFG_voltage = battery_meter_get_battery_voltage(KAL_TRUE);  //ADC采样获取到电压
  17.         gFG_voltage_init = gFG_voltage;   //记录初始电压
  18.         ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CURRENT, &gFG_current);   //获取电流
  19.         ret=battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CURRENT_SIGN, &gFG_Is_Charging);  //是否在充电

  20.         gFG_voltage = gFG_voltage + fgauge_compensate_battery_voltage_recursion(gFG_voltage, 5);        /* mV */   //对电压做递归步长
  21.         gFG_voltage = gFG_voltage + OCV_BOARD_COMPESATE;

  22.         bm_print(BM_LOG_CRTI, "[FGADC] SWOCV : %d,%d,%d,%d,%d,%d\n",
  23.                  gFG_voltage_init, gFG_voltage, gFG_current, gFG_Is_Charging, gFG_resistance_bat,
  24.                  gFG_compensate_value);
  25. #ifdef INIT_SOC_BY_SW_SOC
  26.         charging_enable = KAL_TRUE;
  27.         battery_charging_control(CHARGING_CMD_ENABLE,&charging_enable);
  28. #endif
  29.         ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CAR, &gFG_columb);  //获取库仑计流量
  30. /* 1.1 Average FG_voltage */
  31.         for (i = 0; i < FG_VBAT_AVERAGE_SIZE; i++) {
  32.                 FGvbatVoltageBuffer[i] = gFG_voltage;
  33.         }

  34.         FGbatteryVoltageSum = gFG_voltage * FG_VBAT_AVERAGE_SIZE;
  35.         gFG_voltage_AVG = gFG_voltage;

  36. #ifdef Q_MAX_BY_CURRENT
  37. /* 1.2 Average FG_current */
  38.         for (i=0; i<FG_CURRENT_AVERAGE_SIZE; i++) {
  39.                 FGCurrentBuffer[i] = gFG_current;            
  40.         }
  41.        
  42.         FGCurrentSum = gFG_current * FG_CURRENT_AVERAGE_SIZE;
  43.         gFG_current_AVG = gFG_current;
  44. #endif

  45. /* 2. Calculate battery capacity by VBAT */
  46.         gFG_capacity_by_v = fgauge_read_capacity_by_v(gFG_voltage);    //根据补偿后的电压插值查找一个电量
  47.         gFG_capacity_by_v_init = gFG_capacity_by_v;    //记录通过电压获取到的电量值

  48. /* 3. Calculate battery capacity by Coulomb Counter */
  49.         gFG_capacity_by_c = fgauge_read_capacity(1);   //通过初始用电深度gFG_DOD0和库仑计流量计算出当前的电量

  50. /* 4. update DOD0 */

  51.         dod_init();    //初始化DOD0

  52.         gFG_current_auto_detect_R_fg_count = 0;

  53.         for (i = 0; i < 10; i++) {
  54.                 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CURRENT, &gFG_current);

  55.                 gFG_current_auto_detect_R_fg_total += gFG_current;
  56.                 gFG_current_auto_detect_R_fg_count++;
  57.         }

  58.         /* double check */
  59.         if (gFG_current_auto_detect_R_fg_total <= 0) {
  60.                 bm_print(BM_LOG_CRTI, "gFG_current_auto_detect_R_fg_total=0, need double check\n");

  61.                 gFG_current_auto_detect_R_fg_count = 0;

  62.                 for (i = 0; i < 10; i++) {
  63.                         ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CURRENT, &gFG_current);

  64.                         gFG_current_auto_detect_R_fg_total += gFG_current;
  65.                         gFG_current_auto_detect_R_fg_count++;
  66.                 }
  67.         }

  68.         gFG_current_auto_detect_R_fg_result =
  69.             gFG_current_auto_detect_R_fg_total / gFG_current_auto_detect_R_fg_count;
  70. #if !defined(DISABLE_RFG_EXIST_CHECK)
  71.         if (gFG_current_auto_detect_R_fg_result <= CURRENT_DETECT_R_FG) {
  72.                 g_auxadc_solution = 1;

  73.                 bm_print(BM_LOG_CRTI,
  74.                          "[FGADC] Detect NO Rfg, use AUXADC report. (%d=%d/%d)(%d)\r\n",
  75.                          gFG_current_auto_detect_R_fg_result, gFG_current_auto_detect_R_fg_total,
  76.                          gFG_current_auto_detect_R_fg_count, g_auxadc_solution);
  77.         } else {
  78.                 if (g_auxadc_solution == 0) {
  79.                         g_auxadc_solution = 0;

  80.                         bm_print(BM_LOG_CRTI,
  81.                                  "[FGADC] Detect Rfg, use FG report. (%d=%d/%d)(%d)\r\n",
  82.                                  gFG_current_auto_detect_R_fg_result,
  83.                                  gFG_current_auto_detect_R_fg_total,
  84.                                  gFG_current_auto_detect_R_fg_count, g_auxadc_solution);
  85.                 } else {
  86.                         bm_print(BM_LOG_CRTI,
  87.                                  "[FGADC] Detect Rfg, but use AUXADC report. due to g_auxadc_solution=%d \r\n",
  88.                                  g_auxadc_solution);
  89.                 }
  90.         }
  91. #endif
  92. /* 5. Logging */
  93.         bm_print(BM_LOG_CRTI,
  94.                  "[FGADC] %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\r\n",
  95.                  gFG_Is_Charging, gFG_current, gFG_columb, gFG_voltage, gFG_capacity_by_v,
  96.                  gFG_capacity_by_c, gFG_capacity_by_c_init, gFG_BATT_CAPACITY,
  97.                  gFG_BATT_CAPACITY_aging, gFG_compensate_value, gFG_ori_voltage,
  98.                  OCV_BOARD_COMPESATE, R_FG_BOARD_SLOPE, gFG_voltage_init, MinErrorOffset, gFG_DOD0,
  99.                  gFG_DOD1, CAR_TUNE_VALUE, AGING_TUNING_VALUE);
  100.         update_fg_dbg_tool_value();
  101. }
复制代码
第三步执行dod_iit()初始化DOD0
  1. void dod_init(void)
  2. {
  3. #if defined(SOC_BY_HW_FG)
  4.         int ret = 0;

  5. #if defined(IS_BATTERY_REMOVE_BY_PMIC)
  6.         kal_int32 gFG_capacity_by_sw_ocv = gFG_capacity_by_v;    //记录通过补偿电压获取到的电量值
  7. #endif //#if defined(IS_BATTERY_REMOVE_BY_PMIC)

  8.         /* use get_hw_ocv----------------------------------------------------------------- */
  9.         ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_OCV, &gFG_voltage);  //获取ocv电压
  10.         gFG_capacity_by_v = fgauge_read_capacity_by_v(gFG_voltage);    //根据ocv电压获取一个电量值

  11.         bm_print(BM_LOG_CRTI, "[FGADC] get_hw_ocv=%d, HW_SOC=%d, SW_SOC = %d\n",
  12.                  gFG_voltage, gFG_capacity_by_v, gFG_capacity_by_v_init);
  13. #if defined(EXTERNAL_SWCHR_SUPPORT)
  14.         /* compare with hw_ocv & sw_ocv, check if less than or equal to 5% tolerance */
  15.         if ((abs(gFG_capacity_by_v_init - gFG_capacity_by_v) > 5)
  16.             && (bat_is_charger_exist() == KAL_TRUE)) {
  17.                 gFG_capacity_by_v = gFG_capacity_by_v_init;
  18.         }
  19. #endif
  20. #if defined(HW_FG_FORCE_USE_SW_OCV)
  21.         gFG_capacity_by_v = gFG_capacity_by_v_init;
  22.         bm_print(BM_LOG_CRTI, "[FGADC] HW_FG_FORCE_USE_SW_OCV : HW_SOC=%d, SW_SOC = %d\n",
  23.                  gFG_capacity_by_v, gFG_capacity_by_v_init);
  24. #endif
  25.         /* ------------------------------------------------------------------------------- */
  26. #endif

  27. #if defined(CONFIG_POWER_EXT)
  28.         g_rtc_fg_soc = gFG_capacity_by_v;
  29. #else
  30.         g_rtc_fg_soc = get_rtc_spare_fg_value();   //获取关机前rtc保存的关机前的电量值
  31. #endif


  32. #if defined(IS_BATTERY_REMOVE_BY_PMIC)

  33.         sprintf(doddbg,"rtc:%d hwocv:(%d:%d) swocv:(%d,%d) %d battery_remove:%d %d %d %d",g_rtc_fg_soc,gFG_voltage,gFG_capacity_by_v,gFG_voltage_init,gFG_capacity_by_v_init,gFG_capacity_by_sw_ocv,is_battery_remove_pmic(),
  34.         CUST_POWERON_DELTA_CAPACITY_TOLRANCE,CUST_POWERON_LOW_CAPACITY_TOLRANCE,CUST_POWERON_DELTA_HW_SW_OCV_CAPACITY_TOLRANCE);

  35. /*
  36.                 if(is_battery_remove_pmic()==0 && (g_rtc_fg_soc != 0))
  37.                 {
  38.                         bm_print(BM_LOG_CRTI, "[FGADC]is_battery_remove()==0 , use rtc_fg_soc%d\n",g_rtc_fg_soc);
  39.                         gFG_capacity_by_v = g_rtc_fg_soc;
  40.                 }
  41.                 else
  42. */
  43.                 {

  44. #if defined(INIT_SOC_BY_SW_SOC)
  45.                         if (((g_rtc_fg_soc != 0)
  46.                                  && (((abs(g_rtc_fg_soc - gFG_capacity_by_v)) <= CUST_POWERON_DELTA_CAPACITY_TOLRANCE)
  47.                                 || (abs(gFG_capacity_by_v_init - g_rtc_fg_soc) < abs(gFG_capacity_by_v - gFG_capacity_by_v_init))))
  48.                                 || ((g_rtc_fg_soc != 0)
  49.                                 && (g_boot_reason == BR_WDT_BY_PASS_PWK || g_boot_reason == BR_WDT
  50.                                         || g_boot_reason == BR_TOOL_BY_PASS_PWK || g_boot_reason == BR_2SEC_REBOOT
  51.                                         || g_boot_mode == RECOVERY_BOOT)))
  52.                
  53. #else   //如果关机前电量不等于0,并且关机前的电量和开机后的电量差值小于30,并且当前的电量大于5或者在充电,那么更新电量为关机前的电量,提高用户体验
  54.                         if (((g_rtc_fg_soc != 0)
  55.                                  && (((abs(g_rtc_fg_soc - gFG_capacity_by_v)) < CUST_POWERON_DELTA_CAPACITY_TOLRANCE))
  56.                                  &&
  57.                                  ((gFG_capacity_by_v > CUST_POWERON_LOW_CAPACITY_TOLRANCE
  58.                                    || bat_is_charger_exist() == KAL_TRUE)))
  59.                                 || ((g_rtc_fg_soc != 0)
  60.                                 && (g_boot_reason == BR_WDT_BY_PASS_PWK || g_boot_reason == BR_WDT
  61.                                         || g_boot_reason == BR_TOOL_BY_PASS_PWK || g_boot_reason == BR_2SEC_REBOOT
  62.                                         || g_boot_mode == RECOVERY_BOOT)))
  63. #endif
  64.                         {
  65.                                 gFG_capacity_by_v = g_rtc_fg_soc;   //更新电量为关机前电量
  66.                         }
  67.                         else
  68.                         {
  69.                                 if(abs(gFG_capacity_by_v-gFG_capacity_by_sw_ocv)>CUST_POWERON_DELTA_HW_SW_OCV_CAPACITY_TOLRANCE)
  70.                                 {
  71.                                         bm_print(BM_LOG_CRTI, "[FGADC] gFG_capacity_by_v=%d, gFG_capacity_by_sw_ocv=%d use SWOCV\n",gFG_capacity_by_v, gFG_capacity_by_sw_ocv);
  72.                                         gFG_capacity_by_v=gFG_capacity_by_sw_ocv;
  73.                                 }
  74.                                 else
  75.                                 {
  76.                                         bm_print(BM_LOG_CRTI, "[FGADC] gFG_capacity_by_v=%d, gFG_capacity_by_sw_ocv=%d use HWOCV\n",gFG_capacity_by_v, gFG_capacity_by_sw_ocv);
  77.                                 }
  78.                         }
  79.                
  80.                 }

  81. #else

  82. #if defined(SOC_BY_HW_FG)
  83. #if defined(INIT_SOC_BY_SW_SOC)
  84.         if (((g_rtc_fg_soc != 0)
  85.              && (((abs(g_rtc_fg_soc - gFG_capacity_by_v)) <= CUST_POWERON_DELTA_CAPACITY_TOLRANCE)
  86.             || (abs(gFG_capacity_by_v_init - g_rtc_fg_soc) < abs(gFG_capacity_by_v - gFG_capacity_by_v_init))))
  87.             || ((g_rtc_fg_soc != 0)
  88.                 && (g_boot_reason == BR_WDT_BY_PASS_PWK || g_boot_reason == BR_WDT
  89.                     || g_boot_reason == BR_TOOL_BY_PASS_PWK || g_boot_reason == BR_2SEC_REBOOT
  90.                     || g_boot_mode == RECOVERY_BOOT)))

  91. #else
  92.         if (((g_rtc_fg_soc != 0)
  93.              && (((abs(g_rtc_fg_soc - gFG_capacity_by_v)) < CUST_POWERON_DELTA_CAPACITY_TOLRANCE))
  94.              &&
  95.              ((gFG_capacity_by_v > CUST_POWERON_LOW_CAPACITY_TOLRANCE
  96.                || bat_is_charger_exist() == KAL_TRUE)))
  97.             || ((g_rtc_fg_soc != 0)
  98.                 && (g_boot_reason == BR_WDT_BY_PASS_PWK || g_boot_reason == BR_WDT
  99.                     || g_boot_reason == BR_TOOL_BY_PASS_PWK || g_boot_reason == BR_2SEC_REBOOT
  100.                     || g_boot_mode == RECOVERY_BOOT)))
  101. #endif
  102.         {
  103.                 gFG_capacity_by_v = g_rtc_fg_soc;
  104.         }
  105. #elif defined(SOC_BY_SW_FG)
  106.         if (((g_rtc_fg_soc != 0)
  107.              && (((abs(g_rtc_fg_soc - gFG_capacity_by_v)) < CUST_POWERON_DELTA_CAPACITY_TOLRANCE)
  108.                  || (abs(g_rtc_fg_soc - g_booting_vbat) < CUST_POWERON_DELTA_CAPACITY_TOLRANCE))
  109.              &&
  110.              ((gFG_capacity_by_v > CUST_POWERON_LOW_CAPACITY_TOLRANCE
  111.                || bat_is_charger_exist() == KAL_TRUE)))
  112.             || ((g_rtc_fg_soc != 0)
  113.                 && (g_boot_reason == BR_WDT_BY_PASS_PWK || g_boot_reason == BR_WDT
  114.                     || g_boot_reason == BR_TOOL_BY_PASS_PWK || g_boot_reason == BR_2SEC_REBOOT
  115.                     || g_boot_mode == RECOVERY_BOOT)))
  116.         {
  117.                 gFG_capacity_by_v = g_rtc_fg_soc;
  118.         }
  119. #endif
  120. #endif     

  121.    
  122.         bm_print(BM_LOG_CRTI, "[FGADC] g_rtc_fg_soc=%d, gFG_capacity_by_v=%d\n",
  123.                  g_rtc_fg_soc, gFG_capacity_by_v);

  124.         if (gFG_capacity_by_v == 0 && bat_is_charger_exist() == KAL_TRUE) {
  125.                 gFG_capacity_by_v = 1;

  126.                 bm_print(BM_LOG_CRTI, "[FGADC] gFG_capacity_by_v=%d\n", gFG_capacity_by_v);
  127.         }
  128.         gFG_capacity = gFG_capacity_by_v;
  129.         gFG_capacity_by_c_init = gFG_capacity;
  130.         gFG_capacity_by_c = gFG_capacity;

  131.         gFG_DOD0 = 100 - gFG_capacity;   //修改用电深度
  132.         gFG_DOD1 = gFG_DOD0;

  133.         gfg_percent_check_point = gFG_capacity;

  134. #if defined(CHANGE_TRACKING_POINT)
  135.         gFG_15_vlot = fgauge_read_v_by_capacity((100 - g_tracking_point));     //获取当前电量对应的电压值
  136.         bm_print(BM_LOG_CRTI, "[FGADC] gFG_15_vlot = %dmV\n", gFG_15_vlot);
  137. #else
  138.         /* gFG_15_vlot = fgauge_read_v_by_capacity(86); //14% */
  139.         gFG_15_vlot = fgauge_read_v_by_capacity((100 - g_tracking_point));
  140.         bm_print(BM_LOG_CRTI, "[FGADC] gFG_15_vlot = %dmV\n", gFG_15_vlot);
  141.         if ((gFG_15_vlot > 3800) || (gFG_15_vlot < 3600)) {
  142.                 bm_print(BM_LOG_CRTI, "[FGADC] gFG_15_vlot(%d) over range, reset to 3700\n",
  143.                          gFG_15_vlot);
  144.                 gFG_15_vlot = 3700;
  145.         }
  146. #endif
  147. }
复制代码
分析的结果就是上面这些,不知道分析的有什么误差,现在的话电量显示异常的问题不知道怎么分析了
我知道答案 回答被采纳将会获得5 RD币 已有1人回答
发表于 2018-2-28 13:54:47 | 显示全部楼层 来自 广东省深圳市
楼主有没有解决啊,我也遇到同样的问题了
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

合作/建议

TEL: 19168984579

工作时间:
周一到周五 9:00-11:30 13:30-19:30
  • 扫一扫关注公众号
  • 扫一扫打开小程序
Copyright © 2013-2024 一牛网 版权所有 All Rights Reserved. 帮助中心|隐私声明|联系我们|手机版|粤ICP备13053961号|营业执照|EDI证
在本版发帖搜索
扫一扫添加微信客服
QQ客服返回顶部
快速回复 返回顶部 返回列表