mirror of
https://github.com/apache/nuttx.git
synced 2026-08-18 02:38:18 +00:00
esp32[c3|c6|h2]: Add RWDT support
This commit is contained in:
parent
44e118eaf2
commit
aa0bb55529
12 changed files with 305 additions and 84 deletions
|
|
@ -328,6 +328,29 @@ config ESPRESSIF_HR_TIMER
|
|||
The HR Timer is built on top of the System Timer (SYSTIMER) peripheral.
|
||||
Timer callbacks are dispatched from a high-priority kernel task.
|
||||
|
||||
config ESPRESSIF_WDT
|
||||
bool
|
||||
default n
|
||||
select WATCHDOG
|
||||
|
||||
config ESPRESSIF_MWDT
|
||||
bool "Main System Watchdog Timer"
|
||||
default n
|
||||
select ESPRESSIF_WDT
|
||||
---help---
|
||||
Includes MWDT.
|
||||
|
||||
config ESPRESSIF_RWDT
|
||||
bool "RTC Watchdog Timer"
|
||||
default n
|
||||
select ESPRESSIF_WDT
|
||||
---help---
|
||||
Includes RWDT. This watchdog timer is from the RTC module.
|
||||
When it is selected, if the developer sets it to reset on expiration
|
||||
it will reset Main System and the RTC module. If you don't want
|
||||
to have the RTC module reset, please, use the Timers' Module WDTs.
|
||||
They will only reset Main System.
|
||||
|
||||
config ESPRESSIF_BROWNOUT_DET
|
||||
bool "Brownout Detector"
|
||||
default y
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ else
|
|||
CHIP_CSRCS += esp_timerisr.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_WATCHDOG),y)
|
||||
ifeq ($(CONFIG_ESPRESSIF_WDT),y)
|
||||
CHIP_CSRCS += esp_wdt.c
|
||||
endif
|
||||
|
||||
|
|
|
|||
|
|
@ -32,9 +32,13 @@
|
|||
|
||||
#include "esp_irq.h"
|
||||
#include "esp_wdt.h"
|
||||
#include "esp_clk.h"
|
||||
#include "esp_rtc_gpio.h"
|
||||
|
||||
#include "hal/mwdt_ll.h"
|
||||
#include "hal/rwdt_ll.h"
|
||||
#include "hal/wdt_hal.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "periph_ctrl.h"
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -43,24 +47,52 @@
|
|||
|
||||
/* MWDT clock period in microseconds */
|
||||
|
||||
#define MWDT_CLK_PERIOD_US (500)
|
||||
#define MWDT_CLK_PERIOD_US (500)
|
||||
|
||||
/* Number of MWDT cycles per microseconds */
|
||||
|
||||
#define MWDT_CYCLES_PER_MS (USEC_PER_MSEC / MWDT_CLK_PERIOD_US)
|
||||
#define MWDT_CYCLES_PER_MS (USEC_PER_MSEC / MWDT_CLK_PERIOD_US)
|
||||
|
||||
/* Convert MWDT timeout cycles to milliseconds */
|
||||
|
||||
#define MWDT_TIMEOUT_MS(t) ((t) * MWDT_CYCLES_PER_MS)
|
||||
#define MWDT_TIMEOUT_MS(t) ((t) * MWDT_CYCLES_PER_MS)
|
||||
|
||||
/* Maximum number of MWDT cycles supported for timeout */
|
||||
|
||||
#define MWDT_MAX_TIMEOUT_MS (UINT32_MAX / MWDT_CYCLES_PER_MS)
|
||||
#define MWDT_MAX_TIMEOUT_MS (UINT32_MAX / MWDT_CYCLES_PER_MS)
|
||||
|
||||
/* Maximum number of cycles supported for a RWDT stage timeout */
|
||||
|
||||
#define RWDT_FULL_STAGE (UINT32_MAX)
|
||||
|
||||
/* Convert RWDT timeout cycles to milliseconds */
|
||||
|
||||
#define RWDT_TIMEOUT_MS(t) (t * rtc_clk_slow_freq_get_hz() / 1000ULL)
|
||||
|
||||
#define WDT_INTR_ENABLE(timer, ctx, en) (timer == RTC ? \
|
||||
rwdt_ll_set_intr_enable(ctx->rwdt_dev, en) : \
|
||||
mwdt_ll_set_intr_enable(ctx->mwdt_dev, en))
|
||||
|
||||
/* Helpers for converting from Q13.19 fixed-point format to float */
|
||||
|
||||
#define N 19
|
||||
#define Q_TO_FLOAT(x) ((float)x/(float)(1<<N))
|
||||
|
||||
#if defined(CONFIG_ARCH_CHIP_ESP32C6) || defined(CONFIG_ARCH_CHIP_ESP32H2)
|
||||
#define RTC_CORE_INTR_SOURCE LP_WDT_INTR_SOURCE
|
||||
#define ESP_IRQ_RTC_CORE ESP_IRQ_LP_WDT
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RTC,
|
||||
TIMER,
|
||||
} wdt_peripherals_t;
|
||||
|
||||
/* This structure provides the private representation of the "lower-half"
|
||||
* driver state structure. This structure must be cast-compatible with the
|
||||
* well-known watchdog_lowerhalf_s structure.
|
||||
|
|
@ -68,13 +100,17 @@
|
|||
|
||||
struct esp_wdt_lowerhalf_s
|
||||
{
|
||||
const struct watchdog_ops_s *ops; /* Lower half operations */
|
||||
uint32_t timeout; /* The current timeout */
|
||||
wdt_stage_action_t action; /* The current action */
|
||||
uint32_t lastreset; /* The last reset time */
|
||||
bool started; /* True: Timer has been started */
|
||||
xcpt_t handler; /* User Handler */
|
||||
void *upper; /* Pointer to watchdog_upperhalf_s */
|
||||
const struct watchdog_ops_s *ops; /* Lower half operations */
|
||||
uint32_t timeout; /* The current timeout */
|
||||
wdt_stage_action_t action; /* The current action */
|
||||
uint32_t lastreset; /* The last reset time */
|
||||
bool started; /* True: Timer has been started */
|
||||
wdt_peripherals_t peripheral; /* Indicates if it is from RTC or Timer Module */
|
||||
xcpt_t handler; /* User Handler */
|
||||
void *upper; /* Pointer to watchdog_upperhalf_s */
|
||||
uint8_t periph; /* Peripheral ID */
|
||||
uint8_t irq; /* Interrupt ID */
|
||||
wdt_hal_context_t *ctx; /* Watchdog HAL context */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -114,17 +150,41 @@ static const struct watchdog_ops_s g_esp_wdg_ops =
|
|||
.ioctl = NULL
|
||||
};
|
||||
|
||||
/* MWDT0 lower-half */
|
||||
|
||||
static struct esp_wdt_lowerhalf_s g_esp_wdt_lowerhalf =
|
||||
{
|
||||
.ops = &g_esp_wdg_ops,
|
||||
.timeout = MWDT_MAX_TIMEOUT_MS
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_MWDT
|
||||
/* Watchdog HAL context */
|
||||
|
||||
static wdt_hal_context_t wdt_hal_ctx;
|
||||
static wdt_hal_context_t mwdt_hal_ctx;
|
||||
|
||||
/* MWDT0 lower-half */
|
||||
|
||||
static struct esp_wdt_lowerhalf_s g_esp_mwdt_lowerhalf =
|
||||
{
|
||||
.ops = &g_esp_wdg_ops,
|
||||
.timeout = MWDT_MAX_TIMEOUT_MS,
|
||||
.periph = TG0_WDT_LEVEL_INTR_SOURCE,
|
||||
.peripheral = TIMER,
|
||||
.irq = ESP_IRQ_TG0_WDT_LEVEL,
|
||||
.ctx = &mwdt_hal_ctx
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_RWDT
|
||||
/* Watchdog HAL context */
|
||||
|
||||
static wdt_hal_context_t rwdt_hal_ctx = RWDT_HAL_CONTEXT_DEFAULT();
|
||||
|
||||
/* RWDT lower-half */
|
||||
|
||||
static struct esp_wdt_lowerhalf_s g_esp_rwdt_lowerhalf =
|
||||
{
|
||||
.ops = &g_esp_wdg_ops,
|
||||
.timeout = RWDT_FULL_STAGE,
|
||||
.periph = RTC_CORE_INTR_SOURCE,
|
||||
.peripheral = RTC,
|
||||
.irq = ESP_IRQ_RTC_CORE,
|
||||
.ctx = &rwdt_hal_ctx
|
||||
};
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
|
|
@ -152,6 +212,7 @@ static int wdt_start(struct watchdog_lowerhalf_s *lower)
|
|||
struct esp_wdt_lowerhalf_s *priv = (struct esp_wdt_lowerhalf_s *)lower;
|
||||
int ret = OK;
|
||||
irqstate_t flags;
|
||||
uint32_t timeout;
|
||||
|
||||
wdinfo("Entry: started\n");
|
||||
|
||||
|
|
@ -166,39 +227,57 @@ static int wdt_start(struct watchdog_lowerhalf_s *lower)
|
|||
|
||||
priv->started = true;
|
||||
|
||||
wdt_hal_write_protect_disable(&wdt_hal_ctx);
|
||||
wdt_hal_write_protect_disable(priv->ctx);
|
||||
|
||||
if (priv->handler == NULL)
|
||||
{
|
||||
/* No user handler, so configure WDT to reset on timeout */
|
||||
|
||||
priv->action = WDT_STAGE_ACTION_RESET_SYSTEM;
|
||||
if (priv->peripheral == TIMER)
|
||||
{
|
||||
priv->action = WDT_STAGE_ACTION_RESET_SYSTEM;
|
||||
timeout = MWDT_TIMEOUT_MS(priv->timeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->action = WDT_STAGE_ACTION_RESET_RTC;
|
||||
timeout = RWDT_TIMEOUT_MS(priv->timeout);
|
||||
}
|
||||
|
||||
wdt_hal_config_stage(&wdt_hal_ctx, WDT_STAGE0,
|
||||
MWDT_TIMEOUT_MS(priv->timeout),
|
||||
wdt_hal_config_stage(priv->ctx, WDT_STAGE0,
|
||||
timeout,
|
||||
priv->action);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Configure WDT to call the user handler on timeout */
|
||||
|
||||
priv->action = WDT_STAGE_ACTION_INT;
|
||||
if (priv->peripheral == TIMER)
|
||||
{
|
||||
priv->action = WDT_STAGE_ACTION_INT;
|
||||
timeout = MWDT_TIMEOUT_MS(priv->timeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->action = WDT_STAGE_ACTION_INT;
|
||||
timeout = RWDT_TIMEOUT_MS(priv->timeout);
|
||||
}
|
||||
|
||||
wdt_hal_config_stage(&wdt_hal_ctx, WDT_STAGE0,
|
||||
MWDT_TIMEOUT_MS(priv->timeout),
|
||||
wdt_hal_config_stage(priv->ctx, WDT_STAGE0,
|
||||
timeout,
|
||||
priv->action);
|
||||
|
||||
/* Enable interrupt */
|
||||
|
||||
mwdt_ll_set_intr_enable(wdt_hal_ctx.mwdt_dev, true);
|
||||
WDT_INTR_ENABLE(priv->peripheral, priv->ctx, true);
|
||||
}
|
||||
|
||||
flags = enter_critical_section();
|
||||
priv->lastreset = clock_systime_ticks();
|
||||
wdt_hal_enable(&wdt_hal_ctx);
|
||||
wdt_hal_enable(priv->ctx);
|
||||
leave_critical_section(flags);
|
||||
|
||||
wdt_hal_write_protect_enable(&wdt_hal_ctx);
|
||||
wdt_hal_write_protect_enable(priv->ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -223,11 +302,11 @@ static int wdt_stop(struct watchdog_lowerhalf_s *lower)
|
|||
{
|
||||
struct esp_wdt_lowerhalf_s *priv = (struct esp_wdt_lowerhalf_s *)lower;
|
||||
|
||||
wdt_hal_write_protect_disable(&wdt_hal_ctx);
|
||||
wdt_hal_write_protect_disable(priv->ctx);
|
||||
|
||||
/* Disable the WDT */
|
||||
|
||||
wdt_hal_disable(&wdt_hal_ctx);
|
||||
wdt_hal_disable(priv->ctx);
|
||||
|
||||
/* In case there is a callback registered, ensure WDT interrupts are
|
||||
* disabled.
|
||||
|
|
@ -235,10 +314,10 @@ static int wdt_stop(struct watchdog_lowerhalf_s *lower)
|
|||
|
||||
if (priv->handler != NULL)
|
||||
{
|
||||
mwdt_ll_set_intr_enable(wdt_hal_ctx.mwdt_dev, false);
|
||||
WDT_INTR_ENABLE(priv->peripheral, priv->ctx, false);
|
||||
}
|
||||
|
||||
wdt_hal_write_protect_enable(&wdt_hal_ctx);
|
||||
wdt_hal_write_protect_enable(priv->ctx);
|
||||
|
||||
priv->started = false;
|
||||
|
||||
|
|
@ -267,16 +346,16 @@ static int wdt_keepalive(struct watchdog_lowerhalf_s *lower)
|
|||
struct esp_wdt_lowerhalf_s *priv = (struct esp_wdt_lowerhalf_s *)lower;
|
||||
irqstate_t flags;
|
||||
|
||||
wdt_hal_write_protect_disable(&wdt_hal_ctx);
|
||||
wdt_hal_write_protect_disable(priv->ctx);
|
||||
|
||||
/* Feed the dog and update the time of last reset */
|
||||
|
||||
flags = enter_critical_section();
|
||||
priv->lastreset = clock_systime_ticks();
|
||||
wdt_hal_feed(&wdt_hal_ctx);
|
||||
wdt_hal_feed(priv->ctx);
|
||||
leave_critical_section(flags);
|
||||
|
||||
wdt_hal_write_protect_enable(&wdt_hal_ctx);
|
||||
wdt_hal_write_protect_enable(priv->ctx);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
|
@ -376,24 +455,47 @@ static int wdt_settimeout(struct watchdog_lowerhalf_s *lower,
|
|||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
|
||||
wdt_hal_write_protect_disable(&wdt_hal_ctx);
|
||||
wdt_hal_write_protect_disable(priv->ctx);
|
||||
|
||||
priv->timeout = timeout;
|
||||
|
||||
if (timeout == 0 || timeout > MWDT_MAX_TIMEOUT_MS)
|
||||
if (priv->peripheral == TIMER)
|
||||
{
|
||||
wderr("ERROR: Cannot represent timeout=%" PRIu32 " > %" PRIu32 "\n",
|
||||
timeout, MWDT_MAX_TIMEOUT_MS);
|
||||
return -ERANGE;
|
||||
if (timeout == 0 || timeout > MWDT_MAX_TIMEOUT_MS)
|
||||
{
|
||||
wderr("ERROR: Cannot represent timeout=%"PRIu32" > %"PRIu32"\n",
|
||||
timeout, MWDT_MAX_TIMEOUT_MS);
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
timeout = MWDT_TIMEOUT_MS(priv->timeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t period_13q19 = esp_clk_slowclk_cal_get();
|
||||
float period = Q_TO_FLOAT(period_13q19);
|
||||
rtc_cycles = 1000.0f / period;
|
||||
rtc_ms_max = (RWDT_FULL_STAGE / (uint32_t)rtc_cycles);
|
||||
|
||||
/* Is this timeout a valid value for RTC WDT? */
|
||||
|
||||
if (timeout == 0 || timeout > rtc_ms_max)
|
||||
{
|
||||
wderr("ERROR: Cannot represent timeout=%"PRIu32" > %"PRIu32"\n",
|
||||
timeout, rtc_ms_max);
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
timeout = timeout * rtc_cycles;
|
||||
}
|
||||
|
||||
wdt_hal_config_stage(&wdt_hal_ctx, WDT_STAGE0,
|
||||
MWDT_TIMEOUT_MS(priv->timeout),
|
||||
wdt_hal_config_stage(priv->ctx, WDT_STAGE0,
|
||||
timeout,
|
||||
priv->action);
|
||||
|
||||
wdt_hal_feed(&wdt_hal_ctx);
|
||||
wdt_hal_feed(priv->ctx);
|
||||
|
||||
wdt_hal_write_protect_enable(&wdt_hal_ctx);
|
||||
wdt_hal_write_protect_enable(priv->ctx);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
|
@ -425,6 +527,7 @@ static xcpt_t wdt_capture(struct watchdog_lowerhalf_s *lower, xcpt_t handler)
|
|||
struct esp_wdt_lowerhalf_s *priv = (struct esp_wdt_lowerhalf_s *)lower;
|
||||
irqstate_t flags;
|
||||
xcpt_t oldhandler;
|
||||
uint32_t timeout;
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
|
||||
|
|
@ -432,7 +535,7 @@ static xcpt_t wdt_capture(struct watchdog_lowerhalf_s *lower, xcpt_t handler)
|
|||
|
||||
oldhandler = priv->handler;
|
||||
|
||||
wdt_hal_write_protect_disable(&wdt_hal_ctx);
|
||||
wdt_hal_write_protect_disable(priv->ctx);
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
|
|
@ -453,34 +556,52 @@ static xcpt_t wdt_capture(struct watchdog_lowerhalf_s *lower, xcpt_t handler)
|
|||
* then change to interrupt.
|
||||
*/
|
||||
|
||||
if (priv->peripheral == TIMER)
|
||||
{
|
||||
timeout = MWDT_TIMEOUT_MS(priv->timeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
timeout = RWDT_TIMEOUT_MS(priv->timeout);
|
||||
}
|
||||
|
||||
priv->action = WDT_STAGE_ACTION_INT;
|
||||
|
||||
wdt_hal_config_stage(&wdt_hal_ctx, WDT_STAGE0,
|
||||
MWDT_TIMEOUT_MS(priv->timeout),
|
||||
wdt_hal_config_stage(priv->ctx, WDT_STAGE0,
|
||||
timeout,
|
||||
priv->action);
|
||||
}
|
||||
|
||||
mwdt_ll_set_intr_enable(wdt_hal_ctx.mwdt_dev, true);
|
||||
WDT_INTR_ENABLE(priv->peripheral, priv->ctx, true);
|
||||
}
|
||||
|
||||
/* In case the user wants to disable the callback */
|
||||
|
||||
else
|
||||
{
|
||||
mwdt_ll_set_intr_enable(wdt_hal_ctx.mwdt_dev, false);
|
||||
if (priv->peripheral == TIMER)
|
||||
{
|
||||
timeout = MWDT_TIMEOUT_MS(priv->timeout);
|
||||
priv->action = WDT_STAGE_ACTION_RESET_SYSTEM;
|
||||
}
|
||||
else
|
||||
{
|
||||
timeout = RWDT_TIMEOUT_MS(priv->timeout);
|
||||
priv->action = WDT_STAGE_ACTION_RESET_RTC;
|
||||
}
|
||||
|
||||
WDT_INTR_ENABLE(priv->peripheral, priv->ctx, false);
|
||||
|
||||
/* Then configure it to reset on WDT expiration */
|
||||
|
||||
priv->action = WDT_STAGE_ACTION_RESET_SYSTEM;
|
||||
|
||||
wdt_hal_config_stage(&wdt_hal_ctx, WDT_STAGE0,
|
||||
MWDT_TIMEOUT_MS(priv->timeout),
|
||||
wdt_hal_config_stage(priv->ctx, WDT_STAGE0,
|
||||
timeout,
|
||||
priv->action);
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
|
||||
wdt_hal_write_protect_enable(&wdt_hal_ctx);
|
||||
wdt_hal_write_protect_enable(priv->ctx);
|
||||
|
||||
return oldhandler;
|
||||
}
|
||||
|
|
@ -513,9 +634,9 @@ static int wdt_handler(int irq, void *context, void *arg)
|
|||
|
||||
/* Clear the Interrupt */
|
||||
|
||||
wdt_hal_write_protect_disable(&wdt_hal_ctx);
|
||||
wdt_hal_handle_intr(&wdt_hal_ctx);
|
||||
wdt_hal_write_protect_enable(&wdt_hal_ctx);
|
||||
wdt_hal_write_protect_disable(priv->ctx);
|
||||
wdt_hal_handle_intr(priv->ctx);
|
||||
wdt_hal_write_protect_enable(priv->ctx);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
|
@ -531,7 +652,9 @@ static int wdt_handler(int irq, void *context, void *arg)
|
|||
* Initialize the watchdog timer.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None.
|
||||
* devpath - The full path to the watchdog. This should
|
||||
* be of the form /dev/watchdogX
|
||||
* wdt_id - A Watchdog Timer instance to be initialized.
|
||||
*
|
||||
* Returned Values:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned on
|
||||
|
|
@ -539,18 +662,47 @@ static int wdt_handler(int irq, void *context, void *arg)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
int esp_wdt_initialize(void)
|
||||
int esp_wdt_initialize(const char *devpath, enum esp_wdt_inst_e wdt_id)
|
||||
{
|
||||
periph_module_enable(PERIPH_TIMG0_MODULE);
|
||||
wdt_hal_init(&wdt_hal_ctx, WDT_MWDT0, MWDT_LL_DEFAULT_CLK_PRESCALER, true);
|
||||
struct esp_wdt_lowerhalf_s *lower = NULL;
|
||||
|
||||
struct esp_wdt_lowerhalf_s *lower = &g_esp_wdt_lowerhalf;
|
||||
switch (wdt_id)
|
||||
{
|
||||
#ifdef CONFIG_ESPRESSIF_MWDT
|
||||
case ESP_WDT_MWDT:
|
||||
{
|
||||
lower = &g_esp_mwdt_lowerhalf;
|
||||
periph_module_enable(PERIPH_TIMG0_MODULE);
|
||||
wdt_hal_init(lower->ctx, WDT_MWDT0,
|
||||
MWDT_LL_DEFAULT_CLK_PRESCALER, true);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_RWDT
|
||||
case ESP_WDT_RWDT:
|
||||
{
|
||||
lower = &g_esp_rwdt_lowerhalf;
|
||||
wdt_hal_init(lower->ctx, WDT_RWDT, 0, true);
|
||||
esp_rtcioirqenable(lower->irq);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
default:
|
||||
{
|
||||
wderr("ERROR: unsupported WDT %d\n", wdt_id);
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize the elements of lower half state structure */
|
||||
|
||||
lower->handler = NULL;
|
||||
lower->timeout = 0;
|
||||
lower->started = wdt_hal_is_enabled(&wdt_hal_ctx);
|
||||
lower->started = wdt_hal_is_enabled(lower->ctx);
|
||||
|
||||
/* Register the watchdog driver as /dev/watchdogX. If the registration goes
|
||||
* right the returned value from watchdog_register is a pointer to
|
||||
|
|
@ -558,7 +710,7 @@ int esp_wdt_initialize(void)
|
|||
* or with the handler's arg.
|
||||
*/
|
||||
|
||||
lower->upper = watchdog_register(CONFIG_WATCHDOG_DEVPATH,
|
||||
lower->upper = watchdog_register(devpath,
|
||||
(struct watchdog_lowerhalf_s *)lower);
|
||||
if (lower->upper == NULL)
|
||||
{
|
||||
|
|
@ -571,17 +723,17 @@ int esp_wdt_initialize(void)
|
|||
return -EEXIST;
|
||||
}
|
||||
|
||||
esp_setup_irq(TG0_WDT_LEVEL_INTR_SOURCE,
|
||||
esp_setup_irq(lower->periph,
|
||||
ESP_IRQ_PRIORITY_DEFAULT,
|
||||
ESP_IRQ_TRIGGER_LEVEL);
|
||||
|
||||
/* Attach the handler for the timer IRQ */
|
||||
|
||||
irq_attach(ESP_IRQ_TG0_WDT_LEVEL, (xcpt_t)wdt_handler, lower);
|
||||
irq_attach(lower->irq, (xcpt_t)wdt_handler, lower);
|
||||
|
||||
/* Enable the allocated CPU interrupt */
|
||||
|
||||
up_enable_irq(ESP_IRQ_TG0_WDT_LEVEL);
|
||||
up_enable_irq(lower->irq);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,18 @@
|
|||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/* Instances of Watchdog Timer */
|
||||
|
||||
enum esp_wdt_inst_e
|
||||
{
|
||||
ESP_WDT_MWDT = 0, /* Main System Watchdog Timer (MWDT) of Timer Group 0 */
|
||||
ESP_WDT_RWDT /* RTC Watchdog Timer (RWDT) */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
|
@ -38,7 +50,9 @@
|
|||
* Initialize the watchdog timer.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None.
|
||||
* devpath - The full path to the watchdog. This should
|
||||
* be of the form /dev/watchdogX
|
||||
* wdt_id - A Watchdog Timer instance to be initialized.
|
||||
*
|
||||
* Returned Values:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned on
|
||||
|
|
@ -46,6 +60,6 @@
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
int esp_wdt_initialize(void);
|
||||
int esp_wdt_initialize(const char *devpath, enum esp_wdt_inst_e wdt_id);
|
||||
|
||||
#endif /* __ARCH_RISCV_SRC_COMMON_ESPRESSIF_ESP_WDT_H */
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ CONFIG_ARCH_STACKDUMP=y
|
|||
CONFIG_BOARD_LOOPSPERMSEC=15000
|
||||
CONFIG_BUILTIN=y
|
||||
CONFIG_DEV_ZERO=y
|
||||
CONFIG_ESPRESSIF_MWDT=y
|
||||
CONFIG_EXAMPLES_WATCHDOG=y
|
||||
CONFIG_FS_PROCFS=y
|
||||
CONFIG_IDLETHREAD_STACKSIZE=2048
|
||||
|
|
@ -44,4 +45,3 @@ CONFIG_SYSTEM_NSH=y
|
|||
CONFIG_TESTING_GETPRIME=y
|
||||
CONFIG_TESTING_OSTEST=y
|
||||
CONFIG_UART0_SERIAL_CONSOLE=y
|
||||
CONFIG_WATCHDOG=y
|
||||
|
|
|
|||
|
|
@ -128,8 +128,16 @@ int esp_bringup(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_WATCHDOG
|
||||
ret = esp_wdt_initialize();
|
||||
#ifdef CONFIG_ESPRESSIF_MWDT
|
||||
ret = esp_wdt_initialize("/dev/watchdog0", ESP_WDT_MWDT);
|
||||
if (ret < 0)
|
||||
{
|
||||
_err("Failed to initialize WDT: %d\n", ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_RWDT
|
||||
ret = esp_wdt_initialize("/dev/watchdog1", ESP_WDT_RWDT);
|
||||
if (ret < 0)
|
||||
{
|
||||
_err("Failed to initialize WDT: %d\n", ret);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ CONFIG_BOARD_LOOPSPERMSEC=15000
|
|||
CONFIG_BUILTIN=y
|
||||
CONFIG_DEV_ZERO=y
|
||||
CONFIG_ESPRESSIF_ESP32C6=y
|
||||
CONFIG_ESPRESSIF_MWDT=y
|
||||
CONFIG_EXAMPLES_WATCHDOG=y
|
||||
CONFIG_FS_PROCFS=y
|
||||
CONFIG_IDLETHREAD_STACKSIZE=2048
|
||||
|
|
@ -46,4 +47,3 @@ CONFIG_SYSTEM_NSH=y
|
|||
CONFIG_TESTING_GETPRIME=y
|
||||
CONFIG_TESTING_OSTEST=y
|
||||
CONFIG_UART0_SERIAL_CONSOLE=y
|
||||
CONFIG_WATCHDOG=y
|
||||
|
|
|
|||
|
|
@ -128,8 +128,16 @@ int esp_bringup(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_WATCHDOG
|
||||
ret = esp_wdt_initialize();
|
||||
#ifdef CONFIG_ESPRESSIF_MWDT
|
||||
ret = esp_wdt_initialize("/dev/watchdog0", ESP_WDT_MWDT);
|
||||
if (ret < 0)
|
||||
{
|
||||
_err("Failed to initialize WDT: %d\n", ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_RWDT
|
||||
ret = esp_wdt_initialize("/dev/watchdog1", ESP_WDT_RWDT);
|
||||
if (ret < 0)
|
||||
{
|
||||
_err("Failed to initialize WDT: %d\n", ret);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ CONFIG_BOARD_LOOPSPERMSEC=15000
|
|||
CONFIG_BUILTIN=y
|
||||
CONFIG_DEV_ZERO=y
|
||||
CONFIG_ESPRESSIF_ESP32C6=y
|
||||
CONFIG_ESPRESSIF_MWDT=y
|
||||
CONFIG_EXAMPLES_WATCHDOG=y
|
||||
CONFIG_FS_PROCFS=y
|
||||
CONFIG_IDLETHREAD_STACKSIZE=2048
|
||||
|
|
@ -46,4 +47,3 @@ CONFIG_SYSTEM_NSH=y
|
|||
CONFIG_TESTING_GETPRIME=y
|
||||
CONFIG_TESTING_OSTEST=y
|
||||
CONFIG_UART0_SERIAL_CONSOLE=y
|
||||
CONFIG_WATCHDOG=y
|
||||
|
|
|
|||
|
|
@ -128,8 +128,16 @@ int esp_bringup(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_WATCHDOG
|
||||
ret = esp_wdt_initialize();
|
||||
#ifdef CONFIG_ESPRESSIF_MWDT
|
||||
ret = esp_wdt_initialize("/dev/watchdog0", ESP_WDT_MWDT);
|
||||
if (ret < 0)
|
||||
{
|
||||
_err("Failed to initialize WDT: %d\n", ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_RWDT
|
||||
ret = esp_wdt_initialize("/dev/watchdog1", ESP_WDT_RWDT);
|
||||
if (ret < 0)
|
||||
{
|
||||
_err("Failed to initialize WDT: %d\n", ret);
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ CONFIG_BOARD_LOOPSPERMSEC=15000
|
|||
CONFIG_BUILTIN=y
|
||||
CONFIG_DEV_ZERO=y
|
||||
CONFIG_ESPRESSIF_ESP32H2=y
|
||||
CONFIG_ESPRESSIF_MWDT=y
|
||||
CONFIG_EXAMPLES_WATCHDOG=y
|
||||
CONFIG_FS_PROCFS=y
|
||||
CONFIG_IDLETHREAD_STACKSIZE=2048
|
||||
|
|
@ -45,4 +46,3 @@ CONFIG_SYSTEM_NSH=y
|
|||
CONFIG_TESTING_GETPRIME=y
|
||||
CONFIG_TESTING_OSTEST=y
|
||||
CONFIG_UART0_SERIAL_CONSOLE=y
|
||||
CONFIG_WATCHDOG=y
|
||||
|
|
|
|||
|
|
@ -120,8 +120,16 @@ int esp_bringup(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_WATCHDOG
|
||||
ret = esp_wdt_initialize();
|
||||
#ifdef CONFIG_ESPRESSIF_MWDT
|
||||
ret = esp_wdt_initialize("/dev/watchdog0", ESP_WDT_MWDT);
|
||||
if (ret < 0)
|
||||
{
|
||||
_err("Failed to initialize WDT: %d\n", ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_RWDT
|
||||
ret = esp_wdt_initialize("/dev/watchdog1", ESP_WDT_RWDT);
|
||||
if (ret < 0)
|
||||
{
|
||||
_err("Failed to initialize WDT: %d\n", ret);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue