[FL-1268] Gauge re-calibration (#471)

* bq27220: add new battery profile parameters
* bq27220: add gauging configuration
* power: change poweroff condition depending on remain capacity
* api-hal-power: update api for f6 target
This commit is contained in:
gornekich 2021-05-18 17:59:16 +03:00 committed by GitHub
parent 6d648da003
commit df4a170213
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 113 additions and 52 deletions

View File

@ -206,7 +206,7 @@ int32_t power_task(void* p) {
model->temperature_gauge = model->temperature_gauge =
api_hal_power_get_battery_temperature(ApiHalPowerICFuelGauge); api_hal_power_get_battery_temperature(ApiHalPowerICFuelGauge);
if(model->voltage_gauge < 3.3f && model->voltage_vbus < 4.0f) { if(model->charge == 0 && model->voltage_vbus < 4.0f) {
battery_low = true; battery_low = true;
} }

View File

@ -24,26 +24,40 @@ static volatile ApiHalPower api_hal_power = {
}; };
const ParamCEDV cedv = { const ParamCEDV cedv = {
.cedv_conf.gauge_conf = {
.CCT = 1,
.CSYNC = 0,
.EDV_CMP = 0,
.SC = 1,
.FIXED_EDV0 = 1,
.FCC_LIM = 1,
.FC_FOR_VDQ = 1,
.IGNORE_SD = 1,
.SME0 = 0,
},
.full_charge_cap = 2100, .full_charge_cap = 2100,
.design_cap = 2100, .design_cap = 2100,
.EMF = 3739, .EDV0 = 3300,
.C0 = 776, .EDV1 = 3321,
.EDV2 = 3355,
.EMF = 3679,
.C0 = 430,
.C1 = 0, .C1 = 0,
.R1 = 193, .R1 = 408,
.R0 = 1, .R0 = 334,
.T0 = 1, .T0 = 4626,
.TC = 11, .TC = 11,
.DOD0 = 4044, .DOD0 = 4044,
.DOD10 = 3899, .DOD10 = 3905,
.DOD20 = 3796, .DOD20 = 3807,
.DOD30 = 3704, .DOD30 = 3718,
.DOD40 = 3627, .DOD40 = 3642,
.DOD50 = 3573, .DOD50 = 3585,
.DOD60 = 3535, .DOD60 = 3546,
.DOD70 = 3501, .DOD70 = 3514,
.DOD80 = 3453, .DOD80 = 3477,
.DOD90 = 3366, .DOD90 = 3411,
.DOD100 = 2419, .DOD100 = 3299,
}; };
void HAL_RCC_CSSCallback(void) { void HAL_RCC_CSSCallback(void) {

View File

@ -24,26 +24,40 @@ static volatile ApiHalPower api_hal_power = {
}; };
const ParamCEDV cedv = { const ParamCEDV cedv = {
.cedv_conf.gauge_conf = {
.CCT = 1,
.CSYNC = 0,
.EDV_CMP = 0,
.SC = 1,
.FIXED_EDV0 = 1,
.FCC_LIM = 1,
.FC_FOR_VDQ = 1,
.IGNORE_SD = 1,
.SME0 = 0,
},
.full_charge_cap = 2100, .full_charge_cap = 2100,
.design_cap = 2100, .design_cap = 2100,
.EMF = 3739, .EDV0 = 3300,
.C0 = 776, .EDV1 = 3321,
.EDV2 = 3355,
.EMF = 3679,
.C0 = 430,
.C1 = 0, .C1 = 0,
.R1 = 193, .R1 = 408,
.R0 = 1, .R0 = 334,
.T0 = 1, .T0 = 4626,
.TC = 11, .TC = 11,
.DOD0 = 4044, .DOD0 = 4044,
.DOD10 = 3899, .DOD10 = 3905,
.DOD20 = 3796, .DOD20 = 3807,
.DOD30 = 3704, .DOD30 = 3718,
.DOD40 = 3627, .DOD40 = 3642,
.DOD50 = 3573, .DOD50 = 3585,
.DOD60 = 3535, .DOD60 = 3546,
.DOD70 = 3501, .DOD70 = 3514,
.DOD80 = 3453, .DOD80 = 3477,
.DOD90 = 3366, .DOD90 = 3411,
.DOD100 = 2419, .DOD100 = 3299,
}; };
void HAL_RCC_CSSCallback(void) { void HAL_RCC_CSSCallback(void) {

View File

@ -53,6 +53,7 @@ bool bq27220_set_parameter_u16(uint16_t address, uint16_t value) {
buffer[4] = value & 0xFF; buffer[4] = value & 0xFF;
return api_hal_i2c_tx(POWER_I2C, BQ27220_ADDRESS, buffer, 5, BQ27220_I2C_TIMEOUT); return api_hal_i2c_tx(POWER_I2C, BQ27220_ADDRESS, buffer, 5, BQ27220_I2C_TIMEOUT);
}); });
delay_us(10000);
uint8_t checksum = bq27220_get_checksum(&buffer[1], 4); uint8_t checksum = bq27220_get_checksum(&buffer[1], 4);
with_api_hal_i2c( with_api_hal_i2c(
bool, &ret, () { bool, &ret, () {
@ -61,59 +62,61 @@ bool bq27220_set_parameter_u16(uint16_t address, uint16_t value) {
buffer[2] = 6; buffer[2] = 6;
return api_hal_i2c_tx(POWER_I2C, BQ27220_ADDRESS, buffer, 3, BQ27220_I2C_TIMEOUT); return api_hal_i2c_tx(POWER_I2C, BQ27220_ADDRESS, buffer, 3, BQ27220_I2C_TIMEOUT);
}); });
delay_us(10000);
return ret; return ret;
} }
bool bq27220_init(const ParamCEDV* cedv) { bool bq27220_init(const ParamCEDV* cedv) {
uint32_t timeout = 100; uint32_t timeout = 100;
uint16_t design_cap = bq27220_get_design_capacity();
if(cedv->design_cap == design_cap) {
FURI_LOG_I("gauge", "Skip battery profile update");
return true;
}
FURI_LOG_I("gauge", "Start updating battery profile");
OperationStatus status = {}; OperationStatus status = {};
if(!bq27220_control(Control_ENTER_CFG_UPDATE)) { if(!bq27220_control(Control_ENTER_CFG_UPDATE)) {
FURI_LOG_E("gauge", "Can't configure update");
return false; return false;
}; };
while((status.CFGUPDATE != 1) && (timeout-- > 0)) { while((status.CFGUPDATE != 1) && (timeout-- > 0)) {
bq27220_get_operation_status(&status); bq27220_get_operation_status(&status);
} }
bq27220_set_parameter_u16(AddressGaugingConfig, cedv->cedv_conf.gauge_conf_raw);
bq27220_set_parameter_u16(AddressFullChargeCapacity, cedv->full_charge_cap); bq27220_set_parameter_u16(AddressFullChargeCapacity, cedv->full_charge_cap);
delay_us(15000);
bq27220_set_parameter_u16(AddressDesignCapacity, cedv->design_cap); bq27220_set_parameter_u16(AddressDesignCapacity, cedv->design_cap);
delay_us(15000);
bq27220_set_parameter_u16(AddressEMF, cedv->EMF); bq27220_set_parameter_u16(AddressEMF, cedv->EMF);
delay_us(15000);
bq27220_set_parameter_u16(AddressC0, cedv->C0); bq27220_set_parameter_u16(AddressC0, cedv->C0);
delay_us(15000);
bq27220_set_parameter_u16(AddressR0, cedv->R0); bq27220_set_parameter_u16(AddressR0, cedv->R0);
delay_us(15000);
bq27220_set_parameter_u16(AddressT0, cedv->T0); bq27220_set_parameter_u16(AddressT0, cedv->T0);
delay_us(15000);
bq27220_set_parameter_u16(AddressR1, cedv->R1); bq27220_set_parameter_u16(AddressR1, cedv->R1);
delay_us(15000);
bq27220_set_parameter_u16(AddressTC, (cedv->TC) << 8 | cedv->C1); bq27220_set_parameter_u16(AddressTC, (cedv->TC) << 8 | cedv->C1);
delay_us(15000);
bq27220_set_parameter_u16(AddressStartDOD0, cedv->DOD0); bq27220_set_parameter_u16(AddressStartDOD0, cedv->DOD0);
delay_us(15000);
bq27220_set_parameter_u16(AddressStartDOD10, cedv->DOD10); bq27220_set_parameter_u16(AddressStartDOD10, cedv->DOD10);
delay_us(15000);
bq27220_set_parameter_u16(AddressStartDOD20, cedv->DOD20); bq27220_set_parameter_u16(AddressStartDOD20, cedv->DOD20);
delay_us(15000);
bq27220_set_parameter_u16(AddressStartDOD30, cedv->DOD30); bq27220_set_parameter_u16(AddressStartDOD30, cedv->DOD30);
delay_us(15000);
bq27220_set_parameter_u16(AddressStartDOD40, cedv->DOD40); bq27220_set_parameter_u16(AddressStartDOD40, cedv->DOD40);
delay_us(15000);
bq27220_set_parameter_u16(AddressStartDOD50, cedv->DOD40); bq27220_set_parameter_u16(AddressStartDOD50, cedv->DOD40);
delay_us(15000);
bq27220_set_parameter_u16(AddressStartDOD60, cedv->DOD60); bq27220_set_parameter_u16(AddressStartDOD60, cedv->DOD60);
delay_us(15000);
bq27220_set_parameter_u16(AddressStartDOD70, cedv->DOD70); bq27220_set_parameter_u16(AddressStartDOD70, cedv->DOD70);
delay_us(15000);
bq27220_set_parameter_u16(AddressStartDOD80, cedv->DOD80); bq27220_set_parameter_u16(AddressStartDOD80, cedv->DOD80);
delay_us(15000);
bq27220_set_parameter_u16(AddressStartDOD90, cedv->DOD90); bq27220_set_parameter_u16(AddressStartDOD90, cedv->DOD90);
delay_us(15000);
bq27220_set_parameter_u16(AddressStartDOD100, cedv->DOD100); bq27220_set_parameter_u16(AddressStartDOD100, cedv->DOD100);
delay_us(15000); bq27220_set_parameter_u16(AddressEDV0, cedv->EDV0);
bq27220_set_parameter_u16(AddressEDV1, cedv->EDV1);
bq27220_set_parameter_u16(AddressEDV2, cedv->EDV2);
bq27220_control(Control_EXIT_CFG_UPDATE); bq27220_control(Control_EXIT_CFG_UPDATE);
delay_us(10000);
design_cap = bq27220_get_design_capacity();
if(cedv->design_cap == design_cap) {
FURI_LOG_I("gauge", "Battery profile update success");
return true; return true;
} else {
FURI_LOG_E("gauge", "Battery profile update failed");
return false;
}
} }
uint16_t bq27220_get_voltage() { uint16_t bq27220_get_voltage() {

View File

@ -44,8 +44,34 @@ typedef struct {
} OperationStatus; } OperationStatus;
typedef struct { typedef struct {
// Low byte, Low bit first
bool CCT : 1;
bool CSYNC : 1;
bool RSVD0 : 1;
bool EDV_CMP : 1;
bool SC : 1;
bool FIXED_EDV0 : 1;
uint8_t RSVD1 : 2;
// High byte, Low bit first
bool FCC_LIM : 1;
bool RSVD2 : 1;
bool FC_FOR_VDQ : 1;
bool IGNORE_SD : 1;
bool SME0 : 1;
uint8_t RSVD3 : 3;
} GaugingConfig;
typedef struct {
union {
GaugingConfig gauge_conf;
uint16_t gauge_conf_raw;
} cedv_conf;
uint16_t full_charge_cap; uint16_t full_charge_cap;
uint16_t design_cap; uint16_t design_cap;
uint16_t EDV0;
uint16_t EDV1;
uint16_t EDV2;
uint16_t EMF; uint16_t EMF;
uint16_t C0; uint16_t C0;
uint16_t R0; uint16_t R0;

View File

@ -67,6 +67,7 @@
#define Control_EXIT_CFG_UPDATE 0x0092 #define Control_EXIT_CFG_UPDATE 0x0092
#define Control_RETURN_TO_ROM 0x0F00 #define Control_RETURN_TO_ROM 0x0F00
#define AddressGaugingConfig 0x929B
#define AddressFullChargeCapacity 0x929D #define AddressFullChargeCapacity 0x929D
#define AddressDesignCapacity 0x929F #define AddressDesignCapacity 0x929F
#define AddressEMF 0x92A3 #define AddressEMF 0x92A3
@ -75,7 +76,10 @@
#define AddressT0 0x92AD #define AddressT0 0x92AD
#define AddressR1 0x92AF #define AddressR1 0x92AF
#define AddressTC 0x92B1 #define AddressTC 0x92B1
#define AddressC1 0x92B1 #define AddressC1 0x92B2
#define AddressEDV0 0x92B4
#define AddressEDV1 0x92B7
#define AddressEDV2 0x92BA
#define AddressStartDOD0 0x92BD #define AddressStartDOD0 0x92BD
#define AddressStartDOD10 0x92BF #define AddressStartDOD10 0x92BF
#define AddressStartDOD20 0x92C1 #define AddressStartDOD20 0x92C1