Initial commit of Arduino libraries

This commit is contained in:
Sam
2025-05-23 10:47:41 +10:00
commit 5bfce5fc3e
2476 changed files with 1108481 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
# The following five lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
set(EXTRA_COMPONENT_DIRS ../../../XPowersLib)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(XPowersLib_Example)

View File

@@ -0,0 +1,10 @@
#
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
# project subdirectory.
#
PROJECT_NAME := XPowersLib_Example
EXTRA_COMPONENT_DIRS = ../../../XPowersLib
include $(IDF_PATH)/make/project.mk

View File

@@ -0,0 +1,73 @@
# XPowersLib Example
### Prerequisites
Please put XPowersLib and esp-idf in the same level directory, after configuring the esp-idf environment variable, enter `XPowersLib/examples/ESP_IDF_Example` and run the idf.py command directly
### Configure the Project
Open the project configuration menu (`idf.py menuconfig`).
In the `XPowers Configuration` menu:
* Select the PMU Type in the `PMU_Type` option.
* In `PMU SCL GPIO Num` select the clock pin to connect to the PMU,the default is 22
* In `PMU SDAGPIO Num` select the data pin connected to the PMU,the default is 21
* Select the interrupt pin connected to the PMU in `PMU Interrupt Pin`, the default is 35
## How to Use Example
Before project configuration and build, be sure to set the correct chip target using `idf.py set-target <chip_name>`.
### Build and Flash
Run `idf.py -p PORT flash monitor` to build, flash and monitor the project.
(To exit the serial monitor, type ``Ctrl-]``.)
See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects.
## Example Output
The output information is to configure the output voltage and enable status of the PMU
```
I (345) mian: I2C initialized successfully
I (355) AXP2101: Init PMU SUCCESS!
I (385) AXP2101: DCDC=======================================================================
I (385) AXP2101: DC1 :ENABLE Voltage:3300 mV
I (385) AXP2101: DC2 :DISABLE Voltage:900 mV
I (395) AXP2101: DC3 :ENABLE Voltage:3300 mV
I (395) AXP2101: DC4 :DISABLE Voltage:1100 mV
I (405) AXP2101: DC5 :DISABLE Voltage:1200 mV
I (405) AXP2101: ALDO=======================================================================
I (415) AXP2101: ALDO1:ENABLE Voltage:1800 mV
I (425) AXP2101: ALDO2:ENABLE Voltage:2800 mV
I (425) AXP2101: ALDO3:ENABLE Voltage:3300 mV
I (435) AXP2101: ALDO4:ENABLE Voltage:3000 mV
I (435) AXP2101: BLDO=======================================================================
I (445) AXP2101: BLDO1:ENABLE Voltage:3300 mV
```
## Build process example
Assuming you don't have esp-idf yet
```
mkdir -p ~/esp
cd ~/esp
git clone --recursive https://github.com/espressif/esp-idf.git
git clone https://github.com/lewisxhe/XPowersLib.git
cd esp-idf
./install.sh
. ./export.sh
cd ..
cd XPowersLib/examples/ESP_IDF_Example
idf.py menuconfig
idf.py build
idf.py -b 921600 flash
idf.py monitor
```

View File

@@ -0,0 +1,5 @@
idf_component_register(SRCS "main.cpp"
"port_axp192.cpp"
"port_axp2101.cpp"
"port_i2c.cpp"
INCLUDE_DIRS ".")

View File

@@ -0,0 +1,59 @@
menu "XPowersLib Configuration"
choice PMU_Type
prompt "XPowers chip type"
default XPOWERS_CHIP_AXP2101 if IDF_TARGET_ESP32
default XPOWERS_CHIP_AXP192
help
Defines the default peripheral for xpowers example
config XPOWERS_CHIP_AXP2101
bool "Xpowers AXP2101"
config XPOWERS_CHIP_AXP192
bool "Xpowers AXP192"
endchoice
choice I2C_COMMUNICATION_METHOD
prompt "XPowersLIb read and write methods"
default I2C_COMMUNICATION_METHOD_BUILTIN_RW
help
Define XPowersLIb read and write methods
config I2C_COMMUNICATION_METHOD_BUILTIN_RW
bool "Implemented using built-in read and write methods"
config I2C_COMMUNICATION_METHOD_CALLBACK_RW
bool "Implemented using read and write callback methods"
endchoice
config I2C_MASTER_PORT_NUM
int "PMU I2C Port Number"
default 1
help
Port number for I2C Master device.
config I2C_MASTER_FREQUENCY
int "Master Frequency"
default 100000
help
I2C Speed of Master device.
config PMU_I2C_SCL
int "PMU SCL GPIO Num"
default 22
help
GPIO number for I2C PMU clock line.
config PMU_I2C_SDA
int "PMU SDA GPIO Num"
default 21
help
GPIO number for I2C PMU data line.
config PMU_INTERRUPT_PIN
int "PMU Interrupt Pin"
default 35
help
PMU interrupt pin.
endmenu

View File

