[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:
		
							parent
							
								
									6d648da003
								
							
						
					
					
						commit
						df4a170213
					
				| @ -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); | ||||||
|  |     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() { | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 gornekich
						gornekich