diff --git a/arch/xtensa/src/esp32/Kconfig b/arch/xtensa/src/esp32/Kconfig index 0a4a19dda0e..6d535f9bc78 100644 --- a/arch/xtensa/src/esp32/Kconfig +++ b/arch/xtensa/src/esp32/Kconfig @@ -223,6 +223,17 @@ config ESP32_MWDT1 Includes MWDT1. This watchdog timer is part of the Group 0 timer submodule. +config ESP32_RWDT + bool "RTC Watchdog Timer" + default n + select ESP32_WTD + ---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 ESP32_UART0 bool "UART 0" default n diff --git a/arch/xtensa/src/esp32/esp32_wtd.c b/arch/xtensa/src/esp32/esp32_wtd.c index 9bd7aa5123b..624fb9a2d8e 100644 --- a/arch/xtensa/src/esp32/esp32_wtd.c +++ b/arch/xtensa/src/esp32/esp32_wtd.c @@ -30,11 +30,17 @@ #include "hardware/esp32_rtccntl.h" #include "esp32_wtd.h" #include "esp32_cpuint.h" +#include "esp32_rtc.h" /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ +/* Helpers for converting from Q13.19 fixed-point format to float */ + +#define N 19 +#define Q_TO_FLOAT(x) ((float)x/(float)(1<base + offset); -} - /**************************************************************************** * Name: esp32_wtd_putreg * @@ -234,7 +222,7 @@ static int esp32_wtd_start(FAR struct esp32_wtd_dev_s *dev) /* If it is a RWDT */ if (((struct esp32_wtd_priv_s *)dev)->base == - RTC_CNTL_WDTCONFIG0_REG) + RTC_CNTL_OPTIONS0_REG) { esp32_wtd_modifyreg32(dev, RWDT_CONFIG0_OFFSET, 0, RTC_CNTL_WDT_EN); } @@ -277,7 +265,7 @@ static int esp32_wtd_set_stg_conf(FAR struct esp32_wtd_dev_s *dev, /* If it is a RWDT */ if (((struct esp32_wtd_priv_s *)dev)->base == - RTC_CNTL_WDTCONFIG0_REG) + RTC_CNTL_OPTIONS0_REG) { mask = (uint32_t)conf << RTC_CNTL_WDT_STG0_S; esp32_wtd_modifyreg32(dev, RWDT_CONFIG0_OFFSET, @@ -300,7 +288,7 @@ static int esp32_wtd_set_stg_conf(FAR struct esp32_wtd_dev_s *dev, /* If it is a RWDT */ if (((struct esp32_wtd_priv_s *)dev)->base == - RTC_CNTL_WDTCONFIG0_REG) + RTC_CNTL_OPTIONS0_REG) { mask = (uint32_t)conf << RTC_CNTL_WDT_STG1_S; esp32_wtd_modifyreg32(dev, RWDT_CONFIG0_OFFSET, @@ -323,7 +311,7 @@ static int esp32_wtd_set_stg_conf(FAR struct esp32_wtd_dev_s *dev, /* If it is a RWDT */ if (((struct esp32_wtd_priv_s *)dev)->base == - RTC_CNTL_WDTCONFIG0_REG) + RTC_CNTL_OPTIONS0_REG) { mask = (uint32_t)conf << RTC_CNTL_WDT_STG2_S; esp32_wtd_modifyreg32(dev, RWDT_CONFIG0_OFFSET, @@ -346,7 +334,7 @@ static int esp32_wtd_set_stg_conf(FAR struct esp32_wtd_dev_s *dev, /* If it is a RWDT */ if (((struct esp32_wtd_priv_s *)dev)->base == - RTC_CNTL_WDTCONFIG0_REG) + RTC_CNTL_OPTIONS0_REG) { mask = (uint32_t)conf << RTC_CNTL_WDT_STG3_S; esp32_wtd_modifyreg32(dev, RWDT_CONFIG0_OFFSET, @@ -390,7 +378,7 @@ static int esp32_wtd_stop(FAR struct esp32_wtd_dev_s *dev) /* If it is a RWDT */ - if (((struct esp32_wtd_priv_s *)dev)->base == RTC_CNTL_WDTCONFIG0_REG) + if (((struct esp32_wtd_priv_s *)dev)->base == RTC_CNTL_OPTIONS0_REG) { esp32_wtd_modifyreg32(dev, RWDT_CONFIG0_OFFSET, RTC_CNTL_WDT_EN, 0); } @@ -423,7 +411,7 @@ static int esp32_wtd_enablewp(FAR struct esp32_wtd_dev_s *dev) /* If it is a RWDT */ - if (((struct esp32_wtd_priv_s *)dev)->base == RTC_CNTL_WDTCONFIG0_REG) + if (((struct esp32_wtd_priv_s *)dev)->base == RTC_CNTL_OPTIONS0_REG) { esp32_wtd_putreg(dev, RWDT_WP_REG, 0); } @@ -456,7 +444,7 @@ static int esp32_wtd_disablewp(FAR struct esp32_wtd_dev_s *dev) /* If it is a RWDT */ - if (((struct esp32_wtd_priv_s *)dev)->base == RTC_CNTL_WDTCONFIG0_REG) + if (((struct esp32_wtd_priv_s *)dev)->base == RTC_CNTL_OPTIONS0_REG) { esp32_wtd_putreg(dev, RWDT_WP_REG, WRITE_PROTECTION_KEY); } @@ -504,28 +492,35 @@ static int esp32_wtd_pre(FAR struct esp32_wtd_dev_s *dev, uint16_t pre) static uint16_t esp32_rtc_clk(FAR struct esp32_wtd_dev_s *dev) { - uint32_t reg_value = 0; - uint8_t cycles_ms = 0; - uint32_t corrected_frequency = 0; + enum esp32_rtc_slow_freq_e slow_clk_rtc; + uint32_t period_13q19; + float period; + float cycles_ms; + uint16_t cycles_ms_int; DEBUGASSERT(dev); - reg_value = esp32_wtd_getreg(dev, RCLK_CONF_REG_OFFSET); + /* Check which clock is sourcing the slow_clk_rtc */ - if ((reg_value & CK8M_D256_OUT_MASK) == CK8M_D256_OUT_MASK) - { - /* TODO: get the correct RTC frequency using the RTC driver API */ - } - else if ((reg_value & CK_XTAL_32K_MASK) == CK_XTAL_32K_MASK) - { - /* TODO: get the correct RTC frequency using the RTC driver API */ - } - else - { - /* TODO: get the correct RTC frequency using the RTC driver API */ - } + slow_clk_rtc = esp32_rtc_get_slow_clk(); - return cycles_ms = (uint8_t)(corrected_frequency / 1000); + /* Get the slow_clk_rtc period in us in Q13.19 fixed point format */ + + period_13q19 = esp32_rtc_clk_cal(slow_clk_rtc, SLOW_CLK_CAL_CYCLES); + + /* Convert from Q13.19 format to float */ + + period = Q_TO_FLOAT(period_13q19); + + /* Get the number of cycles necessary to count 1 ms */ + + cycles_ms = 1000.0 / period; + + /* Get the integer number of cycles */ + + cycles_ms_int = (uint16_t)cycles_ms; + + return cycles_ms_int; } /**************************************************************************** @@ -549,7 +544,7 @@ static int esp32_wtd_settimeout(FAR struct esp32_wtd_dev_s *dev, /* If it is a RWDT */ if (((struct esp32_wtd_priv_s *)dev)->base == - RTC_CNTL_WDTCONFIG0_REG) + RTC_CNTL_OPTIONS0_REG) { esp32_wtd_putreg(dev, RWDT_STAGE0_TIMEOUT_OFFSET, value); } @@ -568,7 +563,7 @@ static int esp32_wtd_settimeout(FAR struct esp32_wtd_dev_s *dev, /* If it is a RWDT */ if (((struct esp32_wtd_priv_s *)dev)->base == - RTC_CNTL_WDTCONFIG0_REG) + RTC_CNTL_OPTIONS0_REG) { esp32_wtd_putreg(dev, RWDT_STAGE1_TIMEOUT_OFFSET, value); } @@ -587,7 +582,7 @@ static int esp32_wtd_settimeout(FAR struct esp32_wtd_dev_s *dev, /* If it is a RWDT */ if (((struct esp32_wtd_priv_s *)dev)->base == - RTC_CNTL_WDTCONFIG0_REG) + RTC_CNTL_OPTIONS0_REG) { esp32_wtd_putreg(dev, RWDT_STAGE2_TIMEOUT_OFFSET, value); } @@ -606,7 +601,7 @@ static int esp32_wtd_settimeout(FAR struct esp32_wtd_dev_s *dev, /* If it is a RWDT */ if (((struct esp32_wtd_priv_s *)dev)->base == - RTC_CNTL_WDTCONFIG0_REG) + RTC_CNTL_OPTIONS0_REG) { esp32_wtd_putreg(dev, RWDT_STAGE3_TIMEOUT_OFFSET, value); } @@ -647,7 +642,7 @@ static int esp32_wtd_feed_dog(FAR struct esp32_wtd_dev_s *dev) /* If it is a RWDT */ - if (((struct esp32_wtd_priv_s *)dev)->base == RTC_CNTL_WDTCONFIG0_REG) + if (((struct esp32_wtd_priv_s *)dev)->base == RTC_CNTL_OPTIONS0_REG) { esp32_wtd_putreg(dev, RWDT_FEED_OFFSET , FEED_DOG); } @@ -768,7 +763,7 @@ static int esp32_wtd_enableint(FAR struct esp32_wtd_dev_s *dev) /* If it is a RWDT */ - if (((struct esp32_wtd_priv_s *)dev)->base == RTC_CNTL_WDTCONFIG0_REG) + if (((struct esp32_wtd_priv_s *)dev)->base == RTC_CNTL_OPTIONS0_REG) { /* Level Interrupt */ @@ -813,7 +808,7 @@ static int esp32_wtd_disableint(FAR struct esp32_wtd_dev_s *dev) /* If it is a RWDT */ - if (((struct esp32_wtd_priv_s *)dev)->base == RTC_CNTL_WDTCONFIG0_REG) + if (((struct esp32_wtd_priv_s *)dev)->base == RTC_CNTL_OPTIONS0_REG) { /* Level Interrupt */ @@ -858,7 +853,7 @@ static int esp32_wtd_ackint(FAR struct esp32_wtd_dev_s *dev) /* If it is a RWDT */ - if (((struct esp32_wtd_priv_s *)dev)->base == RTC_CNTL_WDTCONFIG0_REG) + if (((struct esp32_wtd_priv_s *)dev)->base == RTC_CNTL_OPTIONS0_REG) { esp32_wtd_putreg(dev, RWDT_INT_CLR_REG_OFFSET, RTC_CNTL_WDT_INT_CLR); } diff --git a/arch/xtensa/src/esp32/esp32_wtd_lowerhalf.c b/arch/xtensa/src/esp32/esp32_wtd_lowerhalf.c index 208f3720076..05552524126 100644 --- a/arch/xtensa/src/esp32/esp32_wtd_lowerhalf.c +++ b/arch/xtensa/src/esp32/esp32_wtd_lowerhalf.c @@ -408,7 +408,7 @@ static int esp32_wtd_settimeout(FAR struct watchdog_lowerhalf_s *lower, { FAR struct esp32_wtd_lowerhalf_s *priv = (FAR struct esp32_wtd_lowerhalf_s *)lower; - uint8_t rtc_cycles = 0; + uint16_t rtc_cycles = 0; uint32_t rtc_ms_max = 0; wdinfo("Entry: timeout=%d\n", timeout); diff --git a/arch/xtensa/src/esp32/hardware/esp32_rtccntl.h b/arch/xtensa/src/esp32/hardware/esp32_rtccntl.h index f5d479cef4b..bca54d1d15b 100644 --- a/arch/xtensa/src/esp32/hardware/esp32_rtccntl.h +++ b/arch/xtensa/src/esp32/hardware/esp32_rtccntl.h @@ -57,7 +57,7 @@ #define CK_XTAL_32K_MASK (BIT(30)) #define CK8M_D256_OUT_MASK (BIT(31)) -#define RTC_CNTL_OPTIONS0_REG (DR_REG_RTCCNTL_BASE + 0x0) +#define RTC_CNTL_OPTIONS0_REG (DR_REG_RTCCNTL_BASE + 0x0) /* RTC_CNTL_SW_SYS_RST : WO ;bitpos:[31] ;default: 1'd0 ; */ diff --git a/boards/xtensa/esp32/esp32-devkitc/configs/watchdog/defconfig b/boards/xtensa/esp32/esp32-devkitc/configs/watchdog/defconfig index 38082587afa..5ed701b603e 100644 --- a/boards/xtensa/esp32/esp32-devkitc/configs/watchdog/defconfig +++ b/boards/xtensa/esp32/esp32-devkitc/configs/watchdog/defconfig @@ -20,6 +20,7 @@ CONFIG_BOARD_LOOPSPERMSEC=16717 CONFIG_BUILTIN=y CONFIG_ESP32_MWDT0=y CONFIG_ESP32_MWDT1=y +CONFIG_ESP32_RWDT=y CONFIG_ESP32_UART0=y CONFIG_EXAMPLES_WATCHDOG=y CONFIG_FS_PROCFS=y