Add advanced register control functions (REG0x17-0x1A)

- REG0x17: Add reset(), thermal regulation, converter frequency, and VBUS overvoltage functions
- REG0x18: Add BATFET control functions
- REG0x19: Add peak discharge current, VBAT UVLO, and charge rate functions
- REG0x1A: Add thermistor control functions (ignore, cool/warm current settings)
- Add comprehensive test coverage with enum switch statements in example sketch
- All functions tested with hardware showing correct default values

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Limor Fried 2025-08-10 00:05:30 -04:00
parent 77c4d0c4b3
commit 046a1293ff
3 changed files with 490 additions and 0 deletions

View file

@ -686,4 +686,270 @@ bq25628e_watchdog_t Adafruit_BQ25628E::getWatchdog() {
Adafruit_BusIO_RegisterBits watchdog_bits = Adafruit_BusIO_RegisterBits(&charger_control_reg, 2, 0);
return (bq25628e_watchdog_t)watchdog_bits.read();
}
/*!
* @brief Resets registers to default values and resets timer
* @return True if successful, otherwise false.
*/
bool Adafruit_BQ25628E::reset() {
Adafruit_BusIO_Register charger_control_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_CHARGER_CONTROL_1, 1);
Adafruit_BusIO_RegisterBits reg_rst_bit = Adafruit_BusIO_RegisterBits(&charger_control_reg, 1, 7);
// Set reset bit
if (!reg_rst_bit.write(1)) {
return false;
}
// Wait for bit to clear (indicates reset complete)
uint32_t timeout = millis() + 1000; // 1 second timeout
while (millis() < timeout) {
if (reg_rst_bit.read() == 0) {
return true; // Reset completed
}
delay(1);
}
return false; // Timeout - reset may have failed
}
/*!
* @brief Sets thermal regulation threshold
* @param temp_120c
* True for 120°C threshold, false for 60°C threshold
* @return True if successful, otherwise false.
*/
bool Adafruit_BQ25628E::setThermalRegulation(bool temp_120c) {
Adafruit_BusIO_Register charger_control_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_CHARGER_CONTROL_1, 1);
Adafruit_BusIO_RegisterBits treg_bit = Adafruit_BusIO_RegisterBits(&charger_control_reg, 1, 6);
return treg_bit.write(temp_120c ? 1 : 0);
}
/*!
* @brief Gets thermal regulation threshold setting
* @return True if 120°C threshold, false if 60°C threshold
*/
bool Adafruit_BQ25628E::getThermalRegulation() {
Adafruit_BusIO_Register charger_control_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_CHARGER_CONTROL_1, 1);
Adafruit_BusIO_RegisterBits treg_bit = Adafruit_BusIO_RegisterBits(&charger_control_reg, 1, 6);
return treg_bit.read() == 1;
}
/*!
* @brief Sets converter switching frequency
* @param frequency
* Frequency setting from bq25628e_conv_freq_t enum
* @return True if successful, otherwise false.
*/
bool Adafruit_BQ25628E::setConverterFrequency(bq25628e_conv_freq_t frequency) {
Adafruit_BusIO_Register charger_control_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_CHARGER_CONTROL_1, 1);
Adafruit_BusIO_RegisterBits conv_freq_bits = Adafruit_BusIO_RegisterBits(&charger_control_reg, 2, 4);
return conv_freq_bits.write((uint8_t)frequency);
}
/*!
* @brief Gets converter switching frequency setting
* @return Current frequency setting
*/
bq25628e_conv_freq_t Adafruit_BQ25628E::getConverterFrequency() {
Adafruit_BusIO_Register charger_control_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_CHARGER_CONTROL_1, 1);
Adafruit_BusIO_RegisterBits conv_freq_bits = Adafruit_BusIO_RegisterBits(&charger_control_reg, 2, 4);
return (bq25628e_conv_freq_t)conv_freq_bits.read();
}
/*!
* @brief Sets VBUS overvoltage protection threshold
* @param high_threshold
* True for 18.5V threshold, false for 6.3V threshold
* @return True if successful, otherwise false.
*/
bool Adafruit_BQ25628E::setVBUSOvervoltage(bool high_threshold) {
Adafruit_BusIO_Register charger_control_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_CHARGER_CONTROL_1, 1);
Adafruit_BusIO_RegisterBits vbus_ovp_bit = Adafruit_BusIO_RegisterBits(&charger_control_reg, 1, 0);
return vbus_ovp_bit.write(high_threshold ? 1 : 0);
}
/*!
* @brief Gets VBUS overvoltage protection threshold setting
* @return True if 18.5V threshold, false if 6.3V threshold
*/
bool Adafruit_BQ25628E::getVBUSOvervoltage() {
Adafruit_BusIO_Register charger_control_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_CHARGER_CONTROL_1, 1);
Adafruit_BusIO_RegisterBits vbus_ovp_bit = Adafruit_BusIO_RegisterBits(&charger_control_reg, 1, 0);
return vbus_ovp_bit.read() == 1;
}
/*!
* @brief Sets BATFET control mode
* @param control
* BATFET control setting from bq25628e_batfet_ctrl_t enum
* @return True if successful, otherwise false.
*/
bool Adafruit_BQ25628E::setBATFETcontrol(bq25628e_batfet_ctrl_t control) {
Adafruit_BusIO_Register charger_control_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_CHARGER_CONTROL_2, 1);
Adafruit_BusIO_RegisterBits batfet_ctrl_bits = Adafruit_BusIO_RegisterBits(&charger_control_reg, 2, 0);
return batfet_ctrl_bits.write((uint8_t)control);
}
/*!
* @brief Gets BATFET control mode setting
* @return Current BATFET control setting
*/
bq25628e_batfet_ctrl_t Adafruit_BQ25628E::getBATFETcontrol() {
Adafruit_BusIO_Register charger_control_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_CHARGER_CONTROL_2, 1);
Adafruit_BusIO_RegisterBits batfet_ctrl_bits = Adafruit_BusIO_RegisterBits(&charger_control_reg, 2, 0);
return (bq25628e_batfet_ctrl_t)batfet_ctrl_bits.read();
}
/*!
* @brief Sets battery discharge peak current protection
* @param peak_12a
* True for 12A peak current, false for 6A peak current
* @return True if successful, otherwise false.
*/
bool Adafruit_BQ25628E::setPeakBattDischarge(bool peak_12a) {
Adafruit_BusIO_Register charger_control_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_CHARGER_CONTROL_3, 1);
Adafruit_BusIO_RegisterBits ibat_pk_bits = Adafruit_BusIO_RegisterBits(&charger_control_reg, 2, 6);
return ibat_pk_bits.write(peak_12a ? 0b11 : 0b10);
}
/*!
* @brief Gets battery discharge peak current protection setting
* @return True if 12A peak current, false if 6A peak current
*/
bool Adafruit_BQ25628E::getPeakBattDischarge() {
Adafruit_BusIO_Register charger_control_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_CHARGER_CONTROL_3, 1);
Adafruit_BusIO_RegisterBits ibat_pk_bits = Adafruit_BusIO_RegisterBits(&charger_control_reg, 2, 6);
uint8_t value = ibat_pk_bits.read();
return (value == 0b11); // 11b = 12A, 10b = 6A
}
/*!
* @brief Sets VBAT UVLO threshold
* @param low_threshold
* True for 1.8V UVLO/1.85V SHORT, false for 2.2V UVLO/2.05V SHORT
* @return True if successful, otherwise false.
*/
bool Adafruit_BQ25628E::setVBatUVLO(bool low_threshold) {
Adafruit_BusIO_Register charger_control_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_CHARGER_CONTROL_3, 1);
Adafruit_BusIO_RegisterBits vbat_uvlo_bit = Adafruit_BusIO_RegisterBits(&charger_control_reg, 1, 5);
return vbat_uvlo_bit.write(low_threshold ? 1 : 0);
}
/*!
* @brief Gets VBAT UVLO threshold setting
* @return True if 1.8V UVLO/1.85V SHORT, false if 2.2V UVLO/2.05V SHORT
*/
bool Adafruit_BQ25628E::getVBatUVLO() {
Adafruit_BusIO_Register charger_control_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_CHARGER_CONTROL_3, 1);
Adafruit_BusIO_RegisterBits vbat_uvlo_bit = Adafruit_BusIO_RegisterBits(&charger_control_reg, 1, 5);
return vbat_uvlo_bit.read() == 1;
}
/*!
* @brief Sets charge rate for fast charge stage
* @param rate
* Charge rate setting from bq25628e_charge_rate_t enum
* @return True if successful, otherwise false.
*/
bool Adafruit_BQ25628E::setChargeRate(bq25628e_charge_rate_t rate) {
Adafruit_BusIO_Register charger_control_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_CHARGER_CONTROL_3, 1);
Adafruit_BusIO_RegisterBits chg_rate_bits = Adafruit_BusIO_RegisterBits(&charger_control_reg, 2, 0);
return chg_rate_bits.write((uint8_t)rate);
}
/*!
* @brief Gets charge rate setting
* @return Current charge rate setting
*/
bq25628e_charge_rate_t Adafruit_BQ25628E::getChargeRate() {
Adafruit_BusIO_Register charger_control_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_CHARGER_CONTROL_3, 1);
Adafruit_BusIO_RegisterBits chg_rate_bits = Adafruit_BusIO_RegisterBits(&charger_control_reg, 2, 0);
return (bq25628e_charge_rate_t)chg_rate_bits.read();
}
/*!
* @brief Sets thermistor feedback ignore
* @param ignore
* True to ignore TS feedback, false to use TS feedback
* @return True if successful, otherwise false.
*/
bool Adafruit_BQ25628E::setIgnoreThermistor(bool ignore) {
Adafruit_BusIO_Register ntc_control_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_NTC_CONTROL_0, 1);
Adafruit_BusIO_RegisterBits ts_ignore_bit = Adafruit_BusIO_RegisterBits(&ntc_control_reg, 1, 7);
return ts_ignore_bit.write(ignore ? 1 : 0);
}
/*!
* @brief Gets thermistor feedback ignore setting
* @return True if TS feedback ignored, false if TS feedback used
*/
bool Adafruit_BQ25628E::getIgnoreThermistor() {
Adafruit_BusIO_Register ntc_control_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_NTC_CONTROL_0, 1);
Adafruit_BusIO_RegisterBits ts_ignore_bit = Adafruit_BusIO_RegisterBits(&ntc_control_reg, 1, 7);
return ts_ignore_bit.read() == 1;
}
/*!
* @brief Sets thermistor cool zone current setting
* @param setting
* Current setting from bq25628e_therm_curr_t enum
* @return True if successful, otherwise false.
*/
bool Adafruit_BQ25628E::setCoolThermistorCurrent(bq25628e_therm_curr_t setting) {
Adafruit_BusIO_Register ntc_control_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_NTC_CONTROL_0, 1);
Adafruit_BusIO_RegisterBits ts_iset_cool_bits = Adafruit_BusIO_RegisterBits(&ntc_control_reg, 2, 0);
return ts_iset_cool_bits.write((uint8_t)setting);
}
/*!
* @brief Gets thermistor cool zone current setting
* @return Current cool zone setting
*/
bq25628e_therm_curr_t Adafruit_BQ25628E::getCoolThermistorCurrent() {
Adafruit_BusIO_Register ntc_control_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_NTC_CONTROL_0, 1);
Adafruit_BusIO_RegisterBits ts_iset_cool_bits = Adafruit_BusIO_RegisterBits(&ntc_control_reg, 2, 0);
return (bq25628e_therm_curr_t)ts_iset_cool_bits.read();
}
/*!
* @brief Sets thermistor warm zone current setting
* @param setting
* Current setting from bq25628e_therm_curr_t enum
* @return True if successful, otherwise false.
*/
bool Adafruit_BQ25628E::setWarmThermistorCurrent(bq25628e_therm_curr_t setting) {
Adafruit_BusIO_Register ntc_control_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_NTC_CONTROL_0, 1);
Adafruit_BusIO_RegisterBits ts_iset_warm_bits = Adafruit_BusIO_RegisterBits(&ntc_control_reg, 2, 2);
return ts_iset_warm_bits.write((uint8_t)setting);
}
/*!
* @brief Gets thermistor warm zone current setting
* @return Current warm zone setting
*/
bq25628e_therm_curr_t Adafruit_BQ25628E::getWarmThermistorCurrent() {
Adafruit_BusIO_Register ntc_control_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_NTC_CONTROL_0, 1);
Adafruit_BusIO_RegisterBits ts_iset_warm_bits = Adafruit_BusIO_RegisterBits(&ntc_control_reg, 2, 2);
return (bq25628e_therm_curr_t)ts_iset_warm_bits.read();
}

