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:
parent
f5946a546d
commit
65547044e6
4 changed files with 46 additions and 48 deletions
|
@ -57,18 +57,17 @@ static int counter_esp32_init(const struct device *dev)
|
||||||
{
|
{
|
||||||
const struct counter_esp32_config *cfg = dev->config;
|
const struct counter_esp32_config *cfg = dev->config;
|
||||||
struct counter_esp32_data *data = dev->data;
|
struct counter_esp32_data *data = dev->data;
|
||||||
|
int ret, flags;
|
||||||
|
|
||||||
/* RTC_SLOW_CLK is the default clk source */
|
/* RTC_SLOW_CLK is the default clk source */
|
||||||
clock_control_get_rate(cfg->clock_dev,
|
clock_control_get_rate(cfg->clock_dev,
|
||||||
(clock_control_subsys_t)ESP32_CLOCK_CONTROL_SUBSYS_RTC_SLOW,
|
(clock_control_subsys_t)ESP32_CLOCK_CONTROL_SUBSYS_RTC_SLOW,
|
||||||
&data->clk_src_freq);
|
&data->clk_src_freq);
|
||||||
|
|
||||||
int ret = esp_intr_alloc(cfg->irq_source,
|
flags = ESP_PRIO_TO_FLAGS(cfg->irq_priority) | ESP_INT_FLAGS_CHECK(cfg->irq_flags) |
|
||||||
ESP_PRIO_TO_FLAGS(cfg->irq_priority) |
|
ESP_INTR_FLAG_SHARED;
|
||||||
ESP_INT_FLAGS_CHECK(cfg->irq_flags),
|
ret = esp_intr_alloc(cfg->irq_source, flags,
|
||||||
(ESP32_COUNTER_RTC_ISR_HANDLER)counter_esp32_isr,
|
(ESP32_COUNTER_RTC_ISR_HANDLER)counter_esp32_isr, (void *)dev, NULL);
|
||||||
(void *)dev,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
LOG_ERR("could not allocate interrupt (err %d)", ret);
|
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;
|
const struct device *dev = (const struct device *)arg;
|
||||||
struct counter_esp32_data *data = dev->data;
|
struct counter_esp32_data *data = dev->data;
|
||||||
uint32_t now;
|
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_cancel_alarm(dev, 0);
|
||||||
counter_esp32_get_value(dev, &now);
|
counter_esp32_get_value(dev, &now);
|
||||||
|
|
|
@ -22,9 +22,6 @@
|
||||||
|
|
||||||
LOG_MODULE_REGISTER(espressif_esp32_touch, CONFIG_INPUT_LOG_LEVEL);
|
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
|
#define ESP32_SCAN_DONE_MAX_COUNT 5
|
||||||
|
|
||||||
#if defined(CONFIG_SOC_SERIES_ESP32)
|
#if defined(CONFIG_SOC_SERIES_ESP32)
|
||||||
|
@ -75,7 +72,6 @@ struct esp32_touch_sensor_channel_data {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct esp32_touch_sensor_data {
|
struct esp32_touch_sensor_data {
|
||||||
uint32_t rtc_intr_msk;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void esp32_touch_sensor_interrupt_cb(void *arg)
|
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);
|
uint32_t status = REG_READ(RTC_CNTL_INT_ST_REG);
|
||||||
|
|
||||||
if (arg != NULL) {
|
if (!(status & ESP32_RTC_INTR_MSK)) {
|
||||||
const struct device *dev = arg;
|
return;
|
||||||
struct esp32_touch_sensor_data *dev_data = dev->data;
|
|
||||||
|
|
||||||
if (dev_data->rtc_intr_msk & status) {
|
|
||||||
esp32_touch_sensor_interrupt_cb(arg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
esp32_touch_sensor_interrupt_cb(arg);
|
||||||
REG_WRITE(RTC_CNTL_INT_CLR_REG, status);
|
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.
|
* 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)
|
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 struct esp32_touch_sensor_config *dev_cfg = dev->config;
|
||||||
const int num_channels = dev_cfg->num_channels;
|
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);
|
touch_hal_timeout_set_threshold(SOC_TOUCH_PAD_THRESHOLD_MAX);
|
||||||
#endif /* defined(CONFIG_SOC_SERIES_ESP32) */
|
#endif /* defined(CONFIG_SOC_SERIES_ESP32) */
|
||||||
|
|
||||||
dev_data->rtc_intr_msk = ESP32_RTC_INTR_MSK;
|
flags = ESP_PRIO_TO_FLAGS(DT_IRQ_BY_IDX(DT_NODELABEL(touch), 0, priority)) |
|
||||||
esp32_rtc_isr_install(&esp32_rtc_isr, dev);
|
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)
|
#if defined(CONFIG_SOC_SERIES_ESP32)
|
||||||
touch_hal_intr_enable();
|
touch_hal_intr_enable();
|
||||||
#elif defined(CONFIG_SOC_SERIES_ESP32S2) || defined(CONFIG_SOC_SERIES_ESP32S3)
|
#elif defined(CONFIG_SOC_SERIES_ESP32S2) || defined(CONFIG_SOC_SERIES_ESP32S3)
|
||||||
|
|
|
@ -158,6 +158,7 @@ static int wdt_esp32_init(const struct device *dev)
|
||||||
{
|
{
|
||||||
const struct wdt_esp32_config *const config = dev->config;
|
const struct wdt_esp32_config *const config = dev->config;
|
||||||
struct wdt_esp32_data *data = dev->data;
|
struct wdt_esp32_data *data = dev->data;
|
||||||
|
int ret, flags;
|
||||||
|
|
||||||
if (!device_is_ready(config->clock_dev)) {
|
if (!device_is_ready(config->clock_dev)) {
|
||||||
LOG_ERR("clock control device not ready");
|
LOG_ERR("clock control device not ready");
|
||||||
|
@ -168,12 +169,10 @@ static int wdt_esp32_init(const struct device *dev)
|
||||||
|
|
||||||
wdt_hal_init(&data->hal, config->wdt_inst, MWDT_TICK_PRESCALER, true);
|
wdt_hal_init(&data->hal, config->wdt_inst, MWDT_TICK_PRESCALER, true);
|
||||||
|
|
||||||
int ret = esp_intr_alloc(config->irq_source,
|
flags = ESP_PRIO_TO_FLAGS(config->irq_priority) | ESP_INT_FLAGS_CHECK(config->irq_flags) |
|
||||||
ESP_PRIO_TO_FLAGS(config->irq_priority) |
|
ESP_INTR_FLAG_SHARED;
|
||||||
ESP_INT_FLAGS_CHECK(config->irq_flags),
|
ret = esp_intr_alloc(config->irq_source, flags, (ISR_HANDLER)wdt_esp32_isr, (void *)dev,
|
||||||
(ISR_HANDLER)wdt_esp32_isr,
|
NULL);
|
||||||
(void *)dev,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
LOG_ERR("could not allocate interrupt (err %d)", ret);
|
LOG_ERR("could not allocate interrupt (err %d)", ret);
|
||||||
|
@ -217,6 +216,11 @@ static void wdt_esp32_isr(void *arg)
|
||||||
{
|
{
|
||||||
const struct device *dev = (const struct device *)arg;
|
const struct device *dev = (const struct device *)arg;
|
||||||
struct wdt_esp32_data *data = dev->data;
|
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) {
|
if (data->callback) {
|
||||||
data->callback(dev, 0);
|
data->callback(dev, 0);
|
||||||
|
|
|
@ -103,6 +103,10 @@ static void esp32_xt_wdt_isr(void *arg)
|
||||||
struct esp32_clock_config clk_cfg = {0};
|
struct esp32_clock_config clk_cfg = {0};
|
||||||
uint32_t status = REG_READ(RTC_CNTL_INT_ST_REG);
|
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);
|
REG_WRITE(RTC_CNTL_INT_CLR_REG, status);
|
||||||
|
|
||||||
clk_cfg.rtc.rtc_slow_clock_src = ESP32_RTC_SLOW_CLK_SRC_RC_SLOW;
|
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 = {
|
xt_wdt_hal_config_t xt_wdt_hal_config = {
|
||||||
.timeout = ESP32_XT_WDT_MAX_TIMEOUT,
|
.timeout = ESP32_XT_WDT_MAX_TIMEOUT,
|
||||||
};
|
};
|
||||||
|
int err, flags = 0;
|
||||||
|
|
||||||
xt_wdt_hal_init(&data->hal, &xt_wdt_hal_config);
|
xt_wdt_hal_init(&data->hal, &xt_wdt_hal_config);
|
||||||
xt_wdt_hal_enable_backup_clk(&data->hal,
|
xt_wdt_hal_enable_backup_clk(&data->hal, ESP32_RTC_SLOW_CLK_SRC_RC_SLOW_FREQ/1000);
|
||||||
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);
|
|
||||||
|
|
||||||
|
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) {
|
if (err) {
|
||||||
LOG_ERR("Failed to register ISR\n");
|
LOG_ERR("Failed to register ISR\n");
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue