1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-07-29 09:58:47 +00:00

feat(core): add battery reincarnation into pm charging controller

[no changelog]
This commit is contained in:
kopecdav 2025-07-22 14:00:57 +02:00 committed by kopecdav
parent 42f27aa7fb
commit 2dd30b89f7
3 changed files with 42 additions and 6 deletions

View File

@ -47,6 +47,8 @@ typedef struct {
// BUCKSTATUS register value
// (for debugging purposes, see the datasheet)
uint8_t charge_status;
uint8_t charge_err;
uint8_t charge_sensor_err;
uint8_t buck_status;
uint8_t usb_status;
} pmic_report_t;
@ -135,3 +137,6 @@ typedef enum {
// Set the buck voltage regulator mode
bool pmic_set_buck_mode(pmic_buck_mode_t buck_mode);
// Clears all battery charger errors.
bool pmic_clear_charger_errors(void);

View File

@ -68,6 +68,8 @@ typedef struct {
uint8_t adc_vbat2_result_msb;
uint8_t adc_ibat_meas_status;
uint8_t charging_status;
uint8_t charging_err;
uint8_t charging_sensor_err;
uint8_t buck_status;
uint8_t usb_status;
} npm1300_adc_regs_t;
@ -706,6 +708,8 @@ static void npm1300_calculate_report(npm1300_driver_t* drv,
report->buck_status = r->buck_status;
report->usb_status = r->usb_status;
report->charge_status = r->charging_status;
report->charge_err = r->charging_err;
report->charge_sensor_err = r->charging_sensor_err;
}
// I2C operation for writing constant value to the npm1300 register
@ -805,6 +809,8 @@ static const i2c_op_t npm1300_ops_adc_readout[] = {
NPM_READ_FIELD(NPM1300_ADCVBAT2RESULTMSB, adc_regs.adc_vbat2_result_msb),
NPM_READ_FIELD(NPM1300_ADCIBATMEASSTATUS, adc_regs.adc_ibat_meas_status),
NPM_READ_FIELD(NPM1300_BCHGCHARGESTATUS, adc_regs.charging_status),
NPM_READ_FIELD(NPM1300_BCHGERRREASON, adc_regs.charging_err),
NPM_READ_FIELD(NPM1300_BCHGERRSENSOR, adc_regs.charging_sensor_err),
NPM_READ_FIELD(NPM1300_BUCKSTATUS, adc_regs.buck_status),
NPM_READ_FIELD(NPM1300_USBCDETECTSTATUS, adc_regs.usb_status),
};
@ -815,6 +821,12 @@ static const i2c_op_t npm1300_ops_clear_events[] = {
NPM_WRITE_CONST(NPM1300_EVENTSVBUSIN0CLR, 0x3F),
};
// Clear charger errors and release charging from error state
static const i2c_op_t npm1300_ops_clear_charger_errors[] = {
NPM_WRITE_CONST(NPM1300_TASKCLEARCHGERR, 1),
NPM_WRITE_CONST(NPM1300_TASKRELEASEERR, 1),
};
#define npm1300_i2c_submit(drv, ops) \
_npm1300_i2c_submit(drv, ops, ARRAY_LENGTH(ops))
@ -839,6 +851,20 @@ static void _npm1300_i2c_submit(npm1300_driver_t* drv, const i2c_op_t* ops,
}
}
bool pmic_clear_charger_errors(void) {
npm1300_driver_t* drv = &g_npm1300_driver;
if (!drv->initialized) {
return false;
}
irq_key_t irq_key = irq_lock();
npm1300_i2c_submit(drv, npm1300_ops_clear_charger_errors);
irq_unlock(irq_key);
return true;
}
// npm1300 driver timer callback invoked when `drv->timer` expires.
//
// This function is called in the irq context.

View File

@ -176,12 +176,6 @@ void pm_charging_controller(pm_driver_t* drv) {
pm_temperature_controller(drv);
// Set charging target
if (drv->i_chg_target_ma != pmic_get_charging_limit()) {
// Set charging current limit
pmic_set_charging_limit(drv->i_chg_target_ma);
}
if (drv->soc_target == 100) {
drv->soc_target_reached = false;
} else {
@ -212,9 +206,20 @@ void pm_charging_controller(pm_driver_t* drv) {
drv->i_chg_target_ma = 0;
}
// Set charging target
if (drv->i_chg_target_ma != pmic_get_charging_limit()) {
// Set charging current limit
pmic_set_charging_limit(drv->i_chg_target_ma);
}
if (drv->i_chg_target_ma == 0) {
pmic_set_charging(false);
} else {
// Clear and release charger if it has any errors
if (drv->pmic_data.charge_err || drv->pmic_data.charge_sensor_err) {
pmic_clear_charger_errors();
}
pmic_set_charging(true);
}
}