wdt: add support for WDTs on C6

This commit is contained in:
Marius Vikhammer 2023-01-13 11:36:19 +08:00
parent 8f82c5cdee
commit 5e9e8c396f
30 changed files with 599 additions and 48 deletions

View File

@ -42,6 +42,10 @@ if(CONFIG_SOC_SYSTIMER_SUPPORTED)
list(APPEND sources "patches/esp_rom_systimer.c")
endif()
if(CONFIG_HAL_WDT_USE_ROM_IMPL)
list(APPEND sources "patches/esp_rom_wdt.c")
endif()
idf_component_register(SRCS ${sources}
INCLUDE_DIRS ${include_dirs}
PRIV_REQUIRES ${private_required_comp}
@ -115,6 +119,7 @@ if(BOOTLOADER_BUILD)
rom_linker_script("newlib")
# The linking of the bootloader needs to use the rom_i2c_writeReg_Mask in esp32c6.rom.phy.ld
rom_linker_script("phy")
rom_linker_script("wdt")
elseif(target STREQUAL "esp32h2")
rom_linker_script("newlib")
@ -245,6 +250,11 @@ else() # Regular app build
rom_linker_script("spiflash")
endif()
if(CONFIG_HAL_WDT_USE_ROM_IMPL)
rom_linker_script("wdt")
endif()
if(time_t_size EQUAL 8)
# The ROM functions listed in this linker script depend on sizeof(time_t).
# ESP32-C6 ROM was compiled for 64-bit time_t, only link these functions

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -169,24 +169,6 @@ g_flash_guard_ops = 0x4087fff4;
/* Note: esp_rom_spiflash_write_disable was moved from esp32c6.rom.spiflash.ld */
esp_rom_spiflash_write_disable = 0x40000278;
/***************************************
Group hal_wdt
***************************************/
/* Functions */
wdt_hal_init = 0x40000394;
wdt_hal_deinit = 0x40000398;
wdt_hal_config_stage = 0x4000039c;
wdt_hal_write_protect_disable = 0x400003a0;
wdt_hal_write_protect_enable = 0x400003a4;
wdt_hal_enable = 0x400003a8;
wdt_hal_disable = 0x400003ac;
wdt_hal_handle_intr = 0x400003b0;
wdt_hal_feed = 0x400003b4;
wdt_hal_set_flashboot_en = 0x400003b8;
wdt_hal_is_enabled = 0x400003bc;
/***************************************
Group hal_systimer
***************************************/

View File

@ -0,0 +1,25 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/***************************************
Group hal_wdt
***************************************/
/* Functions */
/* Patch init function to set clock source
wdt_hal_init = 0x40000394;
wdt_hal_deinit = 0x40000398;
*/
wdt_hal_config_stage = 0x4000039c;
wdt_hal_write_protect_disable = 0x400003a0;
wdt_hal_write_protect_enable = 0x400003a4;
wdt_hal_enable = 0x400003a8;
wdt_hal_disable = 0x400003ac;
wdt_hal_handle_intr = 0x400003b0;
wdt_hal_feed = 0x400003b4;
wdt_hal_set_flashboot_en = 0x400003b8;
wdt_hal_is_enabled = 0x400003bc;

View File

@ -6,3 +6,5 @@ entries:
esp_rom_tlsf (noflash)
if SOC_SYSTIMER_SUPPORTED = y:
esp_rom_systimer (noflash)
if CONFIG_HAL_WDT_USE_ROM_IMPL = y:
esp_rom_wdt (noflash)

View File

@ -0,0 +1,125 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "sdkconfig.h"
#include <stddef.h>
#include "hal/wdt_types.h"
#include "hal/wdt_hal.h"
#include "hal/mwdt_ll.h"
#if CONFIG_HAL_WDT_USE_ROM_IMPL
#if CONFIG_IDF_TARGET_ESP32C6
void wdt_hal_init(wdt_hal_context_t *hal, wdt_inst_t wdt_inst, uint32_t prescaler, bool enable_intr)
{
//Initialize HAL context
memset(hal, 0, sizeof(wdt_hal_context_t));
if (wdt_inst == WDT_MWDT0) {
hal->mwdt_dev = &TIMERG0;
}
#if SOC_TIMER_GROUPS >= 2
else if (wdt_inst == WDT_MWDT1) {
hal->mwdt_dev = &TIMERG1;
}
#endif
else {
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 // ESP32C6-TODO, ESP32H2-TODO: IDF-5653
hal->rwdt_dev = &LP_WDT;
#else
hal->rwdt_dev = &RTCCNTL;
#endif
}
hal->inst = wdt_inst;
if (hal->inst == WDT_RWDT) {
//Unlock RTC WDT
rwdt_ll_write_protect_disable(hal->rwdt_dev);
//Disable RTC WDT, all stages, and all interrupts.
rwdt_ll_disable(hal->rwdt_dev);
rwdt_ll_disable_stage(hal->rwdt_dev, WDT_STAGE0);
rwdt_ll_disable_stage(hal->rwdt_dev, WDT_STAGE1);
rwdt_ll_disable_stage(hal->rwdt_dev, WDT_STAGE2);
rwdt_ll_disable_stage(hal->rwdt_dev, WDT_STAGE3);
#ifdef CONFIG_IDF_TARGET_ESP32
//Enable or disable level interrupt. Edge interrupt is always disabled.
rwdt_ll_set_edge_intr(hal->rwdt_dev, false);
rwdt_ll_set_level_intr(hal->rwdt_dev, enable_intr);
#else
//Enable or disable chip reset on timeout, and length of chip reset signal
rwdt_ll_set_chip_reset_width(hal->rwdt_dev, 0);
rwdt_ll_set_chip_reset_en(hal->rwdt_dev, false);
#endif
rwdt_ll_clear_intr_status(hal->rwdt_dev);
rwdt_ll_set_intr_enable(hal->rwdt_dev, enable_intr);
//Set default values
#if SOC_CPU_CORES_NUM > 1
rwdt_ll_set_appcpu_reset_en(hal->rwdt_dev, true);
#endif
rwdt_ll_set_procpu_reset_en(hal->rwdt_dev, true);
rwdt_ll_set_pause_in_sleep_en(hal->rwdt_dev, true);
rwdt_ll_set_cpu_reset_length(hal->rwdt_dev, WDT_RESET_SIG_LENGTH_3_2us);
rwdt_ll_set_sys_reset_length(hal->rwdt_dev, WDT_RESET_SIG_LENGTH_3_2us);
//Lock RTC WDT
rwdt_ll_write_protect_enable(hal->rwdt_dev);
} else {
//Unlock WDT
mwdt_ll_write_protect_disable(hal->mwdt_dev);
//Disable WDT and stages.
mwdt_ll_disable(hal->mwdt_dev);
mwdt_ll_disable_stage(hal->mwdt_dev, 0);
mwdt_ll_disable_stage(hal->mwdt_dev, 1);
mwdt_ll_disable_stage(hal->mwdt_dev, 2);
mwdt_ll_disable_stage(hal->mwdt_dev, 3);
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
//Enable or disable level interrupt. Edge interrupt is always disabled.
mwdt_ll_set_edge_intr(hal->mwdt_dev, false);
mwdt_ll_set_level_intr(hal->mwdt_dev, enable_intr);
#endif
mwdt_ll_clear_intr_status(hal->mwdt_dev);
mwdt_ll_set_intr_enable(hal->mwdt_dev, enable_intr);
//Set default values
mwdt_ll_set_cpu_reset_length(hal->mwdt_dev, WDT_RESET_SIG_LENGTH_3_2us);
mwdt_ll_set_sys_reset_length(hal->mwdt_dev, WDT_RESET_SIG_LENGTH_3_2us);
mwdt_ll_set_clock_source(hal->mwdt_dev, MWDT_CLK_SRC_DEFAULT);
mwdt_ll_enable_clock(hal->mwdt_dev, true);
//Set tick period
mwdt_ll_set_prescaler(hal->mwdt_dev, prescaler);
//Lock WDT
mwdt_ll_write_protect_enable(hal->mwdt_dev);
}
}
void wdt_hal_deinit(wdt_hal_context_t *hal)
{
if (hal->inst == WDT_RWDT) {
//Unlock WDT
rwdt_ll_write_protect_disable(hal->rwdt_dev);
//Disable WDT and clear any interrupts
rwdt_ll_feed(hal->rwdt_dev);
rwdt_ll_disable(hal->rwdt_dev);
rwdt_ll_clear_intr_status(hal->rwdt_dev);
rwdt_ll_set_intr_enable(hal->rwdt_dev, false);
//Lock WDT
rwdt_ll_write_protect_enable(hal->rwdt_dev);
} else {
//Unlock WDT
mwdt_ll_write_protect_disable(hal->mwdt_dev);
//Disable WDT and clear/disable any interrupts
mwdt_ll_feed(hal->mwdt_dev);
mwdt_ll_disable(hal->mwdt_dev);
mwdt_ll_clear_intr_status(hal->mwdt_dev);
mwdt_ll_set_intr_enable(hal->mwdt_dev, false);
mwdt_ll_enable_clock(hal->mwdt_dev, false);
//Lock WDT
mwdt_ll_write_protect_enable(hal->mwdt_dev);
}
//Deinit HAL context
hal->mwdt_dev = NULL;
}
#endif // CONFIG_IDF_TARGET_ESP32C6
#endif // CONFIG_HAL_WDT_USE_ROM_IMPL

View File

@ -16,8 +16,9 @@ extern "C" {
#if SOC_TIMER_GROUPS >= 2
/* All the targets that have more than one timer group are using
* APB clock by default, which frequency is 80MHz.
* Thus, we can determine the default parameter for the prescaler here */
* APB or PLL clock by default (depends on target).
* The following configurations are based on 80MHz clock
*/
#define MWDT0_TICK_PRESCALER 40000
#define MWDT0_TICKS_PER_US 500
#define MWDT1_TICK_PRESCALER 40000

View File

@ -48,6 +48,16 @@
#define BROWNOUT "BROWNOUT_RST"
#define STORE_ERROR LOAD_STORE_ERROR
#elif CONFIG_IDF_TARGET_ESP32C6
#define DEEPSLEEP "DSLEEP"
#define LOAD_STORE_ERROR "Store access fault"
#define RESET "SW_CPU"
#define INT_WDT_PANIC "Interrupt wdt timeout on CPU0"
#define INT_WDT "TG1_WDT_HPSYS"
#define RTC_WDT "LP_WDT_SYS"
#define BROWNOUT "LP_BOD_SYS"
#define STORE_ERROR LOAD_STORE_ERROR
#endif // CONFIG_IDF_TARGET_ESP32
@ -86,7 +96,8 @@ static void setup_values(void)
s_rtc_force_slow_val = CHECK_VALUE;
}
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3)
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3, ESP32C6)
// TODO IDF-5349, enable test when deep sleep is brought up
static void do_deep_sleep(void)
{
setup_values();

View File

@ -23,7 +23,7 @@ void esp_task_wdt_isr_user_handler(void)
timeout_flag = true;
}
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C6, ESP32H2)
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32H2)
TEST_CASE("Task WDT task timeout", "[task_wdt]")
{
timeout_flag = false;
@ -94,7 +94,7 @@ TEST_CASE("Task WDT can be reconfigured", "[task_wdt]")
TEST_ASSERT_EQUAL(ESP_OK, esp_task_wdt_delete(NULL));
TEST_ASSERT_EQUAL(ESP_OK, esp_task_wdt_deinit());
}
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C6, ESP32H2)
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32H2)
TEST_CASE("Task WDT task feed", "[task_wdt]")
{
@ -115,7 +115,7 @@ TEST_CASE("Task WDT task feed", "[task_wdt]")
TEST_ASSERT_EQUAL(ESP_OK, esp_task_wdt_deinit());
}
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C6, ESP32H2)
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32H2)
TEST_CASE("Task WDT user timeout", "[task_wdt]")
{
const char *user_name = "test_user";
@ -134,7 +134,7 @@ TEST_CASE("Task WDT user timeout", "[task_wdt]")
TEST_ASSERT_EQUAL(ESP_OK, esp_task_wdt_delete_user(user_handle));
TEST_ASSERT_EQUAL(ESP_OK, esp_task_wdt_deinit());
}
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C6, ESP32H2)
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32H2)
TEST_CASE("Task WDT user feed", "[task_wdt]")
{

View File

@ -255,6 +255,36 @@ FORCE_INLINE_ATTR void mwdt_ll_set_intr_enable(timg_dev_t *hw, bool enable)
hw->int_ena_timers.wdt_int_ena = enable;
}
/**
* @brief Set the clock source for the MWDT.
*
* @param hw Beginning address of the peripheral registers.
* @param clk_src Clock source
*/
FORCE_INLINE_ATTR void mwdt_ll_set_clock_source(timg_dev_t *hw, mwdt_clock_source_t clk_src)
{
/* No clk source option on ESP32, always use APB as clock source */
(void)hw;
(void)clk_src;
HAL_ASSERT(clk_src == MWDT_CLK_SRC_APB);
}
/**
* @brief Enable MWDT module clock
*
* @param hw Beginning address of the peripheral registers.
* @param en true to enable, false to disable
*/
__attribute__((always_inline))
static inline void mwdt_ll_enable_clock(timg_dev_t *hw, bool en)
{
/* No MWDT specific clock bit on ESP32 */
(void)hw;
(void)en;
}
#ifdef __cplusplus
}
#endif

View File

@ -21,6 +21,7 @@ extern "C" {
#include "esp_attr.h"
#include "hal/misc.h"
#include "hal/check.h"
#include "hal/assert.h"
//Type check wdt_stage_action_t
STATIC_HAL_REG_CHECK("mwdt", WDT_STAGE_ACTION_OFF, TIMG_WDT_STG_SEL_OFF);
@ -246,6 +247,39 @@ FORCE_INLINE_ATTR void mwdt_ll_set_intr_enable(timg_dev_t *hw, bool enable)
hw->int_ena_timers.wdt_int_ena = (enable) ? 1 : 0;
}
/**
* @brief Set the clock source for the MWDT.
*
* @param hw Beginning address of the peripheral registers.
* @param clk_src Clock source
*/
FORCE_INLINE_ATTR void mwdt_ll_set_clock_source(timg_dev_t *hw, mwdt_clock_source_t clk_src)
{
switch (clk_src) {
case MWDT_CLK_SRC_PLL_F40M:
hw->wdtconfig0.wdt_use_xtal = 0;
break;
case MWDT_CLK_SRC_XTAL:
hw->wdtconfig0.wdt_use_xtal = 1;
break;
default:
HAL_ASSERT(false);
break;
}
}
/**
* @brief Enable MWDT module clock
*
* @param hw Beginning address of the peripheral registers.
* @param en true to enable, false to disable
*/
__attribute__((always_inline))
static inline void mwdt_ll_enable_clock(timg_dev_t *hw, bool en)
{
hw->regclk.wdt_clk_is_active = en;
}
#ifdef __cplusplus
}
#endif

View File

@ -249,6 +249,39 @@ FORCE_INLINE_ATTR void mwdt_ll_set_intr_enable(timg_dev_t *hw, bool enable)
hw->int_ena_timers.wdt_int_ena = (enable) ? 1 : 0;
}
/**
* @brief Set the clock source for the MWDT.
*
* @param hw Beginning address of the peripheral registers.
* @param clk_src Clock source
*/
FORCE_INLINE_ATTR void mwdt_ll_set_clock_source(timg_dev_t *hw, mwdt_clock_source_t clk_src)
{
switch (clk_src) {
case MWDT_CLK_SRC_APB:
hw->wdtconfig0.wdt_use_xtal = 0;
break;
case MWDT_CLK_SRC_XTAL:
hw->wdtconfig0.wdt_use_xtal = 1;
break;
default:
HAL_ASSERT(false);
break;
}
}
/**
* @brief Enable MWDT module clock
*
* @param hw Beginning address of the peripheral registers.
* @param en true to enable, false to disable
*/
__attribute__((always_inline))
static inline void mwdt_ll_enable_clock(timg_dev_t *hw, bool en)
{
hw->regclk.wdt_clk_is_active = en;
}
#ifdef __cplusplus
}
#endif

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -17,6 +17,7 @@ extern "C" {
#include <stdbool.h>
#include "soc/timer_periph.h"
#include "soc/timer_group_struct.h"
#include "soc/pcr_struct.h"
#include "hal/wdt_types.h"
#include "hal/assert.h"
#include "esp_attr.h"
@ -249,6 +250,55 @@ FORCE_INLINE_ATTR void mwdt_ll_set_intr_enable(timg_dev_t *hw, bool enable)
hw->int_ena_timers.wdt_int_ena = (enable) ? 1 : 0;
}
/**
* @brief Set the clock source for the MWDT.
*
* @param hw Beginning address of the peripheral registers.
* @param clk_src Clock source
*/
FORCE_INLINE_ATTR void mwdt_ll_set_clock_source(timg_dev_t *hw, mwdt_clock_source_t clk_src)
{
uint8_t clk_id = 0;
switch (clk_src) {
case MWDT_CLK_SRC_XTAL:
clk_id = 0;
break;
case MWDT_CLK_SRC_PLL_F80M:
clk_id = 1;
break;
case MWDT_CLK_SRC_RC_FAST:
clk_id = 2;
break;
default:
HAL_ASSERT(false);
break;
}
if (hw == &TIMERG0) {
PCR.timergroup0_wdt_clk_conf.tg0_wdt_clk_sel = clk_id;
} else {
PCR.timergroup1_wdt_clk_conf.tg1_wdt_clk_sel = clk_id;
}
}
/**
* @brief Enable MWDT module clock
*
* @param hw Beginning address of the peripheral registers.
* @param en true to enable, false to disable
*/
__attribute__((always_inline))
static inline void mwdt_ll_enable_clock(timg_dev_t *hw, bool en)
{
if (hw == &TIMERG0) {
PCR.timergroup0_wdt_clk_conf.tg0_wdt_clk_en = en;
} else {
PCR.timergroup1_wdt_clk_conf.tg1_wdt_clk_en = en;
}
}
#ifdef __cplusplus
}
#endif

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -248,6 +248,34 @@ FORCE_INLINE_ATTR void mwdt_ll_set_intr_enable(timg_dev_t *hw, bool enable)
hw->int_ena_timers.wdt_int_ena = (enable) ? 1 : 0;
}
/**
* @brief Set the clock source for the MWDT.
*
* @param hw Beginning address of the peripheral registers.
* @param clk_src Clock source
*/
FORCE_INLINE_ATTR void mwdt_ll_set_clock_source(timg_dev_t *hw, mwdt_clock_source_t clk_src)
{
// TODO IDF-6643
(void)hw;
(void)clk_src;
}
/**
* @brief Enable MWDT module clock
*
* @param hw Beginning address of the peripheral registers.
* @param en true to enable, false to disable
*/
__attribute__((always_inline))
static inline void mwdt_ll_enable_clock(timg_dev_t *hw, bool en)
{
// TODO IDF-6643
(void)hw;
(void)en;
}
#ifdef __cplusplus
}
#endif

