3 Commits

Author SHA1 Message Date
1a8f4711e8 feat: added task handle 2025-12-07 12:42:08 +03:00
0a770c360c fix: gpio isr service reinitialization error 2025-12-07 12:27:47 +03:00
379fae940b doc: updated readme 2025-11-30 22:43:44 +03:00
4 changed files with 49 additions and 9 deletions

View File

@@ -16,6 +16,14 @@
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/esp_components/zh_vector) 1. [zh_vector](http://git.zh.com.ru/esp_components/zh_vector)

View File

@@ -35,6 +35,8 @@ extern "C"
{ {
#endif #endif
extern TaskHandle_t zh_pcf8574; /*!< Unique task handle. */
/** /**
* @brief Structure for initial initialization of PCF8574 expander. * @brief Structure for initial initialization of PCF8574 expander.
*/ */

View File

@@ -1 +1 @@
2.0.0 2.1.0

View File

@@ -13,9 +13,12 @@ static const char *TAG = "zh_pcf8574";
return err; \ return err; \
} }
static uint8_t _interrupt_gpio = GPIO_NUM_MAX; TaskHandle_t zh_pcf8574 = NULL;
static SemaphoreHandle_t _interrupt_semaphore = NULL; static SemaphoreHandle_t _interrupt_semaphore = NULL;
static uint8_t _interrupt_gpio = GPIO_NUM_MAX;
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 +50,27 @@ 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.");
@@ -159,9 +178,20 @@ 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);
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.") 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.")
}
_interrupt_gpio = config->interrupt_gpio; _interrupt_gpio = config->interrupt_gpio;
return ESP_OK; return ESP_OK;
} }
@@ -196,7 +226,7 @@ static esp_err_t _zh_pcf8574_resources_init(const zh_pcf8574_init_config_t *conf
static esp_err_t _zh_pcf8574_task_init(const zh_pcf8574_init_config_t *config) static esp_err_t _zh_pcf8574_task_init(const zh_pcf8574_init_config_t *config)
{ {
BaseType_t err = xTaskCreatePinnedToCore(&_zh_pcf8574_isr_processing_task, "zh_pcf8574_isr_processing_task", config->stack_size, NULL, config->task_priority, NULL, tskNO_AFFINITY); BaseType_t err = xTaskCreatePinnedToCore(&_zh_pcf8574_isr_processing_task, "zh_pcf8574_isr_processing_task", config->stack_size, NULL, config->task_priority, &zh_pcf8574, tskNO_AFFINITY);
ZH_ERROR_CHECK(err == pdPASS, err, NULL, "Failed to create isr processing task.") ZH_ERROR_CHECK(err == pdPASS, err, NULL, "Failed to create isr processing task.")
return ESP_OK; return ESP_OK;
} }