5 Commits

7 changed files with 77 additions and 112 deletions

View File

@@ -1,6 +1 @@
if(${IDF_TARGET} STREQUAL esp8266) idf_component_register(SRCS "zh_pcf8574.c" INCLUDE_DIRS "include" REQUIRES driver esp_event zh_vector)
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})

View File

@@ -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 ## Tested on
1. [ESP8266 RTOS_SDK v3.4](https://docs.espressif.com/projects/esp8266-rtos-sdk/en/latest/index.html#) 1. [ESP32 ESP-IDF v5.5.1](https://docs.espressif.com/projects/esp-idf/en/v5.5.1/esp32/index.html)
2. [ESP32 ESP-IDF v5.4](https://docs.espressif.com/projects/esp-idf/en/release-v5.4/esp32/index.html)
## Features ## Features
@@ -17,9 +16,17 @@
2. All the INT GPIO's on the extenders must be connected to the one GPIO on ESP. 2. All the INT GPIO's on the extenders must be connected to the one GPIO on ESP.
3. The input GPIO's are always pullup to the power supply. 3. The input GPIO's are always pullup to the power supply.
## Attention
For correct operation, please enable the following settings in the menuconfig:
```text
GPIO_CTRL_FUNC_IN_IRAM
```
## Dependencies ## 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 ## Using
@@ -27,8 +34,8 @@ In an existing project, run the following command to install the components:
```text ```text
cd ../your_project/components cd ../your_project/components
git clone http://git.zh.com.ru/alexey.zholtikov/zh_pcf8574 git clone http://git.zh.com.ru/esp_components/zh_pcf8574
git clone http://git.zh.com.ru/alexey.zholtikov/zh_vector git clone http://git.zh.com.ru/esp_components/zh_vector
``` ```
In the application, add the component: In the application, add the component:
@@ -46,10 +53,7 @@ One expander on bus. All GPIO's as output (except P0 - input). Interrupt is enab
#define I2C_PORT (I2C_NUM_MAX - 1) #define I2C_PORT (I2C_NUM_MAX - 1)
#ifndef CONFIG_IDF_TARGET_ESP8266
i2c_master_bus_handle_t i2c_bus_handle = NULL; i2c_master_bus_handle_t i2c_bus_handle = NULL;
#endif
zh_pcf8574_handle_t pcf8574_handle = {0}; 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. 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,45 +71,25 @@ void print_gpio_status(const char *message, uint8_t reg)
void app_main(void) 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_pcf8574", ESP_LOG_ERROR);
esp_log_level_set("zh_vector", 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_ERROR);
#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
i2c_master_bus_config_t i2c_bus_config = { i2c_master_bus_config_t i2c_bus_config = {
.clk_source = I2C_CLK_SRC_DEFAULT, .clk_source = I2C_CLK_SRC_DEFAULT,
.i2c_port = I2C_PORT, .i2c_port = I2C_PORT,
.scl_io_num = GPIO_NUM_22, // In accordance with used chip. .scl_io_num = GPIO_NUM_22,
.sda_io_num = GPIO_NUM_21, // In accordance with used chip. .sda_io_num = GPIO_NUM_21,
.glitch_ignore_cnt = 7, .glitch_ignore_cnt = 7,
.flags.enable_internal_pullup = true, .flags.enable_internal_pullup = true,
}; };
i2c_new_master_bus(&i2c_bus_config, &i2c_bus_handle); i2c_new_master_bus(&i2c_bus_config, &i2c_bus_handle);
#endif
esp_event_loop_create_default(); // Required only if used input GPIO interrupts. 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_handler_instance_register(ZH_PCF8574, ESP_EVENT_ANY_ID, &zh_pcf8574_event_handler, NULL, NULL); // 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 config = ZH_PCF8574_INIT_CONFIG_DEFAULT();
zh_pcf8574_init_config_t pcf8574_init_config = ZH_PCF8574_INIT_CONFIG_DEFAULT(); config.i2c_handle = i2c_bus_handle;
#ifdef CONFIG_IDF_TARGET_ESP8266 config.i2c_address = 0x38;
pcf8574_init_config.i2c_port = I2C_PORT; config.p0_gpio_work_mode = true; // Required only for input GPIO.
#else config.interrupt_gpio = GPIO_NUM_14; // Required only if used input GPIO interrupts.
pcf8574_init_config.i2c_handle = i2c_bus_handle; zh_pcf8574_init(&config, &pcf8574_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.
zh_pcf8574_init(&pcf8574_init_config, &pcf8574_handle);
uint8_t reg = 0; uint8_t reg = 0;
zh_pcf8574_read(&pcf8574_handle, &reg); zh_pcf8574_read(&pcf8574_handle, &reg);
print_gpio_status("GPIO status: ", reg); print_gpio_status("GPIO status: ", reg);

View File

View File

@@ -6,11 +6,7 @@
#include "esp_log.h" #include "esp_log.h"
#include "driver/gpio.h" #include "driver/gpio.h"
#ifdef CONFIG_IDF_TARGET_ESP8266
#include "driver/i2c.h"
#else
#include "driver/i2c_master.h" #include "driver/i2c_master.h"
#endif
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
#include "esp_event.h" #include "esp_event.h"
@@ -32,8 +28,7 @@
.p5_gpio_work_mode = 0, \ .p5_gpio_work_mode = 0, \
.p6_gpio_work_mode = 0, \ .p6_gpio_work_mode = 0, \
.p7_gpio_work_mode = 0, \ .p7_gpio_work_mode = 0, \
.interrupt_gpio = GPIO_NUM_MAX, \ .interrupt_gpio = GPIO_NUM_MAX}
.i2c_port = 0}
#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C"
@@ -57,10 +52,7 @@ extern "C"
bool p6_gpio_work_mode; /*!< Expander GPIO P6 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. */ 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. */ 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
i2c_master_bus_handle_t i2c_handle; /*!< Unique I2C bus handle. @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; } zh_pcf8574_init_config_t;
/** /**
@@ -72,11 +64,7 @@ extern "C"
uint8_t gpio_work_mode; /*!< Expander GPIO's work mode. */ uint8_t gpio_work_mode; /*!< Expander GPIO's work mode. */
uint8_t gpio_status; /*!< Expander GPIO's status. */ uint8_t gpio_status; /*!< Expander GPIO's status. */
bool is_initialized; /*!< Expander initialization flag. */ 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. */
i2c_master_dev_handle_t dev_handle; /*!< Unique I2C device handle. */ 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; } zh_pcf8574_handle_t;

