drivers: touch/rtc/wdt: esp32: fix conflict among device drivers

allows use of touch_sensor, rtc_counter, and wdt simultaneously by enabling
ESP_INTR_FLAG_SHARED when calling esp_intr_alloc()

Signed-off-by: Marcio Ribeiro <marcio.ribeiro@espressif.com>
This commit is contained in:
Marcio Ribeiro 2024-11-20 18:31:52 -03:00 committed by Benjamin Cabé
commit 65547044e6
4 changed files with 46 additions and 48 deletions

View file

@ -57,18 +57,17 @@ static int counter_esp32_init(const struct device *dev)
{
const struct counter_esp32_config *cfg = dev->config;
struct counter_esp32_data *data = dev->data;
int ret, flags;
/* RTC_SLOW_CLK is the default clk source */
clock_control_get_rate(cfg->clock_dev,
(clock_control_subsys_t)ESP32_CLOCK_CONTROL_SUBSYS_RTC_SLOW,
&data->clk_src_freq);
int ret = esp_intr_alloc(cfg->irq_source,
ESP_PRIO_TO_FLAGS(cfg->irq_priority) |
ESP_INT_FLAGS_CHECK(cfg->irq_flags),
(ESP32_COUNTER_RTC_ISR_HANDLER)counter_esp32_isr,
(void *)dev,
NULL);
flags = ESP_PRIO_TO_FLAGS(cfg->irq_priority) | ESP_INT_FLAGS_CHECK(cfg->irq_flags) |
ESP_INTR_FLAG_SHARED;
ret = esp_intr_alloc(cfg->irq_source, flags,
(ESP32_COUNTER_RTC_ISR_HANDLER)counter_esp32_isr, (void *)dev, NULL);
if (ret != 0) {
LOG_ERR("could not allocate interrupt (err %d)", ret);
@ -228,6 +227,11 @@ static void counter_esp32_isr(void *arg)
const struct device *dev = (const struct device *)arg;
struct counter_esp32_data *data = dev->data;
uint32_t now;
uint32_t status = REG_READ(RTC_CNTL_INT_ST_REG);
if (!(status & RTC_CNTL_MAIN_TIMER_INT_ST_M)) {
return;
}
counter_esp32_cancel_alarm(dev, 0);
counter_esp32_get_value(dev, &now);

View file

@ -22,9 +22,6 @@
LOG_MODULE_REGISTER(espressif_esp32_touch, CONFIG_INPUT_LOG_LEVEL);
BUILD_ASSERT(!IS_ENABLED(CONFIG_COUNTER_RTC_ESP32),
"Conflict detected: COUNTER_RTC_ESP32 enabled");
#define ESP32_SCAN_DONE_MAX_COUNT 5
#if defined(CONFIG_SOC_SERIES_ESP32)
@ -75,7 +72,6 @@ struct esp32_touch_sensor_channel_data {
};
struct esp32_touch_sensor_data {
uint32_t rtc_intr_msk;
};
static void esp32_touch_sensor_interrupt_cb(void *arg)
@ -140,36 +136,18 @@ static void esp32_touch_sensor_interrupt_cb(void *arg)
}
}
static void esp32_rtc_isr(void *arg)
static void esp32_touch_rtc_isr(void *arg)
{
uint32_t status = REG_READ(RTC_CNTL_INT_ST_REG);
if (arg != NULL) {
const struct device *dev = arg;
struct esp32_touch_sensor_data *dev_data = dev->data;
if (!(status & ESP32_RTC_INTR_MSK)) {
return;
}
if (dev_data->rtc_intr_msk & status) {
esp32_touch_sensor_interrupt_cb(arg);
}
}
REG_WRITE(RTC_CNTL_INT_CLR_REG, status);
}
static esp_err_t esp32_rtc_isr_install(intr_handler_t intr_handler, const void *handler_arg)
{
esp_err_t err;
REG_WRITE(RTC_CNTL_INT_ENA_REG, 0);
REG_WRITE(RTC_CNTL_INT_CLR_REG, UINT32_MAX);
err = esp_intr_alloc(DT_IRQ_BY_IDX(DT_NODELABEL(touch), 0, irq),
ESP_PRIO_TO_FLAGS(DT_IRQ_BY_IDX(DT_NODELABEL(touch), 0, priority)) |
ESP_INT_FLAGS_CHECK(DT_IRQ_BY_IDX(DT_NODELABEL(touch), 0, flags)),
intr_handler, (void *)handler_arg, NULL);
return err;
}
/**
* Handle debounced touch sensor touch state.
@ -198,7 +176,8 @@ static void esp32_touch_sensor_change_deferred(struct k_work *work)
static int esp32_touch_sensor_init(const struct device *dev)
{
struct esp32_touch_sensor_data *dev_data = dev->data;
esp_err_t err, flags;
const struct esp32_touch_sensor_config *dev_cfg = dev->config;
const int num_channels = dev_cfg->num_channels;
@ -293,8 +272,16 @@ static int esp32_touch_sensor_init(const struct device *dev)
touch_hal_timeout_set_threshold(SOC_TOUCH_PAD_THRESHOLD_MAX);
#endif /* defined(CONFIG_SOC_SERIES_ESP32) */
dev_data->rtc_intr_msk = ESP32_RTC_INTR_MSK;
esp32_rtc_isr_install(&esp32_rtc_isr, dev);
flags = ESP_PRIO_TO_FLAGS(DT_IRQ_BY_IDX(DT_NODELABEL(touch), 0, priority)) |
ESP_INT_FLAGS_CHECK(DT_IRQ_BY_IDX(DT_NODELABEL(touch), 0, flags)) |
ESP_INTR_FLAG_SHARED;
err = esp_intr_alloc(DT_IRQ_BY_IDX(DT_NODELABEL(touch), 0, irq), flags, esp32_touch_rtc_isr,
(void *)dev, NULL);
if (err) {
LOG_ERR("Failed to register ISR\n");
return -EFAULT;
}
#if defined(CONFIG_SOC_SERIES_ESP32)
touch_hal_intr_enable();
#elif defined(CONFIG_SOC_SERIES_ESP32S2) || defined(CONFIG_SOC_SERIES_ESP32S3)

