diff --git a/Documentation/platforms/xtensa/esp32s3/index.rst b/Documentation/platforms/xtensa/esp32s3/index.rst index b2560f5747..2229f65fa1 100644 --- a/Documentation/platforms/xtensa/esp32s3/index.rst +++ b/Documentation/platforms/xtensa/esp32s3/index.rst @@ -106,7 +106,7 @@ Pulse_CNT No RMT No RNG No RSA No -RTC No +RTC Yes SD/MMC No SDIO No SHA No diff --git a/arch/xtensa/src/esp32s3/esp32s3_wdt.c b/arch/xtensa/src/esp32s3/esp32s3_wdt.c index 855a5dcae0..f9b29439f3 100644 --- a/arch/xtensa/src/esp32s3/esp32s3_wdt.c +++ b/arch/xtensa/src/esp32s3/esp32s3_wdt.c @@ -37,15 +37,17 @@ #include "esp32s3_irq.h" #include "esp32s3_rtc_gpio.h" #include "esp32s3_wdt.h" - -#ifdef CONFIG_ESP32S3_RWDT -# error "RWDT not yet supported due to missing RTC driver!" -#endif +#include /**************************************************************************** * 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 == \ @@ -98,6 +100,7 @@ static int32_t wdt_setisr(struct esp32s3_wdt_dev_s *dev, static void wdt_enableint(struct esp32s3_wdt_dev_s *dev); static void wdt_disableint(struct esp32s3_wdt_dev_s *dev); static void wdt_ackint(struct esp32s3_wdt_dev_s *dev); +static uint16_t wdt_rtc_clk(struct esp32s3_wdt_dev_s *dev); /**************************************************************************** * Private Data @@ -132,7 +135,7 @@ struct esp32s3_wdt_ops_s esp32s3_rwdt_ops = .settimeout = wdt_settimeout, .feed = wdt_feed, .stg_conf = wdt_config_stage, - .rtc_clk = NULL, + .rtc_clk = wdt_rtc_clk, .setisr = wdt_setisr, .enableint = wdt_enableint, .disableint = wdt_disableint, @@ -599,6 +602,70 @@ static void wdt_feed(struct esp32s3_wdt_dev_s *dev) } } +/**************************************************************************** + * Name: wdt_rtc_clk + * + * Description: + * Check the RTC clock source and return the necessary cycles to complete + * 1 ms. + * + * Parameters: + * dev - Pointer to the driver state structure. + * + * Returned Values: + * Number of cycles to complete 1 ms. + * + ****************************************************************************/ + +static uint16_t wdt_rtc_clk(struct esp32s3_wdt_dev_s *dev) +{ + enum esp32s3_rtc_slow_freq_e slow_clk_rtc; + uint32_t period_13q19; + float period; + float cycles_ms; + uint16_t cycles_ms_int; + + /* Calibration map: Maps each RTC SLOW_CLK source to the number + * used to calibrate this source. + */ + + static const enum esp32s3_rtc_cal_sel_e cal_map[] = + { + RTC_CAL_RTC_MUX, + RTC_CAL_32K_XTAL, + RTC_CAL_8MD256 + }; + + DEBUGASSERT(dev); + + /* Check which clock is sourcing the slow_clk_rtc */ + + slow_clk_rtc = esp32s3_rtc_get_slow_clk(); + + /* Get the slow_clk_rtc period in us in Q13.19 fixed point format */ + + period_13q19 = esp32s3_rtc_clk_cal(cal_map[slow_clk_rtc], + SLOW_CLK_CAL_CYCLES); + + /* Assert no error happened during the calibration */ + + DEBUGASSERT(period_13q19 != 0); + + /* 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; +} + /**************************************************************************** * Name: wdt_setisr * diff --git a/arch/xtensa/src/esp32s3/hardware/esp32s3_rtccntl.h b/arch/xtensa/src/esp32s3/hardware/esp32s3_rtccntl.h index 793ebbf50f..de7bd750a7 100644 --- a/arch/xtensa/src/esp32s3/hardware/esp32s3_rtccntl.h +++ b/arch/xtensa/src/esp32s3/hardware/esp32s3_rtccntl.h @@ -33,16 +33,16 @@ /* Offset relative to each watchdog timer instance memory base */ -#define RWDT_CONFIG0_OFFSET 0x0090 +#define RWDT_CONFIG0_OFFSET 0x0098 /* RWDT */ -#define RWDT_STAGE0_TIMEOUT_OFFSET 0x0094 -#define RWDT_STAGE1_TIMEOUT_OFFSET 0x0098 -#define RWDT_STAGE2_TIMEOUT_OFFSET 0x009c -#define RWDT_STAGE3_TIMEOUT_OFFSET 0x00a0 -#define RWDT_FEED_OFFSET 0x00a4 -#define RWDT_WP_REG 0x00a8 +#define RWDT_STAGE0_TIMEOUT_OFFSET 0x009C +#define RWDT_STAGE1_TIMEOUT_OFFSET 0x00A0 +#define RWDT_STAGE2_TIMEOUT_OFFSET 0x00A4 +#define RWDT_STAGE3_TIMEOUT_OFFSET 0x00A8 +#define RWDT_FEED_OFFSET 0x00AC +#define RWDT_WP_REG 0x00B0 #define RWDT_INT_ENA_REG_OFFSET 0x0040 #define RWDT_INT_CLR_REG_OFFSET 0x004c diff --git a/boards/xtensa/esp32s3/esp32s3-devkit/configs/watchdog/defconfig b/boards/xtensa/esp32s3/esp32s3-devkit/configs/watchdog/defconfig index 67c46267a0..76555ca23d 100644 --- a/boards/xtensa/esp32s3/esp32s3-devkit/configs/watchdog/defconfig +++ b/boards/xtensa/esp32s3/esp32s3-devkit/configs/watchdog/defconfig @@ -24,6 +24,7 @@ CONFIG_DEBUG_FULLOPT=y CONFIG_DEBUG_SYMBOLS=y CONFIG_ESP32S3_MWDT0=y CONFIG_ESP32S3_MWDT1=y +CONFIG_ESP32S3_RWDT=y CONFIG_ESP32S3_UART0=y CONFIG_EXAMPLES_WATCHDOG=y CONFIG_FS_PROCFS=y