1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-07-31 10:58:43 +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 // BUCKSTATUS register value
// (for debugging purposes, see the datasheet) // (for debugging purposes, see the datasheet)
uint8_t charge_status; uint8_t charge_status;
uint8_t charge_err;
uint8_t charge_sensor_err;
uint8_t buck_status; uint8_t buck_status;
uint8_t usb_status; uint8_t usb_status;
} pmic_report_t; } pmic_report_t;
@ -135,3 +137,6 @@ typedef enum {
// Set the buck voltage regulator mode // Set the buck voltage regulator mode
bool pmic_set_buck_mode(pmic_buck_mode_t buck_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_vbat2_result_msb;
uint8_t adc_ibat_meas_status; uint8_t adc_ibat_meas_status;
uint8_t charging_status; uint8_t charging_status;
uint8_t charging_err;
uint8_t charging_sensor_err;
uint8_t buck_status; uint8_t buck_status;
uint8_t usb_status; uint8_t usb_status;
} npm1300_adc_regs_t; } npm1300_adc_regs_t;
@ -706,6 +708,8 @@ static void npm1300_calculate_report(npm1300_driver_t* drv,
report->buck_status = r->buck_status; report->buck_status = r->buck_status;
report->usb_status = r->usb_status; report->usb_status = r->usb_status;
report->charge_status = r->charging_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 // 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_ADCVBAT2RESULTMSB, adc_regs.adc_vbat2_result_msb),
NPM_READ_FIELD(NPM1300_ADCIBATMEASSTATUS, adc_regs.adc_ibat_meas_status), NPM_READ_FIELD(NPM1300_ADCIBATMEASSTATUS, adc_regs.adc_ibat_meas_status),
NPM_READ_FIELD(NPM1300_BCHGCHARGESTATUS, adc_regs.charging_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_BUCKSTATUS, adc_regs.buck_status),
NPM_READ_FIELD(NPM1300_USBCDETECTSTATUS, adc_regs.usb_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), 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) \ #define npm1300_i2c_submit(drv, ops) \
_npm1300_i2c_submit(drv, ops, ARRAY_LENGTH(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. // npm1300 driver timer callback invoked when `drv->timer` expires.
// //
// This function is called in the irq context. // 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); 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) { if (drv->soc_target == 100) {
drv->soc_target_reached = false; drv->soc_target_reached = false;
} else { } else {
@ -212,9 +206,20 @@ void pm_charging_controller(pm_driver_t* drv) {
drv->i_chg_target_ma = 0; 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) { if (drv->i_chg_target_ma == 0) {
pmic_set_charging(false); pmic_set_charging(false);
} else { } 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); pmic_set_charging(true);
} }
} }