BMT(battery management task)模块主要包含 ADC management,charging control和 BMT customization等相关内容。
BMT模块软件架构
脉冲充电硬件原理图如下:
charging control 主要阶段的电池电压和充电电流情况如下:
BMT状态转换图如下:
BMT模块客制化
const bmt_customized_struct bmt_charging_para =
{
#if !defined(BMT_CHARGING_DISABLE)
#if defined(DRV_BMT_HIGH_VCHG_ADAPTIVE_CHARGE_CURRENT_SUPPORT)
(kal_int32)CHR_VCHARGER_HV_HIGH, /* kal_int32 VCHARGER_HIGH */
#else
(kal_int32)CHR_VCHARGER_HW_HIGH, /* HW HV*/
#endif
(kal_int32)CHR_VCHARGER_HIGH, /* SW HV */
(kal_int32)CHR_VCHARGER_LOW, /* kal_int32 VCHARGER_LOW */
(kal_int32)CHR_ICHARGE_ON_HIGH, /* kal_int32 ICHARGE_ON_HIGH */
(kal_int32)CHR_ICHARGE_ON_LOW, /* kal_int32 ICHARGE_ON_LOW */
(kal_int32)CHR_ICHARGE_OFF_HIGH, /* kal_int32 ICHARGE_OFF_HIGH */
(kal_int32)CHR_V_PRE2FAST_THRES, /* kal_int32 V_PRE2FAST_THRES */
(kal_int32)CHR_V_PRE2FULL_THRES, /*kal_int32 CHR_V_PRE2FULL_THRES */
(kal_int32)CHR_FAST_ICHARGE_HIGHLEVEL, /* kal_int32 FAST_ICHARGE_HIGHLEVEL */
(kal_int32)CHR_FAST_ICHARGE_LOWLEVEL, /* kal_int32 FAST_ICHARGE_LOWLEVEL */
(kal_int32)CHR_I_TOPOFF2FAST_THRES, /* kal_int32 I_TOPOFF2FAST_THRES */
(kal_int32)CHR_I_TOPOFF2FULL_THRES, /* kal_int32 I_TOPOFF2FULL_THRES */
#if defined(LINEAR_LI_CHARGING) || defined(PULSE_LI_CHARGING)
(kal_int32)CHR_V_FAST2TOPOFF_THRES_LI, /* kal_int32 V_FAST2TOPOFF_THRES */
(kal_int32)CHR_V_FULL2FAST_THRES_LI, /* kal_int32 V_FULL2FAST_THRES */
(kal_int32)CHR_MAX_VBAT_LI, /* kal_int32 MAX_VBAT_LI */
(kal_int32)CHR_V_PROTECT_HIGH_LI, /* kal_int32 V_PROTECT_HIGH_LI */
(kal_int32)CHR_V_PROTECT_LOW_LI, /* kal_int32 V_PROTECT_LOW_LI */
#endif
#if defined(LINEAR_NIMH_CHARGING) || defined(PULSE_NIMH_CHARGING)
(kal_int32)CHR_V_TEMP_FAST2FULL_THRES_NI, /* kal_int32 V_TEMP_FAST2FULL_THRES_NI */
(kal_int32)CHR_V_FULL2FAST_THRES_NI, /* kal_int32 V_FULL2FAST_THRES_NI */
(kal_int32)CHR_MAX_VBAT_NI, /* kal_int32 MAX_VBAT_NI */
#endif
/* PRE CHARGE ,search table */
(kal_uint32)PRE_TON_TIME, /* kal_uint32 PRE_TON */
(kal_uint32)PRE_TOFF_TIME, /* kal_uint32 PRE_TOFF */
/* FAST CHARGE, search table */
(kal_uint32)TOPOFF_TON_TIME, /* kal_uint32 TOPOFF_TON */
(kal_uint32)TOPOFF_TOFF_TIME, /* kal_uint32 TOPOFF_TOFF */
#if defined(PULSE_LI_CHARGING) || defined(PULSE_NIMH_CHARGING)
(kal_uint32)PULSE_POSTFULL_TWAIT_TIME, /* kal_uint32 BATPOSTFULL_TWAIT_LI */
(kal_uint32)PULSE_POSTFULL_TON_TIME, /* kal_uint32 BATPOSTFULL_TON_LI */
(kal_uint32)PULSE_POSTFULL_TOFF_TIME, /* kal_uint32 BATPOSTFULL_TOFF_LI */
#endif
#if defined(LINEAR_LI_CHARGING) || defined(PULSE_LI_CHARGING)
(kal_uint32)BATFULL_TON_TIME_LI, /* kal_uint32 BATFULL_TON_LI */
(kal_uint32)BATFULL_TOFF_TIME_LI, /* kal_uint32 BATFULL_TOFF_LI */
#else
(kal_uint32)BATFULL_TON_TIME_NI; /* unit : second */
(kal_uint32)BATFULL_TOFF_TIME_NI;
#endif
(kal_uint32)CHR_STOP_TOFF_TIME, /* kal_uint32 BATFULL_TOFF */
(kal_uint32)BATHOLD_TOFF_TIME, /* kal_uint32 BATHOLD_OFF */
// kal_int32 CurrOffset[3];
//{
CURRENT_OFFSET_IDLE_MODE, // 100ma
CURRENT_OFFSET_TALK_MODE,
CURRENT_OFFSET_SWOFF_MODE,
//},
(kal_uint32)TOTAL_CHARGE_TIME,
// kal_uint8 TONOFFTABLE[6][2];
//{
(kal_uint8)FAST_ICHARGE_HI_NORMAL_ON, (kal_uint8)FAST_ICHARGE_HI_NORMAL_OFF,
(kal_uint8)FAST_ICHARGE_MID_NORMAL_ON, (kal_uint8)FAST_ICHARGE_MID_NORMAL_OFF,
(kal_uint8)FAST_ICHARGE_LO_NORMAL_ON, (kal_uint8)FAST_ICHARGE_LO_NORMAL_OFF,
(kal_uint8)FAST_ICHARGE_HI_TALK_ON, (kal_uint8)FAST_ICHARGE_HI_TALK_OFF,
(kal_uint8)FAST_ICHARGE_MID_TALK_ON, (kal_uint8)FAST_ICHARGE_MID_TALK_OFF,
(kal_uint8)FAST_ICHARGE_LO_TALK_ON, (kal_uint8)FAST_ICHARGE_LO_TALK_OFF,
//},
#if defined(DRV_BMT_HIGH_VCHG_ADAPTIVE_CHARGE_CURRENT_SUPPORT)
//kal_int32 HIGH_VCHG_TABLE[VCHG_VOL_LEVEL][VCHG_PARAMTER_COUNT];
//{
HIGH_V_VCHG_THRESHHOLD_LEVEL_0, HIGH_V_CHARGING_CURRENT_LEVEL_0, HIGH_V_SAFETY_TIME_LEVEL_0,
HIGH_V_VCHG_THRESHHOLD_LEVEL_1, HIGH_V_CHARGING_CURRENT_LEVEL_1, HIGH_V_SAFETY_TIME_LEVEL_1,
HIGH_V_VCHG_THRESHHOLD_LEVEL_2, HIGH_V_CHARGING_CURRENT_LEVEL_2, HIGH_V_SAFETY_TIME_LEVEL_2,
HIGH_V_VCHG_THRESHHOLD_LEVEL_3, HIGH_V_CHARGING_CURRENT_LEVEL_3, HIGH_V_SAFETY_TIME_LEVEL_3,
HIGH_V_VCHG_THRESHHOLD_LEVEL_4, HIGH_V_CHARGING_CURRENT_LEVEL_4, HIGH_V_SAFETY_TIME_LEVEL_4,
HIGH_V_VCHG_THRESHHOLD_LEVEL_5, HIGH_V_CHARGING_CURRENT_LEVEL_5, HIGH_V_SAFETY_TIME_LEVEL_5,
HIGH_V_VCHG_THRESHHOLD_LEVEL_6, HIGH_V_CHARGING_CURRENT_LEVEL_6, HIGH_V_SAFETY_TIME_LEVEL_6,
//},
#endif
(kal_bool)CHR_BATTERY_TYPE,
(kal_bool)CHR_CHECK_CHARGER_VOLTAGE,
(kal_bool)CHR_CHECK_BATT_TEMP,
#endif //#if !defined(BMT_CHARGING_DISABLE)
(kal_bool)CHR_CHECK_BATTERY,
(kal_uint32)CHR_BATT_EXIST_ADC_THRESHOLD /* kal_uint32 BATT_EXIST_ADC_THRESHOLD */
};
常用客制化参量如下:
充电电流如何设置
充电过程中只有Fast charge(CC)阶段的充电电流是可以通过软件设定的,Pre-charge阶段充电电流是由硬件决定的,一般USB充电时预充电流为70mA,AC充电时预充电流为200mA。TOP-OFF(CV)阶段的充电电流是不断下降的,默认在ICHG<120mA时进入Charger Complete阶段。
CC阶段充电电流的设置可通过修改chr_parameter.h文件中的宏:
// Configuration of AC/USB Charge Current
#define CHR_AC_CHARGE_CURRENT PMU_CHARGE_CURRENT_450_00_MA
#define CHR_USB_CHARGE_CURRENT PMU_CHARGE_CURRENT_450_00_MA
#define CHR_NON_AC_CHARGE_CURRENT PMU_CHARGE_CURRENT_450_00_MA
#define CHR_USB_CHARGING_HOST_CHARGE_CURRENT PMU_CHARGE_CURRENT_450_00_MA
或直接在hal\peripheral\src\bmt_utility.c文件的void bmt_set_chr_current(void)函数中设置:
void bmt_set_chr_current(void)
{
kal_uint32 chr_current = PMU_CHARGE_CURRENT_0_00_MA;
CHR_DET_TYPE_ENUM chr_type;
chr_type = bmt_get_chr_type();
switch (chr_type)
{
case PW_AC_CHR:
chr_current = CHR_AC_CHARGE_CURRENT;//修改CC电流
drv_trace0(TRACE_GROUP_10, BMT_SET_AC_CHARGE_CURRENT_TRC);
break;
case PW_USB_CHR:
chr_current = bmt_usb_chr_current;//修改成USB电流
drv_trace0(TRACE_GROUP_10, BMT_SET_USB_CHARGE_CURRENT_TRC);
break;
case PW_AC_NON_STD_CHR:
chr_current = CHR_NON_AC_CHARGE_CURRENT;
break;
case PW_USB_CHARGING_HOST_CHR:
chr_current = CHR_USB_CHARGING_HOST_CHARGE_CURRENT;
break;
default:
ASSERT(0);
break;
}
通过宏设置的充电电流与实际设置下去的充电电流关系是:
实际设置下去的充电电流是通过hal\peripheral\src\bmt_internal_chr_setting.c中的bmt_find_and_set_the_nearest_current(void *data)函数从hal\peripheral\src\bmt_hw.c中chr_CS_VTH[CS_VTH_SIZE] 表里搜索的与通过宏设置的最接近的那一档。
static DCL_STATUS bmt_find_and_set_the_nearest_current(void *data)
{
DCL_STATUS status = STATUS_OK;
DCL_UINT32 set_chr_current;
DCL_UINT32 array_size;
DCL_UINT16 register_value;
array_size = GETARRAYNUM(chr_CS_VTH);
set_chr_current = bmt_find_closest_level(chr_CS_VTH, array_size, *(DCL_UINT32 *)data);
register_value = bmt_parameter_to_value(chr_CS_VTH, array_size ,set_chr_current);
status = bmt_set_register_value(RG_CS_VTH_OFFSET,RG_CS_VTH_MASK,register_value<<RG_CS_VTH_SHIFT);
return status;
}
const DCL_UINT32 chr_CS_VTH[CS_VTH_SIZE]=
{
PMU_CHARGE_CURRENT_1600_00_MA, PMU_CHARGE_CURRENT_1500_00_MA,
PMU_CHARGE_CURRENT_1400_00_MA, PMU_CHARGE_CURRENT_1300_00_MA,
PMU_CHARGE_CURRENT_1200_00_MA, PMU_CHARGE_CURRENT_1100_00_MA,
PMU_CHARGE_CURRENT_1000_00_MA, PMU_CHARGE_CURRENT_900_00_MA,
PMU_CHARGE_CURRENT_800_00_MA, PMU_CHARGE_CURRENT_700_00_MA,
PMU_CHARGE_CURRENT_600_00_MA, PMU_CHARGE_CURRENT_500_00_MA,
PMU_CHARGE_CURRENT_400_00_MA, PMU_CHARGE_CURRENT_300_00_MA,
PMU_CHARGE_CURRENT_200_00_MA, PMU_CHARGE_CURRENT_70_00_MA
};
停充电流是在chr_parameter.h文件中通过如下宏设置的:
#define CHR_I_TOPOFF2FULL_THRES 120000
此值最小只能设置为60mA,否则充电电流会波动比较大。
电池检测
如果引脚BAT_ON>2.5V,充电器将立即关闭。 这个功能是用来阻止充电器的输入,以防止电线意外被取下。 在充电过程中,电池断开可能导致VBAT电压浪涌,在启动过压保护之前损坏芯片。
电池是否存在的检测接口函数是:
kal_bool bmt_is_bat_on()
{
if(bmt_charging_para->bmt_check_battery)
{
return bmt_is_bat_on_pw();
}
else
{
return bmt_check_if_bat_on();
}
}
首先要将chr_parameter.h文件中的宏CHR_CHECK_BATTERY设置为KAL_TRUE。
电池温度测量与过热保护
温度检测并不是实际去检测温度,而是实时检测BAT_ON引脚的电压而感知温度 BAT_ON Voltage = 2.8V*RNTC/(R1+RNTC) 当温度变化,RNTC变化,BAT_ON引脚电压变化,BB通过电压变化感知温度变化。
注意: 1.在不使用电池充电检测功能时,BAT_ON pin需下拉10K电阻到GND。 2.电路图中R2是为了防止不当的电池设置(BATID pin 直接接电池 GND,中间未加电阻,即没有RNTC)造成在插电池瞬间,可能产生的VRTC电压不稳定,需保留。 3.若电池温度检测功能未使用,请不要把BATID pin接到Base Band。
弹出充电完成提示后为什么ISENSE还有电流
充电完成的判断条件是在CV状态下检测到充电电流小于chr_parameter.h中的设定值:
#define CHR_I_TOPOFF2FULL_THRES 120000
从BMT转换图中可见当VBAT>4.05V时会跳转到CV状态,在CV状态下充电电流不断下降,当充电电流小于120mA时,充电状态跳转到CHR_BATFULL,Show Charger Complete,然后向上层发送充电完成消息BMT_CHARGE_COMPLETE,并启动30分钟定时器BMT_STOP_CHARGE_TIMER,接着会在CHR_BATFULL状态下继续涓流充电30分钟才完全切断充电流程。
static void BMT_CHRTOPOFF_OFF(BATPHYStruct *BATPHYS)
{
drv_trace0(TRACE_STATE, BMT_CHRTOPOFF_OFF_STATE_TRC);
if(bmt_get_chr_cv_det() || (BATPHYS->VBAT >= 4200000))
{
BATFULL_index++;
}
if(BATFULL_index == 6 )
{
// change state to post full
BMT.bat_state = CHR_POSTFULL;
drv_trace0(TRACE_GROUP_10, BMT_CHR_POSTFULL_CHANGE_TRC);
/*30min*/
bmt_set_timer(BMT_STOP_CHARGE_TIMER,STOPTIMER_TIMEOUT_TICK);
bmt_sendMes2UEM(BMT_CHARGE_COMPLETE);
bmt_timer_config(bmt_charging_para.BATPOSTFULL_TWAIT_LI*KAL_TICKS_1_SEC); //wait 90 seconds, then check the vbat at BMT_CHRBATFULL_OFF
BATFULL_index = 0; //reset the index, recount the percentage again.
return;
}
bmt_CtrlCharge((kal_uint8)KAL_TRUE);
bmt_timer_config(bmt_charging_para.TOPOFF_TON*CHARGING_TIME_UNIT);
}
定时器的设置是在:
#define STOPTIMER_TIMEOUT_TICK (KAL_TICKS_1_MIN*30)
有关Vcharger 能够识别的高压和低压值
// For V Charge check, turn on by CHR_CHECK_CHARGER_VOLTAGE = KAL_TRUE
#define CHR_VCHARGER_HW_HIGH PMU_VOLT_07_000000_V
#define CHR_VCHARGER_HIGH 6500000
#define CHR_VCHARGER_LOW 0
chr_parameter.h中的CHR_VCHARGER_HW_HIGH设置的是硬件检测的充电高压,CHR_VCHARGER_HIGH是软件检测的充电高压,CHR_VCHARGER_LOW 目前代码中没有实际用到,是在寄存器CHR_COO[11:8]RG_VCDT_LV_VTH中设置的(具体参考datasheet)。