@@ -0,0 +1,4 @@
#
# "main" pseudo-component makefile.
#
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)

View File

@@ -0,0 +1,90 @@
#include <stdio.h>
#include <cstring>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "sdkconfig.h"
#include "freertos/queue.h"
#define PMU_INPUT_PIN (gpio_num_t)CONFIG_PMU_INTERRUPT_PIN /*!< axp power chip interrupt Pin*/
#define PMU_INPUT_PIN_SEL (1ULL<<PMU_INPUT_PIN)
/*
! WARN:
Please do not run the example without knowing the external load voltage of the PMU,
it may burn your external load, please check the voltage setting before running the example,
if there is any loss, please bear it by yourself
*/
#ifndef XPOWERS_NO_ERROR
#error "Running this example is known to not damage the device! Please go and uncomment this!"
#endif
static const char *TAG = "mian";
extern esp_err_t pmu_init();
extern esp_err_t i2c_init(void);
extern void pmu_isr_handler();
static void pmu_handler_task(void *);
static QueueHandle_t gpio_evt_queue = NULL;
static void IRAM_ATTR pmu_irq_handler(void *arg)
{
uint32_t gpio_num = (uint32_t) arg;
xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);
}
static void irq_init()
{
gpio_config_t io_conf;
io_conf.intr_type = GPIO_INTR_NEGEDGE;
io_conf.mode = GPIO_MODE_INPUT;
io_conf.pin_bit_mask = PMU_INPUT_PIN_SEL;
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
io_conf.pull_up_en = GPIO_PULLUP_ENABLE;
gpio_config(&io_conf);
gpio_set_intr_type(PMU_INPUT_PIN, GPIO_INTR_NEGEDGE);
//install gpio isr service
gpio_install_isr_service(0);
//hook isr handler for specific gpio pin
gpio_isr_handler_add(PMU_INPUT_PIN, pmu_irq_handler, (void *) PMU_INPUT_PIN);
}
extern "C" void app_main(void)
{
//create a queue to handle gpio event from isr
gpio_evt_queue = xQueueCreate(5, sizeof(uint32_t));
// Register PMU interrupt pins
irq_init();
#if CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW || \
((ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_XPOWERS_ESP_IDF_NEW_API))
ESP_ERROR_CHECK(i2c_init());
ESP_LOGI(TAG, "I2C initialized successfully");
#endif
ESP_ERROR_CHECK(pmu_init());
xTaskCreate(pmu_handler_task, "App/pwr", 4 * 1024, NULL, 10, NULL);
ESP_LOGI(TAG, "Run...");
}
static void pmu_handler_task(void *args)
{
uint32_t io_num;
while (1) {
if (xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) {
pmu_isr_handler();
}
}
}

View File

@@ -0,0 +1,325 @@
#include <stdio.h>
#include <cstring>
#include "sdkconfig.h"
#include "esp_log.h"
#include "esp_err.h"
#ifdef CONFIG_XPOWERS_CHIP_AXP192
#define XPOWERS_CHIP_AXP192
#include "XPowersLib.h"
static const char *TAG = "AXP192";
XPowersPMU power;
extern int pmu_register_read(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len);
extern int pmu_register_write_byte(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len);
esp_err_t pmu_init()
{
//* Implemented using read and write callback methods, applicable to other platforms
#if CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW
ESP_LOGI(TAG, "Implemented using read and write callback methods");
if (power.begin(AXP192_SLAVE_ADDRESS, pmu_register_read, pmu_register_write_byte)) {
ESP_LOGI(TAG, "Init PMU SUCCESS!");
} else {
ESP_LOGE(TAG, "Init PMU FAILED!");
return ESP_FAIL;
}
#endif
//* Use the built-in esp-idf communication method
#if CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_XPOWERS_ESP_IDF_NEW_API)
ESP_LOGI(TAG, "Implemented using built-in read and write methods (Use higher version >= 5.0 API)");
// * Using the new API of esp-idf 5.x, you need to pass the I2C BUS handle,
// * which is useful when the bus shares multiple devices.
extern i2c_master_bus_handle_t bus_handle;
if (power.begin(bus_handle, AXP192_SLAVE_ADDRESS)) {
ESP_LOGI(TAG, "Init PMU SUCCESS!");
} else {
ESP_LOGE(TAG, "Init PMU FAILED!");
return false;
}
#else
ESP_LOGI(TAG, "Implemented using built-in read and write methods (Use lower version < 5.0 API)");
if (power.begin((i2c_port_t)CONFIG_I2C_MASTER_PORT_NUM, AXP192_SLAVE_ADDRESS, CONFIG_PMU_I2C_SDA, CONFIG_PMU_I2C_SCL)) {
ESP_LOGI(TAG, "Init PMU SUCCESS!");
} else {
ESP_LOGE(TAG, "Init PMU FAILED!");
return false;
}
#endif //ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)
#endif //CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW
ESP_LOGI(TAG, "getID:0x%x", power.getChipID());
// Set the minimum system operating voltage inside the PMU,
// below this value will shut down the PMU
// Range: 2600~3300mV
power.setSysPowerDownVoltage(2700);
// Set the minimum common working voltage of the PMU VBUS input,
// below this value will turn off the PMU
power.setVbusVoltageLimit(XPOWERS_AXP192_VBUS_VOL_LIM_4V5);
// Turn off USB input current limit
power.setVbusCurrentLimit(XPOWERS_AXP192_VBUS_CUR_LIM_OFF);
// DC1 700~3500mV, IMAX=1.2A
power.setDC1Voltage(3300);
ESP_LOGI(TAG, "DC1 :%s Voltage:%u mV ", power.isEnableDC1() ? "ENABLE" : "DISABLE", power.getDC1Voltage());
// DC2 700~2750mV, IMAX=1.6A;
power.setDC2Voltage(700);
ESP_LOGI(TAG, "DC2 :%s Voltage:%u mV ", power.isEnableDC2() ? "ENABLE" : "DISABLE", power.getDC2Voltage());
// DC3 700~3500mV,IMAX=0.7A;
power.setDC3Voltage(3300);
ESP_LOGI(TAG, "DC3 :%s Voltage:%u mV ", power.isEnableDC3() ? "ENABLE" : "DISABLE", power.getDC3Voltage());
//LDO2 1800~3300V, 100mV/step, IMAX=200mA
power.setLDO2Voltage(1800);
//LDO3 1800~3300V, 100mV/step, IMAX=200mA
power.setLDO3Voltage(1800);
//LDOio 1800~3300V, 100mV/step, IMAX=50mA
power.setLDOioVoltage(3300);
// Enable power output channel
// power.enableDC1();
power.enableDC2();
power.enableDC3();
power.enableLDO2();
power.enableLDO3();
power.enableLDOio();
ESP_LOGI(TAG, "DCDC=======================================================================\n");
ESP_LOGI(TAG, "DC1 :%s Voltage:%u mV \n", power.isEnableDC1() ? "ENABLE" : "DISABLE", power.getDC1Voltage());
ESP_LOGI(TAG, "DC2 :%s Voltage:%u mV \n", power.isEnableDC2() ? "ENABLE" : "DISABLE", power.getDC2Voltage());
ESP_LOGI(TAG, "DC3 :%s Voltage:%u mV \n", power.isEnableDC3() ? "ENABLE" : "DISABLE", power.getDC3Voltage());
ESP_LOGI(TAG, "LDO=======================================================================\n");
ESP_LOGI(TAG, "LDO2: %s Voltage:%u mV\n", power.isEnableLDO2() ? "ENABLE" : "DISABLE", power.getLDO2Voltage());
ESP_LOGI(TAG, "LDO3: %s Voltage:%u mV\n", power.isEnableLDO3() ? "ENABLE" : "DISABLE", power.getLDO3Voltage());
ESP_LOGI(TAG, "LDOio: %s Voltage:%u mV\n", power.isEnableLDOio() ? "ENABLE" : "DISABLE", power.getLDOioVoltage());
ESP_LOGI(TAG, "==========================================================================\n");
// Set the time of pressing the button to turn off
power.setPowerKeyPressOffTime(XPOWERS_POWEROFF_4S);
uint8_t opt = power.getPowerKeyPressOffTime();
ESP_LOGI(TAG, "PowerKeyPressOffTime:");
switch (opt) {
case XPOWERS_POWEROFF_4S: ESP_LOGI(TAG, "4 Second");
break;
case XPOWERS_POWEROFF_6S: ESP_LOGI(TAG, "6 Second");
break;
case XPOWERS_POWEROFF_8S: ESP_LOGI(TAG, "8 Second");
break;
case XPOWERS_POWEROFF_10S: ESP_LOGI(TAG, "10 Second");
break;
default:
break;
}
// Set the button power-on press time
power.setPowerKeyPressOnTime(XPOWERS_POWERON_128MS);
opt = power.getPowerKeyPressOnTime();
ESP_LOGI(TAG, "PowerKeyPressOnTime:");
switch (opt) {
case XPOWERS_POWERON_128MS: ESP_LOGI(TAG, "128 Ms");
break;
case XPOWERS_POWERON_512MS: ESP_LOGI(TAG, "512 Ms");
break;
case XPOWERS_POWERON_1S: ESP_LOGI(TAG, "1 Second");
break;
case XPOWERS_POWERON_2S: ESP_LOGI(TAG, "2 Second");
break;
default:
break;
}
ESP_LOGI(TAG, "===========================================================================");
// 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
power.disableTSPinMeasure();
// power.enableTemperatureMeasure();
// power.disableTemperatureMeasure();
// Enable internal ADC detection
power.enableBattDetection();
power.enableVbusVoltageMeasure();
power.enableBattVoltageMeasure();
power.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,
* */
power.setChargingLedMode(XPOWERS_CHG_LED_OFF);
// Disable all interrupts
power.disableIRQ(XPOWERS_AXP192_ALL_IRQ);
// Clear all interrupt flags
power.clearIrqStatus();
// Enable the required interrupt function
power.enableIRQ(
XPOWERS_AXP192_BAT_INSERT_IRQ | XPOWERS_AXP192_BAT_REMOVE_IRQ | //BATTERY
XPOWERS_AXP192_VBUS_INSERT_IRQ | XPOWERS_AXP192_VBUS_REMOVE_IRQ | //VBUS
XPOWERS_AXP192_PKEY_SHORT_IRQ | XPOWERS_AXP192_PKEY_LONG_IRQ | //POWER KEY
XPOWERS_AXP192_BAT_CHG_DONE_IRQ | XPOWERS_AXP192_BAT_CHG_START_IRQ | //CHARGE
// XPOWERS_AXP192_PKEY_NEGATIVE_IRQ | XPOWERS_AXP192_PKEY_POSITIVE_IRQ | //POWER KEY
XPOWERS_AXP192_TIMER_TIMEOUT_IRQ //Timer
);
// Set constant current charge current limit
power.setChargerConstantCurr(XPOWERS_AXP192_CHG_CUR_280MA);
// Set stop charging termination current
power.setChargerTerminationCurr(XPOWERS_AXP192_CHG_ITERM_LESS_10_PERCENT);
// Set charge cut-off voltage
power.setChargeTargetVoltage(XPOWERS_AXP192_CHG_VOL_4V2);
// Cache writes and reads, as long as the PMU remains powered, the data will always be stored inside the PMU
ESP_LOGI(TAG, "Write pmu data buffer .");
uint8_t data[XPOWERS_AXP192_DATA_BUFFER_SIZE] = {1, 2, 3, 4, 5, 6};
power.writeDataBuffer(data, XPOWERS_AXP192_DATA_BUFFER_SIZE);
memset(data, 0, XPOWERS_AXP192_DATA_BUFFER_SIZE);
ESP_LOGI(TAG, "Read pmu data buffer :");
power.readDataBuffer(data, XPOWERS_AXP192_DATA_BUFFER_SIZE);
ESP_LOG_BUFFER_HEX(TAG, data, XPOWERS_AXP192_DATA_BUFFER_SIZE);
// Set the timing after one minute, the isWdtExpireIrq will be triggered in the loop interrupt function
power.setTimerout(1);
return ESP_OK;
}
void pmu_isr_handler()
{
// Get PMU Interrupt Status Register
power.getIrqStatus();
if (power.isAcinOverVoltageIrq()) {
ESP_LOGI(TAG, "isAcinOverVoltageIrq");
}
if (power.isAcinInserIrq()) {
ESP_LOGI(TAG, "isAcinInserIrq");
}
if (power.isAcinRemoveIrq()) {
ESP_LOGI(TAG, "isAcinRemoveIrq");
}
if (power.isVbusOverVoltageIrq()) {
ESP_LOGI(TAG, "isVbusOverVoltageIrq");
}
if (power.isVbusInsertIrq()) {
ESP_LOGI(TAG, "isVbusInsertIrq");
}
if (power.isVbusRemoveIrq()) {
ESP_LOGI(TAG, "isVbusRemoveIrq");
}
if (power.isVbusLowVholdIrq()) {
ESP_LOGI(TAG, "isVbusLowVholdIrq");
}
if (power.isBatInsertIrq()) {
ESP_LOGI(TAG, "isBatInsertIrq");
}
if (power.isBatRemoveIrq()) {
ESP_LOGI(TAG, "isBatRemoveIrq");
}
if (power.isBattEnterActivateIrq()) {
ESP_LOGI(TAG, "isBattEnterActivateIrq");
}
if (power.isBattExitActivateIrq()) {
ESP_LOGI(TAG, "isBattExitActivateIrq");
}
if (power.isBatChargeStartIrq()) {
ESP_LOGI(TAG, "isBatChargeStartIrq");
}
if (power.isBatChargeDoneIrq()) {
ESP_LOGI(TAG, "isBatChargeDoneIrq");
}
if (power.isBattTempHighIrq()) {
ESP_LOGI(TAG, "isBattTempHighIrq");
}
if (power.isBattTempLowIrq()) {
ESP_LOGI(TAG, "isBattTempLowIrq");
}
if (power.isChipOverTemperatureIrq()) {
ESP_LOGI(TAG, "isChipOverTemperatureIrq");
}
if (power.isChargingCurrentLessIrq()) {
ESP_LOGI(TAG, "isChargingCurrentLessIrq");
}
if (power.isDC1VoltageLessIrq()) {
ESP_LOGI(TAG, "isDC1VoltageLessIrq");
}
if (power.isDC2VoltageLessIrq()) {
ESP_LOGI(TAG, "isDC2VoltageLessIrq");
}
if (power.isDC3VoltageLessIrq()) {
ESP_LOGI(TAG, "isDC3VoltageLessIrq");
}
if (power.isPekeyShortPressIrq()) {
ESP_LOGI(TAG, "isPekeyShortPress");
// enterPmuSleep();
}
if (power.isPekeyLongPressIrq()) {
ESP_LOGI(TAG, "isPekeyLongPress");
}
if (power.isNOEPowerOnIrq()) {
ESP_LOGI(TAG, "isNOEPowerOnIrq");
}
if (power.isNOEPowerDownIrq()) {
ESP_LOGI(TAG, "isNOEPowerDownIrq");
}
if (power.isVbusEffectiveIrq()) {
ESP_LOGI(TAG, "isVbusEffectiveIrq");
}
if (power.isVbusInvalidIrq()) {
ESP_LOGI(TAG, "isVbusInvalidIrq");
}
if (power.isVbusSessionIrq()) {
ESP_LOGI(TAG, "isVbusSessionIrq");
}
if (power.isVbusSessionEndIrq()) {
ESP_LOGI(TAG, "isVbusSessionEndIrq");
}
if (power.isLowVoltageLevel2Irq()) {
ESP_LOGI(TAG, "isLowVoltageLevel2Irq");
}
if (power.isWdtExpireIrq()) {
ESP_LOGI(TAG, "isWdtExpire");
// Clear the timer state and continue to the next timer
power.clearTimerFlag();
}
if (power.isGpio2EdgeTriggerIrq()) {
ESP_LOGI(TAG, "isGpio2EdgeTriggerIrq");
}
if (power.isGpio1EdgeTriggerIrq()) {
ESP_LOGI(TAG, "isGpio1EdgeTriggerIrq");
}
if (power.isGpio0EdgeTriggerIrq()) {
ESP_LOGI(TAG, "isGpio0EdgeTriggerIrq");
}
// Clear PMU Interrupt Status Register
power.clearIrqStatus();
}
#endif /*CONFIG_XPOWERS_AXP192_CHIP_AXP192*/

View File

@@ -0,0 +1,263 @@
#include <stdio.h>
#include <cstring>
#include "sdkconfig.h"
#include "esp_log.h"
#include "esp_err.h"
#ifdef CONFIG_XPOWERS_CHIP_AXP2101
#define XPOWERS_CHIP_AXP2101
#include "XPowersLib.h"
static const char *TAG = "AXP2101";
static XPowersPMU power;
extern int pmu_register_read(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len);
extern int pmu_register_write_byte(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len);
esp_err_t pmu_init()
{
//* Implemented using read and write callback methods, applicable to other platforms
#if CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW
ESP_LOGI(TAG, "Implemented using read and write callback methods");
if (power.begin(AXP2101_SLAVE_ADDRESS, pmu_register_read, pmu_register_write_byte)) {
ESP_LOGI(TAG, "Init PMU SUCCESS!");
} else {
ESP_LOGE(TAG, "Init PMU FAILED!");
return ESP_FAIL;
}
#endif
//* Use the built-in esp-idf communication method
#if CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_XPOWERS_ESP_IDF_NEW_API)
ESP_LOGI(TAG, "Implemented using built-in read and write methods (Use higher version >= 5.0 API)");
// * Using the new API of esp-idf 5.x, you need to pass the I2C BUS handle,
// * which is useful when the bus shares multiple devices.
extern i2c_master_bus_handle_t bus_handle;
if (power.begin(bus_handle, AXP2101_SLAVE_ADDRESS)) {
ESP_LOGI(TAG, "Init PMU SUCCESS!");
} else {
ESP_LOGE(TAG, "Init PMU FAILED!");
return false;
}
#else
ESP_LOGI(TAG, "Implemented using built-in read and write methods (Use lower version < 5.0 API)");
if (power.begin((i2c_port_t)CONFIG_I2C_MASTER_PORT_NUM, AXP2101_SLAVE_ADDRESS, CONFIG_PMU_I2C_SDA, CONFIG_PMU_I2C_SCL)) {
ESP_LOGI(TAG, "Init PMU SUCCESS!");
} else {
ESP_LOGE(TAG, "Init PMU FAILED!");
return false;
}
#endif //ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)
#endif //CONFIG_I2C_COMMUNICATION_METHOD_BUILTIN_RW
//Turn off not use power channel
power.disableDC2();
power.disableDC3();
power.disableDC4();
power.disableDC5();
power.disableALDO1();
power.disableALDO2();
power.disableALDO3();
power.disableALDO4();
power.disableBLDO1();
power.disableBLDO2();
power.disableCPUSLDO();
power.disableDLDO1();
power.disableDLDO2();
//ESP32s3 Core VDD
power.setDC3Voltage(3300);
power.enableDC3();
//Extern 3.3V VDD
power.setDC1Voltage(3300);
power.enableDC1();
// CAM DVDD 1500~1800
power.setALDO1Voltage(1800);
// power.setALDO1Voltage(1500);
power.enableALDO1();
// CAM DVDD 2500~2800
power.setALDO2Voltage(2800);
power.enableALDO2();
// CAM AVDD 2800~3000
power.setALDO4Voltage(3000);
power.enableALDO4();
// PIR VDD 3300
power.setALDO3Voltage(3300);
power.enableALDO3();
// OLED VDD 3300
power.setBLDO1Voltage(3300);
power.enableBLDO1();
// MIC VDD 33000
power.setBLDO2Voltage(3300);
power.enableBLDO2();
ESP_LOGI(TAG, "DCDC=======================================================================\n");
ESP_LOGI(TAG, "DC1 : %s Voltage:%u mV \n", power.isEnableDC1() ? "+" : "-", power.getDC1Voltage());
ESP_LOGI(TAG, "DC2 : %s Voltage:%u mV \n", power.isEnableDC2() ? "+" : "-", power.getDC2Voltage());
ESP_LOGI(TAG, "DC3 : %s Voltage:%u mV \n", power.isEnableDC3() ? "+" : "-", power.getDC3Voltage());
ESP_LOGI(TAG, "DC4 : %s Voltage:%u mV \n", power.isEnableDC4() ? "+" : "-", power.getDC4Voltage());
ESP_LOGI(TAG, "DC5 : %s Voltage:%u mV \n", power.isEnableDC5() ? "+" : "-", power.getDC5Voltage());
ESP_LOGI(TAG, "ALDO=======================================================================\n");
ESP_LOGI(TAG, "ALDO1: %s Voltage:%u mV\n", power.isEnableALDO1() ? "+" : "-", power.getALDO1Voltage());
ESP_LOGI(TAG, "ALDO2: %s Voltage:%u mV\n", power.isEnableALDO2() ? "+" : "-", power.getALDO2Voltage());
ESP_LOGI(TAG, "ALDO3: %s Voltage:%u mV\n", power.isEnableALDO3() ? "+" : "-", power.getALDO3Voltage());
ESP_LOGI(TAG, "ALDO4: %s Voltage:%u mV\n", power.isEnableALDO4() ? "+" : "-", power.getALDO4Voltage());
ESP_LOGI(TAG, "BLDO=======================================================================\n");
ESP_LOGI(TAG, "BLDO1: %s Voltage:%u mV\n", power.isEnableBLDO1() ? "+" : "-", power.getBLDO1Voltage());
ESP_LOGI(TAG, "BLDO2: %s Voltage:%u mV\n", power.isEnableBLDO2() ? "+" : "-", power.getBLDO2Voltage());
ESP_LOGI(TAG, "CPUSLDO====================================================================\n");
ESP_LOGI(TAG, "CPUSLDO: %s Voltage:%u mV\n", power.isEnableCPUSLDO() ? "+" : "-", power.getCPUSLDOVoltage());
ESP_LOGI(TAG, "DLDO=======================================================================\n");
ESP_LOGI(TAG, "DLDO1: %s Voltage:%u mV\n", power.isEnableDLDO1() ? "+" : "-", power.getDLDO1Voltage());
ESP_LOGI(TAG, "DLDO2: %s Voltage:%u mV\n", power.isEnableDLDO2() ? "+" : "-", power.getDLDO2Voltage());
ESP_LOGI(TAG, "===========================================================================\n");
power.clearIrqStatus();
power.enableVbusVoltageMeasure();
power.enableBattVoltageMeasure();
power.enableSystemVoltageMeasure();
power.enableTemperatureMeasure();
// 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
power.disableTSPinMeasure();
// Disable all interrupts
power.disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
// Clear all interrupt flags
power.clearIrqStatus();
// Enable the required interrupt function
power.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
);
/*
The default setting is CHGLED is automatically controlled by the power.
- XPOWERS_CHG_LED_OFF,
- XPOWERS_CHG_LED_BLINK_1HZ,
- XPOWERS_CHG_LED_BLINK_4HZ,
- XPOWERS_CHG_LED_ON,
- XPOWERS_CHG_LED_CTRL_CHG,
* */
power.setChargingLedMode(XPOWERS_CHG_LED_BLINK_1HZ);
// Set the precharge charging current
power.setPrechargeCurr(XPOWERS_AXP2101_PRECHARGE_50MA);
// Set constant current charge current limit
power.setChargerConstantCurr(XPOWERS_AXP2101_CHG_CUR_200MA);
// Set stop charging termination current
power.setChargerTerminationCurr(XPOWERS_AXP2101_CHG_ITERM_25MA);
// Set charge cut-off voltage
power.setChargeTargetVoltage(XPOWERS_AXP2101_CHG_VOL_4V1);
// Set the watchdog trigger event type
// power.setWatchdogConfig(XPOWERS_AXP2101_WDT_IRQ_TO_PIN);
// Set watchdog timeout
power.setWatchdogTimeout(XPOWERS_AXP2101_WDT_TIMEOUT_4S);
// Enable watchdog to trigger interrupt event
power.enableWatchdog();
return ESP_OK;
}
void pmu_isr_handler()
{
// Get PMU Interrupt Status Register
power.getIrqStatus();
if (power.isDropWarningLevel2Irq()) {
ESP_LOGI(TAG, "isDropWarningLevel2");
}
if (power.isDropWarningLevel1Irq()) {
ESP_LOGI(TAG, "isDropWarningLevel1");
}
if (power.isGaugeWdtTimeoutIrq()) {
ESP_LOGI(TAG, "isWdtTimeout");
}
if (power.isBatChargerOverTemperatureIrq()) {
ESP_LOGI(TAG, "isBatChargeOverTemperature");
}
if (power.isBatWorkOverTemperatureIrq()) {
ESP_LOGI(TAG, "isBatWorkOverTemperature");
}
if (power.isBatWorkUnderTemperatureIrq()) {
ESP_LOGI(TAG, "isBatWorkUnderTemperature");
}
if (power.isVbusInsertIrq()) {
ESP_LOGI(TAG, "isVbusInsert");
}
if (power.isVbusRemoveIrq()) {
ESP_LOGI(TAG, "isVbusRemove");
}
if (power.isBatInsertIrq()) {
ESP_LOGI(TAG, "isBatInsert");
}
if (power.isBatRemoveIrq()) {
ESP_LOGI(TAG, "isBatRemove");
}
if (power.isPekeyShortPressIrq()) {
ESP_LOGI(TAG, "isPekeyShortPress");
}
if (power.isPekeyLongPressIrq()) {
ESP_LOGI(TAG, "isPekeyLongPress");
}
if (power.isPekeyNegativeIrq()) {
ESP_LOGI(TAG, "isPekeyNegative");
}
if (power.isPekeyPositiveIrq()) {
ESP_LOGI(TAG, "isPekeyPositive");
}
if (power.isWdtExpireIrq()) {
ESP_LOGI(TAG, "isWdtExpire");
}
if (power.isLdoOverCurrentIrq()) {
ESP_LOGI(TAG, "isLdoOverCurrentIrq");
}
if (power.isBatfetOverCurrentIrq()) {
ESP_LOGI(TAG, "isBatfetOverCurrentIrq");
}
if (power.isBatChargeDoneIrq()) {
ESP_LOGI(TAG, "isBatChargeDone");
}
if (power.isBatChargeStartIrq()) {
ESP_LOGI(TAG, "isBatChargeStart");
}
if (power.isBatDieOverTemperatureIrq()) {
ESP_LOGI(TAG, "isBatDieOverTemperature");
}
if (power.isChargeOverTimeoutIrq()) {
ESP_LOGI(TAG, "isChargeOverTimeout");
}
if (power.isBatOverVoltageIrq()) {
ESP_LOGI(TAG, "isBatOverVoltage");
}
// Clear PMU Interrupt Status Register
power.clearIrqStatus();
}
#endif /*CONFIG_XPOWERS_AXP2101_CHIP_AXP2102*/

