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: 2 additions & 1 deletion src/utility/Power_Class.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,8 @@ namespace m5

/// Get Power Key Press condition.
/// @return 0=none / 1=long pressed / 2=short clicked / 3=both
/// @attention Only for models with AXP192 or AXP2101
/// @attention Only for models with AXP192, AXP2101, or M5PM1.
/// @attention M5PM1 reports only 0 or 2.
/// @attention Once this function is called, the value is reset to 0, and the next time it is pressed on, the value changes.
uint8_t getKeyState(void);

Expand Down
45 changes: 18 additions & 27 deletions src/utility/power/M5PM1_Class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ namespace m5

bool M5PM1_Class::setGPIOFunction(gpio_t pin, gpio_function_t function)
{
if (!is_valid_gpio(pin)) { return false; }
if (!is_valid_gpio(pin)
|| (function != gpio && function != irq && function != special)) { return false; }
auto num = gpio_num(pin);
auto reg = num < 4 ? M5PM1_REG_GPIO_FUNC0 : M5PM1_REG_GPIO_FUNC1;
auto shift = static_cast<std::uint8_t>((num < 4 ? num : num - 4) * 2);
Expand Down Expand Up @@ -215,8 +216,7 @@ namespace m5

bool M5PM1_Class::clearWakeSource(std::uint8_t mask)
{
auto src = readRegister8(M5PM1_REG_WAKE_SRC);
return writeRegister8(M5PM1_REG_WAKE_SRC, src & ~mask);
return writeRegister8(M5PM1_REG_WAKE_SRC, static_cast<std::uint8_t>(~mask & 0x7F));
}

bool M5PM1_Class::clearGPIOIRQStatus(void)
Expand Down Expand Up @@ -264,7 +264,7 @@ namespace m5

bool M5PM1_Class::getBatteryCharge(bool* enabled)
{
if (!_init) { return false; }
if (!_init || enabled == nullptr) { return false; }
std::uint8_t cfg = 0;
if (!readRegister(M5PM1_REG_PWR_CFG, &cfg, 1)) { return false; }
*enabled = cfg & M5PM1_PWR_CFG_CHG_EN;
Expand All @@ -274,25 +274,11 @@ namespace m5
bool M5PM1_Class::setChargeCurrent(std::uint16_t max_mA)
{
return false;
// if (!_init) return false;
// int value = max_mA / 8; // Convert mA to register value (8mA per step)
// if (value > 0) { value -= 1; // 0 = 8mA, 63 = 512mA
// if (value >= 64) value = 63; // max value is 512mA (8 + 63*8)
// }
// return writeRegister8(M5PM1_REG_CHR_CUR, value);
}

bool M5PM1_Class::setChargeVoltage(std::uint16_t max_mV)
{
return false;
// if (!_init) return false;
// int value = (max_mV - 3600) / 15; // Convert mV to register value (15mV per step)
// if (value > 0) { value -= 1; // 0 = 3600mV, 63 = 4545mV
// if (value >= 64) value = 63; // max value is 4545mV (3600 + 63*15)
// }
// uint8_t reg_value = readRegister8(M5PM1_REG_CHR_VOL);
// reg_value &= 0xC0;
// return writeRegister8(M5PM1_REG_CHR_VOL, reg_value | value);
}

std::uint16_t M5PM1_Class::getChargeCurrent(void)
Expand All @@ -314,14 +300,19 @@ namespace m5
{
if (!_init) return 0;
uint8_t irq3 = 0;
if (readRegister(M5PM1_REG_IRQ_STATUS3, &irq3, 1))
{
if (irq3 & ((1 << 0) | (1 << 2))) {
writeRegister8(M5PM1_REG_IRQ_STATUS3, 0);
return 2;
}
}
return 0;
if (!readRegister(M5PM1_REG_IRQ_STATUS3, &irq3, 1)) return 0;
uint8_t pending = irq3 & ((1 << 0) | (1 << 2));
if (!pending) return 0;
if (!writeRegister8(M5PM1_REG_IRQ_STATUS3, static_cast<uint8_t>(~pending & 0x07))) return 0;
_pek_double_pending = (pending & (1 << 2)) != 0;
return 2;
}

bool M5PM1_Class::wasPekDoubleClicked(void)
{
bool result = _pek_double_pending;
_pek_double_pending = false;
return result;
}

std::uint16_t M5PM1_Class::getVBUSVoltage(void)
Expand All @@ -339,7 +330,7 @@ namespace m5

bool M5PM1_Class::getBatteryVoltage(std::uint16_t* millivolt)
{
if (!_init) { return false; }
if (!_init || millivolt == nullptr) { return false; }
std::uint8_t buf[2] = {};
if (!readRegister(M5PM1_REG_VBAT_L, buf, sizeof(buf))) { return false; }
*millivolt = (buf[1] << 8) | buf[0];
Expand Down
34 changes: 27 additions & 7 deletions src/utility/power/M5PM1_Class.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ namespace m5
enum gpio_function_t : std::uint8_t
{ gpio = 0b00
, irq = 0b01
, wake = 0b10
// 0b10 is reserved in the datasheet.
, special = 0b11
};

Expand Down Expand Up @@ -81,7 +81,7 @@ namespace m5
/// @param enable true=enable / false=disable
bool setLDOOutput(bool enable);

/// set PM1 5V DCDC output enable.
/// set PM1 3.3V DCDC rail output enable (PWR_CFG bit1 = 3.3V_DCDC_EN).
/// @param enable true=enable / false=disable
bool setDCDCOutput(bool enable);

Expand Down Expand Up @@ -150,6 +150,9 @@ namespace m5
pwm_polarity_t polarity = pwm_polarity_t::normal, bool enable = true);

/// clear PM1 wake source bits selected by mask.
/// Single-write selective clear assuming the write-zero-to-clear behavior
/// adopted by the official driver; the datasheet does not specify the write polarity.
/// Bits outside [6:0] are written as zero, matching the full-clear precedent.
bool clearWakeSource(std::uint8_t mask = 0x7F);

/// clear all PM1 GPIO IRQ status bits.
Expand Down Expand Up @@ -183,28 +186,42 @@ namespace m5
bool getBatteryCharge(bool* enabled);

/// set battery charge current
/// @param max_mA milli ampere. (8 - 512).
/// @param max_mA ignored; the PM1 has no charge current register.
/// @note The PM1 register map exposes no charge current register; this is a permanent stub returning false.
bool setChargeCurrent(std::uint16_t max_mA);

/// set battery charge voltage
/// @param max_mV milli volt. (3600 - 4545).
/// @param max_mV ignored; the PM1 has no charge voltage register.
/// @note The PM1 register map exposes no charge voltage register; this is a permanent stub returning false.
bool setChargeVoltage(std::uint16_t max_mV);

/// Get whether the battery is currently charging or not.
/// @note The PM1 register map exposes no charging status register; this is a permanent stub returning false.
bool isCharging(void);

// get setting value of battery charge current
/// @return milli ampere. (8 - 512). 0=unknown
/// @return always 0.
/// @note The PM1 register map exposes no charge current register; this is a permanent stub returning 0.
std::uint16_t getChargeCurrent(void);

// get setting value of battery charge voltage
/// @return milli volt. (3600 - 4545). 0=unknown
/// @return always 0.
/// @note The PM1 register map exposes no charge voltage register; this is a permanent stub returning 0.
std::uint16_t getChargeVoltage(void);

/// Get power key press condition.
/// @return 0=none / 2=short clicked
/// @return 0=none / 2=short clicked. For AXP compatibility, a double click
/// also reports 2; use wasPekDoubleClicked() to distinguish it.
/// Only the consumed click flags are cleared; the WAKEUP flag is preserved.
/// Returns 0 and leaves the event pending if the clear write fails.
uint8_t getPekPress(void);

/// Returns whether the most recently reported click (getPekPress() == 2)
/// was a double click, then clears the flag.
/// Call from the task that polls getPekPress() (typically right after
/// M5.update()); the flag is not synchronized across tasks.
bool wasPekDoubleClicked(void);

/// get VIN voltage.
/// @return milli volt. 0=read failed
std::uint16_t getVBUSVoltage(void);
Expand All @@ -224,6 +241,9 @@ namespace m5

/// power off PM1.
bool powerOff(void);

private:
bool _pek_double_pending = false;
};
}

Expand Down
Loading