View File

@@ -1 +1 @@
1.3.1 2.0.1

View File

@@ -16,6 +16,7 @@ static const char *TAG = "zh_pcf8574";
static uint8_t _interrupt_gpio = GPIO_NUM_MAX; static uint8_t _interrupt_gpio = GPIO_NUM_MAX;
static SemaphoreHandle_t _interrupt_semaphore = NULL; static SemaphoreHandle_t _interrupt_semaphore = NULL;
static const uint8_t _gpio_matrix[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; static const uint8_t _gpio_matrix[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
static bool _is_prev_gpio_isr_service = false;
static zh_vector_t _vector = {0}; static zh_vector_t _vector = {0};
@@ -47,11 +48,23 @@ esp_err_t zh_pcf8574_init(const zh_pcf8574_init_config_t *config, zh_pcf8574_han
err = _zh_pcf8574_gpio_init(config, handle); err = _zh_pcf8574_gpio_init(config, handle);
ZH_ERROR_CHECK(err == ESP_OK, err, i2c_master_bus_rm_device(handle->dev_handle), "PCF8574 initialization failed. Interrupt GPIO initialization failed."); ZH_ERROR_CHECK(err == ESP_OK, err, i2c_master_bus_rm_device(handle->dev_handle), "PCF8574 initialization failed. Interrupt GPIO initialization failed.");
err = _zh_pcf8574_resources_init(config); err = _zh_pcf8574_resources_init(config);
ZH_ERROR_CHECK(err == ESP_OK, err, i2c_master_bus_rm_device(handle->dev_handle); gpio_isr_handler_remove(config->interrupt_gpio); gpio_uninstall_isr_service(); if (_is_prev_gpio_isr_service == true)
gpio_reset_pin(config->interrupt_gpio); zh_vector_free(&_vector), "PCF8574 initialization failed. Resources initialization failed."); {
ZH_ERROR_CHECK(err == ESP_OK, err, i2c_master_bus_rm_device(handle->dev_handle); gpio_isr_handler_remove(config->interrupt_gpio); gpio_reset_pin(config->interrupt_gpio); zh_vector_free(&_vector), "PCF8574 initialization failed. Resources initialization failed.");
}
else
{
ZH_ERROR_CHECK(err == ESP_OK, err, i2c_master_bus_rm_device(handle->dev_handle); gpio_isr_handler_remove(config->interrupt_gpio); gpio_uninstall_isr_service(); gpio_reset_pin(config->interrupt_gpio); zh_vector_free(&_vector), "PCF8574 initialization failed. Resources initialization failed.");
}
err = _zh_pcf8574_task_init(config); err = _zh_pcf8574_task_init(config);
ZH_ERROR_CHECK(err == ESP_OK, err, i2c_master_bus_rm_device(handle->dev_handle); gpio_isr_handler_remove(config->interrupt_gpio); gpio_uninstall_isr_service(); if (_is_prev_gpio_isr_service == true)
gpio_reset_pin(config->interrupt_gpio); zh_vector_free(&_vector); vSemaphoreDelete(_interrupt_semaphore), "PCF8574 initialization failed. Task initialization failed."); {
ZH_ERROR_CHECK(err == ESP_OK, err, i2c_master_bus_rm_device(handle->dev_handle); gpio_isr_handler_remove(config->interrupt_gpio); gpio_reset_pin(config->interrupt_gpio); zh_vector_free(&_vector); vSemaphoreDelete(_interrupt_semaphore), "PCF8574 initialization failed. Task initialization failed.");
}
else
{
ZH_ERROR_CHECK(err == ESP_OK, err, i2c_master_bus_rm_device(handle->dev_handle); gpio_isr_handler_remove(config->interrupt_gpio); gpio_uninstall_isr_service(); gpio_reset_pin(config->interrupt_gpio); zh_vector_free(&_vector); vSemaphoreDelete(_interrupt_semaphore), "PCF8574 initialization failed. Task initialization failed.");
}
} }
handle->is_initialized = true; handle->is_initialized = true;
ZH_LOGI("PCF8574 initialization completed successfully."); ZH_LOGI("PCF8574 initialization completed successfully.");
@@ -61,7 +74,7 @@ esp_err_t zh_pcf8574_init(const zh_pcf8574_init_config_t *config, zh_pcf8574_han
esp_err_t zh_pcf8574_read(zh_pcf8574_handle_t *handle, uint8_t *reg) esp_err_t zh_pcf8574_read(zh_pcf8574_handle_t *handle, uint8_t *reg)
{ {
ZH_LOGI("PCF8574 read register started."); ZH_LOGI("PCF8574 read register started.");
ZH_ERROR_CHECK(handle != NULL || reg != NULL, ESP_ERR_INVALID_ARG, NULL, "PCF8574 read register failed. Invalid argument."); ZH_ERROR_CHECK(handle != NULL && reg != NULL, ESP_ERR_INVALID_ARG, NULL, "PCF8574 read register failed. Invalid argument.");
ZH_ERROR_CHECK(handle->is_initialized == true, ESP_ERR_NOT_FOUND, NULL, "PCF8574 read register failed. PCF8574 not initialized."); ZH_ERROR_CHECK(handle->is_initialized == true, ESP_ERR_NOT_FOUND, NULL, "PCF8574 read register failed. PCF8574 not initialized.");
esp_err_t err = _zh_pcf8574_read_register(handle, reg); esp_err_t err = _zh_pcf8574_read_register(handle, reg);
ZH_ERROR_CHECK(err == ESP_OK, err, NULL, "PCF8574 read register failed."); ZH_ERROR_CHECK(err == ESP_OK, err, NULL, "PCF8574 read register failed.");
@@ -94,7 +107,7 @@ esp_err_t zh_pcf8574_reset(zh_pcf8574_handle_t *handle)
esp_err_t zh_pcf8574_read_gpio(zh_pcf8574_handle_t *handle, uint8_t gpio, bool *status) esp_err_t zh_pcf8574_read_gpio(zh_pcf8574_handle_t *handle, uint8_t gpio, bool *status)
{ {
ZH_LOGI("PCF8574 read GPIO started."); ZH_LOGI("PCF8574 read GPIO started.");
ZH_ERROR_CHECK(handle != NULL || status != NULL, ESP_ERR_INVALID_ARG, NULL, "PCF8574 read GPIO failed. Invalid argument."); ZH_ERROR_CHECK(handle != NULL && status != NULL, ESP_ERR_INVALID_ARG, NULL, "PCF8574 read GPIO failed. Invalid argument.");
ZH_ERROR_CHECK(gpio <= 7, ESP_FAIL, NULL, "PCF8574 read GPIO failed. Invalid GPIO number.") ZH_ERROR_CHECK(gpio <= 7, ESP_FAIL, NULL, "PCF8574 read GPIO failed. Invalid GPIO number.")
ZH_ERROR_CHECK(handle->is_initialized == true, ESP_ERR_NOT_FOUND, NULL, "PCF8574 read GPIO failed. PCF8574 not initialized."); ZH_ERROR_CHECK(handle->is_initialized == true, ESP_ERR_NOT_FOUND, NULL, "PCF8574 read GPIO failed. PCF8574 not initialized.");
uint8_t gpio_temp = _gpio_matrix[gpio]; uint8_t gpio_temp = _gpio_matrix[gpio];
@@ -133,9 +146,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->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->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."); 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."); ZH_ERROR_CHECK(config->i2c_handle != NULL, ESP_ERR_INVALID_ARG, NULL, "Invalid I2C handle.");
#endif
return ESP_OK; return ESP_OK;
} }
@@ -161,16 +172,26 @@ static esp_err_t _zh_pcf8574_gpio_init(const zh_pcf8574_init_config_t *config, z
err = gpio_config(&interrupt_gpio_config); err = gpio_config(&interrupt_gpio_config);
ZH_ERROR_CHECK(err == ESP_OK, err, zh_vector_free(&_vector), "GPIO configuration failed.") ZH_ERROR_CHECK(err == ESP_OK, err, zh_vector_free(&_vector), "GPIO configuration failed.")
err = gpio_install_isr_service(ESP_INTR_FLAG_LOWMED); err = gpio_install_isr_service(ESP_INTR_FLAG_LOWMED);
ZH_ERROR_CHECK(err == ESP_OK, err, gpio_reset_pin(config->interrupt_gpio); zh_vector_free(&_vector), "Failed install isr service.") ZH_ERROR_CHECK(err == ESP_OK || err == ESP_ERR_INVALID_STATE, err, gpio_reset_pin(config->interrupt_gpio); zh_vector_free(&_vector), "Failed install isr service.")
if (err == ESP_ERR_INVALID_STATE)
{
_is_prev_gpio_isr_service = true;
}
err = gpio_isr_handler_add(config->interrupt_gpio, _zh_pcf8574_isr_handler, NULL); err = gpio_isr_handler_add(config->interrupt_gpio, _zh_pcf8574_isr_handler, NULL);
if (_is_prev_gpio_isr_service == true)
{
ZH_ERROR_CHECK(err == ESP_OK, err, gpio_reset_pin(config->interrupt_gpio); zh_vector_free(&_vector), "Failed add isr handler.")
}
else
{
ZH_ERROR_CHECK(err == ESP_OK, err, gpio_uninstall_isr_service(); gpio_reset_pin(config->interrupt_gpio); zh_vector_free(&_vector), "Failed add isr handler.") ZH_ERROR_CHECK(err == ESP_OK, err, gpio_uninstall_isr_service(); gpio_reset_pin(config->interrupt_gpio); zh_vector_free(&_vector), "Failed add isr handler.")
}
_interrupt_gpio = config->interrupt_gpio; _interrupt_gpio = config->interrupt_gpio;
return ESP_OK; return ESP_OK;
} }
static esp_err_t _zh_pcf8574_i2c_init(const zh_pcf8574_init_config_t *config, zh_pcf8574_handle_t *handle) 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 = { i2c_device_config_t pcf8574_config = {
.dev_addr_length = I2C_ADDR_BIT_LEN_7, .dev_addr_length = I2C_ADDR_BIT_LEN_7,
.device_address = config->i2c_address, .device_address = config->i2c_address,
@@ -178,18 +199,15 @@ static esp_err_t _zh_pcf8574_i2c_init(const zh_pcf8574_init_config_t *config, zh
}; };
i2c_master_dev_handle_t _dev_handle = NULL; i2c_master_dev_handle_t _dev_handle = NULL;
esp_err_t err = i2c_master_bus_add_device(config->i2c_handle, &pcf8574_config, &_dev_handle); esp_err_t err = i2c_master_bus_add_device(config->i2c_handle, &pcf8574_config, &_dev_handle);
ZH_ERROR_CHECK(err == ESP_OK, err, NULL;, "Failed to add I2C device."); 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); 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."); 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; 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) | 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->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); (config->p1_gpio_work_mode << 1) | (config->p0_gpio_work_mode << 0);
handle->gpio_status = handle->gpio_work_mode; handle->gpio_status = handle->gpio_work_mode;
handle->i2c_address = config->i2c_address; handle->i2c_address = config->i2c_address;
handle->i2c_port = config->i2c_port;
return ESP_OK; return ESP_OK;
} }
@@ -268,17 +286,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) 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); 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."); ZH_ERROR_CHECK(err == ESP_OK, err, NULL, "I2C driver error.");
*reg = handle->gpio_status; *reg = handle->gpio_status;
return ESP_OK; return ESP_OK;
@@ -286,17 +294,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) 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, &reg, sizeof(reg), 1000 / portTICK_PERIOD_MS); esp_err_t err = i2c_master_transmit(handle->dev_handle, &reg, sizeof(reg), 1000 / portTICK_PERIOD_MS);
#endif
ZH_ERROR_CHECK(err == ESP_OK, err, NULL, "I2C driver error."); ZH_ERROR_CHECK(err == ESP_OK, err, NULL, "I2C driver error.");
handle->gpio_status = reg; handle->gpio_status = reg;
return ESP_OK; return ESP_OK;