View File

@ -249,6 +249,40 @@ FORCE_INLINE_ATTR void mwdt_ll_set_intr_enable(timg_dev_t *hw, bool enable)
hw->int_ena_timers.wdt_int_ena = (enable) ? 1 : 0;
}
/**
* @brief Set the clock source for the MWDT.
*
* @param hw Beginning address of the peripheral registers.
* @param clk_src Clock source
*/
FORCE_INLINE_ATTR void mwdt_ll_set_clock_source(timg_dev_t *hw, mwdt_clock_source_t clk_src)
{
switch (clk_src) {
case MWDT_CLK_SRC_APB:
hw->wdtconfig0.wdt_use_xtal = 0;
break;
case MWDT_CLK_SRC_XTAL:
hw->wdtconfig0.wdt_use_xtal = 1;
break;
default:
HAL_ASSERT(false);
break;
}
}
/**
* @brief Enable MWDT module clock
*
* @param hw Beginning address of the peripheral registers.
* @param en true to enable, false to disable
*/
__attribute__((always_inline))
static inline void mwdt_ll_enable_clock(timg_dev_t *hw, bool en)
{
hw->regclk.wdt_clk_is_active = en;
}
#ifdef __cplusplus
}
#endif

View File

@ -259,6 +259,35 @@ FORCE_INLINE_ATTR void mwdt_ll_set_intr_enable(timg_dev_t *hw, bool enable)
hw->int_ena_timers.wdt_int_ena = (enable) ? 1 : 0;
}
/**
* @brief Set the clock source for the MWDT.
*
* @param hw Beginning address of the peripheral registers.
* @param clk_src Clock source
*/
FORCE_INLINE_ATTR void mwdt_ll_set_clock_source(timg_dev_t *hw, mwdt_clock_source_t clk_src)
{
/* No clk source option on S2, always use APB as clock source */
(void)hw;
(void)clk_src;
HAL_ASSERT(clk_src == MWDT_CLK_SRC_APB);
}
/**
* @brief Enable MWDT module clock
*
* @param hw Beginning address of the peripheral registers.
* @param en true to enable, false to disable
*/
__attribute__((always_inline))
static inline void mwdt_ll_enable_clock(timg_dev_t *hw, bool en)
{
/* No MWDT specific clock bit on ESP32S2 */
(void)hw;
(void)en;
}
#ifdef __cplusplus
}
#endif

View File

@ -275,6 +275,35 @@ FORCE_INLINE_ATTR void mwdt_ll_set_intr_enable(timg_dev_t *hw, bool enable)
hw->int_ena_timers.wdt_int_ena = (enable) ? 1 : 0;
}
/**
* @brief Set the clock source for the MWDT.
*
* @param hw Beginning address of the peripheral registers.
* @param clk_src Clock source
*/
FORCE_INLINE_ATTR void mwdt_ll_set_clock_source(timg_dev_t *hw, mwdt_clock_source_t clk_src)
{
/* No clk source option on S3, always use APB as clock source */
(void)hw;
(void)clk_src;
HAL_ASSERT(clk_src == MWDT_CLK_SRC_APB);
}
/**
* @brief Enable MWDT module clock
*
* @param hw Beginning address of the peripheral registers.
* @param en true to enable, false to disable
*/
__attribute__((always_inline))
static inline void mwdt_ll_enable_clock(timg_dev_t *hw, bool en)
{
/* No MWDT specific clock bit on ESP32S3 */
(void)hw;
(void)en;
}
#ifdef __cplusplus
}
#endif

View File

@ -1,19 +1,13 @@
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "soc/clk_tree_defs.h"
#ifdef __cplusplus
extern "C" {
#endif
@ -66,6 +60,8 @@ typedef enum {
} wdt_reset_sig_length_t;
typedef soc_periph_mwdt_clk_src_t mwdt_clock_source_t;
#ifdef __cplusplus
}
#endif

