You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ag...@apache.org on 2020/12/16 13:37:53 UTC

[incubator-nuttx] 02/02: xtensa/esp32: Added support for RTC WDT

This is an automated email from the ASF dual-hosted git repository.

aguettouche pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit add46d04082ab031450ad96dd85fc6176278e31d
Author: Sara Souza <sa...@espressif.com>
AuthorDate: Wed Dec 2 20:02:08 2020 -0300

    xtensa/esp32: Added support for RTC WDT
---
 arch/xtensa/src/esp32/Kconfig                      | 11 +++
 arch/xtensa/src/esp32/esp32_wtd.c                  | 97 ++++++++++------------
 arch/xtensa/src/esp32/esp32_wtd_lowerhalf.c        |  2 +-
 arch/xtensa/src/esp32/hardware/esp32_rtccntl.h     |  2 +-
 .../esp32/esp32-devkitc/configs/watchdog/defconfig |  1 +
 5 files changed, 60 insertions(+), 53 deletions(-)

diff --git a/arch/xtensa/src/esp32/Kconfig b/arch/xtensa/src/esp32/Kconfig
index 0a4a19d..6d535f9 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 9bd7aa5..624fb9a 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<<N))
+
 /****************************************************************************
  * Private Types
  ****************************************************************************/
@@ -55,8 +61,6 @@ struct esp32_wtd_priv_s
 
 /* WTD registers access *****************************************************/
 
-static uint32_t esp32_wtd_getreg(FAR struct esp32_wtd_dev_s *dev,
-                                 uint32_t offset);
 static void esp32_wtd_putreg(FAR struct esp32_wtd_dev_s *dev,
                              uint32_t offset,
                              uint32_t value);
@@ -168,22 +172,6 @@ struct esp32_wtd_priv_s g_esp32_rwtd_priv =
  ****************************************************************************/
 
 /****************************************************************************
- * Name: esp32_wtd_getreg
- *
- * Description:
- *   Get a 32-bit register value by offset
- *
- ****************************************************************************/
-
-static uint32_t esp32_wtd_getreg(FAR struct esp32_wtd_dev_s *dev,
-                                 uint32_t offset)
-{
-  DEBUGASSERT(dev);
-
-  return getreg32(((struct esp32_wtd_priv_s *)dev)->base + offset);
-}
-
-/****************************************************************************
  * Name: esp32_wtd_putreg
  *
  * Description:
@@ -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();
+
+  /* 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 = (uint8_t)(corrected_frequency / 1000);
+  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 208f372..0555252 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 f5d479c..bca54d1 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 3808258..5ed701b 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