xtensa/esp32: Added support for RTC WDT

This commit is contained in:
Sara Souza 2020-12-02 20:02:08 -03:00 committed by Abdelatif Guettouche
parent be12c79c52
commit add46d0408
5 changed files with 60 additions and 53 deletions

View File

@ -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

View File

@ -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);
@ -167,22 +171,6 @@ struct esp32_wtd_priv_s g_esp32_rwtd_priv =
* Private Functions
****************************************************************************/
/****************************************************************************
* 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
*
@ -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);
}

View File

@ -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);

View File

@ -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 ; */

View File

@ -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