Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/utility/Power_Class.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,9 @@ namespace m5

/// get battery current
/// @return battery current [mA] ( +=charge / -=discharge )
/// @attention This reading comes from the hardware of the board: an AXP192, or a
/// dedicated current sense IC ( ex. Core2 v1.1 , M5Tab5 , M5PowerHub ).
/// Boards without either of them return 0.
int32_t getBatteryCurrent(void);

/// Get Ext Port voltage
Expand Down
53 changes: 37 additions & 16 deletions src/utility/power/AXP2101_Class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#endif

#include <algorithm>
#include <limits>

#define IS_BIT_SET(val,mask) (((val)&(mask)) == (mask))

Expand Down Expand Up @@ -213,35 +214,49 @@ return false;
return val >> 2;
}

float AXP2101_Class::getACINVoltage(void)
/// Used where the AXP2101 provides no reading for the requested value.
/// Returning NaN instead of 0 lets the caller tell it from a real zero.
static constexpr float not_available(void)
{
return 0;
return std::numeric_limits<float>::quiet_NaN();
}

/// A 14 bit ADC channel sits at the top of its range when there is nothing to measure
/// on it, so a reading within this margin of full scale is not treated as a value.
/// A channel that does have an input reads far below the margin; measured on a CoreS3,
/// the closest was TS at 5563, while VBUS with nothing connected read 16372.
static constexpr std::size_t adc_full_scale = 0x3FFF;
static constexpr std::size_t adc_invalid_min = adc_full_scale - 32;

float AXP2101_Class::getACINVoltage(void)
{ // The AXP2101 takes its input from VBUS. ( see getVBUSVoltage )
return not_available();
}

float AXP2101_Class::getACINCurrent(void)
{
return 0;
{ // The AXP2101 takes its input from VBUS.
return not_available();
}

float AXP2101_Class::getVBUSVoltage(void)
{
if (isVBUS() == false) { return 0.0f; }

float vBus = readRegister14(0x38);
if (vBus >= 16375) { return 0.0f; }
if (vBus >= adc_invalid_min) { return 0.0f; }

return vBus / 1000.0f;
}

float AXP2101_Class::getVBUSCurrent(void)
{
return 0;
{ // Not provided by the AXP2101. ( see getBatteryChargeCurrent )
return not_available();
}

float AXP2101_Class::getTSVoltage(void)
{
float volt = readRegister14(0x36);
if (volt >= 16375) { return 0.0f; }
if (volt >= adc_invalid_min) { return 0.0f; }

return volt / 2000.0f;
}
Expand All @@ -252,8 +267,8 @@ return 0;
}

float AXP2101_Class::getBatteryPower(void)
{
return 0;
{ // Derived from the battery current, which the AXP2101 does not provide.
return not_available();
}

float AXP2101_Class::getBatteryVoltage(void)
Expand All @@ -262,18 +277,24 @@ return 0;
}

float AXP2101_Class::getBatteryChargeCurrent(void)
{
return 0;
{ // The ADC of the AXP2101 covers VBAT / TS / VBUS / VSYS / TDIE. Current is measured
// by a dedicated sense IC where the board provides one ( ex. INA3221 on Core2 v1.1 ,
// INA226 on M5Tab5 ) , and Power_Class::getBatteryCurrent() reads that IC.
return not_available();
}

float AXP2101_Class::getBatteryDischargeCurrent(void)
{
return 0;
{ // Not provided by the AXP2101. ( see getBatteryChargeCurrent )
return not_available();
}

float AXP2101_Class::getAPSVoltage(void)
{
return 0;
{ // VSYS is the equivalent measurement point on the AXP2101 of the APS rail
// of the AXP192.
float volt = readRegister14(0x3A);
if (volt >= adc_invalid_min) { return 0.0f; }

return volt / 1000.0f;
}

bool AXP2101_Class::enableIRQ(std::uint64_t registerEn)
Expand Down
15 changes: 15 additions & 0 deletions src/utility/power/AXP2101_Class.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,15 +122,30 @@ namespace m5
bool isVBUS(void);
bool getBatState(void);

/// The ADC of the AXP2101 covers these measurement points:
/// VBAT , TS , VBUS , VSYS , TDIE
/// The getters below that fall outside this set return NaN, so that a caller can
/// tell an unavailable reading from a real zero with std::isnan().
/// Current is measured by a dedicated sense IC where the board provides one
/// ( ex. INA3221 on Core2 v1.1 , INA226 on M5Tab5 ) , and Power_Class reads that IC.

float getBatteryVoltage(void);
/// @return NaN. This reading is not provided by the AXP2101.
float getBatteryDischargeCurrent(void);
/// @return NaN. This reading is not provided by the AXP2101.
float getBatteryChargeCurrent(void);
/// @return NaN. Derived from the battery current, which the AXP2101 does not provide.
float getBatteryPower(void);
/// @return NaN. The AXP2101 takes its input from VBUS. ( see getVBUSVoltage )
float getACINVoltage(void);
/// @return NaN. The AXP2101 takes its input from VBUS.
float getACINCurrent(void);
float getVBUSVoltage(void);
/// @return NaN. This reading is not provided by the AXP2101.
float getVBUSCurrent(void);
float getTSVoltage(void);
/// The VSYS voltage is returned, which is the equivalent measurement point on the
/// AXP2101 of the APS rail of the AXP192.
float getAPSVoltage(void);
float getInternalTemperature(void);

Expand Down
Loading