View File

@ -81,6 +81,8 @@ void wdt_hal_init(wdt_hal_context_t *hal, wdt_inst_t wdt_inst, uint32_t prescale
//Set default values
mwdt_ll_set_cpu_reset_length(hal->mwdt_dev, WDT_RESET_SIG_LENGTH_3_2us);
mwdt_ll_set_sys_reset_length(hal->mwdt_dev, WDT_RESET_SIG_LENGTH_3_2us);
mwdt_ll_set_clock_source(hal->mwdt_dev, MWDT_CLK_SRC_DEFAULT);
mwdt_ll_enable_clock(hal->mwdt_dev, true);
//Set tick period
mwdt_ll_set_prescaler(hal->mwdt_dev, prescaler);
//Lock WDT
@ -108,6 +110,7 @@ void wdt_hal_deinit(wdt_hal_context_t *hal)
mwdt_ll_disable(hal->mwdt_dev);
mwdt_ll_clear_intr_status(hal->mwdt_dev);
mwdt_ll_set_intr_enable(hal->mwdt_dev, false);
mwdt_ll_enable_clock(hal->mwdt_dev, false);
//Lock WDT
mwdt_ll_write_protect_enable(hal->mwdt_dev);
}

View File

@ -379,6 +379,24 @@ typedef enum {
ADC_RTC_CLK_SRC_DEFAULT = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the default clock choice */
} soc_periph_adc_rtc_clk_src_t;
//////////////////////////////////////////////////MWDT/////////////////////////////////////////////////////////////////
/**
* @brief Array initializer for all supported clock sources of MWDT
*/
#define SOC_MWDT_CLKS {SOC_MOD_CLK_APB}
/**
* @brief MWDT clock source
*/
typedef enum {
MWDT_CLK_SRC_APB = SOC_MOD_CLK_APB, /*!< Select APB as the source clock */
MWDT_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default clock choice */
} soc_periph_mwdt_clk_src_t;
#ifdef __cplusplus
}
#endif

View File

@ -249,6 +249,24 @@ typedef enum {
GLITCH_FILTER_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB clock as the default clock choice */
} soc_periph_glitch_filter_clk_src_t;
//////////////////////////////////////////////////MWDT/////////////////////////////////////////////////////////////////
/**
* @brief Array initializer for all supported clock sources of MWDT
*/
#define SOC_MWDT_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_PLL_F40M}
/**
* @brief MWDT clock source
*/
typedef enum {
MWDT_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
MWDT_CLK_SRC_PLL_F40M = SOC_MOD_CLK_PLL_F40M, /*!< Select PLL 40 Mhz as the source clock */
MWDT_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F40M, /*!< Select PLL 40 Mhz as the default clock choice */
} soc_periph_mwdt_clk_src_t;
#ifdef __cplusplus
}
#endif

View File

@ -320,6 +320,23 @@ typedef enum {
ADC_DIGI_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default clock choice */
} soc_periph_adc_digi_clk_src_t;
//////////////////////////////////////////////////MWDT/////////////////////////////////////////////////////////////////
/**
* @brief Array initializer for all supported clock sources of MWDT
*/
#define SOC_MWDT_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_APB}
/**
* @brief MWDT clock source
*/
typedef enum {
MWDT_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
MWDT_CLK_SRC_APB = SOC_MOD_CLK_APB, /*!< Select APB as the source clock */
MWDT_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default clock choice */
} soc_periph_mwdt_clk_src_t;
#ifdef __cplusplus
}
#endif

View File

@ -369,6 +369,23 @@ typedef enum {
ADC_DIGI_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the default clock choice */
} soc_periph_adc_digi_clk_src_t;
//////////////////////////////////////////////////MWDT/////////////////////////////////////////////////////////////////
/**
* @brief Array initializer for all supported clock sources of MWDT
*/
#define SOC_MWDT_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_PLL_F80M, SOC_MOD_CLK_RC_FAST}
/**
* @brief MWDT clock source
*/
typedef enum {
MWDT_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
MWDT_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL fixed 80 MHz as the source clock */
MWDT_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RTC fast as the source clock */
MWDT_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL fixed 80 MHz as the default clock choice */
} soc_periph_mwdt_clk_src_t;
#ifdef __cplusplus
}
#endif

View File

@ -411,6 +411,17 @@ typedef enum {
#endif
} soc_periph_adc_digi_clk_src_t;
/**
* @brief MWDT clock source
*/
// TODO: temporary support, need to check while supporting IDF-6643
typedef enum {
MWDT_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
MWDT_CLK_SRC_PLL_F96M = SOC_MOD_CLK_PLL_F96M, /*!< Select PLL fixed 96 MHz as the source clock */
MWDT_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RTC fast as the source clock */
MWDT_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F96M, /*!< Select PLL as the default clock choice */
} soc_periph_mwdt_clk_src_t;
#ifdef __cplusplus
}
#endif

View File

@ -328,6 +328,23 @@ typedef enum {
ADC_DIGI_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the default clock choice */
} soc_periph_adc_digi_clk_src_t;
//////////////////////////////////////////////////MWDT/////////////////////////////////////////////////////////////////
/**
* @brief Array initializer for all supported clock sources of MWDT
*/
#define SOC_MWDT_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_APB}
/**
* @brief MWDT clock source
*/
typedef enum {
MWDT_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
MWDT_CLK_SRC_APB = SOC_MOD_CLK_APB, /*!< Select APB as the source clock */
MWDT_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default clock choice */
} soc_periph_mwdt_clk_src_t;
#ifdef __cplusplus
}
#endif

View File

@ -381,6 +381,23 @@ typedef enum {
ADC_RTC_CLK_SRC_DEFAULT = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the default clock choice */
} soc_periph_adc_rtc_clk_src_t;
//////////////////////////////////////////////////MWDT/////////////////////////////////////////////////////////////////
/**
* @brief Array initializer for all supported clock sources of MWDT
*/
#define SOC_MWDT_CLKS {SOC_MOD_CLK_APB}
/**
* @brief MWDT clock source
*/
typedef enum {
MWDT_CLK_SRC_APB = SOC_MOD_CLK_APB, /*!< Select APB as the source clock */
MWDT_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default clock choice */
} soc_periph_mwdt_clk_src_t;
#ifdef __cplusplus
}
#endif

View File

@ -380,6 +380,22 @@ typedef enum {
ADC_RTC_CLK_SRC_DEFAULT = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the default clock choice */
} soc_periph_adc_rtc_clk_src_t;
//////////////////////////////////////////////////MWDT/////////////////////////////////////////////////////////////////
/**
* @brief Array initializer for all supported clock sources of MWDT
*/
#define SOC_MWDT_CLKS {SOC_MOD_CLK_APB}
/**
* @brief MWDT clock source
*/
typedef enum {
MWDT_CLK_SRC_APB = SOC_MOD_CLK_APB, /*!< Select APB as the source clock */
MWDT_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default clock choice */
} soc_periph_mwdt_clk_src_t;
#ifdef __cplusplus
}
#endif

View File

@ -120,7 +120,6 @@ api-reference/system/freertos_additions
api-reference/system/himem
api-reference/system/power_management
api-reference/system/mem_alloc
api-reference/system/wdts
api-reference/system/misc_system_api
api-reference/system/inc
api-reference/system/inc/show-efuse-table_ESP32-C6

View File

