diff --git a/CMakeLists.txt b/CMakeLists.txt index 123d1f7..49cc12c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1 @@ -if(${IDF_TARGET} STREQUAL esp8266) - set(requires driver zh_vector) -else() - set(requires driver esp_event zh_vector) -endif() -idf_component_register(SRCS "zh_pcf8574.c" INCLUDE_DIRS "include" REQUIRES ${requires}) \ No newline at end of file +idf_component_register(SRCS "zh_pcf8574.c" INCLUDE_DIRS "include" REQUIRES driver esp_event zh_vector) \ No newline at end of file diff --git a/README.md b/README.md index 9d7e6ef..3406c3e 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,8 @@ -# ESP32 ESP-IDF and ESP8266 RTOS SDK component for PCF8574(A) 8-bit I/O expander +# ESP32 ESP-IDF component for PCF8574(A) 8-bit I/O expander ## Tested on -1. [ESP8266 RTOS_SDK v3.4](https://docs.espressif.com/projects/esp8266-rtos-sdk/en/latest/index.html#) -2. [ESP32 ESP-IDF v5.4](https://docs.espressif.com/projects/esp-idf/en/release-v5.4/esp32/index.html) +1. [ESP32 ESP-IDF v5.5.1](https://docs.espressif.com/projects/esp-idf/en/v5.5.1/esp32/index.html) ## Features @@ -19,7 +18,7 @@ ## Dependencies -1. [zh_vector](http://git.zh.com.ru/alexey.zholtikov/zh_vector) +1. [zh_vector](http://git.zh.com.ru/esp_components/zh_vector) ## Using @@ -27,8 +26,8 @@ In an existing project, run the following command to install the components: ```text cd ../your_project/components -git clone http://git.zh.com.ru/alexey.zholtikov/zh_pcf8574 -git clone http://git.zh.com.ru/alexey.zholtikov/zh_vector +git clone http://git.zh.com.ru/esp_components/zh_pcf8574 +git clone http://git.zh.com.ru/esp_components/zh_vector ``` In the application, add the component: @@ -46,10 +45,7 @@ One expander on bus. All GPIO's as output (except P0 - input). Interrupt is enab #define I2C_PORT (I2C_NUM_MAX - 1) -#ifndef CONFIG_IDF_TARGET_ESP8266 i2c_master_bus_handle_t i2c_bus_handle = NULL; -#endif - zh_pcf8574_handle_t pcf8574_handle = {0}; void zh_pcf8574_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data); // Required only if used input GPIO interrupts. @@ -67,41 +63,21 @@ void print_gpio_status(const char *message, uint8_t reg) void app_main(void) { - esp_log_level_set("zh_pcf8574", ESP_LOG_NONE); // For ESP8266 first enable "Component config -> Log output -> Enable log set level" via menuconfig. - esp_log_level_set("zh_vector", ESP_LOG_NONE); // For ESP8266 first enable "Component config -> Log output -> Enable log set level" via menuconfig. -#ifdef CONFIG_IDF_TARGET_ESP8266 - i2c_config_t i2c_config = { - .mode = I2C_MODE_MASTER, - .sda_io_num = GPIO_NUM_4, // In accordance with used chip. - .sda_pullup_en = GPIO_PULLUP_ENABLE, - .scl_io_num = GPIO_NUM_5, // In accordance with used chip. - .scl_pullup_en = GPIO_PULLUP_ENABLE, - }; - i2c_driver_install(I2C_PORT, i2c_config.mode); - i2c_param_config(I2C_PORT, &i2c_config); -#else + esp_log_level_set("zh_pcf8574", ESP_LOG_ERROR); + esp_log_level_set("zh_vector", ESP_LOG_ERROR); i2c_master_bus_config_t i2c_bus_config = { .clk_source = I2C_CLK_SRC_DEFAULT, .i2c_port = I2C_PORT, - .scl_io_num = GPIO_NUM_22, // In accordance with used chip. - .sda_io_num = GPIO_NUM_21, // In accordance with used chip. + .scl_io_num = GPIO_NUM_22, + .sda_io_num = GPIO_NUM_21, .glitch_ignore_cnt = 7, .flags.enable_internal_pullup = true, }; i2c_new_master_bus(&i2c_bus_config, &i2c_bus_handle); -#endif - esp_event_loop_create_default(); // Required only if used input GPIO interrupts. -#ifdef CONFIG_IDF_TARGET_ESP8266 - esp_event_handler_register(ZH_PCF8574, ESP_EVENT_ANY_ID, &zh_pcf8574_event_handler, NULL); // Required only if used input GPIO interrupts. -#else + esp_event_loop_create_default(); // Required only if used input GPIO interrupts. esp_event_handler_instance_register(ZH_PCF8574, ESP_EVENT_ANY_ID, &zh_pcf8574_event_handler, NULL, NULL); // Required only if used input GPIO interrupts. -#endif zh_pcf8574_init_config_t pcf8574_init_config = ZH_PCF8574_INIT_CONFIG_DEFAULT(); -#ifdef CONFIG_IDF_TARGET_ESP8266 - pcf8574_init_config.i2c_port = I2C_PORT; -#else pcf8574_init_config.i2c_handle = i2c_bus_handle; -#endif pcf8574_init_config.i2c_address = 0x38; pcf8574_init_config.p0_gpio_work_mode = true; // Required only for input GPIO. pcf8574_init_config.interrupt_gpio = GPIO_NUM_14; // Required only if used input GPIO interrupts. diff --git a/component.mk b/component.mk deleted file mode 100644 index e69de29..0000000 diff --git a/ds/PCF8574 Remote 8-bit I:O expander for I2C-bus with interrupt.pdf b/ds/PCF8574 Remote 8-bit I:O expander for I2C-bus with interrupt.pdf deleted file mode 100755 index 7c9353a..0000000 Binary files a/ds/PCF8574 Remote 8-bit I:O expander for I2C-bus with interrupt.pdf and /dev/null differ diff --git a/include/zh_pcf8574.h b/include/zh_pcf8574.h index 897fac5..dcc2c6c 100755 --- a/include/zh_pcf8574.h +++ b/include/zh_pcf8574.h @@ -6,11 +6,7 @@ #include "esp_log.h" #include "driver/gpio.h" -#ifdef CONFIG_IDF_TARGET_ESP8266 -#include "driver/i2c.h" -#else #include "driver/i2c_master.h" -#endif #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_event.h" @@ -32,8 +28,7 @@ .p5_gpio_work_mode = 0, \ .p6_gpio_work_mode = 0, \ .p7_gpio_work_mode = 0, \ - .interrupt_gpio = GPIO_NUM_MAX, \ - .i2c_port = 0} + .interrupt_gpio = GPIO_NUM_MAX} #ifdef __cplusplus extern "C" @@ -45,22 +40,19 @@ extern "C" */ typedef struct { - uint8_t task_priority; /*!< Task priority for the PCF8574 expander isr processing. @note It is not recommended to set a value less than 10. */ - uint16_t stack_size; /*!< Stack size for task for the PCF8574 expander isr processing processing. @note The minimum size is 2048 bytes. */ - uint8_t i2c_address; /*!< Expander I2C address. */ - bool p0_gpio_work_mode; /*!< Expander GPIO PO work mode. True for input, false for output. */ - bool p1_gpio_work_mode; /*!< Expander GPIO P1 work mode. True for input, false for output. */ - bool p2_gpio_work_mode; /*!< Expander GPIO P2 work mode. True for input, false for output. */ - bool p3_gpio_work_mode; /*!< Expander GPIO P3 work mode. True for input, false for output. */ - bool p4_gpio_work_mode; /*!< Expander GPIO P4 work mode. True for input, false for output. */ - bool p5_gpio_work_mode; /*!< Expander GPIO P5 work mode. True for input, false for output. */ - bool p6_gpio_work_mode; /*!< Expander GPIO P6 work mode. True for input, false for output. */ - bool p7_gpio_work_mode; /*!< Expander GPIO P7 work mode. True for input, false for output. */ - uint8_t interrupt_gpio; /*!< Interrupt GPIO. @attention Must be same for all PCF8574 expanders. */ - bool i2c_port; /*!< I2C port. @attention Must be same for all PCF8574 expanders. */ -#ifndef CONFIG_IDF_TARGET_ESP8266 + uint8_t task_priority; /*!< Task priority for the PCF8574 expander isr processing. @note It is not recommended to set a value less than 10. */ + uint16_t stack_size; /*!< Stack size for task for the PCF8574 expander isr processing processing. @note The minimum size is 2048 bytes. */ + uint8_t i2c_address; /*!< Expander I2C address. */ + bool p0_gpio_work_mode; /*!< Expander GPIO PO work mode. True for input, false for output. */ + bool p1_gpio_work_mode; /*!< Expander GPIO P1 work mode. True for input, false for output. */ + bool p2_gpio_work_mode; /*!< Expander GPIO P2 work mode. True for input, false for output. */ + bool p3_gpio_work_mode; /*!< Expander GPIO P3 work mode. True for input, false for output. */ + bool p4_gpio_work_mode; /*!< Expander GPIO P4 work mode. True for input, false for output. */ + bool p5_gpio_work_mode; /*!< Expander GPIO P5 work mode. True for input, false for output. */ + bool p6_gpio_work_mode; /*!< Expander GPIO P6 work mode. True for input, false for output. */ + bool p7_gpio_work_mode; /*!< Expander GPIO P7 work mode. True for input, false for output. */ + uint8_t interrupt_gpio; /*!< Interrupt GPIO. @attention Must be same for all PCF8574 expanders. */ i2c_master_bus_handle_t i2c_handle; /*!< Unique I2C bus handle. @attention Must be same for all PCF8574 expanders. */ -#endif } zh_pcf8574_init_config_t; /** @@ -68,16 +60,12 @@ extern "C" */ typedef struct { - uint8_t i2c_address; /*!< Expander I2C address. */ - uint8_t gpio_work_mode; /*!< Expander GPIO's work mode. */ - uint8_t gpio_status; /*!< Expander GPIO's status. */ - bool is_initialized; /*!< Expander initialization flag. */ - bool i2c_port; /*!< I2C port. */ -#ifndef CONFIG_IDF_TARGET_ESP8266 - i2c_master_bus_handle_t i2c_handle; /*!< Unique I2C bus handle. */ + uint8_t i2c_address; /*!< Expander I2C address. */ + uint8_t gpio_work_mode; /*!< Expander GPIO's work mode. */ + uint8_t gpio_status; /*!< Expander GPIO's status. */ + bool is_initialized; /*!< Expander initialization flag. */ i2c_master_dev_handle_t dev_handle; /*!< Unique I2C device handle. */ -#endif - void *system; /*!< System pointer for use in another components. */ + void *system; /*!< System pointer for use in another components. */ } zh_pcf8574_handle_t; ESP_EVENT_DECLARE_BASE(ZH_PCF8574); diff --git a/version.txt b/version.txt index 6261a05..359a5b9 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.3.1 \ No newline at end of file +2.0.0 \ No newline at end of file diff --git a/zh_pcf8574.c b/zh_pcf8574.c index 5085fa4..ac53cf4 100755 --- a/zh_pcf8574.c +++ b/zh_pcf8574.c @@ -133,9 +133,7 @@ static esp_err_t _zh_pcf8574_validate_config(const zh_pcf8574_init_config_t *con ZH_ERROR_CHECK((config->i2c_address >= 0x20 && config->i2c_address <= 0x27) || (config->i2c_address >= 0x38 && config->i2c_address <= 0x3F), ESP_ERR_INVALID_ARG, NULL, "Invalid I2C address."); ZH_ERROR_CHECK(config->task_priority >= 10 && config->stack_size >= 2048, ESP_ERR_INVALID_ARG, NULL, "Invalid task settings."); ZH_ERROR_CHECK(config->interrupt_gpio >= GPIO_NUM_0 && config->interrupt_gpio <= GPIO_NUM_MAX, ESP_ERR_INVALID_ARG, NULL, "Invalid GPIO number."); -#ifndef CONFIG_IDF_TARGET_ESP8266 ZH_ERROR_CHECK(config->i2c_handle != NULL, ESP_ERR_INVALID_ARG, NULL, "Invalid I2C handle."); -#endif return ESP_OK; } @@ -170,7 +168,6 @@ static esp_err_t _zh_pcf8574_gpio_init(const zh_pcf8574_init_config_t *config, z static esp_err_t _zh_pcf8574_i2c_init(const zh_pcf8574_init_config_t *config, zh_pcf8574_handle_t *handle) { -#ifndef CONFIG_IDF_TARGET_ESP8266 i2c_device_config_t pcf8574_config = { .dev_addr_length = I2C_ADDR_BIT_LEN_7, .device_address = config->i2c_address, @@ -181,15 +178,12 @@ static esp_err_t _zh_pcf8574_i2c_init(const zh_pcf8574_init_config_t *config, zh ZH_ERROR_CHECK(err == ESP_OK, err, NULL;, "Failed to add I2C device."); err = i2c_master_probe(config->i2c_handle, config->i2c_address, 1000 / portTICK_PERIOD_MS); ZH_ERROR_CHECK(err == ESP_OK, err, i2c_master_bus_rm_device(_dev_handle), "Expander not connected or not responding."); - handle->i2c_handle = config->i2c_handle; handle->dev_handle = _dev_handle; -#endif handle->gpio_work_mode = (config->p7_gpio_work_mode << 7) | (config->p6_gpio_work_mode << 6) | (config->p5_gpio_work_mode << 5) | (config->p4_gpio_work_mode << 4) | (config->p3_gpio_work_mode << 3) | (config->p2_gpio_work_mode << 2) | (config->p1_gpio_work_mode << 1) | (config->p0_gpio_work_mode << 0); handle->gpio_status = handle->gpio_work_mode; handle->i2c_address = config->i2c_address; - handle->i2c_port = config->i2c_port; return ESP_OK; } @@ -268,17 +262,7 @@ static void IRAM_ATTR _zh_pcf8574_isr_processing_task(void *pvParameter) static esp_err_t _zh_pcf8574_read_register(zh_pcf8574_handle_t *handle, uint8_t *reg) { -#ifdef CONFIG_IDF_TARGET_ESP8266 - i2c_cmd_handle_t i2c_cmd_handle = i2c_cmd_link_create(); - i2c_master_start(i2c_cmd_handle); - i2c_master_write_byte(i2c_cmd_handle, handle->i2c_address << 1 | I2C_MASTER_READ, true); - i2c_master_read_byte(i2c_cmd_handle, &handle->gpio_status, I2C_MASTER_NACK); - i2c_master_stop(i2c_cmd_handle); - esp_err_t err = i2c_master_cmd_begin(handle->i2c_port, i2c_cmd_handle, 1000 / portTICK_PERIOD_MS); - i2c_cmd_link_delete(i2c_cmd_handle); -#else esp_err_t err = i2c_master_receive(handle->dev_handle, &handle->gpio_status, sizeof(handle->gpio_status), 1000 / portTICK_PERIOD_MS); -#endif ZH_ERROR_CHECK(err == ESP_OK, err, NULL, "I2C driver error."); *reg = handle->gpio_status; return ESP_OK; @@ -286,17 +270,7 @@ static esp_err_t _zh_pcf8574_read_register(zh_pcf8574_handle_t *handle, uint8_t static esp_err_t _zh_pcf8574_write_register(zh_pcf8574_handle_t *handle, uint8_t reg) { -#ifdef CONFIG_IDF_TARGET_ESP8266 - i2c_cmd_handle_t i2c_cmd_handle = i2c_cmd_link_create(); - i2c_master_start(i2c_cmd_handle); - i2c_master_write_byte(i2c_cmd_handle, handle->i2c_address << 1 | I2C_MASTER_WRITE, true); - i2c_master_write_byte(i2c_cmd_handle, reg, true); - i2c_master_stop(i2c_cmd_handle); - esp_err_t err = i2c_master_cmd_begin(handle->i2c_port, i2c_cmd_handle, 1000 / portTICK_PERIOD_MS); - i2c_cmd_link_delete(i2c_cmd_handle); -#else esp_err_t err = i2c_master_transmit(handle->dev_handle, ®, sizeof(reg), 1000 / portTICK_PERIOD_MS); -#endif ZH_ERROR_CHECK(err == ESP_OK, err, NULL, "I2C driver error."); handle->gpio_status = reg; return ESP_OK;