View File

@@ -0,0 +1,209 @@
#include <stdio.h>
#include <cstring>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "sdkconfig.h"
#include "esp_idf_version.h"
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_XPOWERS_ESP_IDF_NEW_API)
#include "driver/i2c_master.h"
#else
#include "driver/i2c.h"
#endif
static const char *TAG = "XPowersLib";
#define I2C_MASTER_NUM (i2c_port_t)CONFIG_I2C_MASTER_PORT_NUM
#define I2C_MASTER_SDA_IO (gpio_num_t)CONFIG_PMU_I2C_SDA
#define I2C_MASTER_SCL_IO (gpio_num_t)CONFIG_PMU_I2C_SCL
#define I2C_MASTER_FREQ_HZ CONFIG_I2C_MASTER_FREQUENCY /*!< I2C master clock frequency */
#if CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW
#define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
#define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
#define I2C_MASTER_TIMEOUT_MS 1000
#define WRITE_BIT I2C_MASTER_WRITE /*!< I2C master write */
#define READ_BIT I2C_MASTER_READ /*!< I2C master read */
#define ACK_CHECK_EN 0x1 /*!< I2C master will check ack from slave*/
#define ACK_CHECK_DIS 0x0 /*!< I2C master will not check ack from slave */
#define ACK_VAL (i2c_ack_type_t)0x0 /*!< I2C ack value */
#define NACK_VAL (i2c_ack_type_t)0x1 /*!< I2C nack value */
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_XPOWERS_ESP_IDF_NEW_API)
// The new API passes the device address before initialization,
// AXP2102, 1XP192 belong to the same address
#define PMU_SLAVE_ADDRESS 0X34
i2c_master_dev_handle_t i2c_device;
#endif
/**
* @brief Read a sequence of bytes from a pmu registers
*/
int pmu_register_read(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len)
{
esp_err_t ret;
if (len == 0) {
return ESP_OK;
}
if (data == NULL) {
return ESP_FAIL;
}
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_XPOWERS_ESP_IDF_NEW_API)
ret = i2c_master_transmit_receive(
i2c_device,
(const uint8_t *)&regAddr,
1,
data,
len,
-1);
#else
i2c_cmd_handle_t cmd;
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (devAddr << 1) | WRITE_BIT, ACK_CHECK_EN);
i2c_master_write_byte(cmd, regAddr, ACK_CHECK_EN);
i2c_master_stop(cmd);
ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdTICKS_TO_MS(1000));
i2c_cmd_link_delete(cmd);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "PMU i2c_master_cmd_begin FAILED! > ");
return ESP_FAIL;
}
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (devAddr << 1) | READ_BIT, ACK_CHECK_EN);
if (len > 1) {
i2c_master_read(cmd, data, len - 1, ACK_VAL);
}
i2c_master_read_byte(cmd, &data[len - 1], NACK_VAL);
i2c_master_stop(cmd);
ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdTICKS_TO_MS(1000));
i2c_cmd_link_delete(cmd);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "PMU READ FAILED! > ");
}
#endif
return ret == ESP_OK ? 0 : -1;
}
/**
* @brief Write a byte to a pmu register
*/
int pmu_register_write_byte(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint8_t len)
{
esp_err_t ret;
if (data == NULL) {
return ESP_FAIL;
}
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_XPOWERS_ESP_IDF_NEW_API)
uint8_t *write_buffer = (uint8_t *)malloc(sizeof(uint8_t) * (len + 1));
if (!write_buffer) {
return -1;
}
write_buffer[0] = regAddr;
memcpy(write_buffer + 1, data, len);
ret = i2c_master_transmit(
i2c_device,
write_buffer,
len + 1,
-1);
free(write_buffer);
#else
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (devAddr << 1) | I2C_MASTER_WRITE, ACK_CHECK_EN);
i2c_master_write_byte(cmd, regAddr, ACK_CHECK_EN);
i2c_master_write(cmd, data, len, ACK_CHECK_EN);
i2c_master_stop(cmd);
ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdTICKS_TO_MS(1000));
i2c_cmd_link_delete(cmd);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "PMU WRITE FAILED! < ");
}
#endif
return ret == ESP_OK ? 0 : -1;
}
/**
* @brief i2c master initialization
*/
esp_err_t i2c_init(void)
{
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_XPOWERS_ESP_IDF_NEW_API)
ESP_LOGI(TAG, "Implemented using read and write callback methods (Use higher version >= 5.0 API)");
i2c_master_bus_handle_t bus_handle;
i2c_master_bus_config_t i2c_bus_config;
memset(&i2c_bus_config, 0, sizeof(i2c_bus_config));
i2c_bus_config.clk_source = I2C_CLK_SRC_DEFAULT;
i2c_bus_config.i2c_port = I2C_MASTER_NUM;
i2c_bus_config.scl_io_num = (gpio_num_t)I2C_MASTER_SCL_IO;
i2c_bus_config.sda_io_num = (gpio_num_t)I2C_MASTER_SDA_IO;
i2c_bus_config.glitch_ignore_cnt = 7;
ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_bus_config, &bus_handle));
i2c_device_config_t i2c_dev_conf = {
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
.device_address = PMU_SLAVE_ADDRESS,
.scl_speed_hz = I2C_MASTER_FREQ_HZ,
};
return i2c_master_bus_add_device(bus_handle, &i2c_dev_conf, &i2c_device);
#else
ESP_LOGI(TAG, "Implemented using read and write callback methods (Use lower version < 5.0 API)");
i2c_config_t i2c_conf ;
memset(&i2c_conf, 0, sizeof(i2c_conf));
i2c_conf.mode = I2C_MODE_MASTER;
i2c_conf.sda_io_num = I2C_MASTER_SDA_IO;
i2c_conf.scl_io_num = I2C_MASTER_SCL_IO;
i2c_conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
i2c_conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
i2c_conf.master.clk_speed = I2C_MASTER_FREQ_HZ;
i2c_param_config(I2C_MASTER_NUM, &i2c_conf);
return i2c_driver_install(I2C_MASTER_NUM, i2c_conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
#endif
}
#else
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)) && defined(CONFIG_XPOWERS_ESP_IDF_NEW_API)
#include "soc/clk_tree_defs.h"
i2c_master_bus_handle_t bus_handle;
// * Using the new API of esp-idf 5.x, you need to pass the I2C BUS handle,
// * which is useful when the bus shares multiple devices.
esp_err_t i2c_init(void)
{
i2c_master_bus_config_t i2c_bus_config;
memset(&i2c_bus_config, 0, sizeof(i2c_bus_config));
i2c_bus_config.clk_source = I2C_CLK_SRC_DEFAULT;
i2c_bus_config.i2c_port = I2C_MASTER_NUM;
i2c_bus_config.scl_io_num = I2C_MASTER_SCL_IO;
i2c_bus_config.sda_io_num = I2C_MASTER_SDA_IO;
i2c_bus_config.glitch_ignore_cnt = 7;
return i2c_new_master_bus(&i2c_bus_config, &bus_handle);
}
#endif //ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,0,0)
#endif //CONFIG_I2C_COMMUNICATION_METHOD_CALLBACK_RW

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
#