FIX only use BWM functions is BWM is seated

This commit is contained in:
Niel Nielsen
2026-08-24 17:57:50 +02:00
committed by Philippe Teuwen
parent a8ccbea2bc
commit fb3ec70aec
+30 -17
View File
@@ -122,6 +122,8 @@ static void BWM_ChargerKick(void) {
// confirm against a known-charging module before trusting absolute values. If the gauge
// or charger doesn't ACK, the corresponding lines print "not responding" rather than
// reporting garbage, so this is safe to ship even if an address is wrong on a given board.
static bool g_bwm_present = false;
#ifndef BWM_CHG_ADDR
#define BWM_CHG_ADDR 0x93
#endif
@@ -154,6 +156,9 @@ static bool bwm_gauge_read16(uint8_t cmd, uint16_t *out) {
// Reads the BWM charger + fuel gauge and prints a battery section. Called from
// SendStatus() under #ifdef PM5, so it only runs on a booted PM5 with I2C available.
static void print_pm5_battery_status(void) {
if (g_bwm_present == false) {
return; // no BWM detected at boot; nothing to report
}
DbpString(_CYAN_("Battery / BWM"));
I2C_init(true);
@@ -364,27 +369,32 @@ static bool bwm_gauge_provision_capacity(uint16_t cap_mah) {
// watchdog is thus relied upon off - see REG05 handling)
// REG03 = 0xE1 : 3 A discharge current
// REG0B = 0x6B : 11 mA pre-charge current
void UnitTestMain(void); // strong override of the weak stub in start.c
void UnitTestMain(void) {
StartTicks();
// Probe for the BWM charger over I2C and, if found, apply the charge configuration.
static void bwm_detect_and_init(void) {
I2C_init(true);
// Single bounded probe. Any non-ACK => no BWM fitted; skip everything.
uint8_t v = 0;
if (I2C_BufferReadRaw(&v, 1, 0x01, BWM_CHG_ADDR) > 0) {
if (v & (1u << 3)) { v &= ~(1u << 3); I2C_BufferWrite(&v, 1, 0x01, BWM_CHG_ADDR); }
if (I2C_BufferReadRaw(&v, 1, 0x01, BWM_CHG_ADDR) <= 0) {
g_bwm_present = false;
return;
}
// REG02: charge current = 256 mA
v = 0x1F;
I2C_BufferWrite(&v, 1, 0x02, BWM_CHG_ADDR);
// REG03: discharge current = 3 A
v = 0xE1;
I2C_BufferWrite(&v, 1, 0x03, BWM_CHG_ADDR);
// REG05: disable safety timer (upstream behaviour)
// v = 0x1A;
// I2C_BufferWrite(&v, 1, 0x05, BWM_CHG_ADDR);
// REG0B: pre-charge current = 11 mA
v = 0x6B;
I2C_BufferWrite(&v, 1, 0x0B, BWM_CHG_ADDR);
g_bwm_present = true;
// Enable charging (clear CEB, REG01[3]) + upstream charge profile
// (matches at32_unit_test.c:test_bat_charger_only_settings(), AW32001ECSR).
if (v & (1u << 3)) {
v &= ~(1u << 3);
I2C_BufferWrite(&v, 1, 0x01, BWM_CHG_ADDR);
}
uint8_t w;
w = 0x1F; I2C_BufferWrite(&w, 1, 0x02, BWM_CHG_ADDR); // charge current 256 mA
w = 0xE1; I2C_BufferWrite(&w, 1, 0x03, BWM_CHG_ADDR); // discharge current 3 A
w = 0x1A; I2C_BufferWrite(&w, 1, 0x05, BWM_CHG_ADDR); // safety timer disabled (upstream)
w = 0x6B; I2C_BufferWrite(&w, 1, 0x0B, BWM_CHG_ADDR); // pre-charge 11 mA
}
#endif // WITH_BWM_STATUS
#ifdef WITH_LCD
@@ -4052,6 +4062,9 @@ void __attribute__((noreturn)) AppMain(void) {
// (AT91F_CDC_Enumerate() will be called in the main loop)
usb_disable();
usb_enable();
#ifdef WITH_BWM_STATUS
bwm_detect_and_init(); // probe BWM + apply charge config, off the pre-USB path
#endif
#ifdef WITH_BWM_CHARGERKICK
BWM_ChargerKick();