Skip to content

Commit a7e10f6

Browse files
committed
nicla-system: Avoid High-Z mode when powered from VIN.
1 parent b2311dc commit a7e10f6

File tree

2 files changed

+43
-7
lines changed

2 files changed

+43
-7
lines changed

libraries/Nicla_System/src/BQ25120A.cpp

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,21 @@ uint8_t BQ25120A::getLDOControlRegister()
3030
return readByte(BQ25120A_ADDRESS, BQ25120A_LDO_CTRL);
3131
}
3232

33+
bool BQ25120A::runsOnBattery(uint8_t address){
34+
uint8_t faults = readByteUnprotected(address, BQ25120A_FAULTS);
35+
// Read VIN under voltage fault (VIN_UV on Bit 6) from the faults register.
36+
bool runsOnBattery = (faults & 0b01000000) != 0;
37+
return runsOnBattery;
38+
}
39+
3340
void BQ25120A::writeByte(uint8_t address, uint8_t subAddress, uint8_t data)
3441
{
35-
setHighImpedanceModeEnabled(false);
3642
nicla::_i2c_mutex.lock();
43+
// Only enter active mode when runnning on battery.
44+
// When powered from VIN, driving CD HIGH would disable charging.
45+
if(runsOnBattery(address)){
46+
setHighImpedanceModeEnabled(false);
47+
}
3748
Wire1.beginTransmission(address);
3849
Wire1.write(subAddress);
3950
Wire1.write(data);
@@ -42,19 +53,27 @@ void BQ25120A::writeByte(uint8_t address, uint8_t subAddress, uint8_t data)
4253
setHighImpedanceModeEnabled(true);
4354
}
4455

45-
uint8_t BQ25120A::readByte(uint8_t address, uint8_t subAddress)
46-
{
47-
setHighImpedanceModeEnabled(false);
48-
nicla::_i2c_mutex.lock();
56+
uint8_t BQ25120A::readByteUnprotected(uint8_t address, uint8_t subAddress){
4957
Wire1.beginTransmission(address);
5058
Wire1.write(subAddress);
5159
Wire1.endTransmission(false);
5260
Wire1.requestFrom(address, 1);
5361
uint32_t timeout = 100;
5462
uint32_t start_time = millis();
5563
while(!Wire1.available() && (millis() - start_time) < timeout) {}
56-
uint8_t ret = Wire1.read();
57-
nicla::_i2c_mutex.unlock();
64+
return Wire1.read();
65+
}
66+
67+
uint8_t BQ25120A::readByte(uint8_t address, uint8_t subAddress)
68+
{
69+
nicla::_i2c_mutex.lock();
70+
// Only enter active mode when runnning on battery.
71+
// When powered from VIN, driving CD HIGH would disable charging.
72+
if(runsOnBattery(address)){
73+
setHighImpedanceModeEnabled(false);
74+
}
75+
uint8_t ret = readByteUnprotected(address, subAddress);
76+
nicla::_i2c_mutex.unlock();
5877
setHighImpedanceModeEnabled(true);
5978
return ret;
6079
}

libraries/Nicla_System/src/BQ25120A.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@ class BQ25120A
5757
*/
5858
uint8_t getFastChargeControlRegister();
5959

60+
61+
/**
62+
* @brief Determines if the board is charged from the battery.
63+
*
64+
* @return true If the board is powered from the battery. False, when powered from USB / VIN.
65+
*/
66+
bool runsOnBattery(uint8_t address);
67+
6068
/**
6169
* @brief Writes a byte to the BQ25120A over I2C.
6270
* @param address The I2C address of the BQ25120A.
@@ -89,6 +97,15 @@ class BQ25120A
8997
* @param enabled Defines if the high impedance mode should be enabled or disabled.
9098
*/
9199
void setHighImpedanceModeEnabled(bool enabled);
100+
101+
/**
102+
* @brief Reads a byte from the BQ25120A over I2C without locking the bus through the mutex.
103+
*
104+
* @param address The I2C address of the BQ25120A.
105+
* @param subAddress The memory location of the register to read from.
106+
* @return uint8_t The data read from the register.
107+
*/
108+
uint8_t readByteUnprotected(uint8_t address, uint8_t subAddress);
92109
};
93110

94111
#endif

0 commit comments

Comments
 (0)