Complete ADC function implementation with die temperature support
- Add comprehensive ADC reading functions (IBUS, IBAT, VBUS, VPMID, VBAT, VSYS, TS, TDIE) - Implement proper 2's complement conversion for signed values (IBAT, TDIE) - Add real-time ADC monitoring in test sketch (1-second intervals) - Include die temperature measurement with 0.5°C resolution - Hardware tested with BQ25628E showing correct register access and conversions 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
046a1293ff
commit
07326189f8
3 changed files with 900 additions and 1 deletions
|
|
@ -953,3 +953,404 @@ bq25628e_therm_curr_t Adafruit_BQ25628E::getWarmThermistorCurrent() {
|
|||
|
||||
return (bq25628e_therm_curr_t)ts_iset_warm_bits.read();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets combined charger status flags from both status registers
|
||||
* @return 16-bit status flags: bits 15:8 = REG0x1E, bits 7:0 = REG0x1D
|
||||
*/
|
||||
uint16_t Adafruit_BQ25628E::getChargerStatusFlags() {
|
||||
// Read REG0x1D (Charger Status 0)
|
||||
Adafruit_BusIO_Register status0_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_CHARGER_STATUS_0, 1);
|
||||
uint8_t status0 = status0_reg.read();
|
||||
|
||||
// Read REG0x1E (Charger Status 1)
|
||||
Adafruit_BusIO_Register status1_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_CHARGER_STATUS_1, 1);
|
||||
uint8_t status1 = status1_reg.read();
|
||||
|
||||
// Combine into 16-bit value: high byte = status1, low byte = status0
|
||||
return ((uint16_t)status1 << 8) | status0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets fault status flags from REG0x1F
|
||||
* @return 8-bit fault status flags from REG0x1F_FAULT_Status_0
|
||||
*/
|
||||
uint8_t Adafruit_BQ25628E::getFaultStatusFlags() {
|
||||
// Read REG0x1F (FAULT Status 0)
|
||||
Adafruit_BusIO_Register fault_status_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_FAULT_STATUS_0, 1);
|
||||
|
||||
return fault_status_reg.read();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets combined charger flag registers (clears flags on read)
|
||||
* @return 16-bit flag values: bits 15:8 = REG0x21, bits 7:0 = REG0x20
|
||||
* @note Reading this function clears all flag bits automatically
|
||||
*/
|
||||
uint16_t Adafruit_BQ25628E::getChargerFlags() {
|
||||
// Read REG0x20 (Charger Flag 0) - clears flags on read
|
||||
Adafruit_BusIO_Register flag0_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_CHARGER_FLAG_0, 1);
|
||||
uint8_t flag0 = flag0_reg.read();
|
||||
|
||||
// Read REG0x21 (Charger Flag 1) - clears flags on read
|
||||
Adafruit_BusIO_Register flag1_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_CHARGER_FLAG_1, 1);
|
||||
uint8_t flag1 = flag1_reg.read();
|
||||
|
||||
// Combine into 16-bit value: high byte = flag1, low byte = flag0
|
||||
return ((uint16_t)flag1 << 8) | flag0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets fault flag register (clears flags on read)
|
||||
* @return 8-bit fault flag values from REG0x22_FAULT_Flag_0
|
||||
* @note Reading this function clears all fault flag bits automatically
|
||||
*/
|
||||
uint8_t Adafruit_BQ25628E::getFaultFlags() {
|
||||
// Read REG0x22 (FAULT Flag 0) - clears flags on read
|
||||
Adafruit_BusIO_Register fault_flag_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_FAULT_FLAG_0, 1);
|
||||
|
||||
return fault_flag_reg.read();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Sets interrupt mask for all interrupt sources
|
||||
* @param mask
|
||||
* 32-bit mask value (1 = disable interrupt, 0 = enable interrupt)
|
||||
* @return True if successful, otherwise false.
|
||||
* @note Use BQ25628E_INT_MASK_* defines to construct the mask
|
||||
*/
|
||||
bool Adafruit_BQ25628E::setInterruptMask(uint32_t mask) {
|
||||
// Extract individual register values from 32-bit mask
|
||||
// Mask0 (REG0x23): bits 6:0 (ADC_DONE, TREG, VSYS, IINDPM, VINDPM, SAFETY_TMR, WD)
|
||||
uint8_t mask0 = (mask >> 0) & 0x7F;
|
||||
|
||||
// Mask1 (REG0x24): bits 3,0 (CHG=bit11, VBUS=bit8)
|
||||
uint8_t mask1 = 0;
|
||||
if (mask & BQ25628E_INT_MASK_VBUS) mask1 |= BQ25628E_MASK1_VBUS_MASK;
|
||||
if (mask & BQ25628E_INT_MASK_CHG) mask1 |= BQ25628E_MASK1_CHG_MASK;
|
||||
|
||||
// FMask (REG0x25): bits 7,6,5,3,0 (VBUS_FAULT, BAT_FAULT, SYS_FAULT, TSHUT, TS)
|
||||
uint8_t fmask = 0;
|
||||
if (mask & BQ25628E_INT_MASK_TS) fmask |= BQ25628E_FMASK_TS_MASK;
|
||||
if (mask & BQ25628E_INT_MASK_TSHUT) fmask |= BQ25628E_FMASK_TSHUT_MASK;
|
||||
if (mask & BQ25628E_INT_MASK_SYS_FAULT) fmask |= BQ25628E_FMASK_SYS_FAULT_MASK;
|
||||
if (mask & BQ25628E_INT_MASK_BAT_FAULT) fmask |= BQ25628E_FMASK_BAT_FAULT_MASK;
|
||||
if (mask & BQ25628E_INT_MASK_VBUS_FAULT) fmask |= BQ25628E_FMASK_VBUS_FAULT_MASK;
|
||||
|
||||
// Write to all three mask registers
|
||||
Adafruit_BusIO_Register mask0_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_CHARGER_MASK_0, 1);
|
||||
Adafruit_BusIO_Register mask1_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_CHARGER_MASK_1, 1);
|
||||
Adafruit_BusIO_Register fmask_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_FAULT_MASK_0, 1);
|
||||
|
||||
return mask0_reg.write(mask0) && mask1_reg.write(mask1) && fmask_reg.write(fmask);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets interrupt mask for all interrupt sources
|
||||
* @return 32-bit mask value (1 = interrupt disabled, 0 = interrupt enabled)
|
||||
*/
|
||||
uint32_t Adafruit_BQ25628E::getInterruptMask() {
|
||||
// Read all three mask registers
|
||||
Adafruit_BusIO_Register mask0_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_CHARGER_MASK_0, 1);
|
||||
Adafruit_BusIO_Register mask1_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_CHARGER_MASK_1, 1);
|
||||
Adafruit_BusIO_Register fmask_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_FAULT_MASK_0, 1);
|
||||
|
||||
uint8_t mask0 = mask0_reg.read();
|
||||
uint8_t mask1 = mask1_reg.read();
|
||||
uint8_t fmask = fmask_reg.read();
|
||||
|
||||
// Combine into 32-bit mask
|
||||
uint32_t combined_mask = 0;
|
||||
|
||||
// Mask0 (REG0x23): bits 6:0 map directly to bits 6:0
|
||||
combined_mask |= (mask0 & 0x7F);
|
||||
|
||||
// Mask1 (REG0x24): bits 3,0 map to specific bit positions
|
||||
if (mask1 & BQ25628E_MASK1_VBUS_MASK) combined_mask |= BQ25628E_INT_MASK_VBUS;
|
||||
if (mask1 & BQ25628E_MASK1_CHG_MASK) combined_mask |= BQ25628E_INT_MASK_CHG;
|
||||
|
||||
// FMask (REG0x25): bits 7,6,5,3,0 map to specific bit positions
|
||||
if (fmask & BQ25628E_FMASK_TS_MASK) combined_mask |= BQ25628E_INT_MASK_TS;
|
||||
if (fmask & BQ25628E_FMASK_TSHUT_MASK) combined_mask |= BQ25628E_INT_MASK_TSHUT;
|
||||
if (fmask & BQ25628E_FMASK_SYS_FAULT_MASK) combined_mask |= BQ25628E_INT_MASK_SYS_FAULT;
|
||||
if (fmask & BQ25628E_FMASK_BAT_FAULT_MASK) combined_mask |= BQ25628E_INT_MASK_BAT_FAULT;
|
||||
if (fmask & BQ25628E_FMASK_VBUS_FAULT_MASK) combined_mask |= BQ25628E_INT_MASK_VBUS_FAULT;
|
||||
|
||||
return combined_mask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Enables or disables ADC conversion
|
||||
* @param enable
|
||||
* True to enable ADC, false to disable
|
||||
* @return True if successful, otherwise false.
|
||||
*/
|
||||
bool Adafruit_BQ25628E::setADCEnable(bool enable) {
|
||||
Adafruit_BusIO_Register adc_control_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_ADC_CONTROL, 1);
|
||||
Adafruit_BusIO_RegisterBits adc_enable = Adafruit_BusIO_RegisterBits(&adc_control_reg, 1, 7);
|
||||
|
||||
return adc_enable.write(enable);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets ADC enable status
|
||||
* @return True if ADC is enabled, false otherwise
|
||||
*/
|
||||
bool Adafruit_BQ25628E::getADCEnable() {
|
||||
Adafruit_BusIO_Register adc_control_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_ADC_CONTROL, 1);
|
||||
Adafruit_BusIO_RegisterBits adc_enable = Adafruit_BusIO_RegisterBits(&adc_control_reg, 1, 7);
|
||||
|
||||
return adc_enable.read();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Sets ADC conversion mode
|
||||
* @param one_shot
|
||||
* True for one-shot conversion, false for continuous conversion
|
||||
* @return True if successful, otherwise false.
|
||||
*/
|
||||
bool Adafruit_BQ25628E::setADCOneShot(bool one_shot) {
|
||||
Adafruit_BusIO_Register adc_control_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_ADC_CONTROL, 1);
|
||||
Adafruit_BusIO_RegisterBits adc_rate = Adafruit_BusIO_RegisterBits(&adc_control_reg, 1, 6);
|
||||
|
||||
return adc_rate.write(one_shot);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets ADC conversion mode
|
||||
* @return True if one-shot mode, false if continuous mode
|
||||
*/
|
||||
bool Adafruit_BQ25628E::getADCOneShot() {
|
||||
Adafruit_BusIO_Register adc_control_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_ADC_CONTROL, 1);
|
||||
Adafruit_BusIO_RegisterBits adc_rate = Adafruit_BusIO_RegisterBits(&adc_control_reg, 1, 6);
|
||||
|
||||
return adc_rate.read();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Sets ADC sample rate (bit resolution)
|
||||
* @param sample_rate
|
||||
* Sample rate setting (see bq25628e_adc_sample_t)
|
||||
* @return True if successful, otherwise false.
|
||||
*/
|
||||
bool Adafruit_BQ25628E::setADCSampleRate(bq25628e_adc_sample_t sample_rate) {
|
||||
Adafruit_BusIO_Register adc_control_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_ADC_CONTROL, 1);
|
||||
Adafruit_BusIO_RegisterBits adc_sample = Adafruit_BusIO_RegisterBits(&adc_control_reg, 2, 4);
|
||||
|
||||
return adc_sample.write(sample_rate);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets ADC sample rate setting
|
||||
* @return Current sample rate setting (see bq25628e_adc_sample_t)
|
||||
*/
|
||||
bq25628e_adc_sample_t Adafruit_BQ25628E::getADCSampleRate() {
|
||||
Adafruit_BusIO_Register adc_control_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_ADC_CONTROL, 1);
|
||||
Adafruit_BusIO_RegisterBits adc_sample = Adafruit_BusIO_RegisterBits(&adc_control_reg, 2, 4);
|
||||
|
||||
return (bq25628e_adc_sample_t)adc_sample.read();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Sets ADC function disable flags
|
||||
* @param disable_flags
|
||||
* Bitfield of ADC functions to disable (use BQ25628E_ADC_DIS_* flags)
|
||||
* Setting a bit to 1 disables that ADC function
|
||||
* Setting a bit to 0 enables that ADC function
|
||||
* @return True if successful, otherwise false.
|
||||
* @note Use BQ25628E_ADC_DIS_* defines to construct the disable_flags
|
||||
*/
|
||||
bool Adafruit_BQ25628E::setDisableADC(uint8_t disable_flags) {
|
||||
Adafruit_BusIO_Register adc_func_disable_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_ADC_FUNCTION_DISABLE_0, 1);
|
||||
|
||||
return adc_func_disable_reg.write(disable_flags);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets ADC function disable flags
|
||||
* @return Bitfield of disabled ADC functions (1 = disabled, 0 = enabled)
|
||||
* @note Use BQ25628E_ADC_DIS_* defines to check individual flags
|
||||
*/
|
||||
uint8_t Adafruit_BQ25628E::getDisableADC() {
|
||||
Adafruit_BusIO_Register adc_func_disable_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_ADC_FUNCTION_DISABLE_0, 1);
|
||||
|
||||
return adc_func_disable_reg.read();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets IBUS current measurement from ADC
|
||||
* @return Current in Amperes (positive = from VBUS to PMID, negative = reverse)
|
||||
* @note Requires ADC to be enabled. Returns 2's complement 15-bit value
|
||||
* converted to float with 2mA resolution
|
||||
*/
|
||||
float Adafruit_BQ25628E::getIBUScurrent() {
|
||||
// Read 16-bit IBUS ADC register (little endian)
|
||||
Adafruit_BusIO_Register ibus_adc_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_IBUS_ADC, 2);
|
||||
|
||||
uint16_t raw_value = ibus_adc_reg.read();
|
||||
|
||||
// Extract 15-bit ADC value from bits 15:1 (shift right by 1)
|
||||
uint16_t adc_15bit = raw_value >> 1;
|
||||
|
||||
// Convert from 15-bit 2's complement to signed 16-bit
|
||||
int16_t signed_value;
|
||||
if (adc_15bit & 0x4000) {
|
||||
// Negative value - extend sign bit
|
||||
signed_value = (int16_t)(adc_15bit | 0x8000);
|
||||
} else {
|
||||
// Positive value
|
||||
signed_value = (int16_t)adc_15bit;
|
||||
}
|
||||
|
||||
// Convert to Amperes: 2mA per step
|
||||
return (float)signed_value * 0.002f;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets IBAT current measurement from ADC
|
||||
* @return Current in Amperes (positive = charging, negative = discharging)
|
||||
* @note Requires ADC to be enabled. Returns 2's complement 14-bit value
|
||||
* converted to float with 4mA resolution. Range: -7.5A to +4.0A
|
||||
*/
|
||||
float Adafruit_BQ25628E::getIBATcurrent() {
|
||||
// Read 16-bit IBAT ADC register (little endian)
|
||||
Adafruit_BusIO_Register ibat_adc_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_IBAT_ADC, 2);
|
||||
|
||||
uint16_t raw_value = ibat_adc_reg.read();
|
||||
|
||||
// Extract 14-bit ADC value from bits 15:2 (shift right by 2)
|
||||
uint16_t adc_14bit = raw_value >> 2;
|
||||
|
||||
// Convert from 14-bit 2's complement to signed 16-bit
|
||||
int16_t signed_value;
|
||||
if (adc_14bit & 0x2000) {
|
||||
// Negative value - extend sign bit
|
||||
signed_value = (int16_t)(adc_14bit | 0xC000);
|
||||
} else {
|
||||
// Positive value
|
||||
signed_value = (int16_t)adc_14bit;
|
||||
}
|
||||
|
||||
// Convert to Amperes: 4mA per step
|
||||
return (float)signed_value * 0.004f;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets VBUS voltage measurement from ADC
|
||||
* @return Voltage in Volts. Range: 0V to 18V
|
||||
* @note Requires ADC to be enabled. 3.97mV resolution
|
||||
*/
|
||||
float Adafruit_BQ25628E::getVBUSvoltage() {
|
||||
// Read 16-bit VBUS ADC register (little endian)
|
||||
Adafruit_BusIO_Register vbus_adc_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_VBUS_ADC, 2);
|
||||
|
||||
uint16_t raw_value = vbus_adc_reg.read();
|
||||
|
||||
// Extract voltage value from bits 15:2 (shift right by 2)
|
||||
uint16_t voltage_value = raw_value >> 2;
|
||||
|
||||
// Convert to Volts: 3.97mV per step
|
||||
return (float)voltage_value * 0.00397f;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets VPMID voltage measurement from ADC
|
||||
* @return Voltage in Volts. Range: 0V to 18V
|
||||
* @note Requires ADC to be enabled. 3.97mV resolution
|
||||
*/
|
||||
float Adafruit_BQ25628E::getVPMIDvoltage() {
|
||||
// Read 16-bit VPMID ADC register (little endian)
|
||||
Adafruit_BusIO_Register vpmid_adc_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_VPMID_ADC, 2);
|
||||
|
||||
uint16_t raw_value = vpmid_adc_reg.read();
|
||||
|
||||
// Extract voltage value from bits 15:2 (shift right by 2)
|
||||
uint16_t voltage_value = raw_value >> 2;
|
||||
|
||||
// Convert to Volts: 3.97mV per step
|
||||
return (float)voltage_value * 0.00397f;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets VBAT voltage measurement from ADC
|
||||
* @return Voltage in Volts. Range: 0V to 5.572V
|
||||
* @note Requires ADC to be enabled. 1.99mV resolution
|
||||
*/
|
||||
float Adafruit_BQ25628E::getVBATvoltage() {
|
||||
// Read 16-bit VBAT ADC register (little endian)
|
||||
Adafruit_BusIO_Register vbat_adc_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_VBAT_ADC, 2);
|
||||
|
||||
uint16_t raw_value = vbat_adc_reg.read();
|
||||
|
||||
// Extract voltage value from bits 15:1 (shift right by 1)
|
||||
uint16_t voltage_value = raw_value >> 1;
|
||||
|
||||
// Convert to Volts: 1.99mV per step
|
||||
return (float)voltage_value * 0.00199f;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets VSYS voltage measurement from ADC
|
||||
* @return Voltage in Volts. Range: 0V to 5.572V
|
||||
* @note Requires ADC to be enabled. 1.99mV resolution
|
||||
*/
|
||||
float Adafruit_BQ25628E::getVSYSvoltage() {
|
||||
// Read 16-bit VSYS ADC register (little endian)
|
||||
Adafruit_BusIO_Register vsys_adc_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_VSYS_ADC, 2);
|
||||
|
||||
uint16_t raw_value = vsys_adc_reg.read();
|
||||
|
||||
// Extract voltage value from bits 15:1 (shift right by 1)
|
||||
uint16_t voltage_value = raw_value >> 1;
|
||||
|
||||
// Convert to Volts: 1.99mV per step
|
||||
return (float)voltage_value * 0.00199f;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets thermistor reading as percentage of bias reference
|
||||
* @return Percentage (0-100%). Range: 0% to 98.31%
|
||||
* @note Requires ADC to be enabled and TS pin bias reference active
|
||||
* Uses bits 11:0 with 0.0961% resolution
|
||||
*/
|
||||
float Adafruit_BQ25628E::getThermistorPercent() {
|
||||
// Read 16-bit TS ADC register (little endian)
|
||||
Adafruit_BusIO_Register ts_adc_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_TS_ADC, 2);
|
||||
|
||||
uint16_t raw_value = ts_adc_reg.read();
|
||||
|
||||
// Extract 12-bit value from bits 11:0 (no shift needed)
|
||||
uint16_t ts_value = raw_value & 0x0FFF;
|
||||
|
||||
// Convert to percentage: 0.0961% per step
|
||||
return (float)ts_value * 0.0961f;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets die temperature measurement from ADC
|
||||
* @return Temperature in Celsius. Range: -40°C to +140°C
|
||||
* @note Requires ADC to be enabled. Returns 2's complement 12-bit value
|
||||
* with 0.5°C resolution using bits 11:0
|
||||
*/
|
||||
float Adafruit_BQ25628E::getDieTempC() {
|
||||
// Read 16-bit TDIE ADC register (little endian)
|
||||
Adafruit_BusIO_Register tdie_adc_reg = Adafruit_BusIO_Register(i2c_dev, BQ25628E_REG_TDIE_ADC, 2);
|
||||
|
||||
uint16_t raw_value = tdie_adc_reg.read();
|
||||
|
||||
// Extract 12-bit value from bits 11:0 (no shift needed)
|
||||
uint16_t temp_12bit = raw_value & 0x0FFF;
|
||||
|
||||
// Convert from 12-bit 2's complement to signed 16-bit
|
||||
int16_t signed_value;
|
||||
if (temp_12bit & 0x0800) {
|
||||
// Negative value - extend sign bit
|
||||
signed_value = (int16_t)(temp_12bit | 0xF000);
|
||||
} else {
|
||||
// Positive value
|
||||
signed_value = (int16_t)temp_12bit;
|
||||
}
|
||||
|
||||
// Convert to Celsius: 0.5°C per step
|
||||
return (float)signed_value * 0.5f;
|
||||
}
|
||||
|
|
@ -78,6 +78,126 @@ typedef enum {
|
|||
BQ25628E_THERM_CURR_UNCHANGED = 0b11 /*!< ICHG unchanged */
|
||||
} bq25628e_therm_curr_t;
|
||||
|
||||
/*! Status register bit flags for REG0x1D_Charger_Status_0 */
|
||||
#define BQ25628E_STATUS0_WD_STAT (1 << 0) /*!< WD timer expired */
|
||||
#define BQ25628E_STATUS0_SAFETY_TMR_STAT (1 << 1) /*!< Safety timer expired */
|
||||
#define BQ25628E_STATUS0_VINDPM_STAT (1 << 2) /*!< In VINDPM regulation */
|
||||
#define BQ25628E_STATUS0_IINDPM_STAT (1 << 3) /*!< In IINDPM/ILIM regulation */
|
||||
#define BQ25628E_STATUS0_VSYS_STAT (1 << 4) /*!< In VSYSMIN regulation */
|
||||
#define BQ25628E_STATUS0_TREG_STAT (1 << 5) /*!< In thermal regulation */
|
||||
#define BQ25628E_STATUS0_ADC_DONE_STAT (1 << 6) /*!< ADC conversion complete */
|
||||
|
||||
/*! Status register bit masks for REG0x1E_Charger_Status_1 */
|
||||
#define BQ25628E_STATUS1_VBUS_STAT_MASK (0x07) /*!< VBUS status mask bits 2:0 */
|
||||
#define BQ25628E_STATUS1_CHG_STAT_MASK (0x18) /*!< Charge status mask bits 4:3 */
|
||||
#define BQ25628E_STATUS1_CHG_STAT_SHIFT (3) /*!< Charge status bit shift */
|
||||
|
||||
/*! VBUS Status values */
|
||||
#define BQ25628E_VBUS_STAT_NOT_POWERED (0x00) /*!< Not powered from VBUS */
|
||||
#define BQ25628E_VBUS_STAT_UNKNOWN_ADAPTER (0x04) /*!< Unknown adapter */
|
||||
|
||||
/*! Charge Status values */
|
||||
#define BQ25628E_CHG_STAT_NOT_CHARGING (0x00) /*!< Not charging or terminated */
|
||||
#define BQ25628E_CHG_STAT_CHARGING (0x01) /*!< Trickle/Pre/Fast charge */
|
||||
#define BQ25628E_CHG_STAT_TAPER (0x02) /*!< Taper charge (CV mode) */
|
||||
#define BQ25628E_CHG_STAT_TOPOFF (0x03) /*!< Top-off timer active */
|
||||
|
||||
/*! Fault status register bit flags for REG0x1F_FAULT_Status_0 */
|
||||
#define BQ25628E_FAULT_VBUS_FAULT_STAT (1 << 7) /*!< VBUS fault (OVP/sleep) */
|
||||
#define BQ25628E_FAULT_BAT_FAULT_STAT (1 << 6) /*!< Battery fault (OCP/OVP) */
|
||||
#define BQ25628E_FAULT_SYS_FAULT_STAT (1 << 5) /*!< System fault (short/OVP) */
|
||||
#define BQ25628E_FAULT_TSHUT_STAT (1 << 3) /*!< Thermal shutdown */
|
||||
#define BQ25628E_FAULT_TS_STAT_MASK (0x07) /*!< TS status mask bits 2:0 */
|
||||
|
||||
/*! TS Status values */
|
||||
#define BQ25628E_TS_STAT_NORMAL (0x00) /*!< TS Normal */
|
||||
#define BQ25628E_TS_STAT_COLD (0x01) /*!< TS Cold */
|
||||
#define BQ25628E_TS_STAT_HOT (0x02) /*!< TS Hot */
|
||||
#define BQ25628E_TS_STAT_COOL (0x03) /*!< TS Cool */
|
||||
#define BQ25628E_TS_STAT_WARM (0x04) /*!< TS Warm */
|
||||
#define BQ25628E_TS_STAT_PRECOOL (0x05) /*!< TS Pre-cool */
|
||||
#define BQ25628E_TS_STAT_PREWARM (0x06) /*!< TS Pre-warm */
|
||||
#define BQ25628E_TS_STAT_BIAS_FAULT (0x07) /*!< TS bias reference fault */
|
||||
|
||||
/*! Charger flag register bit flags for REG0x20_Charger_Flag_0 */
|
||||
#define BQ25628E_FLAG0_WD_FLAG (1 << 0) /*!< WD timer expired flag */
|
||||
#define BQ25628E_FLAG0_SAFETY_TMR_FLAG (1 << 1) /*!< Safety timer expired flag */
|
||||
#define BQ25628E_FLAG0_VINDPM_FLAG (1 << 2) /*!< VINDPM regulation flag */
|
||||
#define BQ25628E_FLAG0_IINDPM_FLAG (1 << 3) /*!< IINDPM/ILIM regulation flag */
|
||||
#define BQ25628E_FLAG0_VSYS_FLAG (1 << 4) /*!< VSYSMIN regulation flag */
|
||||
#define BQ25628E_FLAG0_TREG_FLAG (1 << 5) /*!< Thermal regulation flag */
|
||||
#define BQ25628E_FLAG0_ADC_DONE_FLAG (1 << 6) /*!< ADC conversion complete flag */
|
||||
|
||||
/*! Charger flag register bit flags for REG0x21_Charger_Flag_1 */
|
||||
#define BQ25628E_FLAG1_VBUS_FLAG (1 << 0) /*!< VBUS status changed flag */
|
||||
#define BQ25628E_FLAG1_CHG_FLAG (1 << 3) /*!< Charge status changed flag */
|
||||
|
||||
/*! Fault flag register bit flags for REG0x22_FAULT_Flag_0 */
|
||||
#define BQ25628E_FAULT_FLAG_VBUS_FAULT (1 << 7) /*!< VBUS OVP/sleep fault flag */
|
||||
#define BQ25628E_FAULT_FLAG_BAT_FAULT (1 << 6) /*!< Battery OCP/OVP fault flag */
|
||||
#define BQ25628E_FAULT_FLAG_SYS_FAULT (1 << 5) /*!< System OVP/short fault flag */
|
||||
#define BQ25628E_FAULT_FLAG_TSHUT (1 << 3) /*!< Thermal shutdown fault flag */
|
||||
#define BQ25628E_FAULT_FLAG_TS_CHANGED (1 << 0) /*!< TS status changed flag */
|
||||
|
||||
/*! Interrupt mask register bit flags for REG0x23_Charger_Mask_0 */
|
||||
#define BQ25628E_MASK0_ADC_DONE_MASK (1 << 6) /*!< ADC conversion mask */
|
||||
#define BQ25628E_MASK0_TREG_MASK (1 << 5) /*!< Thermal regulation mask */
|
||||
#define BQ25628E_MASK0_VSYS_MASK (1 << 4) /*!< VSYSMIN regulation mask */
|
||||
#define BQ25628E_MASK0_IINDPM_MASK (1 << 3) /*!< IINDPM/ILIM regulation mask */
|
||||
#define BQ25628E_MASK0_VINDPM_MASK (1 << 2) /*!< VINDPM regulation mask */
|
||||
#define BQ25628E_MASK0_SAFETY_TMR_MASK (1 << 1) /*!< Safety timer mask */
|
||||
#define BQ25628E_MASK0_WD_MASK (1 << 0) /*!< Watchdog timer mask */
|
||||
|
||||
/*! Interrupt mask register bit flags for REG0x24_Charger_Mask_1 */
|
||||
#define BQ25628E_MASK1_CHG_MASK (1 << 3) /*!< Charge status change mask */
|
||||
#define BQ25628E_MASK1_VBUS_MASK (1 << 0) /*!< VBUS status change mask */
|
||||
|
||||
/*! Interrupt mask register bit flags for REG0x25_FAULT_Mask_0 */
|
||||
#define BQ25628E_FMASK_VBUS_FAULT_MASK (1 << 7) /*!< VBUS fault mask */
|
||||
#define BQ25628E_FMASK_BAT_FAULT_MASK (1 << 6) /*!< Battery fault mask */
|
||||
#define BQ25628E_FMASK_SYS_FAULT_MASK (1 << 5) /*!< System fault mask */
|
||||
#define BQ25628E_FMASK_TSHUT_MASK (1 << 3) /*!< Thermal shutdown mask */
|
||||
#define BQ25628E_FMASK_TS_MASK (1 << 0) /*!< TS status change mask */
|
||||
|
||||
/*! Combined interrupt mask positions for 32-bit interface */
|
||||
#define BQ25628E_INT_MASK_WD (1UL << 0) /*!< Watchdog timer interrupt */
|
||||
#define BQ25628E_INT_MASK_SAFETY_TMR (1UL << 1) /*!< Safety timer interrupt */
|
||||
#define BQ25628E_INT_MASK_VINDPM (1UL << 2) /*!< VINDPM regulation interrupt */
|
||||
#define BQ25628E_INT_MASK_IINDPM (1UL << 3) /*!< IINDPM/ILIM regulation interrupt */
|
||||
#define BQ25628E_INT_MASK_VSYS (1UL << 4) /*!< VSYSMIN regulation interrupt */
|
||||
#define BQ25628E_INT_MASK_TREG (1UL << 5) /*!< Thermal regulation interrupt */
|
||||
#define BQ25628E_INT_MASK_ADC_DONE (1UL << 6) /*!< ADC conversion interrupt */
|
||||
#define BQ25628E_INT_MASK_VBUS (1UL << 8) /*!< VBUS status change interrupt */
|
||||
#define BQ25628E_INT_MASK_CHG (1UL << 11) /*!< Charge status change interrupt */
|
||||
#define BQ25628E_INT_MASK_TS (1UL << 16) /*!< TS status change interrupt */
|
||||
#define BQ25628E_INT_MASK_TSHUT (1UL << 19) /*!< Thermal shutdown interrupt */
|
||||
#define BQ25628E_INT_MASK_SYS_FAULT (1UL << 21) /*!< System fault interrupt */
|
||||
#define BQ25628E_INT_MASK_BAT_FAULT (1UL << 22) /*!< Battery fault interrupt */
|
||||
#define BQ25628E_INT_MASK_VBUS_FAULT (1UL << 23) /*!< VBUS fault interrupt */
|
||||
|
||||
/*! Default interrupt mask: Enable only CHG and VBUS interrupts, disable all others */
|
||||
#define BQ25628E_INT_MASK_DEFAULT (~(BQ25628E_INT_MASK_CHG | BQ25628E_INT_MASK_VBUS))
|
||||
|
||||
/*!
|
||||
* @brief ADC sample rate settings
|
||||
*/
|
||||
typedef enum {
|
||||
BQ25628E_ADC_SAMPLE_12BIT = 0b00, /*!< 12-bit effective resolution */
|
||||
BQ25628E_ADC_SAMPLE_11BIT = 0b01, /*!< 11-bit effective resolution */
|
||||
BQ25628E_ADC_SAMPLE_10BIT = 0b10, /*!< 10-bit effective resolution */
|
||||
BQ25628E_ADC_SAMPLE_9BIT = 0b11 /*!< 9-bit effective resolution */
|
||||
} bq25628e_adc_sample_t;
|
||||
|
||||
/*! ADC function disable flags for REG0x27_ADC_Function_Disable_0 */
|
||||
#define BQ25628E_ADC_DIS_IBUS (1 << 7) /*!< Disable IBUS ADC */
|
||||
#define BQ25628E_ADC_DIS_IBAT (1 << 6) /*!< Disable IBAT ADC */
|
||||
#define BQ25628E_ADC_DIS_VBUS (1 << 5) /*!< Disable VBUS ADC */
|
||||
#define BQ25628E_ADC_DIS_VBAT (1 << 4) /*!< Disable VBAT ADC */
|
||||
#define BQ25628E_ADC_DIS_VSYS (1 << 3) /*!< Disable VSYS ADC */
|
||||
#define BQ25628E_ADC_DIS_TS (1 << 2) /*!< Disable TS ADC */
|
||||
#define BQ25628E_ADC_DIS_TDIE (1 << 1) /*!< Disable TDIE ADC */
|
||||
#define BQ25628E_ADC_DIS_VPMID (1 << 0) /*!< Disable VPMID ADC */
|
||||
|
||||
/*! Register addresses for the BQ25628E */
|
||||
#define BQ25628E_REG_CHARGE_CURRENT_LIMIT 0x02
|
||||
#define BQ25628E_REG_CHARGE_VOLTAGE_LIMIT 0x04
|
||||
|
|
@ -217,6 +337,35 @@ public:
|
|||
bool setWarmThermistorCurrent(bq25628e_therm_curr_t setting);
|
||||
bq25628e_therm_curr_t getWarmThermistorCurrent();
|
||||
|
||||
uint16_t getChargerStatusFlags();
|
||||
uint8_t getFaultStatusFlags();
|
||||
uint16_t getChargerFlags();
|
||||
uint8_t getFaultFlags();
|
||||
|
||||
bool setInterruptMask(uint32_t mask);
|
||||
uint32_t getInterruptMask();
|
||||
|
||||
bool setADCEnable(bool enable);
|
||||
bool getADCEnable();
|
||||
|
||||
bool setADCOneShot(bool one_shot);
|
||||
bool getADCOneShot();
|
||||
|
||||
bool setADCSampleRate(bq25628e_adc_sample_t sample_rate);
|
||||
bq25628e_adc_sample_t getADCSampleRate();
|
||||
|
||||
bool setDisableADC(uint8_t disable_flags);
|
||||
uint8_t getDisableADC();
|
||||
|
||||
float getIBUScurrent();
|
||||
float getIBATcurrent();
|
||||
float getVBUSvoltage();
|
||||
float getVPMIDvoltage();
|
||||
float getVBATvoltage();
|
||||
float getVSYSvoltage();
|
||||
float getThermistorPercent();
|
||||
float getDieTempC();
|
||||
|
||||
private:
|
||||
Adafruit_I2CDevice *i2c_dev; /*!< Pointer to I2C bus interface */
|
||||
};
|
||||
|
|
|
|||
|
|
@ -352,9 +352,358 @@ void setup() {
|
|||
break;
|
||||
}
|
||||
|
||||
// Enable ADC and set to 12-bit mode by default
|
||||
Serial.println(F("Enabling ADC with 12-bit resolution..."));
|
||||
if (bq.setADCEnable(true) && bq.setADCSampleRate(BQ25628E_ADC_SAMPLE_12BIT)) {
|
||||
Serial.println(F("ADC configured successfully"));
|
||||
} else {
|
||||
Serial.println(F("Failed to configure ADC"));
|
||||
}
|
||||
|
||||
// Test ADC configuration functions
|
||||
bool adc_enabled = bq.getADCEnable();
|
||||
Serial.print(F("ADC enabled: "));
|
||||
Serial.println(adc_enabled ? F("true") : F("false"));
|
||||
|
||||
bool adc_oneshot = bq.getADCOneShot();
|
||||
Serial.print(F("ADC one-shot mode: "));
|
||||
Serial.println(adc_oneshot ? F("true") : F("false"));
|
||||
|
||||
bq25628e_adc_sample_t sample_rate = bq.getADCSampleRate();
|
||||
Serial.print(F("ADC sample rate: "));
|
||||
switch (sample_rate) {
|
||||
case BQ25628E_ADC_SAMPLE_12BIT:
|
||||
Serial.println(F("12-bit"));
|
||||
break;
|
||||
case BQ25628E_ADC_SAMPLE_11BIT:
|
||||
Serial.println(F("11-bit"));
|
||||
break;
|
||||
case BQ25628E_ADC_SAMPLE_10BIT:
|
||||
Serial.println(F("10-bit"));
|
||||
break;
|
||||
case BQ25628E_ADC_SAMPLE_9BIT:
|
||||
Serial.println(F("9-bit"));
|
||||
break;
|
||||
}
|
||||
|
||||
// Ensure all ADC functions are enabled (disable_flags = 0x00)
|
||||
Serial.println(F("Ensuring all ADC functions are enabled..."));
|
||||
if (bq.setDisableADC(0x00)) {
|
||||
Serial.println(F("ADC functions configured successfully"));
|
||||
} else {
|
||||
Serial.println(F("Failed to configure ADC functions"));
|
||||
}
|
||||
|
||||
// Display ADC function enable status
|
||||
uint8_t adc_disable_flags = bq.getDisableADC();
|
||||
Serial.print(F("ADC Function Status (0x"));
|
||||
Serial.print(adc_disable_flags, HEX);
|
||||
Serial.println(F("):"));
|
||||
|
||||
Serial.print(F(" IBUS ADC: "));
|
||||
Serial.println((adc_disable_flags & BQ25628E_ADC_DIS_IBUS) ? F("Disabled") : F("Enabled"));
|
||||
|
||||
Serial.print(F(" IBAT ADC: "));
|
||||
Serial.println((adc_disable_flags & BQ25628E_ADC_DIS_IBAT) ? F("Disabled") : F("Enabled"));
|
||||
|
||||
Serial.print(F(" VBUS ADC: "));
|
||||
Serial.println((adc_disable_flags & BQ25628E_ADC_DIS_VBUS) ? F("Disabled") : F("Enabled"));
|
||||
|
||||
Serial.print(F(" VBAT ADC: "));
|
||||
Serial.println((adc_disable_flags & BQ25628E_ADC_DIS_VBAT) ? F("Disabled") : F("Enabled"));
|
||||
|
||||
Serial.print(F(" VSYS ADC: "));
|
||||
Serial.println((adc_disable_flags & BQ25628E_ADC_DIS_VSYS) ? F("Disabled") : F("Enabled"));
|
||||
|
||||
Serial.print(F(" TS ADC: "));
|
||||
Serial.println((adc_disable_flags & BQ25628E_ADC_DIS_TS) ? F("Disabled") : F("Enabled"));
|
||||
|
||||
Serial.print(F(" TDIE ADC: "));
|
||||
Serial.println((adc_disable_flags & BQ25628E_ADC_DIS_TDIE) ? F("Disabled") : F("Enabled"));
|
||||
|
||||
Serial.print(F(" VPMID ADC: "));
|
||||
Serial.println((adc_disable_flags & BQ25628E_ADC_DIS_VPMID) ? F("Disabled") : F("Enabled"));
|
||||
|
||||
Serial.println(F("All tests completed!"));
|
||||
|
||||
// Set interrupt mask to enable only CHG and VBUS interrupts, disable all others
|
||||
Serial.println(F("Setting interrupt mask (CHG + VBUS enabled, others disabled)..."));
|
||||
uint32_t intMask = BQ25628E_INT_MASK_WD | BQ25628E_INT_MASK_SAFETY_TMR |
|
||||
BQ25628E_INT_MASK_VINDPM | BQ25628E_INT_MASK_IINDPM |
|
||||
BQ25628E_INT_MASK_VSYS | BQ25628E_INT_MASK_TREG |
|
||||
BQ25628E_INT_MASK_ADC_DONE | BQ25628E_INT_MASK_TS |
|
||||
BQ25628E_INT_MASK_TSHUT | BQ25628E_INT_MASK_SYS_FAULT |
|
||||
BQ25628E_INT_MASK_BAT_FAULT | BQ25628E_INT_MASK_VBUS_FAULT;
|
||||
// CHG and VBUS interrupts NOT included in mask = they remain enabled
|
||||
|
||||
if (bq.setInterruptMask(intMask)) {
|
||||
Serial.println(F("Interrupt mask set successfully"));
|
||||
} else {
|
||||
Serial.println(F("Failed to set interrupt mask"));
|
||||
}
|
||||
|
||||
// Read back and display interrupt mask
|
||||
uint32_t readMask = bq.getInterruptMask();
|
||||
Serial.print(F("Current interrupt mask: 0x"));
|
||||
Serial.println(readMask, HEX);
|
||||
}
|
||||
|
||||
void printChargerStatus() {
|
||||
uint16_t statusFlags = bq.getChargerStatusFlags();
|
||||
uint8_t faultFlags = bq.getFaultStatusFlags();
|
||||
uint16_t chargerFlags = bq.getChargerFlags();
|
||||
uint8_t faultFlagsCleared = bq.getFaultFlags();
|
||||
uint8_t status0 = statusFlags & 0xFF;
|
||||
uint8_t status1 = (statusFlags >> 8) & 0xFF;
|
||||
uint8_t flag0 = chargerFlags & 0xFF;
|
||||
uint8_t flag1 = (chargerFlags >> 8) & 0xFF;
|
||||
|
||||
Serial.println(F("=== Charger Status ==="));
|
||||
Serial.print(F("Status: 0x"));
|
||||
Serial.print(statusFlags, HEX);
|
||||
Serial.print(F(", Fault: 0x"));
|
||||
Serial.print(faultFlags, HEX);
|
||||
Serial.print(F(", Flags: 0x"));
|
||||
Serial.print(chargerFlags, HEX);
|
||||
Serial.print(F(", FaultFlags: 0x"));
|
||||
Serial.println(faultFlagsCleared, HEX);
|
||||
|
||||
// REG0x1D Status 0 flags
|
||||
Serial.print(F("Status 0 (0x"));
|
||||
Serial.print(status0, HEX);
|
||||
Serial.println(F("):"));
|
||||
|
||||
if (status0 & BQ25628E_STATUS0_WD_STAT) {
|
||||
Serial.println(F(" ⚠️ WD Timer Expired"));
|
||||
}
|
||||
if (status0 & BQ25628E_STATUS0_SAFETY_TMR_STAT) {
|
||||
Serial.println(F(" ⚠️ Safety Timer Expired"));
|
||||
}
|
||||
if (status0 & BQ25628E_STATUS0_VINDPM_STAT) {
|
||||
Serial.println(F(" 📉 VINDPM Regulation Active"));
|
||||
}
|
||||
if (status0 & BQ25628E_STATUS0_IINDPM_STAT) {
|
||||
Serial.println(F(" 📉 IINDPM/ILIM Regulation Active"));
|
||||
}
|
||||
if (status0 & BQ25628E_STATUS0_VSYS_STAT) {
|
||||
Serial.println(F(" 📉 VSYSMIN Regulation Active"));
|
||||
}
|
||||
if (status0 & BQ25628E_STATUS0_TREG_STAT) {
|
||||
Serial.println(F(" 🌡️ Thermal Regulation Active"));
|
||||
}
|
||||
if (status0 & BQ25628E_STATUS0_ADC_DONE_STAT) {
|
||||
Serial.println(F(" ✅ ADC Conversion Complete"));
|
||||
}
|
||||
|
||||
// REG0x1E Status 1 flags
|
||||
Serial.print(F("Status 1 (0x"));
|
||||
Serial.print(status1, HEX);
|
||||
Serial.println(F("):"));
|
||||
|
||||
// VBUS Status (bits 2:0)
|
||||
uint8_t vbus_stat = status1 & BQ25628E_STATUS1_VBUS_STAT_MASK;
|
||||
Serial.print(F(" 🔌 VBUS: "));
|
||||
switch (vbus_stat) {
|
||||
case BQ25628E_VBUS_STAT_NOT_POWERED:
|
||||
Serial.println(F("Not Powered"));
|
||||
break;
|
||||
case BQ25628E_VBUS_STAT_UNKNOWN_ADAPTER:
|
||||
Serial.println(F("Unknown Adapter"));
|
||||
break;
|
||||
default:
|
||||
Serial.print(F("Status Code "));
|
||||
Serial.println(vbus_stat);
|
||||
break;
|
||||
}
|
||||
|
||||
// Charge Status (bits 4:3)
|
||||
uint8_t chg_stat = (status1 & BQ25628E_STATUS1_CHG_STAT_MASK) >> BQ25628E_STATUS1_CHG_STAT_SHIFT;
|
||||
Serial.print(F(" 🔋 Charge: "));
|
||||
switch (chg_stat) {
|
||||
case BQ25628E_CHG_STAT_NOT_CHARGING:
|
||||
Serial.println(F("Not Charging/Terminated"));
|
||||
break;
|
||||
case BQ25628E_CHG_STAT_CHARGING:
|
||||
Serial.println(F("Charging (CC mode)"));
|
||||
break;
|
||||
case BQ25628E_CHG_STAT_TAPER:
|
||||
Serial.println(F("Taper Charge (CV mode)"));
|
||||
break;
|
||||
case BQ25628E_CHG_STAT_TOPOFF:
|
||||
Serial.println(F("Top-off Timer Active"));
|
||||
break;
|
||||
}
|
||||
|
||||
// REG0x1F Fault Status flags
|
||||
Serial.print(F("Fault Status (0x"));
|
||||
Serial.print(faultFlags, HEX);
|
||||
Serial.println(F("):"));
|
||||
|
||||
if (faultFlags & BQ25628E_FAULT_VBUS_FAULT_STAT) {
|
||||
Serial.println(F(" 🚨 VBUS Fault (OVP/Sleep)"));
|
||||
}
|
||||
if (faultFlags & BQ25628E_FAULT_BAT_FAULT_STAT) {
|
||||
Serial.println(F(" 🚨 Battery Fault (OCP/OVP)"));
|
||||
}
|
||||
if (faultFlags & BQ25628E_FAULT_SYS_FAULT_STAT) {
|
||||
Serial.println(F(" 🚨 System Fault (Short/OVP)"));
|
||||
}
|
||||
if (faultFlags & BQ25628E_FAULT_TSHUT_STAT) {
|
||||
Serial.println(F(" 🔥 Thermal Shutdown"));
|
||||
}
|
||||
|
||||
// TS Status (bits 2:0)
|
||||
uint8_t ts_stat = faultFlags & BQ25628E_FAULT_TS_STAT_MASK;
|
||||
Serial.print(F(" 🌡️ TS Status: "));
|
||||
switch (ts_stat) {
|
||||
case BQ25628E_TS_STAT_NORMAL:
|
||||
Serial.println(F("Normal"));
|
||||
break;
|
||||
case BQ25628E_TS_STAT_COLD:
|
||||
Serial.println(F("Cold"));
|
||||
break;
|
||||
case BQ25628E_TS_STAT_HOT:
|
||||
Serial.println(F("Hot"));
|
||||
break;
|
||||
case BQ25628E_TS_STAT_COOL:
|
||||
Serial.println(F("Cool"));
|
||||
break;
|
||||
case BQ25628E_TS_STAT_WARM:
|
||||
Serial.println(F("Warm"));
|
||||
break;
|
||||
case BQ25628E_TS_STAT_PRECOOL:
|
||||
Serial.println(F("Pre-cool"));
|
||||
break;
|
||||
case BQ25628E_TS_STAT_PREWARM:
|
||||
Serial.println(F("Pre-warm"));
|
||||
break;
|
||||
case BQ25628E_TS_STAT_BIAS_FAULT:
|
||||
Serial.println(F("Bias Reference Fault"));
|
||||
break;
|
||||
}
|
||||
|
||||
// REG0x20/0x21 Charger Flag status (cleared on read!)
|
||||
if (flag0 != 0 || flag1 != 0) {
|
||||
Serial.print(F("Charger Flags (0x"));
|
||||
Serial.print(flag1, HEX);
|
||||
Serial.print(F("/0x"));
|
||||
Serial.print(flag0, HEX);
|
||||
Serial.println(F(") - CLEARED:"));
|
||||
|
||||
// Flag0 bits
|
||||
if (flag0 & BQ25628E_FLAG0_WD_FLAG) {
|
||||
Serial.println(F(" 🚩 WD Timer Expired"));
|
||||
}
|
||||
if (flag0 & BQ25628E_FLAG0_SAFETY_TMR_FLAG) {
|
||||
Serial.println(F(" 🚩 Safety Timer Expired"));
|
||||
}
|
||||
if (flag0 & BQ25628E_FLAG0_VINDPM_FLAG) {
|
||||
Serial.println(F(" 🚩 VINDPM Regulation Event"));
|
||||
}
|
||||
if (flag0 & BQ25628E_FLAG0_IINDPM_FLAG) {
|
||||
Serial.println(F(" 🚩 IINDPM/ILIM Regulation Event"));
|
||||
}
|
||||
if (flag0 & BQ25628E_FLAG0_VSYS_FLAG) {
|
||||
Serial.println(F(" 🚩 VSYSMIN Regulation Event"));
|
||||
}
|
||||
if (flag0 & BQ25628E_FLAG0_TREG_FLAG) {
|
||||
Serial.println(F(" 🚩 Thermal Regulation Event"));
|
||||
}
|
||||
if (flag0 & BQ25628E_FLAG0_ADC_DONE_FLAG) {
|
||||
Serial.println(F(" 🚩 ADC Conversion Complete"));
|
||||
}
|
||||
|
||||
// Flag1 bits
|
||||
if (flag1 & BQ25628E_FLAG1_VBUS_FLAG) {
|
||||
Serial.println(F(" 🚩 VBUS Status Changed"));
|
||||
}
|
||||
if (flag1 & BQ25628E_FLAG1_CHG_FLAG) {
|
||||
Serial.println(F(" 🚩 Charge Status Changed"));
|
||||
}
|
||||
} else {
|
||||
Serial.println(F("No charger flags set"));
|
||||
}
|
||||
|
||||
// REG0x22 Fault Flag status (cleared on read!)
|
||||
if (faultFlagsCleared != 0) {
|
||||
Serial.print(F("Fault Flags (0x"));
|
||||
Serial.print(faultFlagsCleared, HEX);
|
||||
Serial.println(F(") - CLEARED:"));
|
||||
|
||||
if (faultFlagsCleared & BQ25628E_FAULT_FLAG_VBUS_FAULT) {
|
||||
Serial.println(F(" 💥 VBUS Fault Event (OVP/Sleep)"));
|
||||
}
|
||||
if (faultFlagsCleared & BQ25628E_FAULT_FLAG_BAT_FAULT) {
|
||||
Serial.println(F(" 💥 Battery Fault Event (OCP/OVP)"));
|
||||
}
|
||||
if (faultFlagsCleared & BQ25628E_FAULT_FLAG_SYS_FAULT) {
|
||||
Serial.println(F(" 💥 System Fault Event (OVP/Short)"));
|
||||
}
|
||||
if (faultFlagsCleared & BQ25628E_FAULT_FLAG_TSHUT) {
|
||||
Serial.println(F(" 💥 Thermal Shutdown Event"));
|
||||
}
|
||||
if (faultFlagsCleared & BQ25628E_FAULT_FLAG_TS_CHANGED) {
|
||||
Serial.println(F(" 💥 TS Status Changed Event"));
|
||||
}
|
||||
} else {
|
||||
Serial.println(F("No fault flags set"));
|
||||
}
|
||||
|
||||
// Display current interrupt mask status
|
||||
uint32_t currentMask = bq.getInterruptMask();
|
||||
Serial.print(F("INT Mask: CHG="));
|
||||
Serial.print((currentMask & BQ25628E_INT_MASK_CHG) ? F("OFF") : F("ON"));
|
||||
Serial.print(F(", VBUS="));
|
||||
Serial.print((currentMask & BQ25628E_INT_MASK_VBUS) ? F("OFF") : F("ON"));
|
||||
Serial.print(F(", Others="));
|
||||
Serial.println((currentMask & ~(BQ25628E_INT_MASK_CHG | BQ25628E_INT_MASK_VBUS)) ? F("OFF") : F("ON"));
|
||||
|
||||
Serial.println(F("====================="));
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
delay(1000);
|
||||
static unsigned long lastStatusTime = 0;
|
||||
static unsigned long lastADCTime = 0;
|
||||
unsigned long currentTime = millis();
|
||||
|
||||
// Print all ADC values every 1 second
|
||||
if (currentTime - lastADCTime >= 1000) {
|
||||
float ibus_current = bq.getIBUScurrent();
|
||||
float ibat_current = bq.getIBATcurrent();
|
||||
float vbus_voltage = bq.getVBUSvoltage();
|
||||
float vpmid_voltage = bq.getVPMIDvoltage();
|
||||
float vbat_voltage = bq.getVBATvoltage();
|
||||
float vsys_voltage = bq.getVSYSvoltage();
|
||||
float thermistor_percent = bq.getThermistorPercent();
|
||||
float die_temp = bq.getDieTempC();
|
||||
|
||||
Serial.print(F("ADC: IBUS="));
|
||||
Serial.print(ibus_current, 3);
|
||||
Serial.print(F("A, IBAT="));
|
||||
Serial.print(ibat_current, 3);
|
||||
Serial.print(F("A, VBUS="));
|
||||
Serial.print(vbus_voltage, 3);
|
||||
Serial.print(F("V, VPMID="));
|
||||
Serial.print(vpmid_voltage, 3);
|
||||
Serial.print(F("V, VBAT="));
|
||||
Serial.print(vbat_voltage, 3);
|
||||
Serial.print(F("V, VSYS="));
|
||||
Serial.print(vsys_voltage, 3);
|
||||
Serial.print(F("V, TS="));
|
||||
Serial.print(thermistor_percent, 1);
|
||||
Serial.print(F("%, TDIE="));
|
||||
Serial.print(die_temp, 1);
|
||||
Serial.println(F("°C"));
|
||||
|
||||
lastADCTime = currentTime;
|
||||
}
|
||||
|
||||
// Print status every 5 seconds
|
||||
if (currentTime - lastStatusTime >= 5000) {
|
||||
printChargerStatus();
|
||||
lastStatusTime = currentTime;
|
||||
}
|
||||
|
||||
delay(100);
|
||||
}
|
||||
Loading…
Reference in a new issue