View file

@ -38,6 +38,46 @@ typedef enum {
BQ25628E_WATCHDOG_200S = 0b11 /*!< 200 second watchdog */
} bq25628e_watchdog_t;
/*!
* @brief Converter switching frequency settings
*/
typedef enum {
BQ25628E_CONV_FREQ_1500KHZ = 0b00, /*!< 1.5 MHz nominal */
BQ25628E_CONV_FREQ_1350KHZ = 0b01, /*!< 1.35 MHz (-10%) */
BQ25628E_CONV_FREQ_1650KHZ = 0b10, /*!< 1.65 MHz (+10%) */
BQ25628E_CONV_FREQ_RESERVED = 0b11 /*!< Reserved */
} bq25628e_conv_freq_t;
/*!
* @brief BATFET control settings
*/
typedef enum {
BQ25628E_BATFET_NORMAL = 0b00, /*!< Normal operation */
BQ25628E_BATFET_SHUTDOWN = 0b01, /*!< Shutdown mode */
BQ25628E_BATFET_SHIP = 0b10, /*!< Ship mode */
BQ25628E_BATFET_RESET = 0b11 /*!< System power reset */
} bq25628e_batfet_ctrl_t;
/*!
* @brief Charge rate settings
*/
typedef enum {
BQ25628E_CHARGE_RATE_1C = 0b00, /*!< 1C charge rate */
BQ25628E_CHARGE_RATE_2C = 0b01, /*!< 2C charge rate */
BQ25628E_CHARGE_RATE_4C = 0b10, /*!< 4C charge rate */
BQ25628E_CHARGE_RATE_6C = 0b11 /*!< 6C charge rate */
} bq25628e_charge_rate_t;
/*!
* @brief Thermistor current settings for cool/warm zones
*/
typedef enum {
BQ25628E_THERM_CURR_SUSPEND = 0b00, /*!< Charge suspended */
BQ25628E_THERM_CURR_20PCT = 0b01, /*!< Set ICHG to 20% */
BQ25628E_THERM_CURR_40PCT = 0b10, /*!< Set ICHG to 40% */
BQ25628E_THERM_CURR_UNCHANGED = 0b11 /*!< ICHG unchanged */
} bq25628e_therm_curr_t;
/*! Register addresses for the BQ25628E */
#define BQ25628E_REG_CHARGE_CURRENT_LIMIT 0x02
#define BQ25628E_REG_CHARGE_VOLTAGE_LIMIT 0x04
@ -145,6 +185,38 @@ public:
bool setWatchdog(bq25628e_watchdog_t setting);
bq25628e_watchdog_t getWatchdog();
bool reset();
bool setThermalRegulation(bool temp_120c);
bool getThermalRegulation();
bool setConverterFrequency(bq25628e_conv_freq_t frequency);
bq25628e_conv_freq_t getConverterFrequency();
bool setVBUSOvervoltage(bool high_threshold);
bool getVBUSOvervoltage();
bool setBATFETcontrol(bq25628e_batfet_ctrl_t control);
bq25628e_batfet_ctrl_t getBATFETcontrol();
bool setPeakBattDischarge(bool peak_12a);
bool getPeakBattDischarge();
bool setVBatUVLO(bool low_threshold);
bool getVBatUVLO();
bool setChargeRate(bq25628e_charge_rate_t rate);
bq25628e_charge_rate_t getChargeRate();
bool setIgnoreThermistor(bool ignore);
bool getIgnoreThermistor();
bool setCoolThermistorCurrent(bq25628e_therm_curr_t setting);
bq25628e_therm_curr_t getCoolThermistorCurrent();
bool setWarmThermistorCurrent(bq25628e_therm_curr_t setting);
bq25628e_therm_curr_t getWarmThermistorCurrent();
private:
Adafruit_I2CDevice *i2c_dev; /*!< Pointer to I2C bus interface */
};

