From fc7b3924fd97a9017d8ae91e42b06a4d960e4877 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Wed, 23 Nov 2022 12:47:11 +0100 Subject: [PATCH 1/2] Nicla: tune PMIC charger --- libraries/Nicla_System/src/Nicla_System.cpp | 21 ++++++++++++++++++++- libraries/Nicla_System/src/Nicla_System.h | 2 ++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/libraries/Nicla_System/src/Nicla_System.cpp b/libraries/Nicla_System/src/Nicla_System.cpp index af2e461a2..98f3731df 100644 --- a/libraries/Nicla_System/src/Nicla_System.cpp +++ b/libraries/Nicla_System/src/Nicla_System.cpp @@ -106,16 +106,35 @@ uint8_t nicla::readLDOreg() bool nicla::enableCharge(uint8_t mA) { - digitalWrite(p25, LOW); if (mA < 35) { _chg_reg = ((mA-5) << 2); } else { _chg_reg = (((mA-40)/10) << 2) | 0x80; } _pmic.writeByte(BQ25120A_ADDRESS, BQ25120A_FAST_CHG, _chg_reg); + + // For very depleted batteries, set ULVO at the vary minimum to re-enable charging + _pmic.writeByte(BQ25120A_ADDRESS, BQ25120A_ILIM_UVLO_CTRL, 0x3F); + + // also set max battery voltage to 4.2V (VBREG) + // _pmic.writeByte(BQ25120A_ADDRESS, BQ25120A_BATTERY_CTRL, (4.2f - 3.6f)*100); + return _pmic.readByte(BQ25120A_ADDRESS, BQ25120A_FAST_CHG) == _chg_reg; } +uint8_t nicla::getFault() { + return _pmic.readByte(BQ25120A_ADDRESS, BQ25120A_FAULTS); +} + + +float nicla::getBetteryStatus() { + _pmic.writeByte(BQ25120A_ADDRESS, BQ25120A_BATT_MON, 1); + delay(2); + uint8_t data = _pmic.readByte(BQ25120A_ADDRESS, BQ25120A_BATT_MON); + float res = 0.6f + (data >> 5) * 0.1f + (data >> 2) * 0.02f - 0.01f; + return res; +} + void nicla::checkChgReg() { if (_chg_reg != _pmic.readByte(BQ25120A_ADDRESS, BQ25120A_FAST_CHG)) { diff --git a/libraries/Nicla_System/src/Nicla_System.h b/libraries/Nicla_System/src/Nicla_System.h index 688e91c38..19907ad70 100644 --- a/libraries/Nicla_System/src/Nicla_System.h +++ b/libraries/Nicla_System/src/Nicla_System.h @@ -20,6 +20,8 @@ class nicla { static bool enterShipMode(); static uint8_t readLDOreg(); static bool enableCharge(uint8_t mA = 20); + static float getBetteryStatus(); + static uint8_t getFault(); static RGBled leds; static BQ25120A _pmic; From d9732f9004c453ff9561dcfed9bc142d0b529fb1 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Thu, 1 Dec 2022 09:20:23 +0100 Subject: [PATCH 2/2] nicla: also disable NTC stopping charge via API --- libraries/Nicla_System/src/Nicla_System.cpp | 54 +++++++++++++++++---- libraries/Nicla_System/src/Nicla_System.h | 17 +++++-- 2 files changed, 59 insertions(+), 12 deletions(-) diff --git a/libraries/Nicla_System/src/Nicla_System.cpp b/libraries/Nicla_System/src/Nicla_System.cpp index 98f3731df..9939d0b86 100644 --- a/libraries/Nicla_System/src/Nicla_System.cpp +++ b/libraries/Nicla_System/src/Nicla_System.cpp @@ -104,34 +104,70 @@ uint8_t nicla::readLDOreg() return _pmic.readByte(BQ25120A_ADDRESS, BQ25120A_LDO_CTRL); } -bool nicla::enableCharge(uint8_t mA) +bool nicla::ntc_disabled; + +bool nicla::enableCharge(uint8_t mA, bool disable_ntc) { - if (mA < 35) { + if (mA < 5) { + _chg_reg = 0x3; + } else if (mA < 35) { _chg_reg = ((mA-5) << 2); } else { _chg_reg = (((mA-40)/10) << 2) | 0x80; } _pmic.writeByte(BQ25120A_ADDRESS, BQ25120A_FAST_CHG, _chg_reg); - // For very depleted batteries, set ULVO at the vary minimum to re-enable charging + // For very depleted batteries, set ULVO at the very minimum to re-enable charging _pmic.writeByte(BQ25120A_ADDRESS, BQ25120A_ILIM_UVLO_CTRL, 0x3F); + // Disable TS and interrupt on charge + ntc_disabled = disable_ntc; + if (ntc_disabled) { + _pmic.writeByte(BQ25120A_ADDRESS, BQ25120A_TS_CONTROL, 1 << 3); + } + // also set max battery voltage to 4.2V (VBREG) // _pmic.writeByte(BQ25120A_ADDRESS, BQ25120A_BATTERY_CTRL, (4.2f - 3.6f)*100); return _pmic.readByte(BQ25120A_ADDRESS, BQ25120A_FAST_CHG) == _chg_reg; } -uint8_t nicla::getFault() { - return _pmic.readByte(BQ25120A_ADDRESS, BQ25120A_FAULTS); +uint16_t nicla::getFault() { + uint16_t tmp = _pmic.readByte(BQ25120A_ADDRESS, BQ25120A_FAULTS) << 8; + tmp |= (_pmic.readByte(BQ25120A_ADDRESS, BQ25120A_TS_CONTROL) & 0x60); + return tmp; } - -float nicla::getBetteryStatus() { +int nicla::getBatteryStatus() { _pmic.writeByte(BQ25120A_ADDRESS, BQ25120A_BATT_MON, 1); - delay(2); + delay(3); uint8_t data = _pmic.readByte(BQ25120A_ADDRESS, BQ25120A_BATT_MON); - float res = 0.6f + (data >> 5) * 0.1f + (data >> 2) * 0.02f - 0.01f; + float percent = 0.6f + (data >> 5) * 0.1f + ((data >> 2) & 0x7) * 0.02f; + + int res = 0; + if (percent >= 0.98) { + res |= BATTERY_FULL; + } else if (percent >= 0.94){ + res |= BATTERY_ALMOST_FULL; + } else if (percent >= 0.90){ + res |= BATTERY_HALF; + } else if (percent >= 0.86){ + res |= BATTERY_ALMOST_EMPTY; + } else { + res |= BATTERY_EMPTY; + } + + if (!ntc_disabled) { + auto ts = ((_pmic.readByte(BQ25120A_ADDRESS, BQ25120A_TS_CONTROL) >> 5) & 0x3); + if (ts == 1) { + res |= BATTERY_COLD; + } else if (ts == 2) { + res |= BATTERY_COOL; + } else if (ts == 3) { + res |= BATTERY_HOT; + } + } + return res; } diff --git a/libraries/Nicla_System/src/Nicla_System.h b/libraries/Nicla_System/src/Nicla_System.h index 19907ad70..502efdf62 100644 --- a/libraries/Nicla_System/src/Nicla_System.h +++ b/libraries/Nicla_System/src/Nicla_System.h @@ -10,6 +10,16 @@ #define USE_FASTCHG_TO_KICK_WATCHDOG 1 +#define BATTERY_FULL 5 +#define BATTERY_ALMOST_FULL 4 +#define BATTERY_HALF 3 +#define BATTERY_ALMOST_EMPTY 2 +#define BATTERY_EMPTY 1 +#define BATTERY_COLD (1 << 4) +#define BATTERY_COOL (2 << 4) +#define BATTERY_HOT (3 << 4) +#define BATTERY_CHARGING (1 << 7) + class nicla { public: @@ -19,9 +29,10 @@ class nicla { static bool disableLDO(); static bool enterShipMode(); static uint8_t readLDOreg(); - static bool enableCharge(uint8_t mA = 20); - static float getBetteryStatus(); - static uint8_t getFault(); + static bool enableCharge(uint8_t mA = 20, bool disable_ntc = true); + static int getBatteryStatus(); + static uint16_t getFault(); + static bool ntc_disabled; static RGBled leds; static BQ25120A _pmic;