[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:
		@@ -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;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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);
 | 
				
			||||||
    return true;
 | 
					    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;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        FURI_LOG_E("gauge", "Battery profile update failed");
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint16_t bq27220_get_voltage() {
 | 
					uint16_t bq27220_get_voltage() {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user