mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-07-28 04:07:47 +00:00
[P138] Add IP5306 library to lib folder
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 honey the codewitch
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,13 @@
|
||||
# button
|
||||
|
||||
This library allows you to use the IP5306 power management module
|
||||
|
||||
```
|
||||
[env:node32s]
|
||||
platform = espressif32
|
||||
board = node32s
|
||||
framework = arduino
|
||||
lib_deps =
|
||||
codewitch-honey-crisis/htcw_ip5306@^0.1.0
|
||||
lib_ldf_mode = deep
|
||||
```
|
||||
@@ -0,0 +1,108 @@
|
||||
#pragma once
|
||||
#include <Arduino.h>
|
||||
#include <Wire.h>
|
||||
namespace arduino {
|
||||
enum struct ip5306_shutdown {
|
||||
after_8s=0,
|
||||
after_32s=1,
|
||||
after_16s=2,
|
||||
after_64s=3
|
||||
};
|
||||
enum struct ip5306_charging_full_voltage {
|
||||
at_4_14v=0,
|
||||
at_4_17v=1,
|
||||
at_4_185v=2,
|
||||
at_4_2v=3,
|
||||
};
|
||||
enum struct ip5306_press_time {
|
||||
press_2_seconds=0,
|
||||
press_3_seconds=1
|
||||
};
|
||||
enum struct ip5306_end_charge_current {
|
||||
at_200mA = 0,
|
||||
at_400mA = 1,
|
||||
at_500mA = 2,
|
||||
at_600mA = 3
|
||||
};
|
||||
enum struct ip5306_voltage_pressure {
|
||||
none = 0,
|
||||
p_14mV=1,
|
||||
p_28mV=2,
|
||||
p_42mV=3
|
||||
};
|
||||
enum struct ip5306_charge_cutoff_voltage {
|
||||
at_4_2v = 0,
|
||||
at_4_3v = 1,
|
||||
at_4_35v = 2,
|
||||
at_4_4v = 3
|
||||
};
|
||||
enum struct ip5306_source {
|
||||
battery = 0,
|
||||
vin = 1
|
||||
};
|
||||
enum struct ip5306_load {
|
||||
heavy = 0,
|
||||
light = 1
|
||||
};
|
||||
enum struct ip5306_presses {
|
||||
short_press_twice = 0,
|
||||
long_press_once = 1
|
||||
};
|
||||
class ip5306 {
|
||||
TwoWire& m_i2c;
|
||||
public:
|
||||
constexpr static const uint8_t address = 0x75;
|
||||
inline ip5306(TwoWire& i2c=Wire) : m_i2c(i2c) {
|
||||
|
||||
}
|
||||
bool key_off() const;
|
||||
void key_off(bool value);
|
||||
bool boost_output() const;
|
||||
void boost_output(bool value);
|
||||
bool power_on_load() const;
|
||||
void power_on_load(bool value);
|
||||
bool charger() const;
|
||||
void charger(bool value);
|
||||
bool boost() const;
|
||||
void boost(bool value);
|
||||
bool low_battery_shutdown() const;
|
||||
void low_battery_shutdown(bool value);
|
||||
bool boost_after_vin() const;
|
||||
void boost_after_vin(bool value);
|
||||
bool short_press_boot_switch() const;
|
||||
void short_press_boot_switch(bool value);
|
||||
ip5306_presses flashlight_clicks() const;
|
||||
void flashlight_clicks(ip5306_presses value);
|
||||
ip5306_presses boost_off_clicks() const;
|
||||
void boost_off_clicks(ip5306_presses value);
|
||||
ip5306_shutdown light_load_shutdown_time() const;
|
||||
void light_load_shutdown_time(ip5306_shutdown value);
|
||||
ip5306_press_time long_press_time() const;
|
||||
void long_press_time(ip5306_press_time value);
|
||||
ip5306_charging_full_voltage charging_full_stop_voltage() const;
|
||||
void charging_full_stop_voltage(ip5306_charging_full_voltage value);
|
||||
float charge_under_voltage_loop() const;
|
||||
void charge_under_voltage_loop(float value);
|
||||
ip5306_end_charge_current end_charge_current_detection() const;
|
||||
void end_charge_current_detection(ip5306_end_charge_current value);
|
||||
ip5306_voltage_pressure voltage_pressure() const;
|
||||
void voltage_pressure(ip5306_voltage_pressure value);
|
||||
ip5306_charge_cutoff_voltage charge_cutoff_voltage() const;
|
||||
void charge_cutoff_voltage(ip5306_charge_cutoff_voltage value);
|
||||
ip5306_source charge_cc_loop() const;
|
||||
void charge_cc_loop(ip5306_source value);
|
||||
unsigned vin_current() const;
|
||||
void vin_current(unsigned value);
|
||||
bool short_press_detected() const;
|
||||
void clear_short_press_detected();
|
||||
bool long_press_detected() const;
|
||||
void clear_long_press_detected();
|
||||
bool double_click_detected() const;
|
||||
void clear_double_click_detected();
|
||||
ip5306_source power_source() const;
|
||||
bool battery_full() const;
|
||||
ip5306_load output_load() const;
|
||||
float charge_level() const;
|
||||
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "htcw_ip5306",
|
||||
"version": "0.1.0",
|
||||
"description": "Provides support for the IP5306 power module",
|
||||
"keywords": ["power", "battery", "sleep"],
|
||||
"authors": {
|
||||
"name":"honey the codewitch",
|
||||
"homepage": "https://www.codeproject.com/Members/code-witch"
|
||||
},
|
||||
"license": "MIT",
|
||||
"frameworks": ["arduino"],
|
||||
"platforms": "*",
|
||||
"repository":
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/codewitch-honey-crisis/htcw_ip5306.git"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,250 @@
|
||||
#include <ip5306.hpp>
|
||||
namespace arduino {
|
||||
// based on
|
||||
// https://gist.github.com/me-no-dev/7702f08dd578de5efa47caf322250b57
|
||||
|
||||
/*
|
||||
** IP5306 Power Module
|
||||
*/
|
||||
|
||||
/* M5 Defaults
|
||||
KeyOff: Enabled
|
||||
BoostOutput: Disabled
|
||||
PowerOnLoad: Enabled
|
||||
Charger: Enabled
|
||||
Boost: Enabled
|
||||
LowBatShutdown: Enabled
|
||||
ShortPressBoostSwitch: Disabled
|
||||
FlashlightClicks: Double Press
|
||||
BoostOffClicks: Long Press
|
||||
BoostAfterVin: Open
|
||||
LongPressTime: 2s
|
||||
ChargeUnderVoltageLoop: 4.55V
|
||||
ChargeCCLoop: Vin
|
||||
VinCurrent: 2250mA
|
||||
VoltagePressure: 28mV
|
||||
ChargingFullStopVoltage: 4.17V
|
||||
LightLoadShutdownTime: 32s
|
||||
EndChargeCurrentDetection: 500mA
|
||||
ChargeCutoffVoltage: 4.2V
|
||||
*/
|
||||
|
||||
#define IP5306_REG_SYS_0 0x00
|
||||
#define IP5306_REG_SYS_1 0x01
|
||||
#define IP5306_REG_SYS_2 0x02
|
||||
#define IP5306_REG_CHG_0 0x20
|
||||
#define IP5306_REG_CHG_1 0x21
|
||||
#define IP5306_REG_CHG_2 0x22
|
||||
#define IP5306_REG_CHG_3 0x23
|
||||
#define IP5306_REG_CHG_4 0x24
|
||||
#define IP5306_REG_READ_0 0x70
|
||||
#define IP5306_REG_READ_1 0x71
|
||||
#define IP5306_REG_READ_2 0x72
|
||||
#define IP5306_REG_READ_3 0x77
|
||||
#define IP5306_REG_READ_4 0x78
|
||||
|
||||
#define IP5306_LEDS2PCT(byte) \
|
||||
((byte & 0x01 ? 25 : 0) + \
|
||||
(byte & 0x02 ? 25 : 0) + \
|
||||
(byte & 0x04 ? 25 : 0) + \
|
||||
(byte & 0x08 ? 25 : 0))
|
||||
|
||||
int ip5306_get_reg(TwoWire& i2c, uint8_t reg){
|
||||
i2c.beginTransmission(ip5306::address);
|
||||
i2c.write(reg);
|
||||
if(i2c.endTransmission(false) == 0 && i2c.requestFrom(0x75, 1)){
|
||||
return i2c.read();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ip5306_set_reg(TwoWire& i2c, uint8_t reg, uint8_t value){
|
||||
i2c.beginTransmission(ip5306::address);
|
||||
i2c.write(reg);
|
||||
i2c.write(value);
|
||||
if(i2c.endTransmission(true) == 0){
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t ip5306_get_bits(TwoWire& i2c, uint8_t reg, uint8_t index, uint8_t bits){
|
||||
int value = ip5306_get_reg(i2c,reg);
|
||||
if(value < 0){
|
||||
Serial.printf("ip5306_get_bits fail: 0x%02x\n", reg);
|
||||
return 0;
|
||||
}
|
||||
return (value >> index) & ((1 << bits)-1);
|
||||
}
|
||||
|
||||
void ip5306_set_bits(TwoWire& i2c, uint8_t reg, uint8_t index, uint8_t bits, uint8_t value){
|
||||
uint8_t mask = (1 << bits) - 1;
|
||||
int v = ip5306_get_reg(i2c,reg);
|
||||
if(v < 0){
|
||||
Serial.printf("ip5306_get_reg fail: 0x%02x\n", reg);
|
||||
return;
|
||||
}
|
||||
v &= ~(mask << index);
|
||||
v |= ((value & mask) << index);
|
||||
if(ip5306_set_reg(i2c,reg, v)){
|
||||
Serial.printf("ip5306_set_bits fail: 0x%02x\n", reg);
|
||||
}
|
||||
}
|
||||
|
||||
bool ip5306::key_off() const {
|
||||
return ip5306_get_bits(m_i2c,IP5306_REG_SYS_0, 0, 1);
|
||||
}
|
||||
void ip5306::key_off(bool value) {
|
||||
ip5306_set_bits(m_i2c,IP5306_REG_SYS_0, 0, 1, value);
|
||||
}
|
||||
bool ip5306::boost_output() const {
|
||||
return ip5306_get_bits(m_i2c,IP5306_REG_SYS_0, 1, 1);
|
||||
}
|
||||
void ip5306::boost_output(bool value) {
|
||||
ip5306_set_bits(m_i2c,IP5306_REG_SYS_0, 1, 1, value);
|
||||
}
|
||||
|
||||
bool ip5306::power_on_load() const {
|
||||
return ip5306_get_bits(m_i2c,IP5306_REG_SYS_0, 2, 1);
|
||||
}
|
||||
void ip5306::power_on_load(bool value) {
|
||||
ip5306_set_bits(m_i2c,IP5306_REG_SYS_0, 2, 1, value);
|
||||
}
|
||||
bool ip5306::charger() const {
|
||||
return ip5306_get_bits(m_i2c,IP5306_REG_SYS_0, 4, 1);
|
||||
|
||||
}
|
||||
void ip5306::charger(bool value) {
|
||||
ip5306_set_bits(m_i2c,IP5306_REG_SYS_0, 4, 1, value);
|
||||
}
|
||||
bool ip5306::boost() const {
|
||||
return ip5306_get_bits(m_i2c,IP5306_REG_SYS_0, 5, 1);
|
||||
}
|
||||
void ip5306::boost(bool value) {
|
||||
ip5306_set_bits(m_i2c,IP5306_REG_SYS_0, 5, 1, value);
|
||||
}
|
||||
bool ip5306::low_battery_shutdown() const {
|
||||
return ip5306_get_bits(m_i2c,IP5306_REG_SYS_1, 0, 1);
|
||||
}
|
||||
void ip5306::low_battery_shutdown(bool value) {
|
||||
ip5306_set_bits(m_i2c,IP5306_REG_SYS_1, 0, 1, value);
|
||||
}
|
||||
bool ip5306::boost_after_vin() const {
|
||||
return ip5306_get_bits(m_i2c,IP5306_REG_SYS_1, 2, 1);
|
||||
}
|
||||
void ip5306::boost_after_vin(bool value) {
|
||||
ip5306_set_bits(m_i2c,IP5306_REG_SYS_1, 2, 1, value);
|
||||
}
|
||||
bool ip5306::short_press_boot_switch() const {
|
||||
return ip5306_get_bits(m_i2c,IP5306_REG_SYS_1, 5, 1);
|
||||
}
|
||||
void ip5306::short_press_boot_switch(bool value) {
|
||||
return ip5306_set_bits(m_i2c,IP5306_REG_SYS_1, 5, 1, value);
|
||||
}
|
||||
ip5306_presses ip5306::flashlight_clicks() const {
|
||||
return (ip5306_presses)ip5306_get_bits(m_i2c,IP5306_REG_SYS_1, 6, 1);
|
||||
}
|
||||
void ip5306::flashlight_clicks(ip5306_presses value) {
|
||||
ip5306_set_bits(m_i2c,IP5306_REG_SYS_1, 6, 1, (int)value);
|
||||
}
|
||||
ip5306_presses ip5306::boost_off_clicks() const {
|
||||
return (ip5306_presses)(1-ip5306_get_bits(m_i2c,IP5306_REG_SYS_1, 7, 1));
|
||||
}
|
||||
void ip5306::boost_off_clicks(ip5306_presses value) {
|
||||
ip5306_set_bits(m_i2c,IP5306_REG_SYS_1, 7, 1, 1-((int)value));
|
||||
}
|
||||
ip5306_shutdown ip5306::light_load_shutdown_time() const {
|
||||
return (ip5306_shutdown)ip5306_get_bits(m_i2c,IP5306_REG_SYS_2, 2, 2);
|
||||
}
|
||||
void ip5306::light_load_shutdown_time(ip5306_shutdown value) {
|
||||
ip5306_set_bits(m_i2c,IP5306_REG_SYS_2, 2, 2, (int)value);
|
||||
}
|
||||
ip5306_press_time ip5306::long_press_time() const {
|
||||
return (ip5306_press_time)ip5306_get_bits(m_i2c,IP5306_REG_SYS_2, 4, 1);
|
||||
}
|
||||
void ip5306::long_press_time(ip5306_press_time value) {
|
||||
ip5306_set_bits(m_i2c,IP5306_REG_SYS_2, 4, 1, (int)value);
|
||||
}
|
||||
ip5306_charging_full_voltage ip5306::charging_full_stop_voltage() const {
|
||||
return (ip5306_charging_full_voltage)ip5306_get_bits(m_i2c,IP5306_REG_CHG_0, 0, 2);
|
||||
}
|
||||
void ip5306::charging_full_stop_voltage(ip5306_charging_full_voltage value) {
|
||||
ip5306_set_bits(m_i2c,IP5306_REG_CHG_0, 0, 2, (int)value);
|
||||
}
|
||||
float ip5306::charge_under_voltage_loop() const {
|
||||
//Automatically adjust the charging current when the voltage of VOUT is greater than the set value
|
||||
//Vout=4.45V + (v * 0.05V) (default 4.55V)
|
||||
//When charging at the maximum current, the charge is less than the set value. Slowly reducing the charging current to maintain this voltage
|
||||
int v = ip5306_get_bits(m_i2c,IP5306_REG_CHG_1, 2, 3);
|
||||
return 4.45+(v*.05);
|
||||
}
|
||||
void ip5306::charge_under_voltage_loop(float value) {
|
||||
value-=4.45;
|
||||
int i = value/.05;
|
||||
ip5306_set_bits(m_i2c,IP5306_REG_CHG_1, 2, 3, i);
|
||||
}
|
||||
ip5306_end_charge_current ip5306::end_charge_current_detection() const {
|
||||
return (ip5306_end_charge_current)ip5306_get_bits(m_i2c,IP5306_REG_CHG_1, 6, 2);
|
||||
}
|
||||
void ip5306::end_charge_current_detection(ip5306_end_charge_current value) {
|
||||
ip5306_set_bits(m_i2c,IP5306_REG_CHG_1, 6, 2, (int)value);
|
||||
}
|
||||
ip5306_voltage_pressure ip5306::voltage_pressure() const {
|
||||
return (ip5306_voltage_pressure)ip5306_get_bits(m_i2c,IP5306_REG_CHG_2, 0, 2);
|
||||
}
|
||||
void ip5306::voltage_pressure(ip5306_voltage_pressure value) {
|
||||
ip5306_set_bits(m_i2c,IP5306_REG_CHG_2, 0, 2, (int)value);
|
||||
}
|
||||
ip5306_charge_cutoff_voltage ip5306::charge_cutoff_voltage() const {
|
||||
return (ip5306_charge_cutoff_voltage)ip5306_get_bits(m_i2c,IP5306_REG_CHG_2, 2, 2);
|
||||
}
|
||||
void ip5306::charge_cutoff_voltage(ip5306_charge_cutoff_voltage value) {
|
||||
ip5306_set_bits(m_i2c,IP5306_REG_CHG_2, 2, 2, (int)value);
|
||||
}
|
||||
ip5306_source ip5306::charge_cc_loop() const {
|
||||
return (ip5306_source)ip5306_get_bits(m_i2c,IP5306_REG_CHG_3, 5, 1);
|
||||
}
|
||||
void ip5306::charge_cc_loop(ip5306_source value) {
|
||||
ip5306_set_bits(m_i2c,IP5306_REG_CHG_3, 5, 1, (int)value);
|
||||
}
|
||||
unsigned ip5306::vin_current() const {
|
||||
int v = ip5306_get_bits(m_i2c,IP5306_REG_CHG_4, 0, 5);
|
||||
return (v*100)+50;
|
||||
}
|
||||
void ip5306::vin_current(unsigned value) {
|
||||
//ImA=(v*100)+50 (default 2250mA)
|
||||
ip5306_set_bits(m_i2c,IP5306_REG_CHG_4, 0, 5, (value-50)/100);
|
||||
}
|
||||
bool ip5306::short_press_detected() const {
|
||||
return ip5306_get_bits(m_i2c,IP5306_REG_READ_3, 0, 1);
|
||||
}
|
||||
void ip5306::clear_short_press_detected() {
|
||||
ip5306_set_bits(m_i2c,IP5306_REG_READ_3, 0, 1, 1);
|
||||
}
|
||||
bool ip5306::long_press_detected() const {
|
||||
return ip5306_get_bits(m_i2c,IP5306_REG_READ_3, 1, 1);
|
||||
}
|
||||
void ip5306::clear_long_press_detected() {
|
||||
ip5306_set_bits(m_i2c,IP5306_REG_READ_3, 1, 1, 1);
|
||||
}
|
||||
bool ip5306::double_click_detected() const {
|
||||
return ip5306_get_bits(m_i2c,IP5306_REG_READ_3, 2, 1);
|
||||
}
|
||||
void ip5306::clear_double_click_detected() {
|
||||
ip5306_set_bits(m_i2c,IP5306_REG_READ_3, 2, 1, 1);
|
||||
}
|
||||
ip5306_source ip5306::power_source() const {
|
||||
return (ip5306_source)ip5306_get_bits(m_i2c,IP5306_REG_READ_0, 3, 1);
|
||||
}
|
||||
bool ip5306::battery_full() const {
|
||||
return ip5306_get_bits(m_i2c,IP5306_REG_READ_1, 3, 1);
|
||||
}
|
||||
ip5306_load ip5306::output_load() const {
|
||||
return (ip5306_load)ip5306_get_bits(m_i2c,IP5306_REG_READ_2, 2, 1);
|
||||
}
|
||||
float ip5306::charge_level() const {
|
||||
// LED[0-4] State (inverted)
|
||||
return IP5306_LEDS2PCT(((~ip5306_get_bits(m_i2c,IP5306_REG_READ_4, 4, 4)) & 0x0F))/100.0;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user