View file

@ -25,6 +25,13 @@ void setup() {
Serial.println(F("BQ25628E Found!"));
// Reset chip to default values
if (bq.reset()) {
Serial.println(F("Reset successful"));
} else {
Serial.println(F("Reset failed"));
}
// Uncomment to set charge current limit to 1.0A
// bq.setChargeCurrentLimitA(1.0);
@ -200,6 +207,151 @@ void setup() {
break;
}
// Uncomment to set thermal regulation to 60°C
// bq.setThermalRegulation(false);
// Test thermal regulation setting
bool thermal_120c = bq.getThermalRegulation();
Serial.print(F("Thermal regulation: "));
Serial.println(thermal_120c ? F("120°C") : F("60°C"));
// Uncomment to set converter frequency to 1.35MHz
// bq.setConverterFrequency(BQ25628E_CONV_FREQ_1350KHZ);
// Test converter frequency setting
bq25628e_conv_freq_t conv_freq = bq.getConverterFrequency();
Serial.print(F("Converter frequency: "));
switch (conv_freq) {
case BQ25628E_CONV_FREQ_1500KHZ:
Serial.println(F("1.5MHz"));
break;
case BQ25628E_CONV_FREQ_1350KHZ:
Serial.println(F("1.35MHz"));
break;
case BQ25628E_CONV_FREQ_1650KHZ:
Serial.println(F("1.65MHz"));
break;
case BQ25628E_CONV_FREQ_RESERVED:
Serial.println(F("Reserved"));
break;
}
// Uncomment to set VBUS OVP to 6.3V
// bq.setVBUSOvervoltage(false);
// Test VBUS overvoltage setting
bool vbus_high_ovp = bq.getVBUSOvervoltage();
Serial.print(F("VBUS OVP threshold: "));
Serial.println(vbus_high_ovp ? F("18.5V") : F("6.3V"));
// Uncomment to set BATFET to ship mode (WARNING: will disconnect battery)
// bq.setBATFETcontrol(BQ25628E_BATFET_SHIP);
// Test BATFET control setting
bq25628e_batfet_ctrl_t batfet_ctrl = bq.getBATFETcontrol();
Serial.print(F("BATFET control: "));
switch (batfet_ctrl) {
case BQ25628E_BATFET_NORMAL:
Serial.println(F("Normal"));
break;
case BQ25628E_BATFET_SHUTDOWN:
Serial.println(F("Shutdown"));
break;
case BQ25628E_BATFET_SHIP:
Serial.println(F("Ship"));
break;
case BQ25628E_BATFET_RESET:
Serial.println(F("Reset"));
break;
}
// Uncomment to set peak discharge current to 6A
// bq.setPeakBattDischarge(false);
// Test peak battery discharge setting
bool peak_12a = bq.getPeakBattDischarge();
Serial.print(F("Peak discharge current: "));
Serial.println(peak_12a ? F("12A") : F("6A"));
// Uncomment to set VBAT UVLO to 1.8V threshold
// bq.setVBatUVLO(true);
// Test VBAT UVLO setting
bool vbat_uvlo_low = bq.getVBatUVLO();
Serial.print(F("VBAT UVLO threshold: "));
Serial.println(vbat_uvlo_low ? F("1.8V") : F("2.2V"));
// Uncomment to set charge rate to 2C
// bq.setChargeRate(BQ25628E_CHARGE_RATE_2C);
// Test charge rate setting
bq25628e_charge_rate_t charge_rate = bq.getChargeRate();
Serial.print(F("Charge rate: "));
switch (charge_rate) {
case BQ25628E_CHARGE_RATE_1C:
Serial.println(F("1C"));
break;
case BQ25628E_CHARGE_RATE_2C:
Serial.println(F("2C"));
break;
case BQ25628E_CHARGE_RATE_4C:
Serial.println(F("4C"));
break;
case BQ25628E_CHARGE_RATE_6C:
Serial.println(F("6C"));
break;
}
// Uncomment to ignore thermistor
// bq.setIgnoreThermistor(true);
// Test thermistor ignore setting
bool ignore_thermistor = bq.getIgnoreThermistor();
Serial.print(F("Ignore thermistor: "));
Serial.println(ignore_thermistor ? F("true") : F("false"));
// Uncomment to set cool thermistor current to 40%
// bq.setCoolThermistorCurrent(BQ25628E_THERM_CURR_40PCT);
// Test cool thermistor current setting
bq25628e_therm_curr_t cool_current = bq.getCoolThermistorCurrent();
Serial.print(F("Cool thermistor current: "));
switch (cool_current) {
case BQ25628E_THERM_CURR_SUSPEND:
Serial.println(F("Suspended"));
break;
case BQ25628E_THERM_CURR_20PCT:
Serial.println(F("20%"));
break;
case BQ25628E_THERM_CURR_40PCT:
Serial.println(F("40%"));
break;
case BQ25628E_THERM_CURR_UNCHANGED:
Serial.println(F("Unchanged"));
break;
}
// Uncomment to set warm thermistor current to 20%
// bq.setWarmThermistorCurrent(BQ25628E_THERM_CURR_20PCT);
// Test warm thermistor current setting
bq25628e_therm_curr_t warm_current = bq.getWarmThermistorCurrent();
Serial.print(F("Warm thermistor current: "));
switch (warm_current) {
case BQ25628E_THERM_CURR_SUSPEND:
Serial.println(F("Suspended"));
break;
case BQ25628E_THERM_CURR_20PCT:
Serial.println(F("20%"));
break;
case BQ25628E_THERM_CURR_40PCT:
Serial.println(F("40%"));
break;
case BQ25628E_THERM_CURR_UNCHANGED:
Serial.println(F("Unchanged"));
break;
}
Serial.println(F("All tests completed!"));
}