View file

@ -158,6 +158,7 @@ static int wdt_esp32_init(const struct device *dev)
{
const struct wdt_esp32_config *const config = dev->config;
struct wdt_esp32_data *data = dev->data;
int ret, flags;
if (!device_is_ready(config->clock_dev)) {
LOG_ERR("clock control device not ready");
@ -168,11 +169,9 @@ static int wdt_esp32_init(const struct device *dev)
wdt_hal_init(&data->hal, config->wdt_inst, MWDT_TICK_PRESCALER, true);
int ret = esp_intr_alloc(config->irq_source,
ESP_PRIO_TO_FLAGS(config->irq_priority) |
ESP_INT_FLAGS_CHECK(config->irq_flags),
(ISR_HANDLER)wdt_esp32_isr,
(void *)dev,
flags = ESP_PRIO_TO_FLAGS(config->irq_priority) | ESP_INT_FLAGS_CHECK(config->irq_flags) |
ESP_INTR_FLAG_SHARED;
ret = esp_intr_alloc(config->irq_source, flags, (ISR_HANDLER)wdt_esp32_isr, (void *)dev,
NULL);
if (ret != 0) {
@ -217,6 +216,11 @@ static void wdt_esp32_isr(void *arg)
{
const struct device *dev = (const struct device *)arg;
struct wdt_esp32_data *data = dev->data;
uint32_t status = REG_READ(RTC_CNTL_INT_ST_REG);
if (!(status & RTC_CNTL_WDT_INT_ST)) {
return;
}
if (data->callback) {
data->callback(dev, 0);

View file

@ -103,6 +103,10 @@ static void esp32_xt_wdt_isr(void *arg)
struct esp32_clock_config clk_cfg = {0};
uint32_t status = REG_READ(RTC_CNTL_INT_ST_REG);
if (!(status & RTC_CNTL_XTAL32K_DEAD_INT_ST)) {
return;
}
REG_WRITE(RTC_CNTL_INT_CLR_REG, status);
clk_cfg.rtc.rtc_slow_clock_src = ESP32_RTC_SLOW_CLK_SRC_RC_SLOW;
@ -123,16 +127,15 @@ static int esp32_xt_wdt_init(const struct device *dev)
xt_wdt_hal_config_t xt_wdt_hal_config = {
.timeout = ESP32_XT_WDT_MAX_TIMEOUT,
};
int err, flags = 0;
xt_wdt_hal_init(&data->hal, &xt_wdt_hal_config);
xt_wdt_hal_enable_backup_clk(&data->hal,
ESP32_RTC_SLOW_CLK_SRC_RC_SLOW_FREQ/1000);
int err = esp_intr_alloc(cfg->irq_source,
ESP_PRIO_TO_FLAGS(cfg->irq_priority) |
ESP_INT_FLAGS_CHECK(cfg->irq_flags),
(ISR_HANDLER)esp32_xt_wdt_isr, (void *)dev, NULL);
xt_wdt_hal_enable_backup_clk(&data->hal, ESP32_RTC_SLOW_CLK_SRC_RC_SLOW_FREQ/1000);
flags = ESP_PRIO_TO_FLAGS(cfg->irq_priority) | ESP_INT_FLAGS_CHECK(cfg->irq_flags) |
ESP_INTR_FLAG_SHARED;
err = esp_intr_alloc(cfg->irq_source, flags, (ISR_HANDLER)esp32_xt_wdt_isr, (void *)dev,
NULL);
if (err) {
LOG_ERR("Failed to register ISR\n");
return -EFAULT;