diff --git a/README.md b/README.md index 742913a5..5b392701 100644 --- a/README.md +++ b/README.md @@ -234,6 +234,7 @@ or [GitLab examples](https://gitlab.com/UncleRus/esp-idf-lib/tree/master/example | **ds3502** | Driver for nonvolatile digital potentiometer DS3502 | BSD-3-Clause | esp32, esp8266, esp32s2, esp32c3 | yes | | **example** | An example component | ISC | esp32, esp8266, esp32s2, esp32c3 | n/a | | **hd44780** | Driver for HD44780 compatible LCD text displays | BSD-3-Clause | esp32, esp8266, esp32s2, esp32c3 | no | +| **mp2660** | Driver for MP2660 5V USB, 500mA, I2C-Controlled Linear Charger with Power Path Management for Single-Cell Li-Ion Battery | BSD-3-Clause | esp32, esp32s2, esp32c3 | yes | | **pca9685** | Driver for 16-channel, 12-bit PWM PCA9685 | BSD-3-Clause | esp32, esp8266, esp32s2, esp32c3 | yes | | **rda5807m** | Driver for single-chip broadcast FM radio tuner RDA5807M | BSD-3-Clause | esp32, esp8266, esp32s2, esp32c3 | yes | | **tca9548** | Driver for TCA9548A/PCA9548A low-voltage 8-channel I2C switch | BSD-3-Clause | esp32, esp8266, esp32s2, esp32c3 | yes | @@ -325,6 +326,7 @@ or [GitLab examples](https://gitlab.com/UncleRus/esp-idf-lib/tree/master/example - [jsuiker](https://github.com/jsuiker): `dht` - [Julian Doerner](https://github.com/juliandoerner): `tsl2591` - [Lucio Tarantino](https://github.com/dianlight): `ads111x` +- [Manuel Markwort](https://github.com/mmarkwort): `mp2660` - [Marc Luehr](https://github.com/th3link): `veml7700` - [Nate Usher](https://github.com/nated0g): `scd30` - Pavel Merzlyakov: `ds1302` diff --git a/components/mp2660/.eil.yml b/components/mp2660/.eil.yml new file mode 100644 index 00000000..9c695602 --- /dev/null +++ b/components/mp2660/.eil.yml @@ -0,0 +1,19 @@ +name: mp2660 +description: Driver for MP2660 5V USB, 500mA, I2C-Controlled Linear Charger with Power Path Management for Single-Cell Li-Ion Battery +version: 1.0.0 +groups: + - misc +code_owners: + - mmarkwort +depends: + - i2cdev + - esp_idf_lib_helpers +thread_safe: yes +targets: + - esp32 + - esp32s2 + - esp32c3 +license: BSD-3 +copyrights: + - name: mmarkwort + year: 2023 diff --git a/components/mp2660/CMakeLists.txt b/components/mp2660/CMakeLists.txt new file mode 100644 index 00000000..9f824f6c --- /dev/null +++ b/components/mp2660/CMakeLists.txt @@ -0,0 +1,5 @@ +idf_component_register( + SRCS mp2660.c + INCLUDE_DIRS . + REQUIRES i2cdev esp_idf_lib_helpers +) diff --git a/components/mp2660/LICENSE b/components/mp2660/LICENSE new file mode 100644 index 00000000..56e9058a --- /dev/null +++ b/components/mp2660/LICENSE @@ -0,0 +1,26 @@ +Copyright (c) 2023 Manuel Markwort (https://github.com/mmarkwort) + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of itscontributors +may be used to endorse or promote products derived from this software without +specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/components/mp2660/component.mk b/components/mp2660/component.mk new file mode 100644 index 00000000..60e16f4b --- /dev/null +++ b/components/mp2660/component.mk @@ -0,0 +1,2 @@ +COMPONENT_ADD_INCLUDEDIRS = . +COMPONENT_DEPENDS = i2cdev esp_idf_lib_helpers diff --git a/components/mp2660/mp2660.c b/components/mp2660/mp2660.c new file mode 100644 index 00000000..00b55c78 --- /dev/null +++ b/components/mp2660/mp2660.c @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2017 Gunar Schorcht + * Copyright (c) 2019 Ruslan V. Uss + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of itscontributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file mp2660.c + * + * ESP-IDF driver for Monolithic Systems 5V USB, 500mA, I2C-Controlled Linear Charger with Power Path Management for Single-Cell Li-Ion Battery + * + * Copyright (c) 2023 Manuel Markwort \n + * + * BSD Licensed as described in the file LICENSE + */ + +#include +#include "mp2660.h" + +#define I2C_FREQ_HZ 400000 // 400kHz + +#define MP2660_SOURCE_CONTROL_REG_ADDR 0x00 +#define MP2660_POWER_ON_CONFIG_REG_ADDR 0x01 +#define MP2660_CURENT_CONTROL_REG_ADDR 0x02 +#define MP2660_PRECHARGE_TERMINATION_CURRENT_REG_ADDR 0x03 +#define MP2660_CHARGE_VOLTAGE_CONTROL_REG_ADDR 0x04 +#define MP2660_CHARGE_TERMINATION_TIMER_CONTROL_REG_ADDR 0x05 +#define MP2660_MISC_OPERATION_CONTROL_REG_ADDR 0x06 +#define MP2660_SYSTEM_STATUS_REG_ADDR 0x07 +#define MP2660_FAULT_REG_ADDR 0x08 + +#define CHECK_ARG(VAL) do { if (!(VAL)) return ESP_ERR_INVALID_ARG; } while (0) + +esp_err_t mp2660_init_desc(i2c_dev_t *dev, i2c_port_t port, gpio_num_t sda_gpio, gpio_num_t scl_gpio) +{ + CHECK_ARG(dev); + + dev->port = port; + dev->addr = MP2660_I2C_ADDR; + dev->cfg.sda_io_num = sda_gpio; + dev->cfg.scl_io_num = scl_gpio; +#if HELPER_TARGET_IS_ESP32 + dev->cfg.master.clk_speed = I2C_FREQ_HZ; +#endif + + return i2c_dev_create_mutex(dev); +} + +esp_err_t mp2660_free_desc(i2c_dev_t *dev) +{ + CHECK_ARG(dev); + + return i2c_dev_delete_mutex(dev); +} + +esp_err_t mp2660_read(i2c_dev_t *dev, uint8_t addr, void* data) +{ + CHECK_ARG(dev); + + I2C_DEV_TAKE_MUTEX(dev); + I2C_DEV_CHECK(dev, i2c_dev_read_reg(dev, addr, data, 1)); + I2C_DEV_GIVE_MUTEX(dev); + + return ESP_OK; +} + +esp_err_t mp2660_write(i2c_dev_t *dev, uint8_t addr, void* data) +{ + CHECK_ARG(dev); + + I2C_DEV_TAKE_MUTEX(dev); + I2C_DEV_CHECK(dev, i2c_dev_write_reg(dev, addr, data, 1)); + I2C_DEV_GIVE_MUTEX(dev); + + return ESP_OK; +} + +esp_err_t mp2660_get_input_source(i2c_dev_t *dev, mp2660_input_source_t* input_source) +{ + return mp2660_read(dev, MP2660_SOURCE_CONTROL_REG_ADDR, input_source); +} + +esp_err_t mp2660_set_input_source(i2c_dev_t *dev, mp2660_input_source_t* input_source) +{ + return mp2660_write(dev, MP2660_SOURCE_CONTROL_REG_ADDR, input_source); +} + +esp_err_t mp2660_get_pwr_on_conf(i2c_dev_t *dev, mp2660_power_on_conf_t* pwr_config) +{ + return mp2660_read(dev, MP2660_POWER_ON_CONFIG_REG_ADDR, pwr_config); +} + +esp_err_t mp2660_set_pwr_on_conf(i2c_dev_t *dev, mp2660_power_on_conf_t* pwr_config) +{ + return mp2660_write(dev, MP2660_POWER_ON_CONFIG_REG_ADDR, pwr_config); +} + +esp_err_t mp2660_get_chrg_current_ctrl(i2c_dev_t *dev, mp2660_charge_current_ctrl_t* chrg_current_ctrl) +{ + return mp2660_read(dev, MP2660_CURENT_CONTROL_REG_ADDR, chrg_current_ctrl); +} + +esp_err_t mp2660_set_chrg_current_ctrl(i2c_dev_t *dev, mp2660_charge_current_ctrl_t* chrg_current_ctrl) +{ + return mp2660_write(dev, MP2660_CURENT_CONTROL_REG_ADDR, chrg_current_ctrl); +} + +esp_err_t mp2660_get_pre_chrg_term_current(i2c_dev_t *dev, mp2660_pre_charge_term_current_t* pre_chrg_term_current) +{ + return mp2660_read(dev, MP2660_PRECHARGE_TERMINATION_CURRENT_REG_ADDR, pre_chrg_term_current); +} + +esp_err_t mp2660_set_pre_chrg_term_current(i2c_dev_t *dev, mp2660_pre_charge_term_current_t* pre_chrg_term_current) +{ + return mp2660_write(dev, MP2660_PRECHARGE_TERMINATION_CURRENT_REG_ADDR, pre_chrg_term_current); +} + +esp_err_t mp2660_get_chrg_voltage_control(i2c_dev_t *dev, mp2660_charge_voltage_ctrl_t* chrg_voltage_ctrl) +{ + return mp2660_read(dev, MP2660_CHARGE_VOLTAGE_CONTROL_REG_ADDR, chrg_voltage_ctrl); +} + +esp_err_t mp2660_set_chrg_voltage_control(i2c_dev_t *dev, mp2660_charge_voltage_ctrl_t* chrg_voltage_ctrl) +{ + return mp2660_write(dev, MP2660_CHARGE_VOLTAGE_CONTROL_REG_ADDR, chrg_voltage_ctrl); +} + +esp_err_t mp2660_get_chrg_term_timer_control(i2c_dev_t *dev, mp2660_charge_term_timer_ctrl_t* charge_term_timer_ctrl) +{ + return mp2660_read(dev, MP2660_CHARGE_TERMINATION_TIMER_CONTROL_REG_ADDR, charge_term_timer_ctrl); +} + +esp_err_t mp2660_set_chrg_term_timer_control(i2c_dev_t *dev, mp2660_charge_term_timer_ctrl_t* charge_term_timer_ctrl) +{ + return mp2660_write(dev, MP2660_CHARGE_TERMINATION_TIMER_CONTROL_REG_ADDR, charge_term_timer_ctrl); +} + +esp_err_t mp2660_get_misc_op_control(i2c_dev_t *dev, mp2660_misc_op_ctrl_t* misc_op_ctrl) +{ + return mp2660_read(dev, MP2660_MISC_OPERATION_CONTROL_REG_ADDR, misc_op_ctrl); +} + +esp_err_t mp2660_set_misc_op_control(i2c_dev_t *dev, mp2660_misc_op_ctrl_t* misc_op_ctrl) +{ + return mp2660_write(dev, MP2660_MISC_OPERATION_CONTROL_REG_ADDR, misc_op_ctrl); +} + +esp_err_t mp2660_get_sys_status(i2c_dev_t *dev, mp2660_sys_status_t* sys_status) +{ + return mp2660_read(dev, MP2660_SYSTEM_STATUS_REG_ADDR, sys_status); +} + +esp_err_t mp2660_get_fault(i2c_dev_t *dev, mp2660_fault_t* fault) +{ + return mp2660_read(dev, MP2660_FAULT_REG_ADDR, fault); +} \ No newline at end of file diff --git a/components/mp2660/mp2660.h b/components/mp2660/mp2660.h new file mode 100644 index 00000000..e2649b48 --- /dev/null +++ b/components/mp2660/mp2660.h @@ -0,0 +1,405 @@ +/* + * Copyright (c) 2017 Gunar Schorcht + * Copyright (c) 2019 Ruslan V. Uss + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of itscontributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file mp2660.h + * @defgroup mp2660 mp2660 + * @{ + * + * ESP-IDF driver for Monolithic Systems 5V USB, 500mA, I2C-Controlled Linear Charger with Power Path Management for Single-Cell Li-Ion Battery + * + * Copyright (c) 2023 Manuel Markwort \n + * + * BSD Licensed as described in the file LICENSE + */ + +#ifndef __MP2660_H__ +#define __MP2660_H__ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define MP2660_I2C_ADDR 0x09 //!< I2C address +#define MP2660_SOURCE_CONTROL_REG_DEFAULT 0x4F +#define MP2660_POWER_ON_CONFIG_REG_DEFAULT 0x4 +#define MP2660_CURENT_CONTROL_REG_DEFAULT 0xE +#define MP2660_PRECHARGE_TERMINATION_CURRENT_REG_DEFAULT 0x4A +#define MP2660_CHARGE_VOLTAGE_CONTROL_REG_DEFAULT 0xA3 +#define MP2660_CHARGE_TERMINATION_TIMER_CONTROL_REG_DEFAULT 0x4A +#define MP2660_MISC_OPERATION_CONTROL_REG_DEFAULT 0xB +#define MP2660_SYSTEM_STATUS_REG_DEFAULT 0x0 +#define MP2660_FAULT_REG_DEFAULT 0x0 + +// Input Source Control Register/Address: 00h (Default: 0100 1111) +typedef struct +{ + union { + struct { + uint8_t i_in_lim_0 : 1; // 000: 85mA, 001: 130mA, 010: 175mA, 011: 220mA, 100: 265mA, 101: 310mA, 110: 355mA, 111: 455mA, Default: 455mA (111) + uint8_t i_in_lim_1 : 1; + uint8_t i_in_lim_2 : 1; + uint8_t v_in_min_0 : 1; // 80mV / RW / VIn Min Offset: 3.88V, Range 3.88V - 5.08V, Default: 4.60V (1001) + uint8_t v_in_min_1 : 1; // 160mV / RW + uint8_t v_in_min_2 : 1; // 320mV / RW + uint8_t v_in_min_3 : 1; // 640mV / RW + uint8_t en_hiz : 1; // 0: Disable 1: Enable / RW / This bit only controls the on and off of the LDO FET. + } data_fields; + struct { + uint8_t reg; + } register_data; + }; + +} mp2660_input_source_t; + +// Power-On Configuration Register / Address: 01h (Default: 0000 0100) +typedef struct +{ + union { + struct { + uint8_t v_batt_uvlo_0 : 1; // 0.1V / RW / Offset: 2.4V, Range: 2.4V - 3.1V, Default: 2.8V (100) + uint8_t v_batt_uvlo_1 : 1; // 0.2V / RW + uint8_t v_batt_uvlo_2 : 1; // 0.4V / RW + uint8_t ceb : 1; // 0: Charge enable 1: Charge disable / RW / Default: Charge enable (0) + uint8_t reserved_1 : 1; // NA + uint8_t reserved_2 : 1; // NA + uint8_t i2c_watchdog_timer : 1; // 0: Normal 1: Reset / RW / Default: Normal (0) + uint8_t reg_reset : 1; // 0: Keep current setting 1: Reset / RW / Default: Keep current register setting (0) + } data_fields; + struct { + uint8_t reg; + } register_data; + }; + +} mp2660_power_on_conf_t; + +// Charge Current Control Register/ Address: 02h (Default: 0000 1110) +typedef struct +{ + union { + struct { + uint8_t icc_4 : 1; // 272mA / RW / Offset: 8mA, Range: 8mA - 535mA, Default: 246mA (01110) + uint8_t icc_3 : 1; // 136mA / RW + uint8_t icc_2 : 1; // 68mA / RW + uint8_t icc_1 : 1; // 34mA / RW + uint8_t icc_0 : 1; // 17mA / RW + uint8_t reserved_3 : 1; // NA + uint8_t reserved_2 : 1; // NA + uint8_t reserved_1 : 1; // NA + } data_fields; + struct { + uint8_t reg; + } register_data; + }; + +} mp2660_charge_current_ctrl_t; + +// Pre-Charge/ Termination Current/ Address: 03h (Default: 0100 1010) +typedef struct +{ + union { + struct { + uint8_t reserved_1 : 1; // NA + uint8_t i_dschg_3 : 1; // 800mA / RW / Offset: 200mA, Range: 200mA - 1.6A, Default: 1.0A (1001) + uint8_t i_dschg_2 : 1; // 400mA / RW + uint8_t i_dschg_1 : 1; // 200mA / RW + uint8_t i_dschg_0 : 1; // 100mA / RW + uint8_t reserved_2 : 1; // NA + uint8_t i_pre_1 : 1; // 14mA / RW / Offset: 6mA, Range: 6mA - 27mA, Default: 20mA (10) + uint8_t i_pre_0 : 1; // 7mA / RW + } data_fields; + struct { + uint8_t reg; + } register_data; + }; + +} mp2660_pre_charge_term_current_t; + +// Charge Voltage Control Register/ Address: 04h (Default: 1010 0011) +typedef struct +{ + union { + struct { + uint8_t v_bat_reg_5 : 1; // 480mV / RW / Offset: 3.60V, Range: 3.60V - 4.545V, Default: 4.2V (101000) + uint8_t v_bat_reg_4 : 1; // 240mV / RW + uint8_t v_bat_reg_3 : 1; // 120mV / RW + uint8_t v_bat_reg_2 : 1; // 60mV / RW + uint8_t v_bat_reg_1 : 1; // 30mV / RW + uint8_t v_bat_reg_0 : 1; // 15mV / RW + uint8_t v_batt_pre : 1; // 0: 2.8V 1: 3.0V / RW / Default: 3.0V (1) + uint8_t v_batt_rech : 1; // 0: 150mV 1: 300mV / RW / Default: 300mV (1) + } data_fields; + struct { + uint8_t reg; + } register_data; + }; + +} mp2660_charge_voltage_ctrl_t; + +// Charge Termination/Timer Control Register / Address: 05h (Default: 0100 1010) +typedef struct +{ + union { + struct { + uint8_t reserved : 1; // NA + uint8_t en_term : 1; // 0: Disable 1: Enable / RW / Default: Enable (1) + uint8_t watchdog_1 : 1; // 00: Disable timer 01: 40s 10: 80s 11: 160s / RW / Default: Disable timer (00) + uint8_t watchdog_0 : 1; // + uint8_t en_timer : 1; // 0: Disable 1: Enable / RW / Default: Enable timer (1) + uint8_t chg_timer_1 : 1; // 00: 3hrs 01: 5hrs 10: 8hrs 11: 12hrs / RW / Default: 5hrs (01) + uint8_t chg_timer_0 : 1; // + uint8_t term_tmr : 1; // 0: Disable 1: Enable / RW / Default: Disable (0) + } data_fields; + struct { + uint8_t reg; + } register_data; + }; + +} mp2660_charge_term_timer_ctrl_t; + +// Miscellaneous Operation Control Register/ Address: 06h (Default: 0000 1011) +typedef struct +{ + union { + struct { + uint8_t reserved_1 : 1; // NA + uint8_t tmr2x_en : 1; // 0: Disable 2X extended safety timer during PPM 1: Enable 2X extended safety timer during PPM / RW / Default: Disable (0) + uint8_t fet_dis : 1; // 0: Enable 1: Turn off / RW / Default: Enable (0) + uint8_t reserved_2 : 1; // NA + uint8_t en_ntc : 1; // 0: Disable 1: Enable / RW / Default: Enable (1) + uint8_t reserved_3 : 1; // NA + uint8_t tj_reg_0 : 1; // 00: 60°C 01: 80°C 10: 100°C 11: 120°C / RW / 120°C (11) + uint8_t tj_reg_1 : 1; // + } data_fields; + struct { + uint8_t reg; + } register_data; + }; + +} mp2660_misc_op_ctrl_t; + +// System Status Register/ Address: 07h (Default: 0000 0000) +typedef struct +{ + union { + struct { + uint8_t reserved_1 : 1; // NA + uint8_t rev_1 : 1; // Revision number / R / Default: (00) + uint8_t rev_0 : 1; // + uint8_t chg_stat_1 : 1; // 00: Not charging 01: Pre-charge 10: Charge 11: Charge done / R / Default: Not charging (00) + uint8_t chg_stat_0 : 1; // + uint8_t ppm_stat : 1; // 0: No PPM 1: In PPM / R / Default: No PPM (0) (no power-path management happens) + uint8_t pg_stat : 1; // 0: Power fail 1: Power good / R / Default: Power fail (0) + uint8_t therm_stat : 1; // 0: No thermal regulation 1: In thermal regulation / R / No thermal regulation (0) + } data_fields; + struct { + uint8_t reg; + } register_data; + }; + +} mp2660_sys_status_t; + +// Fault Register/ Address: 08h (Default: 0000 0000) +typedef struct +{ + union { + struct { + uint8_t reserved_1 : 1; // NA + uint8_t watchdog_fault : 1; // 0: Normal 1: Watchdog timer expiration / R / Default: Normal (0) + uint8_t vin_fault : 1; // 0: Normal 1: Input fault (OVP or bad source) / R / Default: Normal (0) + uint8_t them_sd : 1; // 0: Normal 1: Thermal shutdown / R / Default: Normal (0) + uint8_t bat_fault : 1; // 0: Normal 1: Battery OVP / R / Default: Normal (0) + uint8_t stmr_fault : 1; // 0: Normal 1: Safety timer expiration / R / Default: Normal (0) + uint8_t reserved_2 : 1; // NA + uint8_t reserved_3 : 1; // NA + } data_fields; + struct { + uint8_t reg; + } register_data; + }; + +} mp2660_fault_t; + +/** + * @brief Initialize device descriptor + * + * @param dev Device descriptor + * @param port I2C port + * @param sda_gpio SDA GPIO pin + * @param scl_gpio SCL GPIO pin + * @return `ESP_OK` on success + */ +esp_err_t mp2660_init_desc(i2c_dev_t *dev, i2c_port_t port, gpio_num_t sda_gpio, gpio_num_t scl_gpio); + +/** + * @brief Free device descriptor + * + * @param dev Device descriptor + * @return `ESP_OK` on success + */ +esp_err_t mp2660_free_desc(i2c_dev_t *dev); + +/** + * @brief Reads input source register + * @param dev Device descriptor + * @param input_source Target buffer + * @return `ESP_OK` on success + */ +esp_err_t mp2660_get_input_source(i2c_dev_t *dev, mp2660_input_source_t* input_source); + +/** + * @brief Writes input source register + * @param dev Device descriptor + * @param input_source Source buffer + * @return `ESP_OK` on success + */ +esp_err_t mp2660_set_input_source(i2c_dev_t *dev, mp2660_input_source_t* input_source); + +/** + * @brief Reads power configuration register + * @param dev Device descriptor + * @param pwr_config Target buffer + * @return `ESP_OK` on success + */ +esp_err_t mp2660_get_pwr_on_conf(i2c_dev_t *dev, mp2660_power_on_conf_t* pwr_config); + +/** + * @brief Writes power configuration register + * @param dev Device descriptor + * @param pwr_config Source buffer + * @return `ESP_OK` on success + */ +esp_err_t mp2660_set_pwr_on_conf(i2c_dev_t *dev, mp2660_power_on_conf_t* pwr_config); + +/** + * @brief Reads charge current control register + * @param dev Device descriptor + * @param chrg_current_ctrl Target buffer + * @return `ESP_OK` on success + */ +esp_err_t mp2660_get_chrg_current_ctrl(i2c_dev_t *dev, mp2660_charge_current_ctrl_t* chrg_current_ctrl); + +/** + * @brief Writes charge current control register + * @param dev Device descriptor + * @param chrg_current_ctrl Source buffer + * @return `ESP_OK` on success + */ +esp_err_t mp2660_set_chrg_current_ctrl(i2c_dev_t *dev, mp2660_charge_current_ctrl_t* chrg_current_ctrl); + +/** + * @brief Reads pre-charge / termination current register + * @param dev Device descriptor + * @param pre_chrg_term_current Target buffer + * @return `ESP_OK` on success + */ +esp_err_t mp2660_get_pre_chrg_term_current(i2c_dev_t *dev, mp2660_pre_charge_term_current_t* pre_chrg_term_current); + +/** + * @brief Writes pre-charge / termination current register + * @param dev Device descriptor + * @param pre_chrg_term_current Source buffer + * @return `ESP_OK` on success + */ +esp_err_t mp2660_set_pre_chrg_term_current(i2c_dev_t *dev, mp2660_pre_charge_term_current_t* pre_chrg_term_current); + +/** + * @brief Reads charge voltage control register + * @param dev Device descriptor + * @param chrg_voltage_ctrl Target buffer + * @return `ESP_OK` on success + */ +esp_err_t mp2660_get_chrg_voltage_control(i2c_dev_t *dev, mp2660_charge_voltage_ctrl_t* chrg_voltage_ctrl); + +/** + * @brief Writes charge voltage control register + * @param dev Device descriptor + * @param chrg_voltage_ctrl Source buffer + * @return `ESP_OK` on success + */ +esp_err_t mp2660_set_chrg_voltage_control(i2c_dev_t *dev, mp2660_charge_voltage_ctrl_t* chrg_voltage_ctrl); + +/** + * @brief Reads charge termination / timer control register + * @param dev Device descriptor + * @param charge_term_timer_ctrl Target buffer + * @return `ESP_OK` on success + */ +esp_err_t mp2660_get_chrg_term_timer_control(i2c_dev_t *dev, mp2660_charge_term_timer_ctrl_t* charge_term_timer_ctrl); + +/** + * @brief Writes charge termination / timer control register + * @param dev Device descriptor + * @param charge_term_timer_ctrl Source buffer + * @return `ESP_OK` on success + */ +esp_err_t mp2660_set_chrg_term_timer_control(i2c_dev_t *dev, mp2660_charge_term_timer_ctrl_t* charge_term_timer_ctrl); + +/** + * @brief Reads miscellaneous operation control register + * @param dev Device descriptor + * @param misc_op_ctrl Target buffer + * @return `ESP_OK` on success + */ +esp_err_t mp2660_get_misc_op_control(i2c_dev_t *dev, mp2660_misc_op_ctrl_t* misc_op_ctrl); + +/** + * @brief Writes miscellaneous operation control register + * @param dev Device descriptor + * @param misc_op_ctrl Source buffer + * @return `ESP_OK` on success + */ +esp_err_t mp2660_set_misc_op_control(i2c_dev_t *dev, mp2660_misc_op_ctrl_t* misc_op_ctrl); + +/** + * @brief Reads system status register + * @param dev Device descriptor + * @param sys_status Target buffer + * @return `ESP_OK` on success + */ +esp_err_t mp2660_get_sys_status(i2c_dev_t *dev, mp2660_sys_status_t* sys_status); + +/** + * @brief Reads fault register + * @param dev Device descriptor + * @param fault Target buffer + * @return `ESP_OK` on success + */ +esp_err_t mp2660_get_fault(i2c_dev_t *dev, mp2660_fault_t* fault); + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif \ No newline at end of file diff --git a/devtools/persons.yml b/devtools/persons.yml index 6b5dd2cc..9e8c3989 100644 --- a/devtools/persons.yml +++ b/devtools/persons.yml @@ -157,3 +157,6 @@ full_name: Jakub Turek gh_id: QB4-dev +- name: mmarkwort + full_name: Manuel Markwort + gh_id: mmarkwort diff --git a/examples/mp2660/default/CMakeLists.txt b/examples/mp2660/default/CMakeLists.txt new file mode 100644 index 00000000..998dc994 --- /dev/null +++ b/examples/mp2660/default/CMakeLists.txt @@ -0,0 +1,8 @@ +# The following 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 ${CMAKE_CURRENT_SOURCE_DIR}/../../../components) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(example-mp2660) diff --git a/examples/mp2660/default/Makefile b/examples/mp2660/default/Makefile new file mode 100644 index 00000000..edc9ef30 --- /dev/null +++ b/examples/mp2660/default/Makefile @@ -0,0 +1,6 @@ +#V := 1 +PROJECT_NAME := example-mp2660 + +EXTRA_COMPONENT_DIRS := $(CURDIR)/../../../components + +include $(IDF_PATH)/make/project.mk diff --git a/examples/mp2660/default/README.md b/examples/mp2660/default/README.md new file mode 100644 index 00000000..17297b4a --- /dev/null +++ b/examples/mp2660/default/README.md @@ -0,0 +1,57 @@ +# Example for `mp2660` driver + +## What it does + +It reads all registers from IC + +## Wiring + +Connect `SCL` and `SDA` pins to the following pins with appropriate pull-up +resistors. + +| Name | Description | Defaults | +|------|-------------|----------| +| `CONFIG_EXAMPLE_I2C_MASTER_SCL` | GPIO number for `SCL` | "22" for `esp32`, `esp32s2`, and `esp32s3` | +| `CONFIG_EXAMPLE_I2C_MASTER_SDA` | GPIO number for `SDA` | "21" for `esp32`, `esp32s2`, and `esp32s3` | + +## Example log + +```console +I (0) cpu_start: App cpu up. +I (137) cpu_start: Pro cpu start user code +I (137) cpu_start: cpu freq: 80000000 Hz +I (137) cpu_start: Application information: +I (138) cpu_start: Project name: Esp32.MP2660.I2C +I (143) cpu_start: App version: 0.0.1 +I (147) cpu_start: Compile time: Oct 9 2023 22:57:10 +I (152) cpu_start: ELF file SHA256: 8231edda675415ce... +I (157) cpu_start: ESP-IDF: v5.0.1 +I (161) cpu_start: Min chip rev: v0.0 +I (165) cpu_start: Max chip rev: v3.99 +I (169) cpu_start: Chip rev: v3.0 +I (173) heap_init: Initializing. RAM available for dynamic allocation: +I (179) heap_init: At 3FFAE6E0 len 0000F480 (61 KiB): DRAM +I (184) heap_init: At 3FFC16B0 len 0001E950 (122 KiB): DRAM +I (189) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM +I (195) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM +I (200) heap_init: At 4008BB98 len 00014468 (81 KiB): IRAM +I (207) spi_flash: detected chip: generic +I (209) spi_flash: flash io: dio +I (214) cpu_start: Starting scheduler on PRO CPU. +I (0) cpu_start: Starting scheduler on APP CPU. +E (00:00:03.084) i2cdev: Could not read from device [0x09 at 0]: 263 (ESP_ERR_TIMEOUT) +I (00:00:03.085) Main: Result reading fault register: ESP_ERR_TIMEOUT +E (00:00:03.088) i2cdev: Could not read from device [0x09 at 0]: -1 (ESP_FAIL) +I (00:00:03.095) Main: Result reading fault register: ESP_FAIL +I (00:00:03.101) Main: Result reading fault register: ESP_OK +I (00:00:03.106) Main: Result: 0000004f, EnHIZ: 0, VInMin3: 1, VInMin2: 0, VInMin1: 0, VInMin0: 1, IInLim_2: 1, IInLim_1: 1, IInLim_0: 1 +I (00:00:03.118) Main: Result: 00000004, UVLO 0: 0, UVLO 1: 0, UVLO 2: 1, CEB: 0, WatchdogTimer: 0, RegisterReset: 0 +I (00:00:03.128) Main: Result: 0000000e, ICC 0: 0, ICC 1: 1, ICC 2: 1, ICC 3: 1, ICC 4: 0 +I (00:00:03.136) Main: Result: 0000004a, DSCHG 0: 0, DSCHG 1: 1, DSCHG 2: 0, DSCHG 3: 1, IPre 0: 0, IPre 1: 1 +I (00:00:03.146) Main: Result: 000000a3, VBattReg 0: 1, VBattReg 1: 0, VBattReg 2: 0, VBattReg 3: 0, VBattReg 4: 1, VBattReg 5: 1, VBatt pre: 0, VBatt rech: 1 +I (00:00:03.160) Main: Result: 0000004a, EnTerm: 1, WatchDog 0: 1, WatchDog 1: 0, EnTimer: 0, ChgTimer 0: 1, ChgTimer 1: 0, TermTmr: 0 +I (00:00:03.172) Main: Result: 0000000b, TMR2XEn: 1, FetDis: 0, EnNtc: 0, TJReg 0: 0, TJReg 1: 0 +I (00:00:03.180) Main: Result: 00000080, Rev 1: 0, Rev 0: 0, ChgStat 1: 0, ChgStat 0: 0, PPMStat: 0, PGStat: 0, ThermStat: 1 +I (00:00:03.191) Main: Result: 00000080, WatchdogFault: 0, VinFault: 0, ThemSd: 0, BatFault 0: 0, StmrFault: 0 +I (00:00:03.200) Main: Done. +``` diff --git a/examples/mp2660/default/main/CMakeLists.txt b/examples/mp2660/default/main/CMakeLists.txt new file mode 100644 index 00000000..cf2c455c --- /dev/null +++ b/examples/mp2660/default/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "main.c" + INCLUDE_DIRS ".") diff --git a/examples/mp2660/default/main/Kconfig.projbuild b/examples/mp2660/default/main/Kconfig.projbuild new file mode 100644 index 00000000..bc7cc696 --- /dev/null +++ b/examples/mp2660/default/main/Kconfig.projbuild @@ -0,0 +1,17 @@ +menu "Example configuration" + config EXAMPLE_I2C_MASTER_SCL + int "SCL GPIO Number" + default 5 if IDF_TARGET_ESP8266 + default 6 if IDF_TARGET_ESP32C3 + default 22 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 + help + GPIO number for I2C Master clock line. + + config EXAMPLE_I2C_MASTER_SDA + int "SDA GPIO Number" + default 4 if IDF_TARGET_ESP8266 + default 5 if IDF_TARGET_ESP32C3 + default 21 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 + help + GPIO number for I2C Master data line. +endmenu diff --git a/examples/mp2660/default/main/component.mk b/examples/mp2660/default/main/component.mk new file mode 100644 index 00000000..7700ea99 --- /dev/null +++ b/examples/mp2660/default/main/component.mk @@ -0,0 +1 @@ +COMPONENT_ADD_INCLUDEDIRS = . include/ diff --git a/examples/mp2660/default/main/main.c b/examples/mp2660/default/main/main.c new file mode 100644 index 00000000..ac86b2be --- /dev/null +++ b/examples/mp2660/default/main/main.c @@ -0,0 +1,227 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef APP_CPU_NUM +#define APP_CPU_NUM PRO_CPU_NUM +#endif + +static const char* MAIN_LOG_TAG = "Main"; + +void task(void *pvParameters) +{ + i2c_dev_t charger; + memset(&charger, 0, sizeof(i2c_dev_t)); + + i2cdev_init(); + + esp_err_t err = mp2660_init_desc(&charger, 0, CONFIG_EXAMPLE_I2C_MASTER_SDA, CONFIG_EXAMPLE_I2C_MASTER_SCL); + if(err != ESP_OK) + { + ESP_LOGI(MAIN_LOG_TAG, "Cannot init MP2660: %s", esp_err_to_name(err)); + return; + } + + vTaskDelay(pdMS_TO_TICKS(2000)); + + do + { + mp2660_fault_t fault; + err = mp2660_get_fault(&charger, &fault); + + ESP_LOGI(MAIN_LOG_TAG, "Result reading fault register: %s", esp_err_to_name(err)); + + } while (err != ESP_OK); + + for(;;) + { + mp2660_input_source_t input_source; + err = mp2660_get_input_source(&charger, &input_source); + if(err != ESP_OK) + { + ESP_LOGI(MAIN_LOG_TAG, "Cannot read MP2660 input source register: %s", esp_err_to_name(err)); + } + else + { + ESP_LOGI(MAIN_LOG_TAG, "Result: %08x, EnHIZ: %d, VInMin3: %d, VInMin2: %d, VInMin1: %d, VInMin0: %d, IInLim_2: %d, IInLim_1: %d, IInLim_0: %d", + input_source.register_data.reg, + input_source.data_fields.en_hiz, + input_source.data_fields.v_in_min_3, + input_source.data_fields.v_in_min_2, + input_source.data_fields.v_in_min_1, + input_source.data_fields.v_in_min_0, + input_source.data_fields.i_in_lim_2, + input_source.data_fields.i_in_lim_1, + input_source.data_fields.i_in_lim_0); + } + + mp2660_power_on_conf_t pwr_conf; + err = mp2660_get_pwr_on_conf(&charger, &pwr_conf); + + if(err != ESP_OK) + { + ESP_LOGI(MAIN_LOG_TAG, "Cannot read MP2660 power configuration register: %s", esp_err_to_name(err)); + } + else + { + ESP_LOGI(MAIN_LOG_TAG, "Result: %08x, UVLO 0: %d, UVLO 1: %d, UVLO 2: %d, CEB: %d, WatchdogTimer: %d, RegisterReset: %d", + pwr_conf.register_data.reg, + pwr_conf.data_fields.v_batt_uvlo_0, + pwr_conf.data_fields.v_batt_uvlo_1, + pwr_conf.data_fields.v_batt_uvlo_2, + pwr_conf.data_fields.ceb, + pwr_conf.data_fields.i2c_watchdog_timer, + pwr_conf.data_fields.reg_reset); + } + + mp2660_charge_current_ctrl_t charge_current_ctrl; + err = mp2660_get_chrg_current_ctrl(&charger, &charge_current_ctrl); + + if(err != ESP_OK) + { + ESP_LOGI(MAIN_LOG_TAG, "Cannot read MP2660 charge current control register: %s", esp_err_to_name(err)); + } + else + { + ESP_LOGI(MAIN_LOG_TAG, "Result: %08x, ICC 0: %d, ICC 1: %d, ICC 2: %d, ICC 3: %d, ICC 4: %d", + charge_current_ctrl.register_data.reg, + charge_current_ctrl.data_fields.icc_0, + charge_current_ctrl.data_fields.icc_1, + charge_current_ctrl.data_fields.icc_2, + charge_current_ctrl.data_fields.icc_3, + charge_current_ctrl.data_fields.icc_4); + } + + mp2660_pre_charge_term_current_t pre_chrg_term_current; + err = mp2660_get_pre_chrg_term_current(&charger, &pre_chrg_term_current); + + if(err != ESP_OK) + { + ESP_LOGI(MAIN_LOG_TAG, "Cannot read MP2660 pre charge/termination current control register: %s", esp_err_to_name(err)); + } + else + { + ESP_LOGI(MAIN_LOG_TAG, "Result: %08x, DSCHG 0: %d, DSCHG 1: %d, DSCHG 2: %d, DSCHG 3: %d, IPre 0: %d, IPre 1: %d", + pre_chrg_term_current.register_data.reg, + pre_chrg_term_current.data_fields.i_dschg_0, + pre_chrg_term_current.data_fields.i_dschg_1, + pre_chrg_term_current.data_fields.i_dschg_2, + pre_chrg_term_current.data_fields.i_dschg_3, + pre_chrg_term_current.data_fields.i_pre_0, + pre_chrg_term_current.data_fields.i_pre_1); + } + + mp2660_charge_voltage_ctrl_t chrg_voltage_ctrl; + err = mp2660_get_chrg_voltage_control(&charger, &chrg_voltage_ctrl); + + if(err != ESP_OK) + { + ESP_LOGI(MAIN_LOG_TAG, "Cannot read MP2660 charge voltage control register: %s", esp_err_to_name(err)); + } + else + { + ESP_LOGI(MAIN_LOG_TAG, "Result: %08x, VBattReg 0: %d, VBattReg 1: %d, VBattReg 2: %d, VBattReg 3: %d, VBattReg 4: %d, VBattReg 5: %d, VBatt pre: %d, VBatt rech: %d", + chrg_voltage_ctrl.register_data.reg, + chrg_voltage_ctrl.data_fields.v_bat_reg_0, + chrg_voltage_ctrl.data_fields.v_bat_reg_1, + chrg_voltage_ctrl.data_fields.v_bat_reg_2, + chrg_voltage_ctrl.data_fields.v_bat_reg_3, + chrg_voltage_ctrl.data_fields.v_bat_reg_4, + chrg_voltage_ctrl.data_fields.v_bat_reg_5, + chrg_voltage_ctrl.data_fields.v_batt_pre, + chrg_voltage_ctrl.data_fields.v_batt_rech); + } + + mp2660_charge_term_timer_ctrl_t charge_term_timer_ctrl; + err = mp2660_get_chrg_term_timer_control(&charger, &charge_term_timer_ctrl); + + if(err != ESP_OK) + { + ESP_LOGI(MAIN_LOG_TAG, "Cannot read MP2660 charge termination / timer control register: %s", esp_err_to_name(err)); + } + else + { + ESP_LOGI(MAIN_LOG_TAG, "Result: %08x, EnTerm: %d, WatchDog 0: %d, WatchDog 1: %d, EnTimer: %d, ChgTimer 0: %d, ChgTimer 1: %d, TermTmr: %d", + charge_term_timer_ctrl.register_data.reg, + charge_term_timer_ctrl.data_fields.en_term, + charge_term_timer_ctrl.data_fields.watchdog_0, + charge_term_timer_ctrl.data_fields.watchdog_1, + charge_term_timer_ctrl.data_fields.en_timer, + charge_term_timer_ctrl.data_fields.chg_timer_0, + charge_term_timer_ctrl.data_fields.chg_timer_1, + charge_term_timer_ctrl.data_fields.term_tmr); + } + + mp2660_misc_op_ctrl_t misc_op_ctrl; + err = mp2660_get_misc_op_control(&charger, &misc_op_ctrl); + + if(err != ESP_OK) + { + ESP_LOGI(MAIN_LOG_TAG, "Cannot read MP2660 misc operation control register: %s", esp_err_to_name(err)); + } + else + { + ESP_LOGI(MAIN_LOG_TAG, "Result: %08x, TMR2XEn: %d, FetDis: %d, EnNtc: %d, TJReg 0: %d, TJReg 1: %d", + misc_op_ctrl.register_data.reg, + misc_op_ctrl.data_fields.tmr2x_en, + misc_op_ctrl.data_fields.fet_dis, + misc_op_ctrl.data_fields.en_ntc, + misc_op_ctrl.data_fields.tj_reg_0, + misc_op_ctrl.data_fields.tj_reg_1); + } + + mp2660_sys_status_t sys_status; + err = mp2660_get_sys_status(&charger, &sys_status); + + if(err != ESP_OK) + { + ESP_LOGI(MAIN_LOG_TAG, "Cannot read MP2660 system status register: %s", esp_err_to_name(err)); + } + else + { + ESP_LOGI(MAIN_LOG_TAG, "Result: %08x, Rev 1: %d, Rev 0: %d, ChgStat 1: %d, ChgStat 0: %d, PPMStat: %d, PGStat: %d, ThermStat: %d", + sys_status.register_data.reg, + sys_status.data_fields.rev_1, + sys_status.data_fields.rev_0, + sys_status.data_fields.chg_stat_1, + sys_status.data_fields.chg_stat_0, + sys_status.data_fields.ppm_stat, + sys_status.data_fields.pg_stat, + sys_status.data_fields.therm_stat); + } + + mp2660_fault_t fault; + err = mp2660_get_fault(&charger, &fault); + + if(err != ESP_OK) + { + ESP_LOGI(MAIN_LOG_TAG, "Cannot read MP2660 fault register: %s", esp_err_to_name(err)); + } + else + { + ESP_LOGI(MAIN_LOG_TAG, "Result: %08x, WatchdogFault: %d, VinFault: %d, ThemSd: %d, BatFault 0: %d, StmrFault: %d", + fault.register_data.reg, + fault.data_fields.watchdog_fault, + fault.data_fields.vin_fault, + fault.data_fields.them_sd, + fault.data_fields.bat_fault, + fault.data_fields.stmr_fault); + } + + ESP_LOGI(MAIN_LOG_TAG, "Done."); + + vTaskDelay(pdMS_TO_TICKS(3000)); + } +} + +void app_main() +{ + ESP_ERROR_CHECK(i2cdev_init()); + + xTaskCreatePinnedToCore(task, "test", configMINIMAL_STACK_SIZE * 8, NULL, 5, NULL, APP_CPU_NUM); +} diff --git a/examples/mp2660/default/sdkconfig.defaults.esp8266 b/examples/mp2660/default/sdkconfig.defaults.esp8266 new file mode 100644 index 00000000..79a53171 --- /dev/null +++ b/examples/mp2660/default/sdkconfig.defaults.esp8266 @@ -0,0 +1 @@ +CONFIG_NEWLIB_LIBRARY_LEVEL_NORMAL=y