From 7433f984c33f1370c36bd4ed12553d83b5025026 Mon Sep 17 00:00:00 2001 From: Liu Zhongwei Date: Wed, 11 Dec 2024 18:48:49 +0800 Subject: [PATCH 1/2] fix(repo): compile *.cpp files on MicroPython --- CHANGELOG.md | 6 ++++++ idf_component.yml | 2 +- library.properties | 2 +- micropython.cmake | 5 +++-- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f893249..cef8c7e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # ChangeLog +## v1.0.1 - 2024-12-11 + +### Bug Fixes: + +* fix(repo): compile *.cpp files on MicroPython + ## v1.0.0 - 2024-12-06 ### Enhancements: diff --git a/idf_component.yml b/idf_component.yml index 5d75262..f4b137c 100644 --- a/idf_component.yml +++ b/idf_component.yml @@ -1,4 +1,4 @@ -version: "1.0.0" +version: "1.0.1" description: ESP32_IO_Expander is a library designed for driving IO expander chips using ESP SoCs url: https://github.com/esp-arduino-libs/ESP32_IO_Expander repository: https://github.com/esp-arduino-libs/ESP32_IO_Expander.git diff --git a/library.properties b/library.properties index b15e1ee..df3c950 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP32_IO_Expander -version=1.0.0 +version=1.0.1 author=espressif maintainer=espressif sentence=ESP32_IO_Expander is a library designed for driving IO expander chips using ESP SoCs diff --git a/micropython.cmake b/micropython.cmake index 207fc55..ed63811 100644 --- a/micropython.cmake +++ b/micropython.cmake @@ -4,10 +4,11 @@ add_library(usermod_esp_io_expander INTERFACE) # Set the source directorya and find all source files. set(SRC_DIR ${CMAKE_CURRENT_LIST_DIR}/src) -file(GLOB_RECURSE SRCS ${SRC_DIR}/*.c) +file(GLOB_RECURSE SRCS_C ${SRC_DIR}/*.c) +file(GLOB_RECURSE SRCS_CXX ${SRC_DIR}/*.cpp) # Add our source files to the library. -target_sources(usermod_esp_io_expander INTERFACE ${SRCS}) +target_sources(usermod_esp_io_expander INTERFACE ${SRCS_C} ${SRCS_CXX}) # Add the current directory as an include directory. target_include_directories(usermod_esp_io_expander INTERFACE ${SRC_DIR}) From cbd89f6e917f3009ab464976ad169ad34ef40341 Mon Sep 17 00:00:00 2001 From: Liu Zhongwei Date: Fri, 3 Jan 2025 15:40:00 +0800 Subject: [PATCH 2/2] feat(base): update base class --- CHANGELOG.md | 6 +- CMakeLists.txt | 2 +- examples/ch422g/ch422g.ino | 1 - idf_component.yml | 2 +- micropython.cmake | 6 + src/ESP_IOExpander_Library.h | 1 - src/chip/esp_expander_base.cpp | 175 +++++++++++++--- src/chip/esp_expander_base.hpp | 251 ++++++++++------------- src/chip/esp_expander_ch422g.cpp | 27 ++- src/chip/esp_expander_ch422g.hpp | 14 +- src/chip/esp_expander_ht8574.cpp | 19 +- src/chip/esp_expander_ht8574.hpp | 10 +- src/chip/esp_expander_tca95xx_16bit.cpp | 19 +- src/chip/esp_expander_tca95xx_16bit.hpp | 10 +- src/chip/esp_expander_tca95xx_8bit.cpp | 19 +- src/chip/esp_expander_tca95xx_8bit.hpp | 10 +- src/esp_expander_utils.h | 1 + src/port/esp_io_expander.c | 1 - src/port/esp_io_expander.h | 4 - src/port/esp_io_expander_ch422g.c | 1 - src/port/esp_io_expander_ch422g.h | 1 - src/port/esp_io_expander_ht8574.c | 1 - src/port/esp_io_expander_tca9554.c | 1 - src/port/esp_io_expander_tca95xx_16bit.c | 1 - test_apps/main/test_chip_general.cpp | 19 +- test_apps/sdkconfig.ci.debug_log | 2 + 26 files changed, 350 insertions(+), 254 deletions(-) create mode 100644 test_apps/sdkconfig.ci.debug_log diff --git a/CHANGELOG.md b/CHANGELOG.md index cef8c7e..eebfcfa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # ChangeLog -## v1.0.1 - 2024-12-11 +## v1.0.1 - 2025-01-23 + +### Enhancements: + +* feat(base): update base class ### Bug Fixes: diff --git a/CMakeLists.txt b/CMakeLists.txt index 6eefe2d..c1af501 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,4 +13,4 @@ idf_component_register( driver ) -target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-missing-field-initializers) +target_compile_options(${COMPONENT_LIB} PUBLIC -Wno-missing-field-initializers) diff --git a/examples/ch422g/ch422g.ino b/examples/ch422g/ch422g.ino index 51f067c..89709e1 100644 --- a/examples/ch422g/ch422g.ino +++ b/examples/ch422g/ch422g.ino @@ -34,7 +34,6 @@ Since the input/output mode of CH422G's IO0-7 must remain consistent, the driver will only set IO0-7 to input mode when it determines that all pins are configured as input. Using pinMode and multiPinMode will be invalid. You can only set the pin working mode through enableAllIO_Input, enableAllIO_Output, enableOC_PushPull and enableOC_OpenDrain - * */ #include diff --git a/idf_component.yml b/idf_component.yml index f4b137c..846d206 100644 --- a/idf_component.yml +++ b/idf_component.yml @@ -6,5 +6,5 @@ issues: https://github.com/esp-arduino-libs/ESP32_IO_Expander/issues dependencies: idf: ">=5.1" espressif/esp-lib-utils: - version: ">=0.1.0,<=0.2.0" + version: "0.1.*" public: true diff --git a/micropython.cmake b/micropython.cmake index ed63811..62d0d5a 100644 --- a/micropython.cmake +++ b/micropython.cmake @@ -13,5 +13,11 @@ target_sources(usermod_esp_io_expander INTERFACE ${SRCS_C} ${SRCS_CXX}) # Add the current directory as an include directory. target_include_directories(usermod_esp_io_expander INTERFACE ${SRC_DIR}) +# Add compile options. Since the target is not created by `idf_component_register()`, we need to add the `ESP_PLATFORM` define manually. +target_compile_options(usermod_esp_io_expander + INTERFACE + -Wno-missing-field-initializers -DESP_PLATFORM $<$:-std=gnu++2b> +) + # Link our INTERFACE library to the usermod target. target_link_libraries(usermod INTERFACE usermod_esp_io_expander) diff --git a/src/ESP_IOExpander_Library.h b/src/ESP_IOExpander_Library.h index 5280839..fb9fa32 100644 --- a/src/ESP_IOExpander_Library.h +++ b/src/ESP_IOExpander_Library.h @@ -6,7 +6,6 @@ /** * This file is just to keep the compatibility with the old version of the library. Please use the file `esp_io_expander.hpp` instead. - * */ #pragma once diff --git a/src/chip/esp_expander_base.cpp b/src/chip/esp_expander_base.cpp index 3ee7e66..d535efe 100644 --- a/src/chip/esp_expander_base.cpp +++ b/src/chip/esp_expander_base.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,20 +13,138 @@ namespace esp_expander { +void Base::Config::convertPartialToFull(void) +{ + ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS(); + + if (isHostConfigValid() && std::holds_alternative(host.value())) { +#if ESP_UTILS_CONF_LOG_LEVEL == ESP_UTILS_LOG_LEVEL_DEBUG + printHostConfig(); +#endif // ESP_UTILS_LOG_LEVEL_DEBUG + auto &config = std::get(host.value()); + host = HostFullConfig{ + .mode = I2C_MODE_MASTER, + .sda_io_num = config.sda_io_num, + .scl_io_num = config.scl_io_num, + .sda_pullup_en = config.sda_pullup_en, + .scl_pullup_en = config.scl_pullup_en, + .master = { + .clk_speed = static_cast(config.clk_speed), + }, + .clk_flags = I2C_SCLK_SRC_FLAG_FOR_NOMAL, + }; + } + + ESP_UTILS_LOG_TRACE_EXIT_WITH_THIS(); +} + +void Base::Config::printHostConfig(void) const +{ + ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS(); + + if (!isHostConfigValid()) { + ESP_UTILS_LOGI("\n\t{Host config}[skipped]"); + goto end; + } + + if (std::holds_alternative(host.value())) { + auto &config = std::get(host.value()); + ESP_UTILS_LOGI( + "\n\t{Host config}[full]\n" + "\t\t-> [host_id]: %d\n" + "\t\t-> [mode]: %d\n" + "\t\t-> [sda_io_num]: %d\n" + "\t\t-> [scl_io_num]: %d\n" + "\t\t-> [sda_pullup_en]: %d\n" + "\t\t-> [scl_pullup_en]: %d\n" + "\t\t-> [master.clk_speed]: %d\n" + "\t\t-> [clk_flags]: %d" + , host_id + , config.mode + , config.sda_io_num + , config.scl_io_num + , config.sda_pullup_en + , config.scl_pullup_en + , config.master.clk_speed + , config.clk_flags + ); + } else { + auto &config = std::get(host.value()); + ESP_UTILS_LOGI( + "\n\t{Host config}[partial]\n" + "\t\t-> [host_id]: %d\n" + "\t\t-> [sda_io_num]: %d\n" + "\t\t-> [scl_io_num]: %d\n" + "\t\t-> [sda_pullup_en]: %d\n" + "\t\t-> [scl_pullup_en]: %d\n" + "\t\t-> [clk_speed]: %d" + , host_id + , config.sda_io_num + , config.scl_io_num + , config.sda_pullup_en + , config.scl_pullup_en + , config.clk_speed + ); + } + +end: + ESP_UTILS_LOG_TRACE_EXIT_WITH_THIS(); +} + +void Base::Config::printDeviceConfig(void) const +{ + ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS(); + + ESP_UTILS_LOGI( + "\n\t{Device config}[partial]\n" + "\t\t-> [host_id]: %d\n" + "\t\t-> [address]: 0x%02X" + , host_id + , device.address + ); + + ESP_UTILS_LOG_TRACE_EXIT_WITH_THIS(); +} + +bool Base::configHostSkipInit(bool skip_init) +{ + ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS(); + + ESP_UTILS_CHECK_FALSE_RETURN(!isOverState(State::INIT), false, "Should be called before `init()`"); + + _is_host_skip_init = skip_init; + + ESP_UTILS_LOG_TRACE_EXIT_WITH_THIS(); + + return true; +} + bool Base::init(void) { ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS(); - ESP_UTILS_CHECK_FALSE_RETURN(!checkIsInit(), false, "Already initialized"); + ESP_UTILS_CHECK_FALSE_RETURN(!isOverState(State::INIT), false, "Already initialized"); + + // Convert the partial configuration to full configuration + _config.convertPartialToFull(); +#if ESP_UTILS_CONF_LOG_LEVEL == ESP_UTILS_LOG_LEVEL_DEBUG + _config.printHostConfig(); + _config.printDeviceConfig(); +#endif // ESP_UTILS_LOG_LEVEL_DEBUG - if (!checkIsSkipInitHost()) { - ESP_UTILS_CHECK_ERROR_RETURN(i2c_param_config(getHostID(), &_host_config), false, "I2C param config failed"); + // Initialize the I2C host if not skipped + if (!isHostSkipInit()) { + i2c_port_t host_id = static_cast(getConfig().host_id); ESP_UTILS_CHECK_ERROR_RETURN( - i2c_driver_install(getHostID(), _host_config.mode, 0, 0, 0), false, "I2C driver install failed" + i2c_param_config(host_id, getHostFullConfig()), false, "I2C param config failed" ); - ESP_UTILS_LOGI("Init I2C host(%d)", _host_id); + ESP_UTILS_CHECK_ERROR_RETURN( + i2c_driver_install(host_id, getHostFullConfig()->mode, 0, 0, 0), false, "I2C driver install failed" + ); + ESP_UTILS_LOGD("Init I2C host(%d)", static_cast(host_id)); } - _flags.is_init = true; + + setState(State::INIT); ESP_UTILS_LOG_TRACE_EXIT_WITH_THIS(); @@ -37,7 +155,7 @@ bool Base::reset(void) { ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS(); - ESP_UTILS_CHECK_FALSE_RETURN(checkIsBegun(), false, "Not begun"); + ESP_UTILS_CHECK_FALSE_RETURN(isOverState(State::BEGIN), false, "Not begun"); ESP_UTILS_CHECK_ERROR_RETURN(esp_io_expander_reset(device_handle), false, "Reset failed"); @@ -50,20 +168,20 @@ bool Base::del(void) { ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS(); - if (checkIsBegun()) { + if (device_handle != nullptr) { ESP_UTILS_CHECK_ERROR_RETURN(esp_io_expander_del(device_handle), false, "Delete failed"); device_handle = nullptr; - ESP_UTILS_LOGD("Delete IO expander(@%p)", device_handle); + ESP_UTILS_LOGD("Delete @%p", device_handle); } - if (checkIsInit()) { - if (!checkIsSkipInitHost()) { - ESP_UTILS_CHECK_ERROR_RETURN(i2c_driver_delete(getHostID()), false, "I2C driver delete failed"); - ESP_UTILS_LOGI("Delete I2C host(%d)", _host_id); - } - _flags.is_init = false; + if (isOverState(State::INIT) && !isHostSkipInit()) { + i2c_port_t host_id = static_cast(getConfig().host_id); + ESP_UTILS_CHECK_ERROR_RETURN(i2c_driver_delete(host_id), false, "I2C driver delete failed"); + ESP_UTILS_LOGD("Delete I2C host(%d)", static_cast(host_id)); } + setState(State::DEINIT); + ESP_UTILS_LOG_TRACE_EXIT_WITH_THIS(); return true; @@ -73,7 +191,7 @@ bool Base::pinMode(uint8_t pin, uint8_t mode) { ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS(); - ESP_UTILS_CHECK_FALSE_RETURN(checkIsBegun(), false, "Not begun"); + ESP_UTILS_CHECK_FALSE_RETURN(isOverState(State::BEGIN), false, "Not begun"); ESP_UTILS_LOGD("Param: pin(%d), mode(%d)", pin, mode); ESP_UTILS_CHECK_FALSE_RETURN(IS_VALID_PIN(pin), false, "Invalid pin"); @@ -91,7 +209,7 @@ bool Base::digitalWrite(uint8_t pin, uint8_t value) { ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS(); - ESP_UTILS_CHECK_FALSE_RETURN(checkIsBegun(), false, "Not begun"); + ESP_UTILS_CHECK_FALSE_RETURN(isOverState(State::BEGIN), false, "Not begun"); ESP_UTILS_LOGD("Param: pin(%d), value(%d)", pin, value); ESP_UTILS_CHECK_FALSE_RETURN(IS_VALID_PIN(pin), false, "Invalid pin"); @@ -109,7 +227,7 @@ int Base::digitalRead(uint8_t pin) { ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS(); - ESP_UTILS_CHECK_FALSE_RETURN(checkIsBegun(), false, "Not begun"); + ESP_UTILS_CHECK_FALSE_RETURN(isOverState(State::BEGIN), false, "Not begun"); ESP_UTILS_LOGD("Param: pin(%d)", pin); ESP_UTILS_CHECK_FALSE_RETURN(IS_VALID_PIN(pin), -1, "Invalid pin"); @@ -128,7 +246,7 @@ bool Base::multiPinMode(uint32_t pin_mask, uint8_t mode) { ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS(); - ESP_UTILS_CHECK_FALSE_RETURN(checkIsBegun(), false, "Not begun"); + ESP_UTILS_CHECK_FALSE_RETURN(isOverState(State::BEGIN), false, "Not begun"); ESP_UTILS_LOGD("Param: pin_mask(%0x), mode(%d)", pin_mask, mode); ESP_UTILS_CHECK_FALSE_RETURN((mode == INPUT) || (mode == OUTPUT), false, "Invalid mode"); @@ -145,7 +263,7 @@ bool Base::multiDigitalWrite(uint32_t pin_mask, uint8_t value) { ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS(); - ESP_UTILS_CHECK_FALSE_RETURN(checkIsBegun(), false, "Not begun"); + ESP_UTILS_CHECK_FALSE_RETURN(isOverState(State::BEGIN), false, "Not begun"); ESP_UTILS_LOGD("Param: pin_mask(%0x), value(%d)", pin_mask, value); @@ -160,7 +278,7 @@ int64_t Base::multiDigitalRead(uint32_t pin_mask) { ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS(); - ESP_UTILS_CHECK_FALSE_RETURN(checkIsBegun(), false, "Not begun"); + ESP_UTILS_CHECK_FALSE_RETURN(isOverState(State::BEGIN), false, "Not begun"); ESP_UTILS_LOGD("Param: pin_mask(%0x)", pin_mask); @@ -172,11 +290,11 @@ int64_t Base::multiDigitalRead(uint32_t pin_mask) return level; } -bool Base::printStatus(void) +bool Base::printStatus(void) const { ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS(); - ESP_UTILS_CHECK_FALSE_RETURN(checkIsBegun(), false, "Not begun"); + ESP_UTILS_CHECK_FALSE_RETURN(isOverState(State::BEGIN), false, "Not begun"); ESP_UTILS_CHECK_ERROR_RETURN(esp_io_expander_print_state(device_handle), false, "Print state failed"); @@ -185,4 +303,13 @@ bool Base::printStatus(void) return true; } +Base::HostFullConfig *Base::getHostFullConfig() +{ + if (std::holds_alternative(_config.host.value())) { + _config.convertPartialToFull(); + } + + return &std::get(_config.host.value()); +} + } // namespace esp_expander diff --git a/src/chip/esp_expander_base.hpp b/src/chip/esp_expander_base.hpp index 402ad7f..957a620 100644 --- a/src/chip/esp_expander_base.hpp +++ b/src/chip/esp_expander_base.hpp @@ -1,12 +1,13 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once -#include +#include +#include #include "driver/i2c.h" #include "port/esp_io_expander.h" @@ -29,92 +30,81 @@ namespace esp_expander { /** * @brief The IO expander device class * - * @note This is a base class for all chips. Due to it is a virtual class, users cannot use it directly - * + * @note This class is a base class for all types of IO expander chips. Due to it is a virtual class, users cannot use + * it directly */ class Base { public: - /* Default I2C host ID */ - constexpr static int HOST_ID_DEFAULT = static_cast(I2C_NUM_0); + /** + * Here are some default values for I2C bus + */ + constexpr static int I2C_HOST_ID_DEFAULT = static_cast(I2C_NUM_0); + constexpr static int I2C_CLK_SPEED_DEFAULT = 400 * 1000; + + using DeviceHandle = esp_io_expander_handle_t; + + struct HostPartialConfig { + int sda_io_num = -1; + int scl_io_num = -1; + bool sda_pullup_en = GPIO_PULLUP_ENABLE; + bool scl_pullup_en = GPIO_PULLUP_ENABLE; + int clk_speed = I2C_CLK_SPEED_DEFAULT; + }; + using HostFullConfig = i2c_config_t; + using HostConfig = std::variant; + + struct DeviceConfig { + uint8_t address = 0; + }; /** * @brief Configuration for Base object - * */ struct Config { - i2c_port_t getHostID(void) const - { - return static_cast(host_id); - } - - i2c_config_t getHostConfig(void) const - { - return { - .mode = I2C_MODE_MASTER, - .sda_io_num = host_sda_io_num, - .scl_io_num = host_scl_io_num, - .sda_pullup_en = host_sda_pullup_en, - .scl_pullup_en = host_scl_pullup_en, - .master = { - .clk_speed = host_clk_speed, - }, - .clk_flags = I2C_SCLK_SRC_FLAG_FOR_NOMAL, - }; - } + void convertPartialToFull(void); + void printHostConfig(void) const; + void printDeviceConfig(void) const; - uint8_t getDeviceAddress(void) const + bool isHostConfigValid(void) const { - return device_address; + return host.has_value(); } - static Config create(int scl_io, int sda_io, uint8_t address) - { - return Config{ - .host_sda_io_num = sda_io, - .host_scl_io_num = scl_io, - .device_address = address, - .skip_init_host = false, - }; - } - - static Config create(int host_id, uint8_t address) - { - return Config{ - .host_id = host_id, - .device_address = address, - .skip_init_host = true, - }; - } + int host_id = I2C_HOST_ID_DEFAULT; /*!< I2C host ID */ + std::optional host; /*!< I2C host configuration */ + DeviceConfig device = {}; /*!< I2C device configuration */ + }; - // Host - int host_id = HOST_ID_DEFAULT; /*!< I2C host ID */ - int host_sda_io_num = -1; /*!< I2C SDA pin number */ - int host_scl_io_num = -1; /*!< I2C SCL pin number */ - bool host_sda_pullup_en = GPIO_PULLUP_ENABLE; /*!< I2C SDA pullup enable */ - bool host_scl_pullup_en = GPIO_PULLUP_ENABLE; /*!< I2C SCL pullup enable */ - uint32_t host_clk_speed = 400000; /*!< I2C clock speed */ - // Device - uint8_t device_address = 0; /*!< I2C device 7-bit address */ - // Extra - bool skip_init_host = false; /*!< Skip I2C initialization when call `init()` */ + /** + * @brief The driver state enumeration + */ + enum class State : uint8_t { + DEINIT = 0, + INIT, + BEGIN, }; +// *INDENT-OFF* /** * @brief Construct a base device. With this function, call `init()` will initialize I2C by using the host * configuration. * * @param[in] scl_io I2C SCL pin number * @param[in] sda_io I2C SDA pin number - * @param[in] address I2C device 7-bit address. Should be like `ESP_IO_EXPANDER_I2C__ADDRESS`. - * + * @param[in] address I2C device 7-bit address. Should be like `ESP_IO_EXPANDER_I2C__ADDRESS`. */ - Base(int scl_io, int sda_io, uint8_t address) + Base(int scl_io, int sda_io, uint8_t address): + _config{ + .host_id = I2C_HOST_ID_DEFAULT, + .host = HostPartialConfig{ + .sda_io_num = sda_io, + .scl_io_num = scl_io, + }, + .device = DeviceConfig{ + .address = address + } + } { - auto config = Config::create(scl_io, sda_io, address); - _host_id = config.getHostID(); - _host_config = config.getHostConfig(); - _device_address = config.getDeviceAddress(); - _flags.skip_init_host = config.skip_init_host; } /** @@ -122,49 +112,43 @@ class Base { * initialize it manually. * * @param[in] host_id I2C host ID. - * @param[in] address I2C device 7-bit address. Should be like `ESP_IO_EXPANDER_I2C__ADDRESS`. - * + * @param[in] address I2C device 7-bit address. Should be like `ESP_IO_EXPANDER_I2C__ADDRESS`. */ - Base(int host_id, uint8_t address) + Base(int host_id, uint8_t address): + _config{ + .host_id = host_id, + .device = DeviceConfig{ + .address = address + } + } { - auto config = Config::create(host_id, address); - _host_id = config.getHostID(); - _host_config = config.getHostConfig(); - _device_address = config.getDeviceAddress(); - _flags.skip_init_host = config.skip_init_host; } +// *INDENT-ON* /** * @brief Construct a base device. * * @param[in] config Configuration for the object - * */ - Base(const Config &config) - { - _host_id = config.getHostID(); - _host_config = config.getHostConfig(); - _device_address = config.getDeviceAddress(); - _flags.skip_init_host = config.skip_init_host; - } + Base(const Config &config): _config(config) {} /** - * @deprecated Deprecated and will be removed in the next major version. Please use other constructors instead. + * @brief Virtual desutruct object. * + * @note Here make it virtual so that we can delete the derived object by using the base pointer. */ - Base(i2c_port_t id, uint8_t address, int scl_io, int sda_io): - Base(scl_io, sda_io, address) - { - _host_id = id; - } + virtual ~Base() = default; /** - * @brief Virtual desutruct object. + * @brief Configure whether to skip I2C initialization * - * @note Here make it virtual so that we can delete the derived object by using the base pointer. + * @note This function should be called before `init()`. + * + * @param[in] skip_init Whether to skip I2C initialization * + * @return true if success, otherwise false */ - virtual ~Base() = default; + bool configHostSkipInit(bool skip_init); /** * @brief Initialize object @@ -172,7 +156,6 @@ class Base { * @note This function will initialize I2C if needed. * * @return true if success, otherwise false - * */ bool init(void); @@ -180,7 +163,6 @@ class Base { * @brief Begin object * * @note This function typically calls `esp_io_expander_new_i2c_*()` to create the IO expander handle. - * */ virtual bool begin(void) = 0; @@ -188,13 +170,11 @@ class Base { * @brief Reset object * * @return true if success, otherwise false - * */ bool reset(void); /** * @brief Delete object - * */ bool del(void); @@ -207,7 +187,6 @@ class Base { * @param[in] mode Pin mode (INPUT / OUTPUT) * * @return true if success, otherwise false - * */ bool pinMode(uint8_t pin, uint8_t mode); @@ -220,7 +199,6 @@ class Base { * @param[in] value Pin level (HIGH / LOW) * * @return true if success, otherwise false - * */ bool digitalWrite(uint8_t pin, uint8_t value); @@ -232,7 +210,6 @@ class Base { * @param[in] pin Pin number (0-31) * * @return Pin level. HIGH or LOW if success, otherwise -1 - * */ int digitalRead(uint8_t pin); @@ -243,7 +220,6 @@ class Base { * @param mode Mode to set (INPUT / OUTPUT) * * @return true if success, otherwise false - * */ bool multiPinMode(uint32_t pin_mask, uint8_t mode); @@ -254,7 +230,6 @@ class Base { * @param value Value to write (HIGH / LOW) * * @return true if success, otherwise false - * */ bool multiDigitalWrite(uint32_t pin_mask, uint8_t value); @@ -264,7 +239,6 @@ class Base { * @param pin_mask Pin mask (Bitwise OR of `IO_EXPANDER_PIN_NUM_*`) * * @return Pin levels, every bit represents a pin (HIGH / LOW) - * */ int64_t multiDigitalRead(uint32_t pin_mask); @@ -272,80 +246,79 @@ class Base { * @brief Print IO expander status, include pin index, direction, input level and output level * * @return Pin levels, every bit represents a pin (HIGH / LOW) - * */ - bool printStatus(void); + bool printStatus(void) const; /** - * @brief Get low-level handle. Users can use this handle to call low-level functions (esp_io_expander_*()). + * @brief Check if the driver has reached or passed the specified state * - * @return Handle if success, otherwise nullptr + * @param[in] state The state to check against current state * + * @return true if current state >= given state, otherwise false */ - esp_io_expander_handle_t getDeviceHandle(void) + bool isOverState(State state) const { - return device_handle; + return (_state >= state); } /** - * @deprecated Deprecated and will be removed in the next major version. Please use `getDeviceHandle()` instead. + * @brief Get the IO expander configuration * + * @return IO expander Configuration */ - [[deprecated("Deprecated and will be removed in the next major version. Please use `getDeviceHandle()` instead.")]] - esp_io_expander_handle_t getHandle(void) + const Config &getConfig(void) const { - return getDeviceHandle(); + return _config; } -protected: - bool checkIsInit(void) - { - return _flags.is_init; - } - - bool checkIsBegun(void) + /** + * @brief Get low-level handle. Users can use this handle to call low-level functions (esp_io_expander_*()). + * + * @return Device handle if success, otherwise nullptr + */ + DeviceHandle getDeviceHandle(void) const { - return (device_handle != nullptr); + return device_handle; } - bool checkIsSkipInitHost(void) + // TODO: Remove in the next major version + Base(i2c_port_t id, uint8_t address, int scl_io, int sda_io): + Base(scl_io, sda_io, address) { - return _flags.skip_init_host; + _config.host_id = id; } - - i2c_port_t getHostID(void) + [[deprecated("Deprecated and will be removed in the next major version. Please use `getDeviceHandle()` instead.")]] + esp_io_expander_handle_t getHandle(void) const { - return static_cast(_host_id); + return getDeviceHandle(); } - const i2c_config_t &getHostConfig(void) +protected: + bool isHostSkipInit(void) const { - return _host_config; + return !_config.isHostConfigValid() || _is_host_skip_init; } - uint8_t getDeviceAddress(void) + void setState(State state) { - return _device_address; + _state = state; } - esp_io_expander_handle_t device_handle = nullptr; + DeviceHandle device_handle = nullptr; private: - struct { - uint8_t is_init: 1; - uint8_t skip_init_host: 1; - } _flags = {}; - // Host - int _host_id = HOST_ID_DEFAULT; - i2c_config_t _host_config = {}; - // Device - uint8_t _device_address = 0; + HostFullConfig *getHostFullConfig(); + + State _state = State::DEINIT; + bool _is_host_skip_init = false; + Config _config = {}; }; } // namespace esp_expander /** - * @deprecated Deprecated and will be removed in the next major version. Please use `esp_expander::Base` instead. + * @brief Alias for backward compatibility * + * @deprecated Use `esp_expander::Base` instead */ -typedef esp_expander::Base ESP_IOExpander __attribute__((deprecated("Deprecated and will be removed in the next major version. Please use `esp_expander::Base` instead."))); +using ESP_IOExpander [[deprecated("Use `esp_expander::Base` instead.")]] = esp_expander::Base; diff --git a/src/chip/esp_expander_ch422g.cpp b/src/chip/esp_expander_ch422g.cpp index f2cd30a..1a0dcbd 100644 --- a/src/chip/esp_expander_ch422g.cpp +++ b/src/chip/esp_expander_ch422g.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -23,14 +23,21 @@ bool CH422G::begin(void) { ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS(); - ESP_UTILS_CHECK_FALSE_RETURN(checkIsInit(), false, "Not initialized"); - ESP_UTILS_CHECK_FALSE_RETURN(!checkIsBegun(), false, "Already begun"); + ESP_UTILS_CHECK_FALSE_RETURN(!isOverState(State::BEGIN), false, "Already begun"); + + // Initialize the device if not initialized + if (!isOverState(State::INIT)) { + ESP_UTILS_CHECK_FALSE_RETURN(init(), false, "Init failed"); + } ESP_UTILS_CHECK_ERROR_RETURN( - esp_io_expander_new_i2c_ch422g(getHostID(), getDeviceAddress(), &device_handle), false, - "Create CH422G IO expander failed" + esp_io_expander_new_i2c_ch422g( + static_cast(getConfig().host_id), getConfig().device.address, &device_handle + ), false, "Create CH422G failed" ); - ESP_UTILS_LOGD("Create CH422G IO expander(@%p)", device_handle); + ESP_UTILS_LOGD("Create CH422G @%p", device_handle); + + setState(State::BEGIN); ESP_UTILS_LOG_TRACE_EXIT_WITH_THIS(); @@ -41,7 +48,7 @@ bool CH422G::enableOC_OpenDrain(void) { ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS(); - ESP_UTILS_CHECK_FALSE_RETURN(checkIsBegun(), false, "Not begun"); + ESP_UTILS_CHECK_FALSE_RETURN(isOverState(State::BEGIN), false, "Not begun"); ESP_UTILS_CHECK_ERROR_RETURN( esp_io_expander_ch422g_set_oc_open_drain(device_handle), false, "Set OC open-drain failed" @@ -56,7 +63,7 @@ bool CH422G::enableOC_PushPull(void) { ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS(); - ESP_UTILS_CHECK_FALSE_RETURN(checkIsBegun(), false, "Not begun"); + ESP_UTILS_CHECK_FALSE_RETURN(isOverState(State::BEGIN), false, "Not begun"); ESP_UTILS_CHECK_ERROR_RETURN( esp_io_expander_ch422g_set_oc_push_pull(device_handle), false, "Set OC push-pull failed" @@ -71,7 +78,7 @@ bool CH422G::enableAllIO_Input(void) { ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS(); - ESP_UTILS_CHECK_FALSE_RETURN(checkIsBegun(), false, "Not begun"); + ESP_UTILS_CHECK_FALSE_RETURN(isOverState(State::BEGIN), false, "Not begun"); ESP_UTILS_CHECK_ERROR_RETURN( esp_io_expander_ch422g_set_all_input(device_handle), false, "Set all input failed" @@ -86,7 +93,7 @@ bool CH422G::enableAllIO_Output(void) { ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS(); - ESP_UTILS_CHECK_FALSE_RETURN(checkIsBegun(), false, "Not begun"); + ESP_UTILS_CHECK_FALSE_RETURN(isOverState(State::BEGIN), false, "Not begun"); ESP_UTILS_CHECK_ERROR_RETURN( esp_io_expander_ch422g_set_all_output(device_handle), false, "Set all output failed" diff --git a/src/chip/esp_expander_ch422g.hpp b/src/chip/esp_expander_ch422g.hpp index ac7281f..ab54b04 100644 --- a/src/chip/esp_expander_ch422g.hpp +++ b/src/chip/esp_expander_ch422g.hpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -18,7 +18,6 @@ namespace esp_expander { * | Pin Number | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | * | ------------ | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | * | Function | IO0 | IO1 | IO2 | IO3 | IO4 | IO5 | IO6 | IO7 | OC0 | OC1 | OC2 | OC3 | - * */ class CH422G: public Base { public: @@ -29,7 +28,6 @@ class CH422G: public Base { * @param[in] scl_io I2C SCL pin number * @param[in] sda_io I2C SDA pin number * @param[in] address I2C device 7-bit address. Should be like `ESP_IO_EXPANDER_I2C__ADDRESS`. - * */ CH422G(int scl_io, int sda_io, uint8_t address): Base(scl_io, sda_io, address) {} @@ -39,7 +37,6 @@ class CH422G: public Base { * * @param[in] host_id I2C host ID. * @param[in] address I2C device 7-bit address. Should be like `ESP_IO_EXPANDER_I2C__ADDRESS`. - * */ CH422G(int host_id, uint8_t address): Base(host_id, address) {} @@ -47,20 +44,17 @@ class CH422G: public Base { * @brief Construct a CH422G device. * * @param[in] config Configuration for the object - * */ CH422G(const Config &config): Base(config) {} /** * @deprecated Deprecated and will be removed in the next major version. Please use other constructors instead. - * */ [[deprecated("Deprecated and will be removed in the next major version. Please use other constructors instead.")]] CH422G(i2c_port_t id, uint8_t address, int scl_io, int sda_io): Base(id, address, scl_io, sda_io) {} /** * @brief Desutruct object. This function will call `del()` to delete the object. - * */ ~CH422G() override; @@ -71,7 +65,6 @@ class CH422G: public Base { * @note This function sets all IO0-7 pins to output high-level mode by default. * * @return true if success, otherwise false - * */ bool begin(void) override; @@ -79,7 +72,6 @@ class CH422G: public Base { * @brief Enable OC0-OC3 output open-drain * * @return true if success, otherwise false - * */ bool enableOC_OpenDrain(void); @@ -87,7 +79,6 @@ class CH422G: public Base { * @brief Enable OC0-OC3 output push-pull (default mode when power-on) * * @return true if success, otherwise false - * */ bool enableOC_PushPull(void); @@ -99,7 +90,6 @@ class CH422G: public Base { * input mode when it determines that all pins are configured as input. * * @return true if success, otherwise false - * */ bool enableAllIO_Input(void); @@ -107,7 +97,6 @@ class CH422G: public Base { * @brief Enable IO0-7 output mode * * @return true if success, otherwise false - * */ bool enableAllIO_Output(void); }; @@ -116,6 +105,5 @@ class CH422G: public Base { /** * @deprecated Deprecated and will be removed in the next major version. Please use `esp_expander::CH422G` instead. - * */ typedef esp_expander::CH422G ESP_IOExpander_CH422G __attribute__((deprecated("Deprecated and will be removed in the next major version. Please use `esp_expander::CH422G` instead."))); diff --git a/src/chip/esp_expander_ht8574.cpp b/src/chip/esp_expander_ht8574.cpp index e69f566..837f299 100644 --- a/src/chip/esp_expander_ht8574.cpp +++ b/src/chip/esp_expander_ht8574.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -23,14 +23,21 @@ bool HT8574::begin(void) { ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS(); - ESP_UTILS_CHECK_FALSE_RETURN(checkIsInit(), false, "Not initialized"); - ESP_UTILS_CHECK_FALSE_RETURN(!checkIsBegun(), false, "Already begun"); + ESP_UTILS_CHECK_FALSE_RETURN(!isOverState(State::BEGIN), false, "Already begun"); + + // Initialize the device if not initialized + if (!isOverState(State::INIT)) { + ESP_UTILS_CHECK_FALSE_RETURN(init(), false, "Init failed"); + } ESP_UTILS_CHECK_ERROR_RETURN( - esp_io_expander_new_i2c_ht8574(getHostID(), getDeviceAddress(), &device_handle), false, - "Create HT8574 IO expander failed" + esp_io_expander_new_i2c_ht8574( + static_cast(getConfig().host_id), getConfig().device.address, &device_handle + ), false, "Create HT8574 failed" ); - ESP_UTILS_LOGD("Create HT8574 IO expander(@%p)", device_handle); + ESP_UTILS_LOGD("Create HT8574 @%p", device_handle); + + setState(State::BEGIN); ESP_UTILS_LOG_TRACE_EXIT_WITH_THIS(); diff --git a/src/chip/esp_expander_ht8574.hpp b/src/chip/esp_expander_ht8574.hpp index 87cd23b..e7b68ce 100644 --- a/src/chip/esp_expander_ht8574.hpp +++ b/src/chip/esp_expander_ht8574.hpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,7 +14,6 @@ namespace esp_expander { * @brief The HT8574 IO expander device class * * @note This class is a derived class of `esp_expander::Base`, user can use it directly - * */ class HT8574: public Base { public: @@ -25,7 +24,6 @@ class HT8574: public Base { * @param[in] scl_io I2C SCL pin number * @param[in] sda_io I2C SDA pin number * @param[in] address I2C device 7-bit address. Should be like `ESP_IO_EXPANDER_I2C__ADDRESS`. - * */ HT8574(int scl_io, int sda_io, uint8_t address): Base(scl_io, sda_io, address) {} @@ -35,7 +33,6 @@ class HT8574: public Base { * * @param[in] host_id I2C host ID. * @param[in] address I2C device 7-bit address. Should be like `ESP_IO_EXPANDER_I2C__ADDRESS`. - * */ HT8574(int host_id, uint8_t address): Base(host_id, address) {} @@ -43,20 +40,17 @@ class HT8574: public Base { * @brief Construct a HT8574 device. * * @param[in] config Configuration for the object - * */ HT8574(const Config &config): Base(config) {} /** * @deprecated Deprecated and will be removed in the next major version. Please use other constructors instead. - * */ [[deprecated("Deprecated and will be removed in the next major version. Please use other constructors instead.")]] HT8574(i2c_port_t id, uint8_t address, int scl_io, int sda_io): Base(id, address, scl_io, sda_io) {} /** * @brief Desutruct object. This function will call `del()` to delete the object. - * */ ~HT8574() override; @@ -67,7 +61,6 @@ class HT8574: public Base { * @note The driver initialization by default sets CH422G's IO0-7 to output high-level mode. * * @return true if success, otherwise false - * */ bool begin(void) override; }; @@ -76,6 +69,5 @@ class HT8574: public Base { /** * @deprecated Deprecated and will be removed in the next major version. Please use `esp_expander::HT8574` instead. - * */ typedef esp_expander::HT8574 ESP_IOExpander_HT8574 __attribute__((deprecated("Deprecated and will be removed in the next major version. Please use `esp_expander::HT8574` instead."))); diff --git a/src/chip/esp_expander_tca95xx_16bit.cpp b/src/chip/esp_expander_tca95xx_16bit.cpp index 2f5c8f7..68f4702 100644 --- a/src/chip/esp_expander_tca95xx_16bit.cpp +++ b/src/chip/esp_expander_tca95xx_16bit.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -23,14 +23,21 @@ bool TCA95XX_16BIT::begin(void) { ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS(); - ESP_UTILS_CHECK_FALSE_RETURN(checkIsInit(), false, "Not initialized"); - ESP_UTILS_CHECK_FALSE_RETURN(!checkIsBegun(), false, "Already begun"); + ESP_UTILS_CHECK_FALSE_RETURN(!isOverState(State::BEGIN), false, "Already begun"); + + // Initialize the bus if not initialized + if (!isOverState(State::INIT)) { + ESP_UTILS_CHECK_FALSE_RETURN(init(), false, "Init failed"); + } ESP_UTILS_CHECK_ERROR_RETURN( - esp_io_expander_new_i2c_tca95xx_16bit(getHostID(), getDeviceAddress(), &device_handle), false, - "Create TCA95XX_16BIT IO expander failed" + esp_io_expander_new_i2c_tca95xx_16bit( + static_cast(getConfig().host_id), getConfig().device.address, &device_handle + ), false, "Create TCA95XX_16BIT failed" ); - ESP_UTILS_LOGD("Create TCA95XX_16BIT IO expander(@%p)", device_handle); + ESP_UTILS_LOGD("Create TCA95XX_16BIT @%p", device_handle); + + setState(State::BEGIN); ESP_UTILS_LOG_TRACE_EXIT_WITH_THIS(); diff --git a/src/chip/esp_expander_tca95xx_16bit.hpp b/src/chip/esp_expander_tca95xx_16bit.hpp index b27ea6d..94f4c35 100644 --- a/src/chip/esp_expander_tca95xx_16bit.hpp +++ b/src/chip/esp_expander_tca95xx_16bit.hpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,7 +14,6 @@ namespace esp_expander { * @brief The TCA95XX_16BIT IO expander device class * * @note This class is a derived class of `esp_expander::Base`, user can use it directly - * */ class TCA95XX_16BIT: public Base { public: @@ -25,7 +24,6 @@ class TCA95XX_16BIT: public Base { * @param[in] scl_io I2C SCL pin number * @param[in] sda_io I2C SDA pin number * @param[in] address I2C device 7-bit address. Should be like `ESP_IO_EXPANDER_I2C__ADDRESS`. - * */ TCA95XX_16BIT(int scl_io, int sda_io, uint8_t address): Base(scl_io, sda_io, address) {} @@ -35,7 +33,6 @@ class TCA95XX_16BIT: public Base { * * @param[in] host_id I2C host ID. * @param[in] address I2C device 7-bit address. Should be like `ESP_IO_EXPANDER_I2C__ADDRESS`. - * */ TCA95XX_16BIT(int host_id, uint8_t address): Base(host_id, address) {} @@ -43,20 +40,17 @@ class TCA95XX_16BIT: public Base { * @brief Construct a TCA95XX_16BIT device. * * @param[in] config Configuration for the object - * */ TCA95XX_16BIT(const Config &config): Base(config) {} /** * @deprecated Deprecated and will be removed in the next major version. Please use other constructors instead. - * */ [[deprecated("Deprecated and will be removed in the next major version. Please use other constructors instead.")]] TCA95XX_16BIT(i2c_port_t id, uint8_t address, int scl_io, int sda_io): Base(id, address, scl_io, sda_io) {} /** * @brief Desutruct object. This function will call `del()` to delete the object. - * */ ~TCA95XX_16BIT() override; @@ -67,7 +61,6 @@ class TCA95XX_16BIT: public Base { * @note This function sets all pins to inpurt mode by default. * * @return true if success, otherwise false - * */ bool begin(void) override; }; @@ -76,6 +69,5 @@ class TCA95XX_16BIT: public Base { /** * @deprecated Deprecated and will be removed in the next major version. Please use `esp_expander::TCA95XX_16BIT` instead. - * */ typedef esp_expander::TCA95XX_16BIT ESP_IOExpander_TCA95xx_16bit __attribute__((deprecated("Deprecated and will be removed in the next major version. Please use `esp_expander::TCA95XX_16BIT` instead."))); diff --git a/src/chip/esp_expander_tca95xx_8bit.cpp b/src/chip/esp_expander_tca95xx_8bit.cpp index 7ea43c6..60ebdca 100644 --- a/src/chip/esp_expander_tca95xx_8bit.cpp +++ b/src/chip/esp_expander_tca95xx_8bit.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -23,14 +23,21 @@ bool TCA95XX_8BIT::begin(void) { ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS(); - ESP_UTILS_CHECK_FALSE_RETURN(checkIsInit(), false, "Not initialized"); - ESP_UTILS_CHECK_FALSE_RETURN(!checkIsBegun(), false, "Already begun"); + ESP_UTILS_CHECK_FALSE_RETURN(!isOverState(State::BEGIN), false, "Already begun"); + + // Initialize the device if not initialized + if (!isOverState(State::INIT)) { + ESP_UTILS_CHECK_FALSE_RETURN(init(), false, "Init failed"); + } ESP_UTILS_CHECK_ERROR_RETURN( - esp_io_expander_new_i2c_tca9554(getHostID(), getDeviceAddress(), &device_handle), false, - "Create TCA95XX_8BIT IO expander failed" + esp_io_expander_new_i2c_tca9554( + static_cast(getConfig().host_id), getConfig().device.address, &device_handle + ), false, "Create TCA95XX_8BIT failed" ); - ESP_UTILS_LOGD("Create TCA95XX_8BIT IO expander(@%p)", device_handle); + ESP_UTILS_LOGD("Create TCA95XX_8BIT @%p", device_handle); + + setState(State::BEGIN); ESP_UTILS_LOG_TRACE_EXIT_WITH_THIS(); diff --git a/src/chip/esp_expander_tca95xx_8bit.hpp b/src/chip/esp_expander_tca95xx_8bit.hpp index 75da75e..0946a3f 100644 --- a/src/chip/esp_expander_tca95xx_8bit.hpp +++ b/src/chip/esp_expander_tca95xx_8bit.hpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,7 +14,6 @@ namespace esp_expander { * @brief The TCA95XX_8BIT IO expander device class * * @note This class is a derived class of `esp_expander::Base`, user can use it directly - * */ class TCA95XX_8BIT: public Base { public: @@ -25,7 +24,6 @@ class TCA95XX_8BIT: public Base { * @param[in] scl_io I2C SCL pin number * @param[in] sda_io I2C SDA pin number * @param[in] address I2C device 7-bit address. Should be like `ESP_IO_EXPANDER_I2C__ADDRESS`. - * */ TCA95XX_8BIT(int scl_io, int sda_io, uint8_t address): Base(scl_io, sda_io, address) {} @@ -35,7 +33,6 @@ class TCA95XX_8BIT: public Base { * * @param[in] host_id I2C host ID. * @param[in] address I2C device 7-bit address. Should be like `ESP_IO_EXPANDER_I2C__ADDRESS`. - * */ TCA95XX_8BIT(int host_id, uint8_t address): Base(host_id, address) {} @@ -43,20 +40,17 @@ class TCA95XX_8BIT: public Base { * @brief Construct a TCA95XX_8BIT device. * * @param[in] config Configuration for the object - * */ TCA95XX_8BIT(const Config &config): Base(config) {} /** * @deprecated Deprecated and will be removed in the next major version. Please use other constructors instead. - * */ [[deprecated("Deprecated and will be removed in the next major version. Please use other constructors instead.")]] TCA95XX_8BIT(i2c_port_t id, uint8_t address, int scl_io, int sda_io): Base(id, address, scl_io, sda_io) {} /** * @brief Desutruct object. This function will call `del()` to delete the object. - * */ ~TCA95XX_8BIT() override; @@ -67,7 +61,6 @@ class TCA95XX_8BIT: public Base { * @note This function sets all pins to inpurt mode by default. * * @return true if success, otherwise false - * */ bool begin(void) override; }; @@ -76,6 +69,5 @@ class TCA95XX_8BIT: public Base { /** * @deprecated Deprecated and will be removed in the next major version. Please use `esp_expander::TCA95XX_8BIT` instead. - * */ typedef esp_expander::TCA95XX_8BIT ESP_IOExpander_TCA95xx_8bit __attribute__((deprecated("Deprecated and will be removed in the next major version. Please use `esp_expander::TCA95XX_8BIT` instead."))); diff --git a/src/esp_expander_utils.h b/src/esp_expander_utils.h index a107319..922dc85 100644 --- a/src/esp_expander_utils.h +++ b/src/esp_expander_utils.h @@ -8,3 +8,4 @@ // Define the log tag for the current library, should be declared before `esp_lib_utils.hpp` #define ESP_UTILS_LOG_TAG "Expander" #include "esp_lib_utils.h" +#include "esp_utils_helpers.h" diff --git a/src/port/esp_io_expander.c b/src/port/esp_io_expander.c index b27c743..d93f50b 100644 --- a/src/port/esp_io_expander.c +++ b/src/port/esp_io_expander.c @@ -19,7 +19,6 @@ /** * @brief Register type - * */ typedef enum { REG_INPUT = 0, diff --git a/src/port/esp_io_expander.h b/src/port/esp_io_expander.h index e36adf4..a01f066 100644 --- a/src/port/esp_io_expander.h +++ b/src/port/esp_io_expander.h @@ -24,14 +24,12 @@ extern "C" { /** * @brief IO Expander Device Type - * */ typedef struct esp_io_expander_s esp_io_expander_t; typedef esp_io_expander_t *esp_io_expander_handle_t; /** * @brief IO Expander Pin Num - * */ typedef enum { IO_EXPANDER_PIN_NUM_0 = (1ULL << 0), @@ -70,7 +68,6 @@ typedef enum { /** * @brief IO Expander Pin direction - * */ typedef enum { IO_EXPANDER_INPUT, /*!< Input direction */ @@ -79,7 +76,6 @@ typedef enum { /** * @brief IO Expander Configuration Type - * */ typedef struct { uint8_t io_count; /*!< Count of device's IO, must be less or equal than `IO_COUNT_MAX` */ diff --git a/src/port/esp_io_expander_ch422g.c b/src/port/esp_io_expander_ch422g.c index 9b6ce6a..59c8d17 100644 --- a/src/port/esp_io_expander_ch422g.c +++ b/src/port/esp_io_expander_ch422g.c @@ -48,7 +48,6 @@ /** * @brief Device Structure Type - * */ typedef struct { esp_io_expander_t base; diff --git a/src/port/esp_io_expander_ch422g.h b/src/port/esp_io_expander_ch422g.h index 46f4f2a..1aecf43 100644 --- a/src/port/esp_io_expander_ch422g.h +++ b/src/port/esp_io_expander_ch422g.h @@ -37,7 +37,6 @@ esp_err_t esp_io_expander_new_i2c_ch422g(i2c_port_t i2c_num, uint32_t i2c_addres /** * @brief I2C address of the ch422g. Just to keep the same with other IO expanders, but it is ignored. - * */ #define ESP_IO_EXPANDER_I2C_CH422G_ADDRESS (0x24) diff --git a/src/port/esp_io_expander_ht8574.c b/src/port/esp_io_expander_ht8574.c index 5236bf3..bbfd79a 100644 --- a/src/port/esp_io_expander_ht8574.c +++ b/src/port/esp_io_expander_ht8574.c @@ -29,7 +29,6 @@ /** * @brief Device Structure Type - * */ typedef struct { esp_io_expander_t base; diff --git a/src/port/esp_io_expander_tca9554.c b/src/port/esp_io_expander_tca9554.c index f3ebaf1..3732bd7 100644 --- a/src/port/esp_io_expander_tca9554.c +++ b/src/port/esp_io_expander_tca9554.c @@ -34,7 +34,6 @@ /** * @brief Device Structure Type - * */ typedef struct { esp_io_expander_t base; diff --git a/src/port/esp_io_expander_tca95xx_16bit.c b/src/port/esp_io_expander_tca95xx_16bit.c index 18edd5a..b9f2f17 100644 --- a/src/port/esp_io_expander_tca95xx_16bit.c +++ b/src/port/esp_io_expander_tca95xx_16bit.c @@ -34,7 +34,6 @@ /** * @brief Device Structure Type - * */ typedef struct { esp_io_expander_t base; diff --git a/test_apps/main/test_chip_general.cpp b/test_apps/main/test_chip_general.cpp index 5542dd8..007d627 100644 --- a/test_apps/main/test_chip_general.cpp +++ b/test_apps/main/test_chip_general.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -83,8 +83,9 @@ static void test_device(std::shared_ptr device) ESP_LOGI(TAG, "Test constructor with (const Config &config) (external I2C)"); \ Base::Config external_i2c_config = { \ .host_id = TEST_HOST_ID, \ - .device_address = TEST_DEVICE_ADDRESS, \ - .skip_init_host = true, \ + .device = Base::DeviceConfig{ \ + .address = TEST_DEVICE_ADDRESS, \ + }, \ }; \ expander = CREATE_DEVICE(device_name, external_i2c_config); \ test_device(expander); \ @@ -101,10 +102,13 @@ static void test_device(std::shared_ptr device) ESP_LOGI(TAG, "Test constructor with (const Config &config) (internal I2C)"); \ Base::Config internal_i2c_config = { \ .host_id = TEST_HOST_ID, \ - .host_sda_io_num = TEST_HOST_I2C_SDA_PIN, \ - .host_scl_io_num = TEST_HOST_I2C_SCL_PIN, \ - .device_address = TEST_DEVICE_ADDRESS, \ - .skip_init_host = false, \ + .host = Base::HostPartialConfig{ \ + .sda_io_num = TEST_HOST_I2C_SDA_PIN, \ + .scl_io_num = TEST_HOST_I2C_SCL_PIN, \ + }, \ + .device = Base::DeviceConfig{ \ + .address = TEST_DEVICE_ADDRESS, \ + }, \ }; \ expander = CREATE_DEVICE(device_name, internal_i2c_config); \ test_device(expander); \ @@ -164,7 +168,6 @@ static void test_device(std::shared_ptr device) /** * Here to create test cases for different devices - * */ CREATE_TEST_CASE(TCA95XX_8BIT) CREATE_TEST_CASE(TCA95XX_16BIT) diff --git a/test_apps/sdkconfig.ci.debug_log b/test_apps/sdkconfig.ci.debug_log new file mode 100644 index 0000000..191f9c8 --- /dev/null +++ b/test_apps/sdkconfig.ci.debug_log @@ -0,0 +1,2 @@ +CONFIG_ESP_UTILS_CONF_LOG_LEVEL_DEBUG=y +CONFIG_ESP_UTILS_CONF_ENABLE_LOG_TRACE=y pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy