wdt: add support for H2

This commit is contained in:
Marius Vikhammer 2023-02-17 14:51:00 +08:00
parent d55060d184
commit 5d26a0de9a
24 changed files with 139 additions and 83 deletions

View File

@ -119,11 +119,16 @@ 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")
if(CONFIG_HAL_WDT_USE_ROM_IMPL)
rom_linker_script("wdt")
endif()
rom_linker_script("version")
elseif(target STREQUAL "esp32h2")
rom_linker_script("newlib")
if(CONFIG_HAL_WDT_USE_ROM_IMPL)
rom_linker_script("wdt")
endif()
endif()
else() # Regular app build
@ -261,6 +266,10 @@ else() # Regular app build
rom_linker_script("spiflash")
endif()
if(CONFIG_HAL_WDT_USE_ROM_IMPL)
rom_linker_script("wdt")
endif()
if(CONFIG_NEWLIB_NANO_FORMAT)
# nano formatting functions in ROM are also built for 64-bit time_t.
rom_linker_script("newlib-nano")

View File

@ -66,3 +66,7 @@ config ESP_ROM_HAS_NEWLIB_NORMAL_FORMAT
config ESP_ROM_REV0_HAS_NO_ECDSA_INTERFACE
bool
default y
config ESP_ROM_WDT_INIT_PATCH
bool
default y

View File

@ -22,3 +22,4 @@
#define ESP_ROM_HAS_REGI2C_BUG (1) // ROM has the regi2c bug
#define ESP_ROM_HAS_NEWLIB_NORMAL_FORMAT (1) // ROM has the newlib normal/full version of formatting functions (as opposed to the nano versions)
#define ESP_ROM_REV0_HAS_NO_ECDSA_INTERFACE (1) // ECO 0 does not have ets_ecdsa_verify symbol, future revision will have it
#define ESP_ROM_WDT_INIT_PATCH (1) // ROM version does not configure the clock

View File

@ -54,3 +54,7 @@ config ESP_ROM_WITHOUT_REGI2C
config ESP_ROM_HAS_NEWLIB_NANO_FORMAT
bool
default y
config ESP_ROM_WDT_INIT_PATCH
bool
default y

View File

@ -19,3 +19,4 @@
#define ESP_ROM_HAS_SPI_FLASH (1) // ROM has the implementation of SPI Flash driver
#define ESP_ROM_WITHOUT_REGI2C (1) // ROM has no regi2c APIs
#define ESP_ROM_HAS_NEWLIB_NANO_FORMAT (1) // ROM has the newlib nano versions of formatting functions
#define ESP_ROM_WDT_INIT_PATCH (1) // ROM version does not configure the clock

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
*/
@ -160,24 +160,6 @@ g_flash_guard_ops = 0x4084fff4;
/* Note: esp_rom_spiflash_write_disable was moved from esp32c6.rom.spiflash.ld */
esp_rom_spiflash_write_disable = 0x40000270;
/***************************************
Group hal_wdt
***************************************/
/* Functions */
wdt_hal_init = 0x4000038c;
wdt_hal_deinit = 0x40000390;
wdt_hal_config_stage = 0x40000394;
wdt_hal_write_protect_disable = 0x40000398;
wdt_hal_write_protect_enable = 0x4000039c;
wdt_hal_enable = 0x400003a0;
wdt_hal_disable = 0x400003a4;
wdt_hal_handle_intr = 0x400003a8;
wdt_hal_feed = 0x400003ac;
wdt_hal_set_flashboot_en = 0x400003b0;
wdt_hal_is_enabled = 0x400003b4;
/***************************************
Group hal_systimer
***************************************/

View File

@ -0,0 +1,26 @@
/*
* 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 = 0x4000038c;
wdt_hal_deinit = 0x40000390;
*/
/* Functions */
wdt_hal_config_stage = 0x40000394;
wdt_hal_write_protect_disable = 0x40000398;
wdt_hal_write_protect_enable = 0x4000039c;
wdt_hal_enable = 0x400003a0;
wdt_hal_disable = 0x400003a4;
wdt_hal_handle_intr = 0x400003a8;
wdt_hal_feed = 0x400003ac;
wdt_hal_set_flashboot_en = 0x400003b0;
wdt_hal_is_enabled = 0x400003b4;

View File

@ -7,13 +7,15 @@
#include "sdkconfig.h"
#include <stddef.h>
#include "esp_rom_caps.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
#if ESP_ROM_WDT_INIT_PATCH
void wdt_hal_init(wdt_hal_context_t *hal, wdt_inst_t wdt_inst, uint32_t prescaler, bool enable_intr)
{
//Initialize HAL context
@ -120,6 +122,6 @@ void wdt_hal_deinit(wdt_hal_context_t *hal)
//Deinit HAL context
hal->mwdt_dev = NULL;
}
#endif // CONFIG_IDF_TARGET_ESP32C6
#endif // ESP_ROM_WDT_INIT_PATCH
#endif // CONFIG_HAL_WDT_USE_ROM_IMPL

View File

@ -6,31 +6,10 @@
#pragma once
#include "system_internal.h"
#include "soc/periph_defs.h"
#ifdef __cplusplus
extern "C" {
#endif
#if SOC_TIMER_GROUPS > 1
/* If we have two hardware timer groups, use the second one for interrupt watchdog. */
#define WDT_LEVEL_INTR_SOURCE ETS_TG1_WDT_LEVEL_INTR_SOURCE
#define IWDT_PRESCALER MWDT1_TICK_PRESCALER // Tick period of 500us if WDT source clock is 80MHz
#define IWDT_TICKS_PER_US MWDT1_TICKS_PER_US
#define IWDT_INSTANCE WDT_MWDT1
#define IWDT_INITIAL_TIMEOUT_S 5
#else
#define WDT_LEVEL_INTR_SOURCE ETS_TG0_WDT_LEVEL_INTR_SOURCE
#define IWDT_PRESCALER MWDT0_TICK_PRESCALER // Tick period of 500us if WDT source clock is 80MHz
#define IWDT_TICKS_PER_US MWDT0_TICKS_PER_US
#define IWDT_INSTANCE WDT_MWDT0
#define IWDT_INITIAL_TIMEOUT_S 5
#endif // SOC_TIMER_GROUPS > 1
/**
* @brief Initialize the non-CPU-specific parts of interrupt watchdog.

View File

@ -11,28 +11,6 @@ extern "C" {
#endif
#include "esp_system.h"
#include "soc/soc_caps.h"
#if SOC_TIMER_GROUPS >= 2
/* All the targets that have more than one timer group are using
* 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
#define MWDT1_TICKS_PER_US 500
#else
/* The targets that have a single timer group use a 40MHz clock for the
* Timer Group 0. Let's adapt the prescaler value accordingly.
*/
#define MWDT0_TICK_PRESCALER 20000
#define MWDT0_TICKS_PER_US 500
#endif
/**
* @brief Internal function to restart PRO and APP CPUs.

View File

@ -10,6 +10,7 @@
#include "sdkconfig.h"
#include "soc/soc_caps.h"
#include "hal/wdt_hal.h"
#include "hal/mwdt_ll.h"
#include "freertos/FreeRTOS.h"
#include "esp_cpu.h"
#include "esp_err.h"
@ -21,6 +22,25 @@
#include "esp_private/periph_ctrl.h"
#include "esp_private/esp_int_wdt.h"
#if SOC_TIMER_GROUPS > 1
/* If we have two hardware timer groups, use the second one for interrupt watchdog. */
#define WDT_LEVEL_INTR_SOURCE ETS_TG1_WDT_LEVEL_INTR_SOURCE
#define IWDT_PRESCALER MWDT_LL_DEFAULT_CLK_PRESCALER // Tick period of 500us if WDT source clock is 80MHz
#define IWDT_TICKS_PER_US 500
#define IWDT_INSTANCE WDT_MWDT1
#define IWDT_INITIAL_TIMEOUT_S 5
#else
#define WDT_LEVEL_INTR_SOURCE ETS_TG0_WDT_LEVEL_INTR_SOURCE
#define IWDT_PRESCALER MWDT_LL_DEFAULT_CLK_PRESCALER // Tick period of 500us if WDT source clock is 80MHz
#define IWDT_TICKS_PER_US 500
#define IWDT_INSTANCE WDT_MWDT0
#define IWDT_INITIAL_TIMEOUT_S 5
#endif // SOC_TIMER_GROUPS > 1
#if CONFIG_ESP_INT_WDT
static wdt_hal_context_t iwdt_context;

View File

@ -17,6 +17,7 @@
#include "hal/timer_hal.h"
#include "hal/wdt_types.h"
#include "hal/wdt_hal.h"
#include "hal/mwdt_ll.h"
#include "esp_private/esp_int_wdt.h"
#include "esp_private/panic_internal.h"
@ -59,6 +60,8 @@
#include "hal/usb_serial_jtag_ll.h"
#endif
#define MWDT_DEFAULT_TICKS_PER_US 500
bool g_panic_abort = false;
static char *s_panic_abort_details = NULL;
@ -183,9 +186,9 @@ void esp_panic_handler_reconfigure_wdts(uint32_t timeout_ms)
//Todo: Refactor to use Interrupt or Task Watchdog API, and a system level WDT context
//Reconfigure TWDT (Timer Group 0)
wdt_hal_init(&wdt0_context, WDT_MWDT0, MWDT0_TICK_PRESCALER, false); //Prescaler: wdt counts in ticks of TG0_WDT_TICK_US
wdt_hal_init(&wdt0_context, WDT_MWDT0, MWDT_LL_DEFAULT_CLK_PRESCALER, false); //Prescaler: wdt counts in ticks of TG0_WDT_TICK_US
wdt_hal_write_protect_disable(&wdt0_context);
wdt_hal_config_stage(&wdt0_context, 0, timeout_ms * 1000 / MWDT0_TICKS_PER_US, WDT_STAGE_ACTION_RESET_SYSTEM); //1 second before reset
wdt_hal_config_stage(&wdt0_context, 0, timeout_ms * 1000 / MWDT_DEFAULT_TICKS_PER_US, WDT_STAGE_ACTION_RESET_SYSTEM); //1 second before reset
wdt_hal_enable(&wdt0_context);
wdt_hal_write_protect_enable(&wdt0_context);

View File

@ -9,6 +9,7 @@
#include <stdio.h>
#include "sdkconfig.h"
#include "hal/wdt_hal.h"
#include "hal/mwdt_ll.h"
#include "esp_err.h"
#include "esp_attr.h"
#include "esp_intr_alloc.h"
@ -17,8 +18,8 @@
#include "esp_private/esp_task_wdt_impl.h"
#define TWDT_INSTANCE WDT_MWDT0
#define TWDT_TICKS_PER_US MWDT0_TICKS_PER_US
#define TWDT_PRESCALER MWDT0_TICK_PRESCALER // Tick period of 500us if WDT source clock is 80MHz
#define TWDT_TICKS_PER_US 500
#define TWDT_PRESCALER MWDT_LL_DEFAULT_CLK_PRESCALER // Tick period of 500us if WDT source clock is 80MHz
#define TWDT_PERIPH_MODULE PERIPH_TIMG0_MODULE
#define TWDT_INTR_SOURCE ETS_TG0_WDT_LEVEL_INTR_SOURCE

View File

@ -23,7 +23,6 @@ void esp_task_wdt_isr_user_handler(void)
timeout_flag = true;
}
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32H2)
TEST_CASE("Task WDT task timeout", "[task_wdt]")
{
timeout_flag = false;
@ -94,7 +93,6 @@ 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(ESP32H2)
TEST_CASE("Task WDT task feed", "[task_wdt]")
{
@ -115,7 +113,6 @@ TEST_CASE("Task WDT task feed", "[task_wdt]")
TEST_ASSERT_EQUAL(ESP_OK, esp_task_wdt_deinit());
}
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32H2)
TEST_CASE("Task WDT user timeout", "[task_wdt]")
{
const char *user_name = "test_user";
@ -134,7 +131,6 @@ 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(ESP32H2)
TEST_CASE("Task WDT user feed", "[task_wdt]")
{

View File

@ -23,6 +23,9 @@ extern "C" {
#include "esp_attr.h"
#include "esp_assert.h"
/* Pre-calculated prescaler to achieve 500 ticks/us (MWDT1_TICKS_PER_US) when using default clock (MWDT_CLK_SRC_DEFAULT ) */
#define MWDT_LL_DEFAULT_CLK_PRESCALER 40000
//Type check wdt_stage_action_t
ESP_STATIC_ASSERT(WDT_STAGE_ACTION_OFF == TIMG_WDT_STG_SEL_OFF, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
ESP_STATIC_ASSERT(WDT_STAGE_ACTION_INT == TIMG_WDT_STG_SEL_INT, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");

View File

@ -23,6 +23,9 @@ extern "C" {
#include "hal/check.h"
#include "hal/assert.h"
/* Pre-calculated prescaler to achieve 500 ticks/us (MWDT1_TICKS_PER_US) when using default clock (MWDT_CLK_SRC_DEFAULT ) */
#define MWDT_LL_DEFAULT_CLK_PRESCALER 20000
//Type check wdt_stage_action_t
STATIC_HAL_REG_CHECK("mwdt", WDT_STAGE_ACTION_OFF, TIMG_WDT_STG_SEL_OFF);
STATIC_HAL_REG_CHECK("mwdt", WDT_STAGE_ACTION_INT, TIMG_WDT_STG_SEL_INT);

View File

@ -23,6 +23,9 @@ extern "C" {
#include "esp_assert.h"
#include "hal/misc.h"
/* Pre-calculated prescaler to achieve 500 ticks/us (MWDT1_TICKS_PER_US) when using default clock (MWDT_CLK_SRC_DEFAULT ) */
#define MWDT_LL_DEFAULT_CLK_PRESCALER 40000
//Type check wdt_stage_action_t
ESP_STATIC_ASSERT(WDT_STAGE_ACTION_OFF == TIMG_WDT_STG_SEL_OFF, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
ESP_STATIC_ASSERT(WDT_STAGE_ACTION_INT == TIMG_WDT_STG_SEL_INT, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");

View File

@ -24,6 +24,9 @@ extern "C" {
#include "esp_assert.h"
#include "hal/misc.h"
/* Pre-calculated prescaler to achieve 500 ticks/us (MWDT1_TICKS_PER_US) when using default clock (MWDT_CLK_SRC_DEFAULT ) */
#define MWDT_LL_DEFAULT_CLK_PRESCALER 40000
//Type check wdt_stage_action_t
ESP_STATIC_ASSERT(WDT_STAGE_ACTION_OFF == TIMG_WDT_STG_SEL_OFF, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
ESP_STATIC_ASSERT(WDT_STAGE_ACTION_INT == TIMG_WDT_STG_SEL_INT, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");

View File

@ -17,11 +17,15 @@ 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"
#include "hal/misc.h"
/* Pre-calculated prescaler to achieve 500 ticks/us (MWDT1_TICKS_PER_US) when using default clock (MWDT_CLK_SRC_DEFAULT ) */
#define MWDT_LL_DEFAULT_CLK_PRESCALER 24000
//Type check wdt_stage_action_t
_Static_assert(WDT_STAGE_ACTION_OFF == TIMG_WDT_STG_SEL_OFF, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
_Static_assert(WDT_STAGE_ACTION_INT == TIMG_WDT_STG_SEL_INT, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
@ -255,11 +259,31 @@ FORCE_INLINE_ATTR void mwdt_ll_set_intr_enable(timg_dev_t *hw, bool enable)
* @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;
uint8_t clk_id = 0;
switch (clk_src) {
case MWDT_CLK_SRC_XTAL:
clk_id = 0;
break;
case MWDT_CLK_SRC_RC_FAST:
clk_id = 1;
break;
case MWDT_CLK_SRC_PLL_F48M:
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;
}
}
/**
@ -271,9 +295,11 @@ FORCE_INLINE_ATTR void mwdt_ll_set_clock_source(timg_dev_t *hw, mwdt_clock_sourc
__attribute__((always_inline))
static inline void mwdt_ll_enable_clock(timg_dev_t *hw, bool en)
{
// TODO IDF-6643
(void)hw;
(void)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

View File

@ -23,6 +23,9 @@ extern "C" {
#include "esp_assert.h"
#include "hal/misc.h"
/* Pre-calculated prescaler to achieve 500 ticks/us (MWDT1_TICKS_PER_US) when using default clock (MWDT_CLK_SRC_DEFAULT ) */
#define MWDT_LL_DEFAULT_CLK_PRESCALER 40000
//Type check wdt_stage_action_t
ESP_STATIC_ASSERT(WDT_STAGE_ACTION_OFF == TIMG_WDT_STG_SEL_OFF, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
ESP_STATIC_ASSERT(WDT_STAGE_ACTION_INT == TIMG_WDT_STG_SEL_INT, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");

View File

@ -23,6 +23,9 @@ extern "C" {
#include "esp_attr.h"
#include "hal/misc.h"
/* Pre-calculated prescaler to achieve 500 ticks/us (MWDT1_TICKS_PER_US) when using default clock (MWDT_CLK_SRC_DEFAULT ) */
#define MWDT_LL_DEFAULT_CLK_PRESCALER 40000
//Type check wdt_stage_action_t
ESP_STATIC_ASSERT(WDT_STAGE_ACTION_OFF == TIMG_WDT_STG_SEL_OFF, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
ESP_STATIC_ASSERT(WDT_STAGE_ACTION_INT == TIMG_WDT_STG_SEL_INT, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");

View File

@ -23,6 +23,9 @@ extern "C" {
#include "esp_attr.h"
#include "esp_assert.h"
/* Pre-calculated prescaler to achieve 500 ticks/us (MWDT1_TICKS_PER_US) when using default clock (MWDT_CLK_SRC_DEFAULT ) */
#define MWDT_LL_DEFAULT_CLK_PRESCALER 40000
/* The value that needs to be written to MWDT_LL_WKEY to write-enable the wdt registers */
#define MWDT_LL_WKEY_VALUE 0x50D83AA1

View File

@ -417,15 +417,19 @@ typedef enum {
//////////////////////////////////////////////////MWDT/////////////////////////////////////////////////////////////////
/**
* @brief Array initializer for all supported clock sources of MWDT
*/
#define SOC_MWDT_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_PLL_F48M, SOC_MOD_CLK_RC_FAST}
/**
* @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_PLL_F48M = SOC_MOD_CLK_PLL_F48M, /*!< Select PLL fixed 48 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 */
MWDT_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F48M, /*!< Select PLL as the default clock choice */
} soc_periph_mwdt_clk_src_t;
//////////////////////////////////////////////////LEDC/////////////////////////////////////////////////////////////////

View File

@ -83,7 +83,6 @@ api-reference/system/chip_revision
api-reference/system/esp_timer
api-reference/system/system_time
api-reference/system/power_management
api-reference/system/wdts
api-reference/system/inc/power_management_esp32
api-reference/system/inc/espefuse_summary_ESP32-H2
api-reference/system/inc/revisions_ESP32-H2