@ -425,7 +425,7 @@ VFS
* :ref:`CONFIG_VFS_SUPPORT_DIR` — can be disabled if the application doesn't use directory related functions, such as ``readdir`` (see the description of this option for the complete list). Applications which only open, read and write specific files and don't need to enumerate or create directories can disable this option, reducing the code size by 0.5 kB or more, depending on the filesystem drivers in use.
* :ref:`CONFIG_VFS_SUPPORT_IO` — can be disabled if the application doesn't use filesystems or file-like peripheral drivers. This disables all VFS functionality, including the three options mentioned above. When this option is disabled, :doc:`console </api-reference/system/console>` can't be used. Note that the application can still use standard I/O functions with socket file descriptors when this option is disabled. Compared to the default configuration, disabling this option reduces code size by about 9.4 kB.
.. only:: esp32c2
.. only:: CONFIG_ESP_ROM_HAS_HAL_SYSTIMER or CONFIG_ESP_ROM_HAS_HAL_WDT
HAL
@@@
@ -435,7 +435,7 @@ VFS
:CONFIG_ESP_ROM_HAS_HAL_SYSTIMER: * Enabling :ref:`CONFIG_HAL_SYSTIMER_USE_ROM_IMPL` can reduce the IRAM usage and binary size by linking in the systimer HAL driver of ROM implementation.
:CONFIG_ESP_ROM_HAS_HAL_WDT: * Enabling :ref:`CONFIG_HAL_WDT_USE_ROM_IMPL` can reduce the IRAM usage and binary size by linking in the watchdog HAL driver of ROM implementation.
.. only:: esp32c2
.. only:: CONFIG_ESP_ROM_HAS_HEAP_TLSF
Heap
@@@@

View File

@ -19,7 +19,7 @@ The various watchdog timers can be enabled using the :ref:`project-configuration
Interrupt Watchdog Timer (IWDT)
-------------------------------
{IDF_IWDT_TIMER_GROUP:default="Timer Group 1", esp32c2="Timer Group 0"}
{IDF_TARGET_IWDT_TIMER_GROUP:default="Timer Group 1", esp32c2="Timer Group 0"}
The purpose of the IWDT is to ensure that interrupt service routines (ISRs) are not blocked from running for a prolonged period of time (i.e., the IWDT timeout period). Blocking ISRs from running in a timely manner is undesirable as it can increases ISR latency, and also prevents task switching (as task switching is executed form an ISR). The things that can block ISRs from running include:
@ -27,7 +27,7 @@ The purpose of the IWDT is to ensure that interrupt service routines (ISRs) are
- Critical Sections (also disables interrupts)
- Other same/higher priority ISRs (will block same/lower priority ISRs from running it completes execution)
The IWDT utilizes the watchdog timer in {IDF_IWDT_TIMER_GROUP} as its underlying hardware timer and leverages the FreeRTOS tick interrupt on each CPU to feed the watchdog timer. If the tick interrupt on a particular CPU is not run at within the IWDT timeout period, it is indicative that something is blocking ISRs from being run on that CPU (see the list of reasons above).
The IWDT utilizes the watchdog timer in {IDF_TARGET_IWDT_TIMER_GROUP} as its underlying hardware timer and leverages the FreeRTOS tick interrupt on each CPU to feed the watchdog timer. If the tick interrupt on a particular CPU is not run at within the IWDT timeout period, it is indicative that something is blocking ISRs from being run on that CPU (see the list of reasons above).
When the IWDT times out, the default action is to invoke the panic handler and display the panic reason as ``Interrupt wdt timeout on CPU0`` or ``Interrupt wdt timeout on CPU1`` (as applicable). Depending on the panic handler's configured behavior (see :ref:`CONFIG_ESP_SYSTEM_PANIC`), users can then debug the source of the IWDT timeout (via the backtrace, OpenOCD, gdbstub etc) or simply reset the chip (which may be preferred in a production environment).
@ -57,7 +57,7 @@ Neither critical sections or interrupt handlers should ever block waiting for an
Task Watchdog Timer (TWDT)
--------------------------
{IDF_TARGET_IDLE_TASKS:default="Idle task", esp32="Idle Tasks of each CPU"}
{IDF_TARGET_IDLE_TASKS:default="Idle task", esp32="Idle Tasks of each CPU", esp32s3="Idle Tasks of each CPU"}
The Task Watchdog Timer (TWDT) is used to monitor particular tasks, ensuring that they are able to execute within a given timeout period. The TWDT primarily watches the {IDF_TARGET_IDLE_TASKS}, however any task can subscribe to be watched by the TWDT. By watching the {IDF_TARGET_IDLE_TASKS}, the TWDT can detect instances of tasks running for a prolonged period of time wihtout yielding. This can be an indicator of poorly written code that spinloops on a peripheral, or a task that is stuck in an infinite loop.

View File

@ -690,7 +690,6 @@ components/hal/include/hal/spi_slave_hd_hal.h
components/hal/include/hal/uhci_types.h
components/hal/include/hal/usb_hal.h
components/hal/include/hal/usb_types_private.h
components/hal/include/hal/wdt_types.h
components/hal/mpu_hal.c
components/hal/sha_hal.c
components/hal/spi_flash_encrypt_hal_iram.c