From f21552130381431872e7de5a5ab297e82c18da4c Mon Sep 17 00:00:00 2001 From: Stefan Thoss Date: Tue, 19 Dec 2023 21:56:15 -0800 Subject: [PATCH] Change to AXP2102 --- .gitignore | 1 + README.md | 5 +- components/axp192/axp192.cpp | 644 -------------- components/{axp192 => axp2101}/__init__.py | 0 components/axp2101/axp2101.cpp | 806 ++++++++++++++++++ .../{axp192/axp192.h => axp2101/axp2101.h} | 39 +- components/{axp192 => axp2101}/sensor.py | 19 +- sample-config/m5core2.yaml | 26 +- sample-config/m5stickc.yaml | 134 --- sample-config/m5tough.yaml | 143 ---- 10 files changed, 856 insertions(+), 961 deletions(-) create mode 100644 .gitignore delete mode 100644 components/axp192/axp192.cpp rename components/{axp192 => axp2101}/__init__.py (100%) create mode 100644 components/axp2101/axp2101.cpp rename components/{axp192/axp192.h => axp2101/axp2101.h} (87%) rename components/{axp192 => axp2101}/sensor.py (70%) delete mode 100644 sample-config/m5stickc.yaml delete mode 100644 sample-config/m5tough.yaml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..722d5e7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.vscode diff --git a/README.md b/README.md index 9a0492c..f979233 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ -# ESPHome AXP192 Component -ESPHome AXP192 Component +# ESPHome AXP2101 Component + +*Work in progress* This custom component it to implement support for the AXP192 for both the M5Stick-C, and the M5Stack Core2, building on top of airy10's code. diff --git a/components/axp192/axp192.cpp b/components/axp192/axp192.cpp deleted file mode 100644 index 0095d43..0000000 --- a/components/axp192/axp192.cpp +++ /dev/null @@ -1,644 +0,0 @@ -#include "axp192.h" -#include "esphome/core/log.h" -#include "esp_sleep.h" -#include - -namespace esphome { -namespace axp192 { - -static const char *TAG = "axp192.sensor"; -void AXP192Component::setup() -{ - switch (this->model_) { - case AXP192_M5STICKC: - { - begin(false, false, false, false, false); - break; - } - case AXP192_M5CORE2: - { - // disable LDO3 Vibration - begin(false, true, false, false, false); - break; - } - case AXP192_M5TOUGH: - { - begin(false, false, false, false, false); - - // If we're waking from a cold boot - if (GetStartupReason() == "ESP_RST_POWERON") - { - ESP_LOGD(TAG, "First power on, restarting ESP..."); - - // Reboot the ESP with the axp initialised - ESP.restart(); - } - break; - } - } -} - -void AXP192Component::dump_config() { - ESP_LOGCONFIG(TAG, "AXP192:"); - LOG_I2C_DEVICE(this); - LOG_SENSOR(" ", "Battery Level", this->batterylevel_sensor_); -} - -float AXP192Component::get_setup_priority() const { return setup_priority::DATA; } - -void AXP192Component::update() { - - if (this->batterylevel_sensor_ != nullptr) { - // To be fixed - // This is not giving the right value - mostly there to have some sample sensor... - float vbat = GetBatVoltage(); - float batterylevel = 100.0 * ((vbat - 3.0) / (4.1 - 3.0)); - - ESP_LOGD(TAG, "Got Battery Level=%f (%f)", batterylevel, vbat); - if (batterylevel > 100.) { - batterylevel = 100; - } - this->batterylevel_sensor_->publish_state(batterylevel); - } - - UpdateBrightness(); -} - - -void AXP192Component::begin(bool disableLDO2, bool disableLDO3, bool disableRTC, bool disableDCDC1, bool disableDCDC3) -{ - switch (this->model_) { - case AXP192_M5STICKC: - { - // Set LDO2 & LDO3(TFT_LED & TFT) 3.0V - Write1Byte(0x28, 0xcc); - break; - } - case AXP192_M5CORE2: - { - // Set DCDC3 (TFT_LED & TFT) 3.0V - Write1Byte(0x27, 0xcc); - // Set LDO2 & LDO3(TFT_LED & TFT) 3.0V - Write1Byte(0x28, 0xcc); - break; - } - case AXP192_M5TOUGH: - { - // Set DCDC3 (TFT_LED & TFT) 3.0V - Write1Byte(0x27, 0xcc); - // Set LDO2 & LDO3(TFT_LED & TFT) 3.0V - Write1Byte(0x28, 0xcc); - break; - } - } - - // Set ADC sample rate to 200hz - Write1Byte(0x84, 0b11110010); - - // Set ADC to All Enable - Write1Byte(0x82, 0xff); - - // Bat charge voltage to 4.2, Current 100MA - Write1Byte(0x33, 0xc0); - - // Depending on configuration enable LDO2, LDO3, DCDC1, DCDC3. - uint8_t buf = (Read8bit(0x12) & 0xef) | 0x4D; - if(disableLDO3) buf &= ~(1<<3); - if(disableLDO2) buf &= ~(1<<2); - if(disableDCDC3) buf &= ~(1<<1); - if(disableDCDC1) buf &= ~(1<<0); - Write1Byte(0x12, buf); - - // 128ms power on, 4s power off - Write1Byte(0x36, 0x0C); - - if(!disableRTC) - { - // Set RTC voltage to 3.3V - Write1Byte(0x91, 0xF0); - - // Set GPIO0 to LDO - Write1Byte(0x90, 0x02); - } - - // Disable vbus hold limit - Write1Byte(0x30, 0x80); - - // Set temperature protection - Write1Byte(0x39, 0xfc); - - // Enable RTC BAT charge - Write1Byte(0x35, 0xa2 & (disableRTC ? 0x7F : 0xFF)); - - // Enable bat detection - Write1Byte(0x32, 0x46); - -} - -void AXP192Component::Write1Byte( uint8_t Addr , uint8_t Data ) -{ - this->write_byte(Addr, Data); -} - -uint8_t AXP192Component::Read8bit( uint8_t Addr ) -{ - uint8_t data; - this->read_byte(Addr, &data); - return data; -} - -uint16_t AXP192Component::Read12Bit( uint8_t Addr) -{ - uint16_t Data = 0; - uint8_t buf[2]; - ReadBuff(Addr,2,buf); - Data = ((buf[0] << 4) + buf[1]); // - return Data; -} - -uint16_t AXP192Component::Read13Bit( uint8_t Addr) -{ - uint16_t Data = 0; - uint8_t buf[2]; - ReadBuff(Addr,2,buf); - Data = ((buf[0] << 5) + buf[1]); // - return Data; -} - -uint16_t AXP192Component::Read16bit( uint8_t Addr ) -{ - uint32_t ReData = 0; - uint8_t Buff[2]; - this->read_bytes(Addr, Buff, sizeof(Buff)); - for( int i = 0 ; i < sizeof(Buff) ; i++ ) - { - ReData <<= 8; - ReData |= Buff[i]; - } - return ReData; -} - -uint32_t AXP192Component::Read24bit( uint8_t Addr ) -{ - uint32_t ReData = 0; - uint8_t Buff[3]; - this->read_bytes(Addr, Buff, sizeof(Buff)); - for( int i = 0 ; i < sizeof(Buff) ; i++ ) - { - ReData <<= 8; - ReData |= Buff[i]; - } - return ReData; -} - -uint32_t AXP192Component::Read32bit( uint8_t Addr ) -{ - uint32_t ReData = 0; - uint8_t Buff[4]; - this->read_bytes(Addr, Buff, sizeof(Buff)); - for( int i = 0 ; i < sizeof(Buff) ; i++ ) - { - ReData <<= 8; - ReData |= Buff[i]; - } - return ReData; -} - -void AXP192Component::ReadBuff( uint8_t Addr , uint8_t Size , uint8_t *Buff ) -{ - this->read_bytes(Addr, Buff, Size); -} - -void AXP192Component::UpdateBrightness() -{ - if (brightness_ == curr_brightness_) - { - return; - } - - ESP_LOGD(TAG, "Brightness=%f (Curr: %f)", brightness_, curr_brightness_); - curr_brightness_ = brightness_; - - const uint8_t c_min = 7; - const uint8_t c_max = 12; - auto ubri = c_min + static_cast(brightness_ * (c_max - c_min)); - - if (ubri > c_max) - { - ubri = c_max; - } - switch (this->model_) { - case AXP192_M5STICKC: - { - uint8_t buf = Read8bit( 0x28 ); - Write1Byte( 0x28 , ((buf & 0x0f) | (ubri << 4)) ); - break; - } - case AXP192_M5CORE2: - { - uint8_t buf = Read8bit( 0x27 ); - Write1Byte( 0x27 , ((buf & 0x80) | (ubri << 3)) ); - break; - } - case AXP192_M5TOUGH: - { - uint8_t buf = Read8bit( 0x27 ); - Write1Byte( 0x27 , ((buf & 0x80) | (ubri << 3)) ); - break; - } - } -} - -bool AXP192Component::GetBatState() -{ - if( Read8bit(0x01) | 0x20 ) - return true; - else - return false; -} - -uint8_t AXP192Component::GetBatData() -{ - return Read8bit(0x75); -} -//---------coulombcounter_from_here--------- -//enable: void EnableCoulombcounter(void); -//disable: void DisableCOulombcounter(void); -//stop: void StopCoulombcounter(void); -//clear: void ClearCoulombcounter(void); -//get charge data: uint32_t GetCoulombchargeData(void); -//get discharge data: uint32_t GetCoulombdischargeData(void); -//get coulomb val affter calculation: float GetCoulombData(void); -//------------------------------------------ -void AXP192Component::EnableCoulombcounter(void) -{ - Write1Byte( 0xB8 , 0x80 ); -} - -void AXP192Component::DisableCoulombcounter(void) -{ - Write1Byte( 0xB8 , 0x00 ); -} - -void AXP192Component::StopCoulombcounter(void) -{ - Write1Byte( 0xB8 , 0xC0 ); -} - -void AXP192Component::ClearCoulombcounter(void) -{ - Write1Byte( 0xB8 , 0xA0 ); -} - -uint32_t AXP192Component::GetCoulombchargeData(void) -{ - return Read32bit(0xB0); -} - -uint32_t AXP192Component::GetCoulombdischargeData(void) -{ - return Read32bit(0xB4); -} - -float AXP192Component::GetCoulombData(void) -{ - - uint32_t coin = 0; - uint32_t coout = 0; - - coin = GetCoulombchargeData(); - coout = GetCoulombdischargeData(); - - //c = 65536 * current_LSB * (coin - coout) / 3600 / ADC rate - //Adc rate can be read from 84H ,change this variable if you change the ADC reate - float ccc = 65536 * 0.5 * (coin - coout) / 3600.0 / 25.0; - return ccc; - -} -//----------coulomb_end_at_here---------- - -uint16_t AXP192Component::GetVbatData(void){ - - uint16_t vbat = 0; - uint8_t buf[2]; - ReadBuff(0x78,2,buf); - vbat = ((buf[0] << 4) + buf[1]); // V - return vbat; -} - -uint16_t AXP192Component::GetVinData(void) -{ - uint16_t vin = 0; - uint8_t buf[2]; - ReadBuff(0x56,2,buf); - vin = ((buf[0] << 4) + buf[1]); // V - return vin; -} - -uint16_t AXP192Component::GetIinData(void) -{ - uint16_t iin = 0; - uint8_t buf[2]; - ReadBuff(0x58,2,buf); - iin = ((buf[0] << 4) + buf[1]); - return iin; -} - -uint16_t AXP192Component::GetVusbinData(void) -{ - uint16_t vin = 0; - uint8_t buf[2]; - ReadBuff(0x5a,2,buf); - vin = ((buf[0] << 4) + buf[1]); // V - return vin; -} - -uint16_t AXP192Component::GetIusbinData(void) -{ - uint16_t iin = 0; - uint8_t buf[2]; - ReadBuff(0x5C,2,buf); - iin = ((buf[0] << 4) + buf[1]); - return iin; -} - -uint16_t AXP192Component::GetIchargeData(void) -{ - uint16_t icharge = 0; - uint8_t buf[2]; - ReadBuff(0x7A,2,buf); - icharge = ( buf[0] << 5 ) + buf[1] ; - return icharge; -} - -uint16_t AXP192Component::GetIdischargeData(void) -{ - uint16_t idischarge = 0; - uint8_t buf[2]; - ReadBuff(0x7C,2,buf); - idischarge = ( buf[0] << 5 ) + buf[1] ; - return idischarge; -} - -uint16_t AXP192Component::GetTempData(void) -{ - uint16_t temp = 0; - uint8_t buf[2]; - ReadBuff(0x5e,2,buf); - temp = ((buf[0] << 4) + buf[1]); - return temp; -} - -uint32_t AXP192Component::GetPowerbatData(void) -{ - uint32_t power = 0; - uint8_t buf[3]; - ReadBuff(0x70,2,buf); - power = (buf[0] << 16) + (buf[1] << 8) + buf[2]; - return power; -} - -uint16_t AXP192Component::GetVapsData(void) -{ - uint16_t vaps = 0; - uint8_t buf[2]; - ReadBuff(0x7e,2,buf); - vaps = ((buf[0] << 4) + buf[1]); - return vaps; -} - -void AXP192Component::SetSleep(void) -{ - Write1Byte(0x31 , Read8bit(0x31) | ( 1 << 3)); // Power off voltag 3.0v - Write1Byte(0x90 , Read8bit(0x90) | 0x07); // GPIO1 floating - Write1Byte(0x82, 0x00); // Disable ADCs - Write1Byte(0x12, Read8bit(0x12) & 0xA1); // Disable all outputs but DCDC1 -} - -// -- sleep -void AXP192Component::DeepSleep(uint64_t time_in_us) -{ - SetSleep(); - esp_sleep_enable_ext0_wakeup((gpio_num_t)37, 0 /* LOW */); - if (time_in_us > 0) - { - esp_sleep_enable_timer_wakeup(time_in_us); - } - else - { - esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER); - } - (time_in_us == 0) ? esp_deep_sleep_start() : esp_deep_sleep(time_in_us); -} - -void AXP192Component::LightSleep(uint64_t time_in_us) -{ - if (time_in_us > 0) - { - esp_sleep_enable_timer_wakeup(time_in_us); - } - else - { - esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER); - } - esp_light_sleep_start(); -} - -// 0 not press, 0x01 long press, 0x02 press -uint8_t AXP192Component::GetBtnPress() -{ - uint8_t state = Read8bit(0x46); - if(state) - { - Write1Byte( 0x46 , 0x03 ); - } - return state; -} - -uint8_t AXP192Component::GetWarningLevel(void) -{ - return Read8bit(0x47) & 0x01; -} - -float AXP192Component::GetBatVoltage() -{ - float ADCLSB = 1.1 / 1000.0; - uint16_t ReData = Read12Bit( 0x78 ); - return ReData * ADCLSB; -} - -float AXP192Component::GetBatCurrent() -{ - float ADCLSB = 0.5; - uint16_t CurrentIn = Read13Bit( 0x7A ); - uint16_t CurrentOut = Read13Bit( 0x7C ); - return ( CurrentIn - CurrentOut ) * ADCLSB; -} - -float AXP192Component::GetVinVoltage() -{ - float ADCLSB = 1.7 / 1000.0; - uint16_t ReData = Read12Bit( 0x56 ); - return ReData * ADCLSB; -} - -float AXP192Component::GetVinCurrent() -{ - float ADCLSB = 0.625; - uint16_t ReData = Read12Bit( 0x58 ); - return ReData * ADCLSB; -} - -float AXP192Component::GetVBusVoltage() -{ - float ADCLSB = 1.7 / 1000.0; - uint16_t ReData = Read12Bit( 0x5A ); - return ReData * ADCLSB; -} - -float AXP192Component::GetVBusCurrent() -{ - float ADCLSB = 0.375; - uint16_t ReData = Read12Bit( 0x5C ); - return ReData * ADCLSB; -} - -float AXP192Component::GetTempInAXP192() -{ - float ADCLSB = 0.1; - const float OFFSET_DEG_C = -144.7; - uint16_t ReData = Read12Bit( 0x5E ); - return OFFSET_DEG_C + ReData * ADCLSB; -} - -float AXP192Component::GetBatPower() -{ - float VoltageLSB = 1.1; - float CurrentLCS = 0.5; - uint32_t ReData = Read24bit( 0x70 ); - return VoltageLSB * CurrentLCS * ReData/ 1000.0; -} - -float AXP192Component::GetBatChargeCurrent() -{ - float ADCLSB = 0.5; - uint16_t ReData = Read13Bit( 0x7A ); - return ReData * ADCLSB; -} - -float AXP192Component::GetAPSVoltage() -{ - float ADCLSB = 1.4 / 1000.0; - uint16_t ReData = Read12Bit( 0x7E ); - return ReData * ADCLSB; -} - -float AXP192Component::GetBatCoulombInput() -{ - uint32_t ReData = Read32bit( 0xB0 ); - return ReData * 65536 * 0.5 / 3600 /25.0; -} - -float AXP192Component::GetBatCoulombOut() -{ - uint32_t ReData = Read32bit( 0xB4 ); - return ReData * 65536 * 0.5 / 3600 /25.0; -} - -void AXP192Component::SetCoulombClear() -{ - Write1Byte(0xB8,0x20); -} - -void AXP192Component::SetLDO2( bool State ) -{ - uint8_t buf = Read8bit(0x12); - if( State == true ) - { - buf = (1<<2) | buf; - } - else - { - buf = ~(1<<2) & buf; - } - Write1Byte( 0x12 , buf ); -} - -void AXP192Component::SetLDO3(bool State) -{ - uint8_t buf = Read8bit(0x12); - if( State == true ) - { - buf = (1<<3) | buf; - } - else - { - buf = ~(1<<3) & buf; - } - Write1Byte( 0x12 , buf ); -} - -void AXP192Component::SetChargeCurrent(uint8_t current) -{ - uint8_t buf = Read8bit(0x33); - buf = (buf & 0xf0) | (current & 0x07); - Write1Byte(0x33, buf); -} - -void AXP192Component::PowerOff() -{ - Write1Byte(0x32, Read8bit(0x32) | 0x80); -} - -void AXP192Component::SetAdcState(bool state) -{ - Write1Byte(0x82, state ? 0xff : 0x00); -} - -std::string AXP192Component::GetStartupReason() { - esp_reset_reason_t reset_reason = ::esp_reset_reason(); - if (reset_reason == ESP_RST_DEEPSLEEP) { - esp_sleep_source_t wake_reason = esp_sleep_get_wakeup_cause(); - if (wake_reason == ESP_SLEEP_WAKEUP_EXT0) - return "ESP_SLEEP_WAKEUP_EXT0"; - if (wake_reason == ESP_SLEEP_WAKEUP_EXT0) - return "ESP_SLEEP_WAKEUP_EXT0"; - if (wake_reason == ESP_SLEEP_WAKEUP_EXT1) - return "ESP_SLEEP_WAKEUP_EXT1"; - if (wake_reason == ESP_SLEEP_WAKEUP_TIMER) - return "ESP_SLEEP_WAKEUP_TIMER"; - if (wake_reason == ESP_SLEEP_WAKEUP_TOUCHPAD) - return "ESP_SLEEP_WAKEUP_TOUCHPAD"; - if (wake_reason == ESP_SLEEP_WAKEUP_ULP) - return "ESP_SLEEP_WAKEUP_ULP"; - if (wake_reason == ESP_SLEEP_WAKEUP_GPIO) - return "ESP_SLEEP_WAKEUP_GPIO"; - if (wake_reason == ESP_SLEEP_WAKEUP_UART) - return "ESP_SLEEP_WAKEUP_UART"; - return std::string{"WAKEUP_UNKNOWN_REASON"}; - } - - if (reset_reason == ESP_RST_UNKNOWN) - return "ESP_RST_UNKNOWN"; - if (reset_reason == ESP_RST_POWERON) - return "ESP_RST_POWERON"; - if (reset_reason == ESP_RST_SW) - return "ESP_RST_SW"; - if (reset_reason == ESP_RST_PANIC) - return "ESP_RST_PANIC"; - if (reset_reason == ESP_RST_INT_WDT) - return "ESP_RST_INT_WDT"; - if (reset_reason == ESP_RST_TASK_WDT) - return "ESP_RST_TASK_WDT"; - if (reset_reason == ESP_RST_WDT) - return "ESP_RST_WDT"; - if (reset_reason == ESP_RST_BROWNOUT) - return "ESP_RST_BROWNOUT"; - if (reset_reason == ESP_RST_SDIO) - return "ESP_RST_SDIO"; - return std::string{"RESET_UNKNOWN_REASON"}; -} - -} -} - diff --git a/components/axp192/__init__.py b/components/axp2101/__init__.py similarity index 100% rename from components/axp192/__init__.py rename to components/axp2101/__init__.py diff --git a/components/axp2101/axp2101.cpp b/components/axp2101/axp2101.cpp new file mode 100644 index 0000000..1243399 --- /dev/null +++ b/components/axp2101/axp2101.cpp @@ -0,0 +1,806 @@ +#include "axp2101.h" +#include "esphome/core/log.h" +#include "esp_sleep.h" +#include + +namespace esphome { +namespace axp2101 { + +static const char *TAG = "axp2101.sensor"; +void AXP2101Component::setup() +{ + Serial.printf("getID:0x%x\n", PMU.getChipID()); + + // Set the minimum common working voltage of the PMU VBUS input, + // below this value will turn off the PMU + PMU.setVbusVoltageLimit(XPOWERS_AXP2101_VBUS_VOL_LIM_4V36); + + // Set the maximum current of the PMU VBUS input, + // higher than this value will turn off the PMU + PMU.setVbusCurrentLimit(XPOWERS_AXP2101_VBUS_CUR_LIM_1500MA); + + + // Get the VSYS shutdown voltage + uint16_t vol = PMU.getSysPowerDownVoltage(); + Serial.printf("-> getSysPowerDownVoltage:%u\n", vol); + + // Set VSY off voltage as 2600mV , Adjustment range 2600mV ~ 3300mV + PMU.setSysPowerDownVoltage(2600); + + vol = PMU.getSysPowerDownVoltage(); + Serial.printf("-> getSysPowerDownVoltage:%u\n", vol); + + + // DC1 IMAX=2A + // 1500~3400mV,100mV/step,20steps + PMU.setDC1Voltage(3300); + Serial.printf("DC1 : %s Voltage:%u mV \n", PMU.isEnableDC1() ? "+" : "-", PMU.getDC1Voltage()); + + // DC2 IMAX=2A + // 500~1200mV 10mV/step,71steps + // 1220~1540mV 20mV/step,17steps + PMU.setDC2Voltage(1000); + Serial.printf("DC2 : %s Voltage:%u mV \n", PMU.isEnableDC2() ? "+" : "-", PMU.getDC2Voltage()); + + // DC3 IMAX = 2A + // 500~1200mV,10mV/step,71steps + // 1220~1540mV,20mV/step,17steps + // 1600~3400mV,100mV/step,19steps + PMU.setDC3Voltage(3300); + Serial.printf("DC3 : %s Voltage:%u mV \n", PMU.isEnableDC3() ? "+" : "-", PMU.getDC3Voltage()); + + // DCDC4 IMAX=1.5A + // 500~1200mV,10mV/step,71steps + // 1220~1840mV,20mV/step,32steps + PMU.setDC4Voltage(1000); + Serial.printf("DC4 : %s Voltage:%u mV \n", PMU.isEnableDC4() ? "+" : "-", PMU.getDC4Voltage()); + + // DC5 IMAX=2A + // 1200mV + // 1400~3700mV,100mV/step,24steps + PMU.setDC5Voltage(3300); + Serial.printf("DC5 : %s Voltage:%u mV \n", PMU.isEnableDC5() ? "+" : "-", PMU.getDC5Voltage()); + + //ALDO1 IMAX=300mA + //500~3500mV, 100mV/step,31steps + PMU.setALDO1Voltage(3300); + + //ALDO2 IMAX=300mA + //500~3500mV, 100mV/step,31steps + PMU.setALDO2Voltage(3300); + + //ALDO3 IMAX=300mA + //500~3500mV, 100mV/step,31steps + PMU.setALDO3Voltage(3300); + + //ALDO4 IMAX=300mA + //500~3500mV, 100mV/step,31steps + PMU.setALDO4Voltage(3300); + + //BLDO1 IMAX=300mA + //500~3500mV, 100mV/step,31steps + PMU.setBLDO1Voltage(3300); + + //BLDO2 IMAX=300mA + //500~3500mV, 100mV/step,31steps + PMU.setBLDO2Voltage(3300); + + //CPUSLDO IMAX=30mA + //500~1400mV,50mV/step,19steps + PMU.setCPUSLDOVoltage(1000); + + //DLDO1 IMAX=300mA + //500~3400mV, 100mV/step,29steps + PMU.setDLDO1Voltage(3300); + + //DLDO2 IMAX=300mA + //500~1400mV, 50mV/step,2steps + PMU.setDLDO2Voltage(3300); + + + // PMU.enableDC1(); + PMU.enableDC2(); + PMU.enableDC3(); + PMU.enableDC4(); + PMU.enableDC5(); + PMU.enableALDO1(); + PMU.enableALDO2(); + PMU.enableALDO3(); + PMU.enableALDO4(); + PMU.enableBLDO1(); + PMU.enableBLDO2(); + PMU.enableCPUSLDO(); + PMU.enableDLDO1(); + PMU.enableDLDO2(); + + + Serial.println("DCDC======================================================================="); + Serial.printf("DC1 : %s Voltage:%u mV \n", PMU.isEnableDC1() ? "+" : "-", PMU.getDC1Voltage()); + Serial.printf("DC2 : %s Voltage:%u mV \n", PMU.isEnableDC2() ? "+" : "-", PMU.getDC2Voltage()); + Serial.printf("DC3 : %s Voltage:%u mV \n", PMU.isEnableDC3() ? "+" : "-", PMU.getDC3Voltage()); + Serial.printf("DC4 : %s Voltage:%u mV \n", PMU.isEnableDC4() ? "+" : "-", PMU.getDC4Voltage()); + Serial.printf("DC5 : %s Voltage:%u mV \n", PMU.isEnableDC5() ? "+" : "-", PMU.getDC5Voltage()); + Serial.println("ALDO======================================================================="); + Serial.printf("ALDO1: %s Voltage:%u mV\n", PMU.isEnableALDO1() ? "+" : "-", PMU.getALDO1Voltage()); + Serial.printf("ALDO2: %s Voltage:%u mV\n", PMU.isEnableALDO2() ? "+" : "-", PMU.getALDO2Voltage()); + Serial.printf("ALDO3: %s Voltage:%u mV\n", PMU.isEnableALDO3() ? "+" : "-", PMU.getALDO3Voltage()); + Serial.printf("ALDO4: %s Voltage:%u mV\n", PMU.isEnableALDO4() ? "+" : "-", PMU.getALDO4Voltage()); + Serial.println("BLDO======================================================================="); + Serial.printf("BLDO1: %s Voltage:%u mV\n", PMU.isEnableBLDO1() ? "+" : "-", PMU.getBLDO1Voltage()); + Serial.printf("BLDO2: %s Voltage:%u mV\n", PMU.isEnableBLDO2() ? "+" : "-", PMU.getBLDO2Voltage()); + Serial.println("CPUSLDO===================================================================="); + Serial.printf("CPUSLDO: %s Voltage:%u mV\n", PMU.isEnableCPUSLDO() ? "+" : "-", PMU.getCPUSLDOVoltage()); + Serial.println("DLDO======================================================================="); + Serial.printf("DLDO1: %s Voltage:%u mV\n", PMU.isEnableDLDO1() ? "+" : "-", PMU.getDLDO1Voltage()); + Serial.printf("DLDO2: %s Voltage:%u mV\n", PMU.isEnableDLDO2() ? "+" : "-", PMU.getDLDO2Voltage()); + Serial.println("==========================================================================="); + + // Set the time of pressing the button to turn off + PMU.setPowerKeyPressOffTime(XPOWERS_POWEROFF_4S); + uint8_t opt = PMU.getPowerKeyPressOffTime(); + Serial.print("PowerKeyPressOffTime:"); + switch (opt) { + case XPOWERS_POWEROFF_4S: Serial.println("4 Second"); + break; + case XPOWERS_POWEROFF_6S: Serial.println("6 Second"); + break; + case XPOWERS_POWEROFF_8S: Serial.println("8 Second"); + break; + case XPOWERS_POWEROFF_10S: Serial.println("10 Second"); + break; + default: + break; + } + // Set the button power-on press time + PMU.setPowerKeyPressOnTime(XPOWERS_POWERON_128MS); + opt = PMU.getPowerKeyPressOnTime(); + Serial.print("PowerKeyPressOnTime:"); + switch (opt) { + case XPOWERS_POWERON_128MS: Serial.println("128 Ms"); + break; + case XPOWERS_POWERON_512MS: Serial.println("512 Ms"); + break; + case XPOWERS_POWERON_1S: Serial.println("1 Second"); + break; + case XPOWERS_POWERON_2S: Serial.println("2 Second"); + break; + default: + break; + } + + Serial.println("==========================================================================="); + + bool en; + + // DCDC 120%(130%) high voltage turn off PMIC function + en = PMU.getDCHighVoltagePowerDowmEn(); + Serial.print("getDCHighVoltagePowerDowmEn:"); + Serial.println(en ? "ENABLE" : "DISABLE"); + // DCDC1 85% low voltage turn off PMIC function + en = PMU.getDC1LowVoltagePowerDowmEn(); + Serial.print("getDC1LowVoltagePowerDowmEn:"); + Serial.println(en ? "ENABLE" : "DISABLE"); + // DCDC2 85% low voltage turn off PMIC function + en = PMU.getDC2LowVoltagePowerDowmEn(); + Serial.print("getDC2LowVoltagePowerDowmEn:"); + Serial.println(en ? "ENABLE" : "DISABLE"); + // DCDC3 85% low voltage turn off PMIC function + en = PMU.getDC3LowVoltagePowerDowmEn(); + Serial.print("getDC3LowVoltagePowerDowmEn:"); + Serial.println(en ? "ENABLE" : "DISABLE"); + // DCDC4 85% low voltage turn off PMIC function + en = PMU.getDC4LowVoltagePowerDowmEn(); + Serial.print("getDC4LowVoltagePowerDowmEn:"); + Serial.println(en ? "ENABLE" : "DISABLE"); + // DCDC5 85% low voltage turn off PMIC function + en = PMU.getDC5LowVoltagePowerDowmEn(); + Serial.print("getDC5LowVoltagePowerDowmEn:"); + Serial.println(en ? "ENABLE" : "DISABLE"); + + // PMU.setDCHighVoltagePowerDowm(true); + // PMU.setDC1LowVoltagePowerDowm(true); + // PMU.setDC2LowVoltagePowerDowm(true); + // PMU.setDC3LowVoltagePowerDowm(true); + // PMU.setDC4LowVoltagePowerDowm(true); + // PMU.setDC5LowVoltagePowerDowm(true); + + // It is necessary to disable the detection function of the TS pin on the board + // without the battery temperature detection function, otherwise it will cause abnormal charging + PMU.disableTSPinMeasure(); + + // PMU.enableTemperatureMeasure(); + + // Enable internal ADC detection + PMU.enableBattDetection(); + PMU.enableVbusVoltageMeasure(); + PMU.enableBattVoltageMeasure(); + PMU.enableSystemVoltageMeasure(); + + + /* + The default setting is CHGLED is automatically controlled by the PMU. + - XPOWERS_CHG_LED_OFF, + - XPOWERS_CHG_LED_BLINK_1HZ, + - XPOWERS_CHG_LED_BLINK_4HZ, + - XPOWERS_CHG_LED_ON, + - XPOWERS_CHG_LED_CTRL_CHG, + * */ + PMU.setChargingLedMode(XPOWERS_CHG_LED_OFF); + + + // Force add pull-up + pinMode(pmu_irq_pin, INPUT_PULLUP); + attachInterrupt(pmu_irq_pin, setFlag, FALLING); + + + // Disable all interrupts + PMU.disableIRQ(XPOWERS_AXP2101_ALL_IRQ); + // Clear all interrupt flags + PMU.clearIrqStatus(); + // Enable the required interrupt function + PMU.enableIRQ( + XPOWERS_AXP2101_BAT_INSERT_IRQ | XPOWERS_AXP2101_BAT_REMOVE_IRQ | //BATTERY + XPOWERS_AXP2101_VBUS_INSERT_IRQ | XPOWERS_AXP2101_VBUS_REMOVE_IRQ | //VBUS + XPOWERS_AXP2101_PKEY_SHORT_IRQ | XPOWERS_AXP2101_PKEY_LONG_IRQ | //POWER KEY + XPOWERS_AXP2101_BAT_CHG_DONE_IRQ | XPOWERS_AXP2101_BAT_CHG_START_IRQ //CHARGE + // XPOWERS_AXP2101_PKEY_NEGATIVE_IRQ | XPOWERS_AXP2101_PKEY_POSITIVE_IRQ | //POWER KEY + ); + + // Set the precharge charging current + PMU.setPrechargeCurr(XPOWERS_AXP2101_PRECHARGE_50MA); + // Set constant current charge current limit + PMU.setChargerConstantCurr(XPOWERS_AXP2101_CHG_CUR_200MA); + // Set stop charging termination current + PMU.setChargerTerminationCurr(XPOWERS_AXP2101_CHG_ITERM_25MA); + + // Set charge cut-off voltage + PMU.setChargeTargetVoltage(XPOWERS_AXP2101_CHG_VOL_4V1); + + // Set the watchdog trigger event type + PMU.setWatchdogConfig(XPOWERS_AXP2101_WDT_IRQ_TO_PIN); + // Set watchdog timeout + PMU.setWatchdogTimeout(XPOWERS_AXP2101_WDT_TIMEOUT_4S); + // Enable watchdog to trigger interrupt event + PMU.enableWatchdog(); + + // PMU.disableWatchdog(); + + // Enable Button Battery charge + PMU.enableButtonBatteryCharge(); + + // Set Button Battery charge voltage + PMU.setButtonBatteryChargeVoltage(3300); +} + +void AXP2101Component::dump_config() { + ESP_LOGCONFIG(TAG, "AXP2101:"); + LOG_I2C_DEVICE(this); + LOG_SENSOR(" ", "Battery Level", this->batterylevel_sensor_); +} + +float AXP2101Component::get_setup_priority() const { return setup_priority::DATA; } + +void AXP2101Component::update() { + + if (this->batterylevel_sensor_ != nullptr) { + float vbat = PMU.getBattVoltage(); + + // The battery percentage may be inaccurate at first use, the PMU will automatically + // learn the battery curve and will automatically calibrate the battery percentage + // after a charge and discharge cycle + float batterylevel; + if (PMU.isBatteryConnect()) { + batterylevel = PMU.getBatteryPercent(); + } else { + batterylevel = 100.0 * ((vbat - 3.0) / (4.1 - 3.0)); + } + + ESP_LOGD(TAG, "Got Battery Level=%f (%f)", batterylevel, vbat); + if (batterylevel > 100.) { + batterylevel = 100; + } + this->batterylevel_sensor_->publish_state(batterylevel); + } + + UpdateBrightness(); +} + +void AXP2101Component::Write1Byte( uint8_t Addr , uint8_t Data ) +{ + this->write_byte(Addr, Data); +} + +uint8_t AXP2101Component::Read8bit( uint8_t Addr ) +{ + uint8_t data; + this->read_byte(Addr, &data); + return data; +} + +uint16_t AXP2101Component::Read12Bit( uint8_t Addr) +{ + uint16_t Data = 0; + uint8_t buf[2]; + ReadBuff(Addr,2,buf); + Data = ((buf[0] << 4) + buf[1]); // + return Data; +} + +uint16_t AXP2101Component::Read13Bit( uint8_t Addr) +{ + uint16_t Data = 0; + uint8_t buf[2]; + ReadBuff(Addr,2,buf); + Data = ((buf[0] << 5) + buf[1]); // + return Data; +} + +uint16_t AXP2101Component::Read16bit( uint8_t Addr ) +{ + uint32_t ReData = 0; + uint8_t Buff[2]; + this->read_bytes(Addr, Buff, sizeof(Buff)); + for( int i = 0 ; i < sizeof(Buff) ; i++ ) + { + ReData <<= 8; + ReData |= Buff[i]; + } + return ReData; +} + +uint32_t AXP2101Component::Read24bit( uint8_t Addr ) +{ + uint32_t ReData = 0; + uint8_t Buff[3]; + this->read_bytes(Addr, Buff, sizeof(Buff)); + for( int i = 0 ; i < sizeof(Buff) ; i++ ) + { + ReData <<= 8; + ReData |= Buff[i]; + } + return ReData; +} + +uint32_t AXP2101Component::Read32bit( uint8_t Addr ) +{ + uint32_t ReData = 0; + uint8_t Buff[4]; + this->read_bytes(Addr, Buff, sizeof(Buff)); + for( int i = 0 ; i < sizeof(Buff) ; i++ ) + { + ReData <<= 8; + ReData |= Buff[i]; + } + return ReData; +} + +void AXP2101Component::ReadBuff( uint8_t Addr , uint8_t Size , uint8_t *Buff ) +{ + this->read_bytes(Addr, Buff, Size); +} + +void AXP2101Component::UpdateBrightness() +{ + if (brightness_ == curr_brightness_) + { + return; + } + + ESP_LOGD(TAG, "Brightness=%f (Curr: %f)", brightness_, curr_brightness_); + curr_brightness_ = brightness_; + + const uint8_t c_min = 7; + const uint8_t c_max = 12; + auto ubri = c_min + static_cast(brightness_ * (c_max - c_min)); + + if (ubri > c_max) + { + ubri = c_max; + } + switch (this->model_) { + case AXP2101_M5STICKC: + { + uint8_t buf = Read8bit( 0x28 ); + Write1Byte( 0x28 , ((buf & 0x0f) | (ubri << 4)) ); + break; + } + case AXP2101_M5CORE2: + { + uint8_t buf = Read8bit( 0x27 ); + Write1Byte( 0x27 , ((buf & 0x80) | (ubri << 3)) ); + break; + } + case AXP2101_M5TOUGH: + { + uint8_t buf = Read8bit( 0x27 ); + Write1Byte( 0x27 , ((buf & 0x80) | (ubri << 3)) ); + break; + } + } +} + +bool AXP2101Component::GetBatState() +{ + if( Read8bit(0x01) | 0x20 ) + return true; + else + return false; +} + +uint8_t AXP2101Component::GetBatData() +{ + return Read8bit(0x75); +} +//---------coulombcounter_from_here--------- +//enable: void EnableCoulombcounter(void); +//disable: void DisableCOulombcounter(void); +//stop: void StopCoulombcounter(void); +//clear: void ClearCoulombcounter(void); +//get charge data: uint32_t GetCoulombchargeData(void); +//get discharge data: uint32_t GetCoulombdischargeData(void); +//get coulomb val affter calculation: float GetCoulombData(void); +//------------------------------------------ +void AXP2101Component::EnableCoulombcounter(void) +{ + Write1Byte( 0xB8 , 0x80 ); +} + +void AXP2101Component::DisableCoulombcounter(void) +{ + Write1Byte( 0xB8 , 0x00 ); +} + +void AXP2101Component::StopCoulombcounter(void) +{ + Write1Byte( 0xB8 , 0xC0 ); +} + +void AXP2101Component::ClearCoulombcounter(void) +{ + Write1Byte( 0xB8 , 0xA0 ); +} + +uint32_t AXP2101Component::GetCoulombchargeData(void) +{ + return Read32bit(0xB0); +} + +uint32_t AXP2101Component::GetCoulombdischargeData(void) +{ + return Read32bit(0xB4); +} + +float AXP2101Component::GetCoulombData(void) +{ + + uint32_t coin = 0; + uint32_t coout = 0; + + coin = GetCoulombchargeData(); + coout = GetCoulombdischargeData(); + + //c = 65536 * current_LSB * (coin - coout) / 3600 / ADC rate + //Adc rate can be read from 84H ,change this variable if you change the ADC reate + float ccc = 65536 * 0.5 * (coin - coout) / 3600.0 / 25.0; + return ccc; + +} +//----------coulomb_end_at_here---------- + +uint16_t AXP2101Component::GetVbatData(void){ + + uint16_t vbat = 0; + uint8_t buf[2]; + ReadBuff(0x78,2,buf); + vbat = ((buf[0] << 4) + buf[1]); // V + return vbat; +} + +uint16_t AXP2101Component::GetVinData(void) +{ + uint16_t vin = 0; + uint8_t buf[2]; + ReadBuff(0x56,2,buf); + vin = ((buf[0] << 4) + buf[1]); // V + return vin; +} + +uint16_t AXP2101Component::GetIinData(void) +{ + uint16_t iin = 0; + uint8_t buf[2]; + ReadBuff(0x58,2,buf); + iin = ((buf[0] << 4) + buf[1]); + return iin; +} + +uint16_t AXP2101Component::GetVusbinData(void) +{ + uint16_t vin = 0; + uint8_t buf[2]; + ReadBuff(0x5a,2,buf); + vin = ((buf[0] << 4) + buf[1]); // V + return vin; +} + +uint16_t AXP2101Component::GetIusbinData(void) +{ + uint16_t iin = 0; + uint8_t buf[2]; + ReadBuff(0x5C,2,buf); + iin = ((buf[0] << 4) + buf[1]); + return iin; +} + +uint16_t AXP2101Component::GetIchargeData(void) +{ + uint16_t icharge = 0; + uint8_t buf[2]; + ReadBuff(0x7A,2,buf); + icharge = ( buf[0] << 5 ) + buf[1] ; + return icharge; +} + +uint16_t AXP2101Component::GetIdischargeData(void) +{ + uint16_t idischarge = 0; + uint8_t buf[2]; + ReadBuff(0x7C,2,buf); + idischarge = ( buf[0] << 5 ) + buf[1] ; + return idischarge; +} + +uint16_t AXP2101Component::GetTempData(void) +{ + uint16_t temp = 0; + uint8_t buf[2]; + ReadBuff(0x5e,2,buf); + temp = ((buf[0] << 4) + buf[1]); + return temp; +} + +uint32_t AXP2101Component::GetPowerbatData(void) +{ + uint32_t power = 0; + uint8_t buf[3]; + ReadBuff(0x70,2,buf); + power = (buf[0] << 16) + (buf[1] << 8) + buf[2]; + return power; +} + +uint16_t AXP2101Component::GetVapsData(void) +{ + uint16_t vaps = 0; + uint8_t buf[2]; + ReadBuff(0x7e,2,buf); + vaps = ((buf[0] << 4) + buf[1]); + return vaps; +} + +void AXP2101Component::SetSleep(void) +{ + Write1Byte(0x31 , Read8bit(0x31) | ( 1 << 3)); // Power off voltag 3.0v + Write1Byte(0x90 , Read8bit(0x90) | 0x07); // GPIO1 floating + Write1Byte(0x82, 0x00); // Disable ADCs + Write1Byte(0x12, Read8bit(0x12) & 0xA1); // Disable all outputs but DCDC1 +} + +// -- sleep +void AXP2101Component::DeepSleep(uint64_t time_in_us) +{ + SetSleep(); + esp_sleep_enable_ext0_wakeup((gpio_num_t)37, 0 /* LOW */); + if (time_in_us > 0) + { + esp_sleep_enable_timer_wakeup(time_in_us); + } + else + { + esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER); + } + (time_in_us == 0) ? esp_deep_sleep_start() : esp_deep_sleep(time_in_us); +} + +void AXP2101Component::LightSleep(uint64_t time_in_us) +{ + if (time_in_us > 0) + { + esp_sleep_enable_timer_wakeup(time_in_us); + } + else + { + esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER); + } + esp_light_sleep_start(); +} + +// 0 not press, 0x01 long press, 0x02 press +uint8_t AXP2101Component::GetBtnPress() +{ + uint8_t state = Read8bit(0x46); + if(state) + { + Write1Byte( 0x46 , 0x03 ); + } + return state; +} + +uint8_t AXP2101Component::GetWarningLevel(void) +{ + return Read8bit(0x47) & 0x01; +} + +float AXP2101Component::GetBatCurrent() +{ + float ADCLSB = 0.5; + uint16_t CurrentIn = Read13Bit( 0x7A ); + uint16_t CurrentOut = Read13Bit( 0x7C ); + return ( CurrentIn - CurrentOut ) * ADCLSB; +} + +float AXP2101Component::GetVinVoltage() +{ + float ADCLSB = 1.7 / 1000.0; + uint16_t ReData = Read12Bit( 0x56 ); + return ReData * ADCLSB; +} + +float AXP2101Component::GetVinCurrent() +{ + float ADCLSB = 0.625; + uint16_t ReData = Read12Bit( 0x58 ); + return ReData * ADCLSB; +} + +float AXP2101Component::GetVBusVoltage() +{ + float ADCLSB = 1.7 / 1000.0; + uint16_t ReData = Read12Bit( 0x5A ); + return ReData * ADCLSB; +} + +float AXP2101Component::GetVBusCurrent() +{ + float ADCLSB = 0.375; + uint16_t ReData = Read12Bit( 0x5C ); + return ReData * ADCLSB; +} + +float AXP2101Component::GetTempInAXP2101() +{ + float ADCLSB = 0.1; + const float OFFSET_DEG_C = -144.7; + uint16_t ReData = Read12Bit( 0x5E ); + return OFFSET_DEG_C + ReData * ADCLSB; +} + +float AXP2101Component::GetBatPower() +{ + float VoltageLSB = 1.1; + float CurrentLCS = 0.5; + uint32_t ReData = Read24bit( 0x70 ); + return VoltageLSB * CurrentLCS * ReData/ 1000.0; +} + +float AXP2101Component::GetBatChargeCurrent() +{ + float ADCLSB = 0.5; + uint16_t ReData = Read13Bit( 0x7A ); + return ReData * ADCLSB; +} + +float AXP2101Component::GetAPSVoltage() +{ + float ADCLSB = 1.4 / 1000.0; + uint16_t ReData = Read12Bit( 0x7E ); + return ReData * ADCLSB; +} + +float AXP2101Component::GetBatCoulombInput() +{ + uint32_t ReData = Read32bit( 0xB0 ); + return ReData * 65536 * 0.5 / 3600 /25.0; +} + +float AXP2101Component::GetBatCoulombOut() +{ + uint32_t ReData = Read32bit( 0xB4 ); + return ReData * 65536 * 0.5 / 3600 /25.0; +} + +void AXP2101Component::SetCoulombClear() +{ + Write1Byte(0xB8,0x20); +} + +void AXP2101Component::SetLDO2( bool State ) +{ + uint8_t buf = Read8bit(0x12); + if( State == true ) + { + buf = (1<<2) | buf; + } + else + { + buf = ~(1<<2) & buf; + } + Write1Byte( 0x12 , buf ); +} + +void AXP2101Component::SetLDO3(bool State) +{ + uint8_t buf = Read8bit(0x12); + if( State == true ) + { + buf = (1<<3) | buf; + } + else + { + buf = ~(1<<3) & buf; + } + Write1Byte( 0x12 , buf ); +} + +void AXP2101Component::SetChargeCurrent(uint8_t current) +{ + uint8_t buf = Read8bit(0x33); + buf = (buf & 0xf0) | (current & 0x07); + Write1Byte(0x33, buf); +} + +void AXP2101Component::PowerOff() +{ + Write1Byte(0x32, Read8bit(0x32) | 0x80); +} + +void AXP2101Component::SetAdcState(bool state) +{ + Write1Byte(0x82, state ? 0xff : 0x00); +} + +std::string AXP2101Component::GetStartupReason() { + esp_reset_reason_t reset_reason = ::esp_reset_reason(); + if (reset_reason == ESP_RST_DEEPSLEEP) { + esp_sleep_source_t wake_reason = esp_sleep_get_wakeup_cause(); + if (wake_reason == ESP_SLEEP_WAKEUP_EXT0) + return "ESP_SLEEP_WAKEUP_EXT0"; + if (wake_reason == ESP_SLEEP_WAKEUP_EXT0) + return "ESP_SLEEP_WAKEUP_EXT0"; + if (wake_reason == ESP_SLEEP_WAKEUP_EXT1) + return "ESP_SLEEP_WAKEUP_EXT1"; + if (wake_reason == ESP_SLEEP_WAKEUP_TIMER) + return "ESP_SLEEP_WAKEUP_TIMER"; + if (wake_reason == ESP_SLEEP_WAKEUP_TOUCHPAD) + return "ESP_SLEEP_WAKEUP_TOUCHPAD"; + if (wake_reason == ESP_SLEEP_WAKEUP_ULP) + return "ESP_SLEEP_WAKEUP_ULP"; + if (wake_reason == ESP_SLEEP_WAKEUP_GPIO) + return "ESP_SLEEP_WAKEUP_GPIO"; + if (wake_reason == ESP_SLEEP_WAKEUP_UART) + return "ESP_SLEEP_WAKEUP_UART"; + return std::string{"WAKEUP_UNKNOWN_REASON"}; + } + + if (reset_reason == ESP_RST_UNKNOWN) + return "ESP_RST_UNKNOWN"; + if (reset_reason == ESP_RST_POWERON) + return "ESP_RST_POWERON"; + if (reset_reason == ESP_RST_SW) + return "ESP_RST_SW"; + if (reset_reason == ESP_RST_PANIC) + return "ESP_RST_PANIC"; + if (reset_reason == ESP_RST_INT_WDT) + return "ESP_RST_INT_WDT"; + if (reset_reason == ESP_RST_TASK_WDT) + return "ESP_RST_TASK_WDT"; + if (reset_reason == ESP_RST_WDT) + return "ESP_RST_WDT"; + if (reset_reason == ESP_RST_BROWNOUT) + return "ESP_RST_BROWNOUT"; + if (reset_reason == ESP_RST_SDIO) + return "ESP_RST_SDIO"; + return std::string{"RESET_UNKNOWN_REASON"}; +} + +} +} diff --git a/components/axp192/axp192.h b/components/axp2101/axp2101.h similarity index 87% rename from components/axp192/axp192.h rename to components/axp2101/axp2101.h index 035fccf..81d6900 100644 --- a/components/axp192/axp192.h +++ b/components/axp2101/axp2101.h @@ -1,17 +1,28 @@ -#ifndef __AXP192_H__ -#define __AXP192_H__ +#ifndef __AXP2101_H__ +#define __AXP2101_H__ #include "esphome/core/component.h" #include "esphome/components/sensor/sensor.h" #include "esphome/components/i2c/i2c.h" -namespace esphome { -namespace axp192 { +#define XPOWERS_CHIP_AXP2101 +#include "XPowersLib.h" -enum AXP192Model { - AXP192_M5STICKC = 0, - AXP192_M5CORE2, - AXP192_M5TOUGH, +bool pmu_flag = 0; +XPowersPMU PMU; + +void setFlag(void) +{ + pmu_flag = true; +} + +namespace esphome { +namespace axp2101 { + +enum AXP2101Model { + AXP2101_M5STICKC = 0, + AXP2101_M5CORE2, + AXP2101_M5TOUGH, }; #define SLEEP_MSEC(us) (((uint64_t)us) * 1000L) @@ -28,11 +39,11 @@ enum AXP192Model { #define CURRENT_630MA (0b0110) #define CURRENT_700MA (0b0111) -class AXP192Component : public PollingComponent, public i2c::I2CDevice { +class AXP2101Component : public PollingComponent, public i2c::I2CDevice { public: void set_batterylevel_sensor(sensor::Sensor *batterylevel_sensor) { batterylevel_sensor_ = batterylevel_sensor; } void set_brightness(float brightness) { brightness_ = brightness; } - void set_model(AXP192Model model) { this->model_ = model; } + void set_model(AXP2101Model model) { this->model_ = model; } // ========== INTERNAL METHODS ========== // (In most use cases you won't need these) @@ -48,7 +59,7 @@ protected: sensor::Sensor *batterylevel_sensor_; float brightness_{1.0f}; float curr_brightness_{-1.0f}; - AXP192Model model_; + AXP2101Model model_; /** M5 Stick Values * LDO2: Display backlight @@ -62,7 +73,6 @@ protected: * LD03: Vibration Motor */ - void begin(bool disableLDO2 = false, bool disableLDO3 = false, bool disableRTC = false, bool disableDCDC1 = false, bool disableDCDC3 = false); void UpdateBrightness(); bool GetBatState(); uint8_t GetBatData(); @@ -94,13 +104,12 @@ protected: // void SetChargeVoltage( uint8_t ); void SetChargeCurrent( uint8_t ); - float GetBatVoltage(); float GetBatCurrent(); float GetVinVoltage(); float GetVinCurrent(); float GetVBusVoltage(); float GetVBusCurrent(); - float GetTempInAXP192(); + float GetTempInAXP2101(); float GetBatPower(); float GetBatChargeCurrent(); float GetAPSVoltage(); @@ -128,4 +137,4 @@ protected: } } -#endif +#endif \ No newline at end of file diff --git a/components/axp192/sensor.py b/components/axp2101/sensor.py similarity index 70% rename from components/axp192/sensor.py rename to components/axp2101/sensor.py index 6781eb3..2b996ba 100644 --- a/components/axp192/sensor.py +++ b/components/axp2101/sensor.py @@ -6,21 +6,19 @@ from esphome.const import CONF_ID,\ DEPENDENCIES = ['i2c'] -axp192_ns = cg.esphome_ns.namespace('axp192') -AXP192Component = axp192_ns.class_('AXP192Component', cg.PollingComponent, i2c.I2CDevice) -AXP192Model = axp192_ns.enum("AXP192Model") +axp2101_ns = cg.esphome_ns.namespace('axp2101') +AXP2101Component = axp2101_ns.class_('AXP2101Component', cg.PollingComponent, i2c.I2CDevice) +AXP2101Model = axp2101_ns.enum("AXP2101Model") MODELS = { - "M5CORE2": AXP192Model.AXP192_M5CORE2, - "M5STICKC": AXP192Model.AXP192_M5STICKC, - "M5TOUGH": AXP192Model.AXP192_M5TOUGH, + "M5CORE2": AXP2101Model.AXP2101_M5CORE2, } -AXP192_MODEL = cv.enum(MODELS, upper=True, space="_") +AXP2101_MODEL = cv.enum(MODELS, upper=True, space="_") CONFIG_SCHEMA = cv.Schema({ - cv.GenerateID(): cv.declare_id(AXP192Component), - cv.Required(CONF_MODEL): AXP192_MODEL, + cv.GenerateID(): cv.declare_id(AXP2101Component), + cv.Required(CONF_MODEL): AXP2101_MODEL, cv.Optional(CONF_BATTERY_LEVEL): sensor.sensor_schema( unit_of_measurement=UNIT_PERCENT, @@ -36,7 +34,10 @@ def to_code(config): yield cg.register_component(var, config) yield i2c.register_i2c_device(var, config) + # cg.add_library("lewisxhe/XPowersLib", "0.2.1") + cg.add(var.set_model(config[CONF_MODEL])) + if CONF_BATTERY_LEVEL in config: conf = config[CONF_BATTERY_LEVEL] sens = yield sensor.new_sensor(conf) diff --git a/sample-config/m5core2.yaml b/sample-config/m5core2.yaml index 8a3c9f8..ea9b355 100644 --- a/sample-config/m5core2.yaml +++ b/sample-config/m5core2.yaml @@ -32,23 +32,22 @@ ota: web_server: -# AXP192 power management - must be present to initialize TFT power on +# axp2101 power management - must be present to initialize TFT power on sensor: - - platform: axp192 + - platform: axp2101 model: M5CORE2 address: 0x34 i2c_id: bus_a update_interval: 30s - brightness: 75% + brightness: 75% battery_level: - name: "${upper_devicename} Battery Level" - id: "${devicename}_batterylevel" + name: "Battery Level" - platform: wifi_signal - name: ${upper_devicename} WiFi Signal - id: wifi_dbm + name: WiFi Signal + - platform: uptime - name: ${upper_devicename} Uptime + name: Uptime Sensor spi: clk_pin: GPIO18 @@ -66,11 +65,10 @@ font: id: font1 size: 8 -# # builtin 80x160 TFT display: - - platform: ili9341 - model: M5STACK - cs_pin: 5 - dc_pin: 15 + - platform: ili9xxx + model: ILI9342 + cs_pin: GPIO5 + dc_pin: GPIO15 lambda: |- - it.line(20, 20, 200, 200); + it.print(80, 0, id(my_font), id(my_red), TextAlign::TOP_CENTER, "Hello World!"); diff --git a/sample-config/m5stickc.yaml b/sample-config/m5stickc.yaml deleted file mode 100644 index c8cebc6..0000000 --- a/sample-config/m5stickc.yaml +++ /dev/null @@ -1,134 +0,0 @@ -esphome: - name: m5stick-c - platform: ESP32 - board: m5stick-c - platformio_options: - upload_speed: 115200 - - # Use this to hardlink the component if it is not discovered - # includes: - # - /config/custom_components/axp192/axp192.h - -wifi: - ssid: "SSID" - password: "PASSPHRASE" - - # Enable fallback hotspot (captive portal) in case wifi connection fails - ap: - ssid: "XXX" - password: "XXX" - -# Enable logging -logger: - -substitutions: - devicename: m5stick - upper_devicename: M5StickC - -captive_portal: - -api: - -ota: - -web_server: - -binary_sensor: - - - platform: gpio - pin: - number: GPIO37 - inverted: true - name: ${upper_devicename} Button A - on_press: - then: - - light.turn_on: led1 - on_release: - then: - - light.turn_off: led1 - - - platform: gpio - pin: - number: GPIO39 - inverted: true - name: ${upper_devicename} Button B - on_press: - then: - - light.turn_on: led1 - on_release: - then: - - light.turn_off: led1 - -# AXP192 power management - must be present to initialize TFT power on -sensor: - - platform: axp192 - model: M5STICKC - address: 0x34 - i2c_id: bus_a - update_interval: 30s - battery_level: - name: "M5Stick Battery Level" - id: "m5stick_batterylevel" - - - platform: wifi_signal - name: ${upper_devicename} WiFi Signal - id: wifi_dbm - - platform: uptime - name: ${upper_devicename} Uptime - -# internal LED -light: - - platform: monochromatic - output: builtin_led - name: ${upper_devicename} Led - id: led1 - -output: - - platform: ledc - pin: 10 - inverted: true - id: builtin_led - -############################################# -### Currently causes an error with compilation -## -# internal IR Transmitter -# remote_transmitter: -# - pin: -# number: GPIO9 -# carrier_duty_percent: 50% -# id: internal -## -### -############################################# -spi: - clk_pin: GPIO13 - mosi_pin: GPIO15 - -i2c: - - id: bus_a - sda: GPIO21 - scl: GPIO22 - scan: True - -font: - - file: 'fonts/arial.ttf' - id: font1 - size: 8 - -# builtin 80x160 TFT -display: - - platform: st7735 - model: "INITR_MINI160X80" - cs_pin: GPIO5 - dc_pin: GPIO23 - reset_pin: GPIO18 - rotation: 270 - device_width: 128 - device_height: 160 - col_start: 0 - row_start: 0 - eight_bit_color: true - update_interval: 5s - lambda: |- - it.print(80, 0, id(font1), TextAlign::TOP_CENTER, "M5Stick Test"); \ No newline at end of file diff --git a/sample-config/m5tough.yaml b/sample-config/m5tough.yaml deleted file mode 100644 index b7743c0..0000000 --- a/sample-config/m5tough.yaml +++ /dev/null @@ -1,143 +0,0 @@ -esphome: - name: m5tough - -esp32: - board: m5stack-core2 - framework: - type: arduino - -# Enable logging -logger: - -# Enable Home Assistant API -api: - -# Enable over the air programming -ota: - -# Enable WiFi connection -wifi: - ssid: !secret wifi_ssid - password: !secret wifi_pass - -# Include the required components for this device -external_components: - - source: github://paulchilton/esphome-axp192 - components: [axp192] - -# SPI bus -spi: - clk_pin: GPIO18 - mosi_pin: GPIO23 - miso_pin: GPIO38 - -# I2C bus -i2c: - - id: bus_a - sda: GPIO21 - scl: GPIO22 - -# Define sensors -sensor: - - platform: axp192 - model: M5TOUGH - address: 0x34 - i2c_id: bus_a - update_interval: 3s - brightness: 75% - - - platform: uptime - name: "Uptime" - - - platform: wifi_signal - name: "WiFi Signal" - update_interval: 60s - id: wifi_strength - -text_sensor: - - platform: wifi_info - ip_address: - id: ip_address - -# M5 Tough has a built in speaker which can be used by home assistant as a media player -media_player: - - platform: i2s_audio - name: M5TOUGH I2S Media Player - dac_type: external - i2s_lrclk_pin: GPIO0 - i2s_dout_pin: GPIO2 - i2s_bclk_pin: GPIO12 - mode: stereo - -# Setup a simple input that triggers when the screen is touched anywhere -binary_sensor: - - platform: gpio - id: touchscreen_pressed - name: Touch Screen Pressed - pin: - number: 39 - - on_press: - then: - - logger.log: "Screen was pressed" - - # Also, send an event to home assistant api to indicate someone has pressed the screen. - - homeassistant.event: - event: esphome.screen_pressed - data: - message: Toughscreen was pressed - -# Fonts used on the display -font: - - file: "gfonts://Roboto" - id: title_font - size: 38 - - file: "gfonts://Roboto" - id: large_font - size: 42 - - file: "gfonts://Roboto" - id: mid_font - size: 28 - - file: "gfonts://Roboto" - id: small_font - size: 18 - -# Colours used on the display -color: - - id: color_white - red: 100% - green: 100% - blue: 100% - - id: color_grey - red: 30% - green: 30% - blue: 40% - - id: color_red - red: 100% - green: 3% - blue: 5% - -# Display definition with a simple header and footer showing WiFi connection details -display: - - platform: ili9341 - # 320x240 - model: M5STACK - cs_pin: GPIO5 - dc_pin: GPIO15 - lambda: |- - // Header - it.print(160, 0, id(title_font), id(color_white), TextAlign::TOP_CENTER, "Hello World"); - it.line(0, 50, it.get_width(), 50, id(color_grey)); - - - // Footer - it.line(0, 215, it.get_width(), 215, id(color_grey)); - if(isnan(id(wifi_strength).state) == 0){ - it.printf(240, 220, id(small_font), id(color_white), TextAlign::TOP_LEFT, "%.1fdB", id(wifi_strength).state); - } - else - { - it.printf(160, 220, id(small_font), id(color_red), TextAlign::TOP_CENTER, "Disconnected"); - } - - it.printf(10, 220, id(small_font), id(color_white), TextAlign::TOP_LEFT, "%s", id(ip_address).state.c_str());