From b413a240cb70c1b9dfa946a368684276a44bd37e Mon Sep 17 00:00:00 2001 From: "Michael (XIAO Xufeng)" Date: Mon, 29 Jul 2019 14:31:30 +0800 Subject: [PATCH 1/6] esp_attr: support force_inline --- components/esp32/include/esp_attr.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/components/esp32/include/esp_attr.h b/components/esp32/include/esp_attr.h index 7a3ec771d..58fef76c7 100644 --- a/components/esp32/include/esp_attr.h +++ b/components/esp32/include/esp_attr.h @@ -34,6 +34,9 @@ // Forces data to be placed to DMA-capable places #define DMA_ATTR WORD_ALIGNED_ATTR DRAM_ATTR +// Forces a function to be inlined +#define FORCE_INLINE_ATTR static inline __attribute__((always_inline)) + // Forces a string into DRAM instead of flash // Use as ets_printf(DRAM_STR("Hello world!\n")); #define DRAM_STR(str) (__extension__({static const DRAM_ATTR char __c[] = (str); (const char *)&__c;})) @@ -45,7 +48,7 @@ // Forces bss variable into external memory. " #define EXT_RAM_ATTR _SECTION_ATTR_IMPL(".ext_ram.bss", __COUNTER__) #else -#define EXT_RAM_ATTR +#define EXT_RAM_ATTR #endif // Forces data into RTC slow memory. See "docs/deep-sleep-stub.rst" From a97fe5615f7e76b194c3d9328cf66f722b5e3b13 Mon Sep 17 00:00:00 2001 From: chenjianqiang Date: Mon, 15 Jul 2019 14:21:36 +0800 Subject: [PATCH 2/6] feat(timer): refator timer group driver (partly pick) --- components/driver/include/driver/timer.h | 18 +-- components/soc/esp32/include/hal/timer_ll.h | 133 ++++++++++++++++++++ components/soc/include/hal/timer_types.h | 44 +++++++ 3 files changed, 178 insertions(+), 17 deletions(-) create mode 100644 components/soc/esp32/include/hal/timer_ll.h create mode 100644 components/soc/include/hal/timer_types.h diff --git a/components/driver/include/driver/timer.h b/components/driver/include/driver/timer.h index cbf2a5bd2..cdff8a1b4 100644 --- a/components/driver/include/driver/timer.h +++ b/components/driver/include/driver/timer.h @@ -19,6 +19,7 @@ #include "soc/soc.h" #include "soc/timer_periph.h" #include "esp_intr_alloc.h" +#include "hal/timer_types.h" #ifdef __cplusplus extern "C" { @@ -36,15 +37,6 @@ typedef enum { TIMER_GROUP_MAX, } timer_group_t; -/** - * @brief Select a hardware timer from timer groups - */ -typedef enum { - TIMER_0 = 0, /*! Date: Thu, 25 Jul 2019 09:52:36 +0800 Subject: [PATCH 3/6] timer_group: support interrupt LL and some utility functions in ISR --- components/driver/include/driver/timer.h | 72 +++++++++++++++++---- components/driver/timer.c | 53 +++++++++++++-- components/soc/esp32/include/hal/timer_ll.h | 62 +++++++++++++++++- components/soc/include/hal/timer_types.h | 12 ++++ 4 files changed, 178 insertions(+), 21 deletions(-) diff --git a/components/driver/include/driver/timer.h b/components/driver/include/driver/timer.h index cdff8a1b4..6ab7e1095 100644 --- a/components/driver/include/driver/timer.h +++ b/components/driver/include/driver/timer.h @@ -246,9 +246,9 @@ esp_err_t timer_set_alarm(timer_group_t group_num, timer_idx_t timer_num, timer_ * @param handle Pointer to return handle. If non-NULL, a handle for the interrupt will * be returned here. * - * @note If the intr_alloc_flags value ESP_INTR_FLAG_IRAM is set, - * the handler function must be declared with IRAM_ATTR attribute - * and can only call functions in IRAM or ROM. It cannot call other timer APIs. + * @note If the intr_alloc_flags value ESP_INTR_FLAG_IRAM is set, + * the handler function must be declared with IRAM_ATTR attribute + * and can only call functions in IRAM or ROM. It cannot call other timer APIs. * Use direct register access to configure timers from inside the ISR in this case. * * @return @@ -258,7 +258,7 @@ esp_err_t timer_set_alarm(timer_group_t group_num, timer_idx_t timer_num, timer_ esp_err_t timer_isr_register(timer_group_t group_num, timer_idx_t timer_num, void (*fn)(void*), void * arg, int intr_alloc_flags, timer_isr_handle_t *handle); /** @brief Initializes and configure the timer. - * + * * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1 * @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1] * @param config Pointer to timer initialization parameters. @@ -284,28 +284,30 @@ esp_err_t timer_get_config(timer_group_t group_num, timer_idx_t timer_num, timer /** @brief Enable timer group interrupt, by enable mask * * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1 - * @param en_mask Timer interrupt enable mask. - * Use TIMG_T0_INT_ENA_M to enable t0 interrupt - * Use TIMG_T1_INT_ENA_M to enable t1 interrupt + * @param intr_mask Timer interrupt enable mask. + * - TIMER_INTR_T0: t0 interrupt + * - TIMER_INTR_T1: t1 interrupt + * - TIMER_INTR_WDT: watchdog interrupt * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error */ -esp_err_t timer_group_intr_enable(timer_group_t group_num, uint32_t en_mask); +esp_err_t timer_group_intr_enable(timer_group_t group_num, timer_intr_t intr_mask); /** @brief Disable timer group interrupt, by disable mask * * @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1 - * @param disable_mask Timer interrupt disable mask. - * Use TIMG_T0_INT_ENA_M to disable t0 interrupt - * Use TIMG_T1_INT_ENA_M to disable t1 interrupt + * @param intr_mask Timer interrupt disable mask. + * - TIMER_INTR_T0: t0 interrupt + * - TIMER_INTR_T1: t1 interrupt + * - TIMER_INTR_WDT: watchdog interrupt * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error */ -esp_err_t timer_group_intr_disable(timer_group_t group_num, uint32_t disable_mask); +esp_err_t timer_group_intr_disable(timer_group_t group_num, timer_intr_t intr_mask); /** @brief Enable timer interrupt * @@ -329,6 +331,52 @@ esp_err_t timer_enable_intr(timer_group_t group_num, timer_idx_t timer_num); */ esp_err_t timer_disable_intr(timer_group_t group_num, timer_idx_t timer_num); +/** @cond */ +/* Utilities functions that can be used in the ISR */ +/* Preview, don't treat them as stable API. */ + +/** + * Clear interrupt status bit. + */ +void timer_group_intr_clr_in_isr(timer_group_t group_num, timer_idx_t timer_num); + +/** + * Enable alarm. + */ +void timer_group_enable_alarm_in_isr(timer_group_t group_num, timer_idx_t timer_num); + +/** + * Get the current counter value. + */ +uint64_t timer_group_get_counter_value_in_isr(timer_group_t group_num, timer_idx_t timer_num); + +/** + * Set the alarm threshold for the timer. + */ +void timer_group_set_alarm_value_in_isr(timer_group_t group_num, timer_idx_t timer_num, uint64_t alarm_val); + +/** + * Enable/disable a counter. + */ +void timer_group_set_counter_enable_in_isr(timer_group_t group_num, timer_idx_t timer_num, timer_start_t counter_en); + +/** + * Get the masked interrupt status. + */ +timer_intr_t timer_group_intr_get_in_isr(timer_group_t group_num); + +/** + * Clear interrupt. + */ +void timer_group_clr_intr_sta_in_isr(timer_group_t group_num, timer_intr_t intr_mask); + +/** + * Get auto reload enable status. + */ +bool timer_group_get_auto_reload_in_isr(timer_group_t group_num, timer_idx_t timer_num); + +/** @endcond */ + #ifdef __cplusplus } #endif diff --git a/components/driver/timer.c b/components/driver/timer.c index 6a82d87fa..67f0fffb3 100644 --- a/components/driver/timer.c +++ b/components/driver/timer.c @@ -19,6 +19,7 @@ #include "freertos/xtensa_api.h" #include "driver/timer.h" #include "driver/periph_ctrl.h" +#include "hal/timer_ll.h" static const char* TIMER_TAG = "timer_group"; #define TIMER_CHECK(a, str, ret_val) \ @@ -35,7 +36,7 @@ static const char* TIMER_TAG = "timer_group"; #define TIMER_SCALE_ERROR "HW TIMER SCALE ERROR" #define TIMER_ALARM_ERROR "HW TIMER ALARM ERROR" #define DIVIDER_RANGE_ERROR "HW TIMER divider outside of [2, 65536] range error" -static timg_dev_t *TG[2] = {&TIMERG0, &TIMERG1}; +DRAM_ATTR static timg_dev_t *TG[2] = {&TIMERG0, &TIMERG1}; static portMUX_TYPE timer_spinlock[TIMER_GROUP_MAX] = {portMUX_INITIALIZER_UNLOCKED, portMUX_INITIALIZER_UNLOCKED}; #define TIMER_ENTER_CRITICAL(mux) portENTER_CRITICAL_SAFE(mux); @@ -171,7 +172,7 @@ esp_err_t timer_set_alarm(timer_group_t group_num, timer_idx_t timer_num, timer_ return ESP_OK; } -esp_err_t timer_isr_register(timer_group_t group_num, timer_idx_t timer_num, +esp_err_t timer_isr_register(timer_group_t group_num, timer_idx_t timer_num, void (*fn)(void*), void * arg, int intr_alloc_flags, timer_isr_handle_t *handle) { TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); @@ -253,7 +254,7 @@ esp_err_t timer_get_config(timer_group_t group_num, timer_idx_t timer_num, timer return ESP_OK; } -esp_err_t timer_group_intr_enable(timer_group_t group_num, uint32_t en_mask) +esp_err_t timer_group_intr_enable(timer_group_t group_num, timer_intr_t en_mask) { TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); portENTER_CRITICAL(&timer_spinlock[group_num]); @@ -262,7 +263,7 @@ esp_err_t timer_group_intr_enable(timer_group_t group_num, uint32_t en_mask) return ESP_OK; } -esp_err_t timer_group_intr_disable(timer_group_t group_num, uint32_t disable_mask) +esp_err_t timer_group_intr_disable(timer_group_t group_num, timer_intr_t disable_mask) { TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); portENTER_CRITICAL(&timer_spinlock[group_num]); @@ -275,14 +276,54 @@ esp_err_t timer_enable_intr(timer_group_t group_num, timer_idx_t timer_num) { TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG); - return timer_group_intr_enable(group_num, BIT(timer_num)); + return timer_group_intr_enable(group_num, TIMER_LL_GET_INTR(timer_num)); } esp_err_t timer_disable_intr(timer_group_t group_num, timer_idx_t timer_num) { TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG); - return timer_group_intr_disable(group_num, BIT(timer_num)); + return timer_group_intr_disable(group_num, TIMER_LL_GET_INTR(timer_num)); } +timer_intr_t IRAM_ATTR timer_group_intr_get_in_isr(timer_group_t group_num) +{ + return timer_ll_intr_status_get(TG[group_num]); +} +void IRAM_ATTR timer_group_intr_clr_in_isr(timer_group_t group_num, timer_idx_t timer_num) +{ + timer_ll_intr_status_clear(TG[group_num], TIMER_LL_GET_INTR(timer_num)); +} + +void IRAM_ATTR timer_group_enable_alarm_in_isr(timer_group_t group_num, timer_idx_t timer_num) +{ + timer_ll_set_alarm_enable(TG[group_num], timer_num, true); +} + +uint64_t IRAM_ATTR timer_group_get_counter_value_in_isr(timer_group_t group_num, timer_idx_t timer_num) +{ + uint64_t val; + timer_ll_get_counter_value(TG[group_num], timer_num, &val); + return val; +} + +void IRAM_ATTR timer_group_set_alarm_value_in_isr(timer_group_t group_num, timer_idx_t timer_num, uint64_t alarm_val) +{ + timer_ll_set_alarm_value(TG[group_num], timer_num, alarm_val); +} + +void IRAM_ATTR timer_group_set_counter_enable_in_isr(timer_group_t group_num, timer_idx_t timer_num, timer_start_t counter_en) +{ + timer_ll_set_counter_enable(TG[group_num], timer_num, counter_en); +} + +void IRAM_ATTR timer_group_clr_intr_sta_in_isr(timer_group_t group_num, timer_intr_t intr_mask) +{ + timer_ll_intr_status_clear(TG[group_num], intr_mask); +} + +bool IRAM_ATTR timer_group_get_auto_reload_in_isr(timer_group_t group_num, timer_idx_t timer_num) +{ + return timer_ll_get_auto_reload(TG[group_num], timer_num); +} diff --git a/components/soc/esp32/include/hal/timer_ll.h b/components/soc/esp32/include/hal/timer_ll.h index cc0cd69c5..d74c00ee7 100644 --- a/components/soc/esp32/include/hal/timer_ll.h +++ b/components/soc/esp32/include/hal/timer_ll.h @@ -24,6 +24,65 @@ extern "C" { #include "hal/timer_types.h" #include "soc/timer_periph.h" +//Helper macro to get corresponding interrupt of a timer +#define TIMER_LL_GET_INTR(TIMER_IDX) ((TIMER_IDX)==TIMER_0? TIMER_INTR_T0: TIMER_INTR_T1) + +#define TIMER_LL_GET_HW(TIMER_GROUP) ((TIMER_GROUP)==0? &TIMERG0: &TIMERG1) + +_Static_assert(TIMER_INTR_T0 == TIMG_T0_INT_CLR, "Add mapping to LL interrupt handling, since it's no longer naturally compatible with the timer_intr_t"); +_Static_assert(TIMER_INTR_T1 == TIMG_T1_INT_CLR, "Add mapping to LL interrupt handling, since it's no longer naturally compatible with the timer_intr_t"); +_Static_assert(TIMER_INTR_WDT == TIMG_WDT_INT_CLR, "Add mapping to LL interrupt handling, since it's no longer naturally compatible with the timer_intr_t"); + +/** + * @brief Enable timer interrupt. + * + * @param hw Beginning address of the peripheral registers. + * @param intr_mask Interrupt enable mask + * + * @return None + */ +static inline void timer_ll_intr_enable(timg_dev_t *hw, timer_intr_t intr_mask) +{ + hw->int_ena.val |= intr_mask; +} + +/** + * @brief Disable timer interrupt. + * + * @param hw Beginning address of the peripheral registers. + * @param intr_mask Interrupt disable mask + * + * @return None + */ +static inline void timer_ll_intr_disable(timg_dev_t *hw, timer_intr_t intr_mask) +{ + hw->int_ena.val &= (~intr_mask); +} + +/** + * @brief Get timer interrupt status. + * + * @param hw Beginning address of the peripheral registers. + * + * @return Masked interrupt status + */ +static inline timer_intr_t timer_ll_intr_status_get(timg_dev_t *hw) +{ + return hw->int_raw.val; +} + +/** + * @brief Clear timer interrupt. + * + * @param hw Beginning address of the peripheral registers. + * @param intr_mask Interrupt mask to clear + * + * @return None + */ +static inline void timer_ll_intr_status_clear(timg_dev_t *hw, timer_intr_t intr_mask) +{ + hw->int_clr_timers.val = intr_mask; +} /** * @brief Get counter vaule from time-base counter @@ -40,8 +99,6 @@ static inline void timer_ll_get_counter_value(timg_dev_t *hw, timer_idx_t timer_ *timer_val = ((uint64_t) hw->hw_timer[timer_num].cnt_high << 32) | (hw->hw_timer[timer_num].cnt_low); } - - /** * @brief Set counter status, enable or disable counter. * @@ -56,7 +113,6 @@ static inline void timer_ll_set_counter_enable(timg_dev_t *hw, timer_idx_t timer hw->hw_timer[timer_num].config.enable = counter_en; } - /** * @brief Get auto reload mode. * diff --git a/components/soc/include/hal/timer_types.h b/components/soc/include/hal/timer_types.h index d555a2115..f1564eee9 100644 --- a/components/soc/include/hal/timer_types.h +++ b/components/soc/include/hal/timer_types.h @@ -20,6 +20,8 @@ extern "C" { #include #include +#include + /** * @brief Select a hardware timer from timer groups @@ -39,6 +41,16 @@ typedef enum { } timer_start_t; +/** + * @brief Interrupt types of the timer. + */ +//this is compatible with the value of esp32. +typedef enum { + TIMER_INTR_T0 = BIT(0), /*!< interrupt of timer 0 */ + TIMER_INTR_T1 = BIT(1), /*!< interrupt of timer 1 */ + TIMER_INTR_WDT = BIT(2), /*!< interrupt of watchdog */ +} timer_intr_t; + #ifdef __cplusplus } #endif From feea477023ccaa2ae05014ce083a7350fd04b1ae Mon Sep 17 00:00:00 2001 From: "Michael (XIAO Xufeng)" Date: Tue, 30 Jul 2019 17:22:51 +0800 Subject: [PATCH 4/6] timer_group: add LL functions for WDT --- components/soc/esp32/include/hal/timer_ll.h | 96 +++++++++++++++++++++ components/soc/include/hal/timer_types.h | 11 +++ 2 files changed, 107 insertions(+) diff --git a/components/soc/esp32/include/hal/timer_ll.h b/components/soc/esp32/include/hal/timer_ll.h index d74c00ee7..f4fa09d94 100644 --- a/components/soc/esp32/include/hal/timer_ll.h +++ b/components/soc/esp32/include/hal/timer_ll.h @@ -184,6 +184,102 @@ static inline void timer_ll_get_alarm_enable(timg_dev_t *hw, timer_idx_t timer_n *alarm_en = hw->hw_timer[timer_num].config.alarm_en; } +/* WDT operations */ + +/** + * Unlock/lock the WDT register in case of mis-operations. + * + * @param hw Beginning address of the peripheral registers. + * @param protect true to lock, false to unlock before operations. + */ + +FORCE_INLINE_ATTR void timer_ll_wdt_set_protect(timg_dev_t* hw, bool protect) +{ + hw->wdt_wprotect=(protect? 0: TIMG_WDT_WKEY_VALUE); +} + +/** + * Initialize WDT. + * + * @param hw Beginning address of the peripheral registers. + * + * @note Call ``timer_ll_wdt_set_protect first`` + */ +FORCE_INLINE_ATTR void timer_ll_wdt_init(timg_dev_t* hw) +{ + hw->wdt_config0.sys_reset_length=7; //3.2uS + hw->wdt_config0.cpu_reset_length=7; //3.2uS + //currently only level interrupt is supported + hw->wdt_config0.level_int_en = 1; + hw->wdt_config0.edge_int_en = 0; +} + +FORCE_INLINE_ATTR void timer_ll_wdt_set_tick(timg_dev_t* hw, int tick_time_us) +{ + hw->wdt_config1.clk_prescale=80*tick_time_us; +} + +FORCE_INLINE_ATTR void timer_ll_wdt_feed(timg_dev_t* hw) +{ + hw->wdt_feed = 1; +} + +FORCE_INLINE_ATTR void timer_ll_wdt_set_timeout(timg_dev_t* hw, int stage, uint32_t timeout_tick) +{ + switch (stage) { + case 0: + hw->wdt_config2=timeout_tick; + break; + case 1: + hw->wdt_config3=timeout_tick; + break; + case 2: + hw->wdt_config4=timeout_tick; + break; + case 3: + hw->wdt_config5=timeout_tick; + break; + default: + abort(); + } +} + +_Static_assert(TIMER_WDT_OFF == TIMG_WDT_STG_SEL_OFF, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with the timer_wdt_behavior_t"); +_Static_assert(TIMER_WDT_INT == TIMG_WDT_STG_SEL_INT, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with the timer_wdt_behavior_t"); +_Static_assert(TIMER_WDT_RESET_CPU == TIMG_WDT_STG_SEL_RESET_CPU, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with the timer_wdt_behavior_t"); +_Static_assert(TIMER_WDT_RESET_SYSTEM == TIMG_WDT_STG_SEL_RESET_SYSTEM, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with the timer_wdt_behavior_t"); + +FORCE_INLINE_ATTR void timer_ll_wdt_set_timeout_behavior(timg_dev_t* hw, int stage, timer_wdt_behavior_t behavior) +{ + switch (stage) { + case 0: + hw->wdt_config0.stg0 = behavior; + break; + case 1: + hw->wdt_config0.stg1 = behavior; + break; + case 2: + hw->wdt_config0.stg2 = behavior; + break; + case 3: + hw->wdt_config0.stg3 = behavior; + break; + default: + abort(); + } +} + +FORCE_INLINE_ATTR void timer_ll_wdt_set_enable(timg_dev_t* hw, bool enable) +{ + hw->wdt_config0.en = enable; +} + +FORCE_INLINE_ATTR void timer_ll_wdt_flashboot_en(timg_dev_t* hw, bool enable) +{ + hw->wdt_config0.flashboot_mod_en = enable; +} + + #ifdef __cplusplus } #endif diff --git a/components/soc/include/hal/timer_types.h b/components/soc/include/hal/timer_types.h index f1564eee9..8ab5757f2 100644 --- a/components/soc/include/hal/timer_types.h +++ b/components/soc/include/hal/timer_types.h @@ -51,6 +51,17 @@ typedef enum { TIMER_INTR_WDT = BIT(2), /*!< interrupt of watchdog */ } timer_intr_t; +/** + * @brief Behavior of the watchdog if a stage times out. + */ +//this is compatible with the value of esp32. +typedef enum { + TIMER_WDT_OFF = 0, ///< The stage is turned off + TIMER_WDT_INT = 1, ///< The stage will trigger an interrupt + TIMER_WDT_RESET_CPU = 2, ///< The stage will reset the CPU + TIMER_WDT_RESET_SYSTEM = 3, ///< The stage will reset the whole system +} timer_wdt_behavior_t; + #ifdef __cplusplus } #endif From 264ffbeb14106ae32c7e156e9c3ad0eff737b503 Mon Sep 17 00:00:00 2001 From: "Michael (XIAO Xufeng)" Date: Wed, 24 Jul 2019 23:18:19 +0800 Subject: [PATCH 5/6] timer_group: use the LL --- components/app_trace/gcov/gcov_rtio.c | 13 +- components/app_trace/test/test_trace.c | 72 +---------- .../bootloader_support/src/bootloader_init.c | 5 +- components/driver/test/test_timer.c | 112 +++++++----------- components/esp32/int_wdt.c | 58 +++++---- components/esp32/panic.c | 43 ++++--- components/esp32/system_api.c | 22 ++-- components/esp32/task_wdt.c | 65 +++++----- components/esp32/test/test_intr_alloc.c | 22 ++-- components/esp32/test/test_reset_reason.c | 5 +- .../include/esp_private/system_internal.h | 2 + components/esp_event/test/test_event.c | 16 +-- components/esp_ringbuf/test/test_ringbuf.c | 4 +- components/freemodbus/port/porttimer.c | 18 ++- components/freemodbus/port/porttimer_m.c | 20 ++-- .../freertos/test/test_freertos_eventgroups.c | 4 +- .../freertos/test/test_freertos_task_notify.c | 12 +- .../freertos/test/test_suspend_scheduler.c | 5 +- .../freertos/test/test_task_suspend_resume.c | 2 +- components/spi_flash/test/test_spi_flash.c | 4 +- .../main/timer_group_example_main.c | 24 ++-- .../sysview_tracing/main/sysview_tracing.c | 29 +---- 22 files changed, 217 insertions(+), 340 deletions(-) diff --git a/components/app_trace/gcov/gcov_rtio.c b/components/app_trace/gcov/gcov_rtio.c index d01d7c6b6..a6008b463 100644 --- a/components/app_trace/gcov/gcov_rtio.c +++ b/components/app_trace/gcov/gcov_rtio.c @@ -21,6 +21,7 @@ #include "soc/timer_periph.h" #include "esp_app_trace.h" #include "esp_private/dbg_stubs.h" +#include "hal/timer_ll.h" #if CONFIG_ESP32_GCOV_ENABLE @@ -124,13 +125,13 @@ void esp_gcov_dump(void) #endif while (!esp_apptrace_host_is_connected(ESP_APPTRACE_DEST_TRAX)) { // to avoid complains that task watchdog got triggered for other tasks - TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE; - TIMERG0.wdt_feed=1; - TIMERG0.wdt_wprotect=0; + timer_ll_wdt_set_protect(&TIMERG0, false); + timer_ll_wdt_feed(&TIMERG0); + timer_ll_wdt_set_protect(&TIMERG0, true); // to avoid reboot on INT_WDT - TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE; - TIMERG1.wdt_feed=1; - TIMERG1.wdt_wprotect=0; + timer_ll_wdt_set_protect(&TIMERG1, false); + timer_ll_wdt_feed(&TIMERG1); + timer_ll_wdt_set_protect(&TIMERG1, true); } esp_dbg_stub_gcov_dump_do(); diff --git a/components/app_trace/test/test_trace.c b/components/app_trace/test/test_trace.c index 3037ab431..2e19e5808 100644 --- a/components/app_trace/test/test_trace.c +++ b/components/app_trace/test/test_trace.c @@ -145,56 +145,16 @@ static void esp_apptrace_test_timer_isr(void *arg) } tim_arg->data.wr_cnt++; - if (tim_arg->group == 0) { - if (tim_arg->id == 0) { - TIMERG0.int_clr_timers.t0 = 1; - TIMERG0.hw_timer[0].update = 1; - TIMERG0.hw_timer[0].config.alarm_en = 1; - } else { - TIMERG0.int_clr_timers.t1 = 1; - TIMERG0.hw_timer[1].update = 1; - TIMERG0.hw_timer[1].config.alarm_en = 1; - } - } - if (tim_arg->group == 1) { - if (tim_arg->id == 0) { - TIMERG1.int_clr_timers.t0 = 1; - TIMERG1.hw_timer[0].update = 1; - TIMERG1.hw_timer[0].config.alarm_en = 1; - } else { - TIMERG1.int_clr_timers.t1 = 1; - TIMERG1.hw_timer[1].update = 1; - TIMERG1.hw_timer[1].config.alarm_en = 1; - } - } + timer_group_intr_clr_in_isr(tim_arg->group, tim_arg->id); + timer_group_enable_alarm_in_isr(tim_arg->group, tim_arg->id); } static void esp_apptrace_test_timer_isr_crash(void *arg) { esp_apptrace_test_timer_arg_t *tim_arg = (esp_apptrace_test_timer_arg_t *)arg; - if (tim_arg->group == 0) { - if (tim_arg->id == 0) { - TIMERG0.int_clr_timers.t0 = 1; - TIMERG0.hw_timer[0].update = 1; - TIMERG0.hw_timer[0].config.alarm_en = 1; - } else { - TIMERG0.int_clr_timers.t1 = 1; - TIMERG0.hw_timer[1].update = 1; - TIMERG0.hw_timer[1].config.alarm_en = 1; - } - } - if (tim_arg->group == 1) { - if (tim_arg->id == 0) { - TIMERG1.int_clr_timers.t0 = 1; - TIMERG1.hw_timer[0].update = 1; - TIMERG1.hw_timer[0].config.alarm_en = 1; - } else { - TIMERG1.int_clr_timers.t1 = 1; - TIMERG1.hw_timer[1].update = 1; - TIMERG1.hw_timer[1].config.alarm_en = 1; - } - } + timer_group_intr_clr_in_isr(tim_arg->group, tim_arg->id); + timer_group_enable_alarm_in_isr(tim_arg->group, tim_arg->id); if (tim_arg->data.wr_cnt < ESP_APPTRACE_TEST_BLOCKS_BEFORE_CRASH) { uint32_t *ts = (uint32_t *)(tim_arg->data.buf + sizeof(uint32_t)); *ts = (uint32_t)esp_apptrace_test_ts_get();//xthal_get_ccount();//xTaskGetTickCount(); @@ -850,28 +810,8 @@ static void esp_sysview_test_timer_isr(void *arg) //ESP_APPTRACE_TEST_LOGI("tim-%d: IRQ %d/%d\n", tim_arg->id, tim_arg->group, tim_arg->timer); - if (tim_arg->group == 0) { - if (tim_arg->timer == 0) { - TIMERG0.int_clr_timers.t0 = 1; - TIMERG0.hw_timer[0].update = 1; - TIMERG0.hw_timer[0].config.alarm_en = 1; - } else { - TIMERG0.int_clr_timers.t1 = 1; - TIMERG0.hw_timer[1].update = 1; - TIMERG0.hw_timer[1].config.alarm_en = 1; - } - } - if (tim_arg->group == 1) { - if (tim_arg->timer == 0) { - TIMERG1.int_clr_timers.t0 = 1; - TIMERG1.hw_timer[0].update = 1; - TIMERG1.hw_timer[0].config.alarm_en = 1; - } else { - TIMERG1.int_clr_timers.t1 = 1; - TIMERG1.hw_timer[1].update = 1; - TIMERG1.hw_timer[1].config.alarm_en = 1; - } - } + timer_group_intr_clr_in_isr(tim_arg->group, tim_arg->id); + timer_group_enable_alarm_in_isr(tim_arg->group, tim_arg->id); } static void esp_sysviewtrace_test_task(void *p) diff --git a/components/bootloader_support/src/bootloader_init.c b/components/bootloader_support/src/bootloader_init.c index 26b8fd0b3..d3196dd85 100644 --- a/components/bootloader_support/src/bootloader_init.c +++ b/components/bootloader_support/src/bootloader_init.c @@ -53,6 +53,7 @@ #include "bootloader_flash_config.h" #include "flash_qio_mode.h" +#include "hal/timer_ll.h" extern int _bss_start; extern int _bss_end; @@ -158,8 +159,8 @@ static esp_err_t bootloader_main(void) /* disable watch dog here */ rtc_wdt_disable(); #endif - REG_SET_FIELD(TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY, TIMG_WDT_WKEY_VALUE); - REG_CLR_BIT( TIMG_WDTCONFIG0_REG(0), TIMG_WDT_FLASHBOOT_MOD_EN ); + timer_ll_wdt_set_protect(&TIMERG0, false); + timer_ll_wdt_flashboot_en(&TIMERG0, false); #ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH const uint32_t spiconfig = ets_efuse_get_spiconfig(); diff --git a/components/driver/test/test_timer.c b/components/driver/test/test_timer.c index bc5f3ae75..7aae242eb 100644 --- a/components/driver/test/test_timer.c +++ b/components/driver/test/test_timer.c @@ -11,68 +11,44 @@ #define TIMER_DELTA 0.001 static bool alarm_flag; -// group0 interruption -static void test_timer_group0_isr(void *para) -{ - int timer_idx = (int) para; - uint64_t timer_val; - double time; - uint64_t alarm_value; - alarm_flag = true; - if (TIMERG0.hw_timer[timer_idx].config.autoreload == 1) { - if (timer_idx == 0) { - TIMERG0.int_clr_timers.t0 = 1; - } else { - TIMERG0.int_clr_timers.t1 = 1; - } - ets_printf("This is TG0 timer[%d] reload-timer alarm!\n", timer_idx); - timer_get_counter_value(TIMER_GROUP_0, timer_idx, &timer_val); - timer_get_counter_time_sec(TIMER_GROUP_0, timer_idx, &time); - ets_printf("time: %.8f S\n", time); - } else { - if (timer_idx == 0) { - TIMERG0.int_clr_timers.t0 = 1; - } else { - TIMERG0.int_clr_timers.t1 = 1; - } - ets_printf("This is TG0 timer[%d] count-up-timer alarm!\n", timer_idx); - timer_get_counter_value(TIMER_GROUP_0, timer_idx, &timer_val); - timer_get_counter_time_sec(TIMER_GROUP_0, timer_idx, &time); - timer_get_alarm_value(TIMER_GROUP_0, timer_idx, &alarm_value); - ets_printf("time: %.8f S\n", time); - double alarm_time = (double) alarm_value / TIMER_SCALE; - ets_printf("alarm_time: %.8f S\n", alarm_time); - } -} +typedef struct { + timer_group_t timer_group; + timer_idx_t timer_idx; +} timer_info_t; -// group1 interruption -static void test_timer_group1_isr(void *para) +#define TIMER_INFO_INIT(TG, TID) {.timer_group = (TG), .timer_idx = (TID),} + +static timer_info_t timer_info[4] = { + TIMER_INFO_INIT(TIMER_GROUP_0, TIMER_0), + TIMER_INFO_INIT(TIMER_GROUP_0, TIMER_1), + TIMER_INFO_INIT(TIMER_GROUP_1, TIMER_0), + TIMER_INFO_INIT(TIMER_GROUP_1, TIMER_1), +}; + +#define GET_TIMER_INFO(TG, TID) (&timer_info[(TG)*2+(TID)]) + +// timer group interruption +static void test_timer_group_isr(void *para) { - int timer_idx = (int) para; + timer_info_t* info = (timer_info_t*) para; + const timer_group_t timer_group = info->timer_group; + const timer_idx_t timer_idx = info->timer_idx; uint64_t timer_val; double time; uint64_t alarm_value; alarm_flag = true; - if (TIMERG1.hw_timer[timer_idx].config.autoreload == 1) { - if (timer_idx == 0) { - TIMERG1.int_clr_timers.t0 = 1; - } else { - TIMERG1.int_clr_timers.t1 = 1; - } - ets_printf("This is TG1 timer[%d] reload-timer alarm!\n", timer_idx); - timer_get_counter_value(TIMER_GROUP_1, timer_idx, &timer_val); - timer_get_counter_time_sec(TIMER_GROUP_1, timer_idx, &time); + if (timer_group_get_auto_reload_in_isr(timer_group, timer_idx)) { + timer_group_intr_clr_in_isr(timer_group, timer_idx); + ets_printf("This is TG%d timer[%d] reload-timer alarm!\n", timer_group, timer_idx); + timer_get_counter_value(timer_group, timer_idx, &timer_val); + timer_get_counter_time_sec(timer_group, timer_idx, &time); ets_printf("time: %.8f S\n", time); } else { - if (timer_idx == 0) { - TIMERG1.int_clr_timers.t0 = 1; - } else { - TIMERG1.int_clr_timers.t1 = 1; - } - ets_printf("This is TG1 timer[%d] count-up-timer alarm!\n", timer_idx); - timer_get_counter_value(TIMER_GROUP_1, timer_idx, &timer_val); - timer_get_counter_time_sec(TIMER_GROUP_1, timer_idx, &time); - timer_get_alarm_value(TIMER_GROUP_1, timer_idx, &alarm_value); + timer_group_intr_clr_in_isr(timer_group, timer_idx); + ets_printf("This is TG%d timer[%d] count-up-timer alarm!\n", timer_group, timer_idx); + timer_get_counter_value(timer_group, timer_idx, &timer_val); + timer_get_counter_time_sec(timer_group, timer_idx, &time); + timer_get_alarm_value(timer_group, timer_idx, &alarm_value); ets_printf("time: %.8f S\n", time); double alarm_time = (double) alarm_value / TIMER_SCALE; ets_printf("alarm_time: %.8f S\n", alarm_time); @@ -86,13 +62,7 @@ static void tg_timer_init(int timer_group, int timer_idx, double alarm_time) timer_set_counter_value(timer_group, timer_idx, 0x0); timer_set_alarm_value(timer_group, timer_idx, alarm_time * TIMER_SCALE); timer_enable_intr(timer_group, timer_idx); - if (timer_group == 0) { - timer_isr_register(timer_group, timer_idx, test_timer_group0_isr, - (void *) timer_idx, ESP_INTR_FLAG_LOWMED, NULL); - } else { - timer_isr_register(timer_group, timer_idx, test_timer_group1_isr, - (void *) timer_idx, ESP_INTR_FLAG_LOWMED, NULL); - } + timer_isr_register(timer_group, timer_idx, test_timer_group_isr, GET_TIMER_INFO(timer_group, timer_idx), ESP_INTR_FLAG_LOWMED, NULL); timer_start(timer_group, timer_idx); } @@ -747,8 +717,8 @@ TEST_CASE("Timer enable timer interrupt", "[hw_timer]") // enable timer_intr0 timer_set_counter_value(TIMER_GROUP_0, TIMER_0, set_timer_val); timer_set_alarm_value(TIMER_GROUP_0, TIMER_0, 1.2 * TIMER_SCALE); - timer_isr_register(TIMER_GROUP_0, TIMER_0, test_timer_group0_isr, - (void *) TIMER_0, ESP_INTR_FLAG_LOWMED, NULL); + timer_isr_register(TIMER_GROUP_0, TIMER_0, test_timer_group_isr, + GET_TIMER_INFO(TIMER_GROUP_0, TIMER_0), ESP_INTR_FLAG_LOWMED, NULL); timer_start(TIMER_GROUP_0, TIMER_0); vTaskDelay(2000 / portTICK_PERIOD_MS); TEST_ASSERT(alarm_flag == true) @@ -765,8 +735,8 @@ TEST_CASE("Timer enable timer interrupt", "[hw_timer]") // enable timer_intr1 timer_set_counter_value(TIMER_GROUP_1, TIMER_1, set_timer_val); timer_set_alarm_value(TIMER_GROUP_1, TIMER_1, 1.2 * TIMER_SCALE); - timer_isr_register(TIMER_GROUP_1, TIMER_1, test_timer_group1_isr, - (void *) TIMER_1, ESP_INTR_FLAG_LOWMED, NULL); + timer_isr_register(TIMER_GROUP_1, TIMER_1, test_timer_group_isr, + GET_TIMER_INFO(TIMER_GROUP_1, TIMER_1), ESP_INTR_FLAG_LOWMED, NULL); timer_start(TIMER_GROUP_1, TIMER_1); vTaskDelay(2000 / portTICK_PERIOD_MS); TEST_ASSERT(alarm_flag == true) @@ -813,23 +783,21 @@ TEST_CASE("Timer enable timer group interrupt", "[hw_timer][ignore]") all_timer_set_alarm_value(1.2); // enable timer group - timer_group_intr_enable(TIMER_GROUP_0, TIMG_T0_INT_ENA_M); - timer_isr_register(TIMER_GROUP_0, TIMER_0, test_timer_group0_isr, - (void *) TIMER_0, ESP_INTR_FLAG_LOWMED, NULL); + timer_group_intr_enable(TIMER_GROUP_0, TIMER_INTR_T0); + timer_isr_register(TIMER_GROUP_0, TIMER_0, test_timer_group_isr, GET_TIMER_INFO(TIMER_GROUP_0, TIMER_0), ESP_INTR_FLAG_LOWMED, NULL); timer_start(TIMER_GROUP_0, TIMER_0); vTaskDelay(2000 / portTICK_PERIOD_MS); TEST_ASSERT(alarm_flag == true); //test enable auto_reload alarm_flag = false; - timer_group_intr_disable(TIMER_GROUP_0, TIMG_T0_INT_ENA_M); + timer_group_intr_disable(TIMER_GROUP_0, TIMER_INTR_T0); timer_start(TIMER_GROUP_0, TIMER_0); vTaskDelay(2000 / portTICK_PERIOD_MS); TEST_ASSERT(alarm_flag == false); - timer_group_intr_enable(TIMER_GROUP_0, TIMG_T0_INT_ENA_M); - timer_isr_register(TIMER_GROUP_0, TIMER_0, test_timer_group0_isr, - (void *) TIMER_0, ESP_INTR_FLAG_LOWMED, NULL); + timer_group_intr_enable(TIMER_GROUP_0, TIMER_INTR_T0); + timer_isr_register(TIMER_GROUP_0, TIMER_0, test_timer_group_isr, GET_TIMER_INFO(TIMER_GROUP_0, TIMER_0), ESP_INTR_FLAG_LOWMED, NULL); timer_start(TIMER_GROUP_0, TIMER_0); vTaskDelay(2000 / portTICK_PERIOD_MS); TEST_ASSERT(alarm_flag == true); diff --git a/components/esp32/int_wdt.c b/components/esp32/int_wdt.c index 8f18f7157..2bfff8078 100644 --- a/components/esp32/int_wdt.c +++ b/components/esp32/int_wdt.c @@ -30,10 +30,11 @@ #include "driver/timer.h" #include "driver/periph_ctrl.h" #include "esp_int_wdt.h" +#include "hal/timer_ll.h" #if CONFIG_ESP_INT_WDT - +#define TG1_WDT_TICK_US 500 #define WDT_INT_NUM 24 @@ -48,11 +49,15 @@ static void IRAM_ATTR tick_hook(void) { } else { //Only feed wdt if app cpu also ticked. if (int_wdt_app_cpu_ticked) { - TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE; - TIMERG1.wdt_config2=CONFIG_ESP_INT_WDT_TIMEOUT_MS*2; //Set timeout before interrupt - TIMERG1.wdt_config3=CONFIG_ESP_INT_WDT_TIMEOUT_MS*4; //Set timeout before reset - TIMERG1.wdt_feed=1; - TIMERG1.wdt_wprotect=0; + timer_ll_wdt_set_protect(&TIMERG1, false); + //Set timeout before interrupt + timer_ll_wdt_set_timeout(&TIMERG1, 0, + CONFIG_ESP_INT_WDT_TIMEOUT_MS*1000/TG1_WDT_TICK_US); + //Set timeout before reset + timer_ll_wdt_set_timeout(&TIMERG1, 1, + 2*CONFIG_ESP_INT_WDT_TIMEOUT_MS*1000/TG1_WDT_TICK_US); + timer_ll_wdt_feed(&TIMERG1); + timer_ll_wdt_set_protect(&TIMERG1, true); int_wdt_app_cpu_ticked=false; } } @@ -60,33 +65,36 @@ static void IRAM_ATTR tick_hook(void) { #else static void IRAM_ATTR tick_hook(void) { if (xPortGetCoreID()!=0) return; - TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE; - TIMERG1.wdt_config2=CONFIG_ESP_INT_WDT_TIMEOUT_MS*2; //Set timeout before interrupt - TIMERG1.wdt_config3=CONFIG_ESP_INT_WDT_TIMEOUT_MS*4; //Set timeout before reset - TIMERG1.wdt_feed=1; - TIMERG1.wdt_wprotect=0; + timer_ll_wdt_set_protect(&TIMERG1, false); + //Set timeout before interrupt + timer_ll_wdt_set_timeout(&TIMERG1, 0, CONFIG_ESP_INT_WDT_TIMEOUT_MS*1000/TG1_WDT_TICK_US); + //Set timeout before reset + timer_ll_wdt_set_timeout(&TIMERG1, 1, 2*CONFIG_ESP_INT_WDT_TIMEOUT_MS*1000/TG1_WDT_TICK_US); + timer_ll_wdt_feed(&TIMERG1); + timer_ll_wdt_set_protect(&TIMERG1, true); } #endif void esp_int_wdt_init(void) { periph_module_enable(PERIPH_TIMG1_MODULE); - TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE; - TIMERG1.wdt_config0.sys_reset_length=7; //3.2uS - TIMERG1.wdt_config0.cpu_reset_length=7; //3.2uS - TIMERG1.wdt_config0.level_int_en=1; - TIMERG1.wdt_config0.stg0=TIMG_WDT_STG_SEL_INT; //1st stage timeout: interrupt - TIMERG1.wdt_config0.stg1=TIMG_WDT_STG_SEL_RESET_SYSTEM; //2nd stage timeout: reset system - TIMERG1.wdt_config1.clk_prescale=80*500; //Prescaler: wdt counts in ticks of 0.5mS //The timer configs initially are set to 5 seconds, to make sure the CPU can start up. The tick hook sets //it to their actual value. - TIMERG1.wdt_config2=10000; - TIMERG1.wdt_config3=10000; - TIMERG1.wdt_config0.en=1; - TIMERG1.wdt_feed=1; - TIMERG1.wdt_wprotect=0; - TIMERG1.int_clr_timers.wdt=1; - timer_group_intr_enable(TIMER_GROUP_1, TIMG_WDT_INT_ENA_M); + timer_ll_wdt_set_protect(&TIMERG1, false); + timer_ll_wdt_init(&TIMERG1); + timer_ll_wdt_set_tick(&TIMERG1, TG1_WDT_TICK_US); //Prescaler: wdt counts in ticks of TG1_WDT_TICK_US + //1st stage timeout: interrupt + timer_ll_wdt_set_timeout_behavior(&TIMERG1, 0, TIMER_WDT_INT); + timer_ll_wdt_set_timeout(&TIMERG1, 0, 5*1000*1000/TG1_WDT_TICK_US); + //2nd stage timeout: reset system + timer_ll_wdt_set_timeout_behavior(&TIMERG1, 1, TIMER_WDT_RESET_SYSTEM); + timer_ll_wdt_set_timeout(&TIMERG1, 1, 5*1000*1000/TG1_WDT_TICK_US); + timer_ll_wdt_set_enable(&TIMERG1, true); + timer_ll_wdt_feed(&TIMERG1); + timer_ll_wdt_set_protect(&TIMERG1, true); + + timer_ll_intr_status_clear(&TIMERG1, TIMER_INTR_WDT); + timer_group_intr_enable(TIMER_GROUP_1, TIMER_INTR_WDT); } void esp_int_wdt_cpu_init(void) diff --git a/components/esp32/panic.c b/components/esp32/panic.c index 4a104f029..b0c6401de 100644 --- a/components/esp32/panic.c +++ b/components/esp32/panic.c @@ -44,6 +44,8 @@ #include "esp_private/system_internal.h" #include "sdkconfig.h" #include "esp_ota_ops.h" +#include "driver/timer.h" +#include "hal/timer_ll.h" #if CONFIG_SYSVIEW_ENABLE #include "SEGGER_RTT.h" #endif @@ -311,7 +313,7 @@ void panicHandler(XtExcFrame *frame) disableAllWdts(); if (frame->exccause == PANIC_RSN_INTWDT_CPU0 || frame->exccause == PANIC_RSN_INTWDT_CPU1) { - TIMERG1.int_clr_timers.wdt = 1; + timer_group_clr_intr_sta_in_isr(TIMER_GROUP_1, TIMER_INTR_WDT); } #if CONFIG_ESP32_APPTRACE_ENABLE #if CONFIG_SYSVIEW_ENABLE @@ -401,19 +403,21 @@ static void illegal_instruction_helper(XtExcFrame *frame) */ static void reconfigureAllWdts(void) { - TIMERG0.wdt_wprotect = TIMG_WDT_WKEY_VALUE; - TIMERG0.wdt_feed = 1; - TIMERG0.wdt_config0.sys_reset_length = 7; //3.2uS - TIMERG0.wdt_config0.cpu_reset_length = 7; //3.2uS - TIMERG0.wdt_config0.stg0 = TIMG_WDT_STG_SEL_RESET_SYSTEM; //1st stage timeout: reset system - TIMERG0.wdt_config1.clk_prescale = 80 * 500; //Prescaler: wdt counts in ticks of 0.5mS - TIMERG0.wdt_config2 = 2000; //1 second before reset - TIMERG0.wdt_config0.en = 1; - TIMERG0.wdt_wprotect = 0; + timer_ll_wdt_set_protect(&TIMERG0, false); + timer_ll_wdt_feed(&TIMERG0); + timer_ll_wdt_init(&TIMERG0); + timer_ll_wdt_set_tick(&TIMERG0, TG0_WDT_TICK_US); //Prescaler: wdt counts in ticks of TG0_WDT_TICK_US + //1st stage timeout: reset system + timer_ll_wdt_set_timeout_behavior(&TIMERG0, 0, TIMER_WDT_RESET_SYSTEM); + //1 second before reset + timer_ll_wdt_set_timeout(&TIMERG0, 0, 1000*1000/TG0_WDT_TICK_US); + timer_ll_wdt_set_enable(&TIMERG0, true); + timer_ll_wdt_set_protect(&TIMERG0, true); + //Disable wdt 1 - TIMERG1.wdt_wprotect = TIMG_WDT_WKEY_VALUE; - TIMERG1.wdt_config0.en = 0; - TIMERG1.wdt_wprotect = 0; + timer_ll_wdt_set_protect(&TIMERG1, false); + timer_ll_wdt_set_enable(&TIMERG1, false); + timer_ll_wdt_set_protect(&TIMERG1, true); } /* @@ -421,12 +425,13 @@ static void reconfigureAllWdts(void) */ static inline void disableAllWdts(void) { - TIMERG0.wdt_wprotect = TIMG_WDT_WKEY_VALUE; - TIMERG0.wdt_config0.en = 0; - TIMERG0.wdt_wprotect = 0; - TIMERG1.wdt_wprotect = TIMG_WDT_WKEY_VALUE; - TIMERG1.wdt_config0.en = 0; - TIMERG1.wdt_wprotect = 0; + timer_ll_wdt_set_protect(&TIMERG0, false); + timer_ll_wdt_set_enable(&TIMERG0, false); + timer_ll_wdt_set_protect(&TIMERG0, true); + + timer_ll_wdt_set_protect(&TIMERG1, false); + timer_ll_wdt_set_enable(&TIMERG1, false); + timer_ll_wdt_set_protect(&TIMERG1, true); } static void esp_panic_dig_reset(void) __attribute__((noreturn)); diff --git a/components/esp32/system_api.c b/components/esp32/system_api.c index 570c0997a..7d3f1a90b 100644 --- a/components/esp32/system_api.c +++ b/components/esp32/system_api.c @@ -38,6 +38,7 @@ #include "esp_private/system_internal.h" #include "esp_efuse.h" #include "esp_efuse_table.h" +#include "hal/timer_ll.h" static const char* TAG = "system_api"; @@ -204,7 +205,7 @@ esp_err_t esp_read_mac(uint8_t* mac, esp_mac_type_t type) ESP_LOGW(TAG, "incorrect mac type"); break; } - + return ESP_OK; } @@ -281,12 +282,13 @@ void IRAM_ATTR esp_restart_noos(void) esp_dport_access_int_abort(); // Disable TG0/TG1 watchdogs - TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE; - TIMERG0.wdt_config0.en = 0; - TIMERG0.wdt_wprotect=0; - TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE; - TIMERG1.wdt_config0.en = 0; - TIMERG1.wdt_wprotect=0; + timer_ll_wdt_set_protect(&TIMERG0, false); + timer_ll_wdt_set_enable(&TIMERG0, false); + timer_ll_wdt_set_protect(&TIMERG0, true); + + timer_ll_wdt_set_protect(&TIMERG1, false); + timer_ll_wdt_set_enable(&TIMERG1, false); + timer_ll_wdt_set_protect(&TIMERG1, true); // Flush any data left in UART FIFOs uart_tx_wait_idle(0); @@ -307,10 +309,10 @@ void IRAM_ATTR esp_restart_noos(void) WRITE_PERI_REG(GPIO_FUNC5_IN_SEL_CFG_REG, 0x30); // Reset wifi/bluetooth/ethernet/sdio (bb/mac) - DPORT_SET_PERI_REG_MASK(DPORT_CORE_RST_EN_REG, + DPORT_SET_PERI_REG_MASK(DPORT_CORE_RST_EN_REG, DPORT_BB_RST | DPORT_FE_RST | DPORT_MAC_RST | DPORT_BT_RST | DPORT_BTMAC_RST | DPORT_SDIO_RST | - DPORT_SDIO_HOST_RST | DPORT_EMAC_RST | DPORT_MACPWR_RST | + DPORT_SDIO_HOST_RST | DPORT_EMAC_RST | DPORT_MACPWR_RST | DPORT_RW_BTMAC_RST | DPORT_RW_BTLP_RST); DPORT_REG_WRITE(DPORT_CORE_RST_EN_REG, 0); @@ -370,7 +372,7 @@ static void get_chip_info_esp32(esp_chip_info_t* out_info) { uint32_t reg = REG_READ(EFUSE_BLK0_RDATA3_REG); memset(out_info, 0, sizeof(*out_info)); - + out_info->model = CHIP_ESP32; if ((reg & EFUSE_RD_CHIP_VER_REV1_M) != 0) { out_info->revision = 1; diff --git a/components/esp32/task_wdt.c b/components/esp32/task_wdt.c index 6675a1a98..c1aa4e976 100644 --- a/components/esp32/task_wdt.c +++ b/components/esp32/task_wdt.c @@ -34,6 +34,8 @@ #include "driver/periph_ctrl.h" #include "esp_task_wdt.h" #include "esp_private/system_internal.h" +#include "hal/timer_ll.h" + static const char *TAG = "task_wdt"; @@ -107,9 +109,9 @@ static twdt_task_t *find_task_in_twdt_list(TaskHandle_t handle, bool *all_reset) static void reset_hw_timer(void) { //All tasks have reset; time to reset the hardware timer. - TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE; - TIMERG0.wdt_feed=1; - TIMERG0.wdt_wprotect=0; + timer_ll_wdt_set_protect(&TIMERG0, false); + timer_ll_wdt_feed(&TIMERG0); + timer_ll_wdt_set_protect(&TIMERG0, true); //Clear all has_reset flags in list for (twdt_task_t *task = twdt_config->list; task != NULL; task = task->next){ task->has_reset=false; @@ -137,11 +139,11 @@ static void task_wdt_isr(void *arg) twdt_task_t *twdttask; const char *cpu; //Reset hardware timer so that 2nd stage timeout is not reached (will trigger system reset) - TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE; - TIMERG0.wdt_feed=1; - TIMERG0.wdt_wprotect=0; + timer_ll_wdt_set_protect(&TIMERG0, false); + timer_ll_wdt_feed(&TIMERG0); + timer_ll_wdt_set_protect(&TIMERG0, true); //Acknowledge interrupt - TIMERG0.int_clr_timers.wdt=1; + timer_group_clr_intr_sta_in_isr(TIMER_GROUP_0, TIMER_INTR_WDT); //We are taking a spinlock while doing I/O (ESP_EARLY_LOGE) here. Normally, that is a pretty //bad thing, possibly (temporarily) hanging up the 2nd core and stopping FreeRTOS. In this case, //something bad already happened and reporting this is considered more important @@ -198,32 +200,33 @@ esp_err_t esp_task_wdt_init(uint32_t timeout, bool panic) //Configure hardware timer periph_module_enable(PERIPH_TIMG0_MODULE); - TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE; //Disable write protection - TIMERG0.wdt_config0.sys_reset_length=7; //3.2uS - TIMERG0.wdt_config0.cpu_reset_length=7; //3.2uS - TIMERG0.wdt_config0.level_int_en=1; - TIMERG0.wdt_config0.stg0=TIMG_WDT_STG_SEL_INT; //1st stage timeout: interrupt - TIMERG0.wdt_config0.stg1=TIMG_WDT_STG_SEL_RESET_SYSTEM; //2nd stage timeout: reset system - TIMERG0.wdt_config1.clk_prescale=80*500; //Prescaler: wdt counts in ticks of 0.5mS - TIMERG0.wdt_config2=twdt_config->timeout*2000; //Set timeout before interrupt - TIMERG0.wdt_config3=twdt_config->timeout*4000; //Set timeout before reset - TIMERG0.wdt_config0.en=1; - TIMERG0.wdt_feed=1; - TIMERG0.wdt_wprotect=0; //Enable write protection - - }else{ //twdt_config previously initialized + timer_ll_wdt_set_protect(&TIMERG0, false); //Disable write protection + timer_ll_wdt_init(&TIMERG0); + timer_ll_wdt_set_tick(&TIMERG0, TG0_WDT_TICK_US); //Prescaler: wdt counts in ticks of TG0_WDT_TICK_US + //1st stage timeout: interrupt + timer_ll_wdt_set_timeout_behavior(&TIMERG0, 0, TIMER_WDT_INT); + timer_ll_wdt_set_timeout(&TIMERG0, 0, twdt_config->timeout*1000*1000/TG0_WDT_TICK_US); + //2nd stage timeout: reset system + timer_ll_wdt_set_timeout_behavior(&TIMERG0, 1, TIMER_WDT_RESET_SYSTEM); + timer_ll_wdt_set_timeout(&TIMERG0, 1, 2*twdt_config->timeout*1000*1000/TG0_WDT_TICK_US); + timer_ll_wdt_set_enable(&TIMERG0, true); + timer_ll_wdt_feed(&TIMERG0); + timer_ll_wdt_set_protect(&TIMERG0, true); //Enable write protection + } else { //twdt_config previously initialized //Reconfigure task wdt twdt_config->panic = panic; twdt_config->timeout = timeout; //Reconfigure hardware timer - TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE; //Disable write protection - TIMERG0.wdt_config0.en=0; //Disable timer - TIMERG0.wdt_config2=twdt_config->timeout*2000; //Set timeout before interrupt - TIMERG0.wdt_config3=twdt_config->timeout*4000; //Set timeout before reset - TIMERG0.wdt_config0.en=1; //Renable timer - TIMERG0.wdt_feed=1; //Reset timer - TIMERG0.wdt_wprotect=0; //Enable write protection + timer_ll_wdt_set_protect(&TIMERG0, false); //Disable write protection + timer_ll_wdt_set_enable(&TIMERG0, false); //Disable timer + //Set timeout before interrupt + timer_ll_wdt_set_timeout(&TIMERG0, 0, twdt_config->timeout*1000*1000/TG0_WDT_TICK_US); + //Set timeout before reset + timer_ll_wdt_set_timeout(&TIMERG0, 1, 2*twdt_config->timeout*1000*1000/TG0_WDT_TICK_US); + timer_ll_wdt_set_enable(&TIMERG0, true); //Renable timer + timer_ll_wdt_feed(&TIMERG0); //Reset timer + timer_ll_wdt_set_protect(&TIMERG0, true); //Enable write protection } portEXIT_CRITICAL(&twdt_spinlock); return ESP_OK; @@ -238,9 +241,9 @@ esp_err_t esp_task_wdt_deinit(void) ASSERT_EXIT_CRIT_RETURN((twdt_config->list == NULL), ESP_ERR_INVALID_STATE); //Disable hardware timer - TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE; //Disable write protection - TIMERG0.wdt_config0.en=0; //Disable timer - TIMERG0.wdt_wprotect=0; //Enable write protection + timer_ll_wdt_set_protect(&TIMERG0, false); //Disable write protection + timer_ll_wdt_set_enable(&TIMERG0, false); //Disable timer + timer_ll_wdt_set_protect(&TIMERG0, true); //Enable write protection ESP_ERROR_CHECK(esp_intr_free(twdt_config->intr_handle)); //Unregister interrupt free(twdt_config); //Free twdt_config diff --git a/components/esp32/test/test_intr_alloc.c b/components/esp32/test/test_intr_alloc.c index 85654c1ae..b17fb9e83 100644 --- a/components/esp32/test/test_intr_alloc.c +++ b/components/esp32/test/test_intr_alloc.c @@ -55,24 +55,20 @@ static void timer_isr(void *arg) int timer_idx = (int)arg; count[timer_idx]++; if (timer_idx==0) { - TIMERG0.int_clr_timers.t0 = 1; - TIMERG0.hw_timer[0].update=1; - TIMERG0.hw_timer[0].config.alarm_en = 1; + timer_group_intr_clr_in_isr(TIMER_GROUP_0, TIMER_0); + timer_group_enable_alarm_in_isr(TIMER_GROUP_0, TIMER_0); } if (timer_idx==1) { - TIMERG0.int_clr_timers.t1 = 1; - TIMERG0.hw_timer[1].update=1; - TIMERG0.hw_timer[1].config.alarm_en = 1; + timer_group_intr_clr_in_isr(TIMER_GROUP_0, TIMER_1); + timer_group_enable_alarm_in_isr(TIMER_GROUP_0, TIMER_1); } if (timer_idx==2) { - TIMERG1.int_clr_timers.t0 = 1; - TIMERG1.hw_timer[0].update=1; - TIMERG1.hw_timer[0].config.alarm_en = 1; + timer_group_intr_clr_in_isr(TIMER_GROUP_1, TIMER_0); + timer_group_enable_alarm_in_isr(TIMER_GROUP_1, TIMER_0); } if (timer_idx==3) { - TIMERG1.int_clr_timers.t1 = 1; - TIMERG1.hw_timer[1].update=1; - TIMERG1.hw_timer[1].config.alarm_en = 1; + timer_group_intr_clr_in_isr(TIMER_GROUP_1, TIMER_1); + timer_group_enable_alarm_in_isr(TIMER_GROUP_1, TIMER_1); } // ets_printf("int %d\n", timer_idx); } @@ -280,7 +276,7 @@ TEST_CASE("allocate 2 handlers for a same source and remove the later one","[esp r=esp_intr_alloc(ETS_SPI2_INTR_SOURCE, ESP_INTR_FLAG_SHARED, int_handler2, &ctx, &handle2); TEST_ESP_OK(r); SPI2.slave.trans_inten = 1; - + printf("trigger first time.\n"); SPI2.slave.trans_done = 1; diff --git a/components/esp32/test/test_reset_reason.c b/components/esp32/test/test_reset_reason.c index da03e8c1e..1aed30039 100644 --- a/components/esp32/test/test_reset_reason.c +++ b/components/esp32/test/test_reset_reason.c @@ -280,11 +280,12 @@ static void timer_group_test_first_stage(void) //Start timer timer_start(TIMER_GROUP_0, TIMER_0); //Waiting for timer_group to generate an interrupt - while( !TIMERG0.int_raw.t0 && loop_cnt++ < 100) { + while( !(timer_group_intr_get_in_isr(TIMER_GROUP_0) & TIMER_INTR_T0) && + loop_cnt++ < 100) { vTaskDelay(200); } //TIMERG0.int_raw.t0 == 1 means an interruption has occurred - TEST_ASSERT_EQUAL(1, TIMERG0.int_raw.t0); + TEST_ASSERT(timer_group_intr_get_in_isr(TIMER_GROUP_0) & TIMER_INTR_T0); esp_restart(); } diff --git a/components/esp_common/include/esp_private/system_internal.h b/components/esp_common/include/esp_private/system_internal.h index e0d95d2f7..8ecef8da9 100644 --- a/components/esp_common/include/esp_private/system_internal.h +++ b/components/esp_common/include/esp_private/system_internal.h @@ -20,6 +20,8 @@ extern "C" { #include "esp_system.h" +#define TG0_WDT_TICK_US 500 + /** * @brief Internal function to restart PRO and APP CPUs. * diff --git a/components/esp_event/test/test_event.c b/components/esp_event/test/test_event.c index 6560bdc5f..b375d3f90 100644 --- a/components/esp_event/test/test_event.c +++ b/components/esp_event/test/test_event.c @@ -30,14 +30,14 @@ static const char* TAG = "test_event"; #define TEST_CONFIG_WAIT_MULTIPLIER 5 -// The initial logging "initializing test" is to ensure mutex allocation is not counted against memory not being freed -// during teardown. +// The initial logging "initializing test" is to ensure mutex allocation is not counted against memory not being freed +// during teardown. #define TEST_SETUP() \ ESP_LOGI(TAG, "initializing test"); \ size_t free_mem_before = heap_caps_get_free_size(MALLOC_CAP_DEFAULT); \ test_setup(); \ s_test_core_id = xPortGetCoreID(); \ - s_test_priority = uxTaskPriorityGet(NULL); + s_test_priority = uxTaskPriorityGet(NULL); #define TEST_TEARDOWN() \ test_teardown(); \ @@ -294,15 +294,11 @@ void IRAM_ATTR test_event_on_timer_alarm(void* para) { /* Retrieve the interrupt status and the counter value from the timer that reported the interrupt */ - TIMERG0.hw_timer[TIMER_0].update = 1; uint64_t timer_counter_value = - ((uint64_t) TIMERG0.hw_timer[TIMER_0].cnt_high) << 32 - | TIMERG0.hw_timer[TIMER_0].cnt_low; - - TIMERG0.int_clr_timers.t0 = 1; + timer_group_get_counter_value_in_isr(TIMER_GROUP_0, TIMER_0); + timer_group_intr_clr_in_isr(TIMER_GROUP_0, TIMER_0); timer_counter_value += (uint64_t) (TIMER_INTERVAL0_SEC * TIMER_SCALE); - TIMERG0.hw_timer[TIMER_0].alarm_high = (uint32_t) (timer_counter_value >> 32); - TIMERG0.hw_timer[TIMER_0].alarm_low = (uint32_t) timer_counter_value; + timer_group_set_alarm_value_in_isr(TIMER_GROUP_0, TIMER_0, timer_counter_value); int data = (int) para; // Posting events with data more than 4 bytes should fail. diff --git a/components/esp_ringbuf/test/test_ringbuf.c b/components/esp_ringbuf/test/test_ringbuf.c index 62ca3c9b1..476283a0b 100644 --- a/components/esp_ringbuf/test/test_ringbuf.c +++ b/components/esp_ringbuf/test/test_ringbuf.c @@ -356,8 +356,8 @@ static int iterations; static void ringbuffer_isr(void *arg) { //Clear timer interrupt - TIMERG0.int_clr_timers.t0 = 1; - TIMERG0.hw_timer[xPortGetCoreID()].config.alarm_en = 1; + timer_group_intr_clr_in_isr(TIMER_GROUP_0, TIMER_0); + timer_group_enable_alarm_in_isr(TIMER_GROUP_0, xPortGetCoreID()); //Test sending to buffer from ISR from ISR if (buf_type < NO_OF_RB_TYPES) { diff --git a/components/freemodbus/port/porttimer.c b/components/freemodbus/port/porttimer.c index 4e832ef73..709031d66 100644 --- a/components/freemodbus/port/porttimer.c +++ b/components/freemodbus/port/porttimer.c @@ -64,19 +64,15 @@ static const USHORT usTimerIndex = CONFIG_FMB_TIMER_INDEX; // Modbus Timer index used by stack static const USHORT usTimerGroupIndex = CONFIG_FMB_TIMER_GROUP; // Modbus Timer group index used by stack -static timg_dev_t *MB_TG[2] = {&TIMERG0, &TIMERG1}; - /* ----------------------- Start implementation -----------------------------*/ static void IRAM_ATTR vTimerGroupIsr(void *param) { - // Retrieve the interrupt status and the counter value - // from the timer that reported the interrupt - uint32_t intr_status = MB_TG[usTimerGroupIndex]->int_st_timers.val; - if (intr_status & BIT(usTimerIndex)) { - MB_TG[usTimerGroupIndex]->int_clr_timers.val |= BIT(usTimerIndex); - (void)pxMBPortCBTimerExpired(); // Timer callback function - MB_TG[usTimerGroupIndex]->hw_timer[usTimerIndex].config.alarm_en = TIMER_ALARM_EN; - } + assert((int)param == usTimerIndex); + // Retrieve the counter value from the timer that reported the interrupt + timer_group_intr_clr_in_isr(usTimerGroupIndex, usTimerIndex); + (void)pxMBPortCBTimerExpired(); // Timer callback function + // Enable alarm + timer_group_enable_alarm_in_isr(usTimerGroupIndex, usTimerIndex); } #endif @@ -113,7 +109,7 @@ BOOL xMBPortTimersInit(USHORT usTim1Timerout50us) "failure to set alarm failure, timer_set_alarm_value() returned (0x%x).", (uint32_t)xErr); // Register ISR for timer - xErr = timer_isr_register(usTimerGroupIndex, usTimerIndex, vTimerGroupIsr, NULL, ESP_INTR_FLAG_IRAM, NULL); + xErr = timer_isr_register(usTimerGroupIndex, usTimerIndex, vTimerGroupIsr, (void*)(uint32_t)usTimerIndex, ESP_INTR_FLAG_IRAM, NULL); MB_PORT_CHECK((xErr == ESP_OK), FALSE, "timer set value failure, timer_isr_register() returned (0x%x).", (uint32_t)xErr); diff --git a/components/freemodbus/port/porttimer_m.c b/components/freemodbus/port/porttimer_m.c index 9ba9f52cd..c2d52281b 100644 --- a/components/freemodbus/port/porttimer_m.c +++ b/components/freemodbus/port/porttimer_m.c @@ -61,22 +61,16 @@ static USHORT usT35TimeOut50us; static const USHORT usTimerIndex = MB_TIMER_INDEX; // Initialize Modbus Timer index used by stack, static const USHORT usTimerGroupIndex = MB_TIMER_GROUP; // Timer group index used by stack -static timg_dev_t *MB_TG[2] = { &TIMERG0, &TIMERG1 }; - /* ----------------------- static functions ---------------------------------*/ static void IRAM_ATTR vTimerGroupIsr(void *param) { - // Retrieve the interrupt status and the counter value - // from the timer that reported the interrupt - uint32_t intr_status = MB_TG[usTimerGroupIndex]->int_st_timers.val; - if (intr_status & BIT(usTimerIndex)) { - MB_TG[usTimerGroupIndex]->int_clr_timers.val |= BIT(usTimerIndex); - MB_TG[usTimerGroupIndex]->hw_timer[usTimerIndex].update = 1; - (void)pxMBMasterPortCBTimerExpired(); // Timer expired callback function - // Enable alarm - MB_TG[usTimerGroupIndex]->hw_timer[usTimerIndex].config.alarm_en = TIMER_ALARM_EN; - } + assert((int)param == usTimerIndex); + // Retrieve the the counter value from the timer that reported the interrupt + timer_group_intr_clr_in_isr(usTimerGroupIndex, usTimerIndex); + (void)pxMBMasterPortCBTimerExpired(); // Timer expired callback function + // Enable alarm + timer_group_enable_alarm_in_isr(usTimerGroupIndex, usTimerIndex); } /* ----------------------- Start implementation -----------------------------*/ @@ -115,7 +109,7 @@ BOOL xMBMasterPortTimersInit(USHORT usTimeOut50us) (uint32_t)xErr); // Register ISR for timer xErr = timer_isr_register(usTimerGroupIndex, usTimerIndex, - vTimerGroupIsr, NULL, ESP_INTR_FLAG_IRAM, NULL); + vTimerGroupIsr, (void*)(uint32_t)usTimerIndex, ESP_INTR_FLAG_IRAM, NULL); MB_PORT_CHECK((xErr == ESP_OK), FALSE, "timer set value failure, timer_isr_register() returned (0x%x).", (uint32_t)xErr); diff --git a/components/freertos/test/test_freertos_eventgroups.c b/components/freertos/test/test_freertos_eventgroups.c index 9b86f759f..1a245e2fb 100644 --- a/components/freertos/test/test_freertos_eventgroups.c +++ b/components/freertos/test/test_freertos_eventgroups.c @@ -138,8 +138,8 @@ static bool test_clear_bits; static void IRAM_ATTR event_group_isr(void *arg) { portBASE_TYPE task_woken = pdFALSE; - TIMERG0.int_clr_timers.t0 = 1; - TIMERG0.hw_timer[xPortGetCoreID()].config.alarm_en = 1; + timer_group_intr_clr_in_isr(TIMER_GROUP_0, TIMER_0); + timer_group_enable_alarm_in_isr(TIMER_GROUP_0, xPortGetCoreID()); if(test_set_bits){ xEventGroupSetBitsFromISR(eg, BITS, &task_woken); diff --git a/components/freertos/test/test_freertos_task_notify.c b/components/freertos/test/test_freertos_task_notify.c index 8179cef9b..226180d8a 100644 --- a/components/freertos/test/test_freertos_task_notify.c +++ b/components/freertos/test/test_freertos_task_notify.c @@ -97,16 +97,10 @@ static void receiver_task (void* arg){ static void IRAM_ATTR sender_ISR (void *arg) { int curcore = xPortGetCoreID(); - if(curcore == 0){ //Clear timer interrupt - //Clear intr and pause via direct reg access as IRAM ISR cannot access timer APIs - TIMERG0.int_clr_timers.t0 = 1; - TIMERG0.hw_timer[0].config.enable = 0; - }else{ - TIMERG0.int_clr_timers.t1 = 1; - TIMERG0.hw_timer[1].config.enable = 0; - } + timer_group_intr_clr_in_isr(TIMER_GROUP_0, curcore); + timer_group_set_counter_enable_in_isr(TIMER_GROUP_0, curcore, TIMER_PAUSE); //Re-enable alarm - TIMERG0.hw_timer[curcore].config.alarm_en = 1; + timer_group_enable_alarm_in_isr(TIMER_GROUP_0, curcore); if(isr_give){ //Test vTaskNotifyGiveFromISR() on same core notifs_sent++; diff --git a/components/freertos/test/test_suspend_scheduler.c b/components/freertos/test/test_suspend_scheduler.c index 9aef2ce7e..9e7b039ed 100644 --- a/components/freertos/test/test_suspend_scheduler.c +++ b/components/freertos/test/test_suspend_scheduler.c @@ -20,9 +20,8 @@ static volatile unsigned isr_count; mutex semaphore to wake up another counter task */ static void timer_group0_isr(void *vp_arg) { - TIMERG0.int_clr_timers.t0 = 1; - TIMERG0.hw_timer[TIMER_0].update = 1; - TIMERG0.hw_timer[TIMER_0].config.alarm_en = 1; + timer_group_intr_clr_in_isr(TIMER_GROUP_0, TIMER_0); + timer_group_enable_alarm_in_isr(TIMER_GROUP_0, TIMER_0); portBASE_TYPE higher_awoken = pdFALSE; isr_count++; xSemaphoreGiveFromISR(isr_semaphore, &higher_awoken); diff --git a/components/freertos/test/test_task_suspend_resume.c b/components/freertos/test/test_task_suspend_resume.c index 7d60de366..9b7c47cd4 100644 --- a/components/freertos/test/test_task_suspend_resume.c +++ b/components/freertos/test/test_task_suspend_resume.c @@ -118,7 +118,7 @@ volatile bool timer_isr_fired; void IRAM_ATTR timer_group0_isr(void *vp_arg) { // Clear interrupt - TIMERG0.int_clr_timers.val = TIMERG0.int_st_timers.val; + timer_group_clr_intr_sta_in_isr(TIMER_GROUP_0, TIMER_0|TIMER_1); timer_isr_fired = true; TaskHandle_t handle = vp_arg; diff --git a/components/spi_flash/test/test_spi_flash.c b/components/spi_flash/test/test_spi_flash.c index 0010f86d8..f94372374 100644 --- a/components/spi_flash/test/test_spi_flash.c +++ b/components/spi_flash/test/test_spi_flash.c @@ -108,8 +108,8 @@ typedef struct { static void IRAM_ATTR timer_isr(void* varg) { block_task_arg_t* arg = (block_task_arg_t*) varg; - TIMERG0.int_clr_timers.t0 = 1; - TIMERG0.hw_timer[0].config.alarm_en = 1; + timer_group_intr_clr_in_isr(TIMER_GROUP_0, TIMER_0); + timer_group_enable_alarm_in_isr(TIMER_GROUP_0, TIMER_0); ets_delay_us(arg->delay_time_us); arg->repeat_count++; } diff --git a/examples/peripherals/timer_group/main/timer_group_example_main.c b/examples/peripherals/timer_group/main/timer_group_example_main.c index 403f9c0a0..cd1e8cdee 100644 --- a/examples/peripherals/timer_group/main/timer_group_example_main.c +++ b/examples/peripherals/timer_group/main/timer_group_example_main.c @@ -60,11 +60,8 @@ void IRAM_ATTR timer_group0_isr(void *para) /* Retrieve the interrupt status and the counter value from the timer that reported the interrupt */ - uint32_t intr_status = TIMERG0.int_st_timers.val; - TIMERG0.hw_timer[timer_idx].update = 1; - uint64_t timer_counter_value = - ((uint64_t) TIMERG0.hw_timer[timer_idx].cnt_high) << 32 - | TIMERG0.hw_timer[timer_idx].cnt_low; + timer_intr_t timer_intr = timer_group_intr_get_in_isr(TIMER_GROUP_0); + uint64_t timer_counter_value = timer_group_get_counter_value_in_isr(TIMER_GROUP_0, timer_idx); /* Prepare basic event data that will be then sent back to the main program task */ @@ -75,22 +72,21 @@ void IRAM_ATTR timer_group0_isr(void *para) /* Clear the interrupt and update the alarm time for the timer with without reload */ - if ((intr_status & BIT(timer_idx)) && timer_idx == TIMER_0) { + if (timer_intr & TIMER_INTR_T0) { evt.type = TEST_WITHOUT_RELOAD; - TIMERG0.int_clr_timers.t0 = 1; + timer_group_intr_clr_in_isr(TIMER_GROUP_0, TIMER_0); timer_counter_value += (uint64_t) (TIMER_INTERVAL0_SEC * TIMER_SCALE); - TIMERG0.hw_timer[timer_idx].alarm_high = (uint32_t) (timer_counter_value >> 32); - TIMERG0.hw_timer[timer_idx].alarm_low = (uint32_t) timer_counter_value; - } else if ((intr_status & BIT(timer_idx)) && timer_idx == TIMER_1) { + timer_group_set_alarm_value_in_isr(TIMER_GROUP_0, timer_idx, timer_counter_value); + } else if (timer_intr & TIMER_INTR_T1) { evt.type = TEST_WITH_RELOAD; - TIMERG0.int_clr_timers.t1 = 1; + timer_group_intr_clr_in_isr(TIMER_GROUP_0, TIMER_1); } else { evt.type = -1; // not supported even type } /* After the alarm has been triggered we need enable it again, so it is triggered the next time */ - TIMERG0.hw_timer[timer_idx].config.alarm_en = TIMER_ALARM_EN; + timer_group_enable_alarm_in_isr(TIMER_GROUP_0, timer_idx); /* Now just send the event data back to the main program task */ xQueueSendFromISR(timer_queue, &evt, NULL); @@ -103,7 +99,7 @@ void IRAM_ATTR timer_group0_isr(void *para) * auto_reload - should the timer auto reload on alarm? * timer_interval_sec - the interval of alarm to set */ -static void example_tg0_timer_init(int timer_idx, +static void example_tg0_timer_init(int timer_idx, bool auto_reload, double timer_interval_sec) { /* Select and initialize basic parameters of the timer */ @@ -123,7 +119,7 @@ static void example_tg0_timer_init(int timer_idx, /* Configure the alarm value and the interrupt on alarm. */ timer_set_alarm_value(TIMER_GROUP_0, timer_idx, timer_interval_sec * TIMER_SCALE); timer_enable_intr(TIMER_GROUP_0, timer_idx); - timer_isr_register(TIMER_GROUP_0, timer_idx, timer_group0_isr, + timer_isr_register(TIMER_GROUP_0, timer_idx, timer_group0_isr, (void *) timer_idx, ESP_INTR_FLAG_IRAM, NULL); timer_start(TIMER_GROUP_0, timer_idx); diff --git a/examples/system/sysview_tracing/main/sysview_tracing.c b/examples/system/sysview_tracing/main/sysview_tracing.c index 3436b4cbc..32c4562e1 100644 --- a/examples/system/sysview_tracing/main/sysview_tracing.c +++ b/examples/system/sysview_tracing/main/sysview_tracing.c @@ -107,32 +107,6 @@ static void example_timer_init(int timer_group, int timer_idx, uint32_t period) timer_enable_intr(timer_group, timer_idx); } -static void example_timer_rearm(int timer_group, int timer_idx) -{ - if (timer_group == 0) { - if (timer_idx == 0) { - TIMERG0.int_clr_timers.t0 = 1; - TIMERG0.hw_timer[0].update = 1; - TIMERG0.hw_timer[0].config.alarm_en = 1; - } else { - TIMERG0.int_clr_timers.t1 = 1; - TIMERG0.hw_timer[1].update = 1; - TIMERG0.hw_timer[1].config.alarm_en = 1; - } - } - if (timer_group == 1) { - if (timer_idx == 0) { - TIMERG1.int_clr_timers.t0 = 1; - TIMERG1.hw_timer[0].update = 1; - TIMERG1.hw_timer[0].config.alarm_en = 1; - } else { - TIMERG1.int_clr_timers.t1 = 1; - TIMERG1.hw_timer[1].update = 1; - TIMERG1.hw_timer[1].config.alarm_en = 1; - } - } -} - static void example_timer_isr(void *arg) { example_event_data_t *tim_arg = (example_event_data_t *)arg; @@ -152,7 +126,8 @@ static void example_timer_isr(void *arg) } } // re-start timer - example_timer_rearm(tim_arg->group, tim_arg->timer); + timer_group_intr_clr_in_isr(tim_arg->group, tim_arg->timer); + timer_group_enable_alarm_in_isr(tim_arg->group, tim_arg->timer); } static void example_task(void *p) From d850a0bd1c7fd96ec7dcf58a13f140124eba3a65 Mon Sep 17 00:00:00 2001 From: "Michael (XIAO Xufeng)" Date: Thu, 8 Aug 2019 17:49:12 +0800 Subject: [PATCH 6/6] esp_attr: add flag_attr to support enums used as flags --- components/cxx/test/test_cxx.cpp | 28 ++++++++++++++++++++++++ components/esp32/include/esp_attr.h | 24 ++++++++++++++++++++ components/soc/include/hal/timer_types.h | 2 +- 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/components/cxx/test/test_cxx.cpp b/components/cxx/test/test_cxx.cpp index 0f5cce331..0bf92f324 100644 --- a/components/cxx/test/test_cxx.cpp +++ b/components/cxx/test/test_cxx.cpp @@ -319,3 +319,31 @@ TEST_CASE("can call std::function and bind", "[cxx]") #endif +/* Tests below are done in the compile time, don't actually get run. */ +/* Check whether a enumerator flag can be used in C++ */ + + +template __attribute__((unused)) static void test_binary_operators() +{ + T flag1 = (T)0; + T flag2 = (T)0; + flag1 = ~flag1; + flag1 = flag1 | flag2; + flag1 = flag1 & flag2; + flag1 = flag1 ^ flag2; + flag1 = flag1 >> 2; + flag1 = flag1 << 2; + flag1 |= flag2; + flag1 &= flag2; + flag1 ^= flag2; + flag1 >>= 2; + flag1 <<= 2; +} + +//Add more types here. If any flags cannot pass the build, use FLAG_ATTR in esp_attr.h +#include "hal/timer_types.h" +template void test_binary_operators(); + + + + diff --git a/components/esp32/include/esp_attr.h b/components/esp32/include/esp_attr.h index 58fef76c7..34458948a 100644 --- a/components/esp32/include/esp_attr.h +++ b/components/esp32/include/esp_attr.h @@ -76,6 +76,30 @@ // Forces to not inline function #define NOINLINE_ATTR __attribute__((noinline)) +// This allows using enum as flags in C++ +// Format: FLAG_ATTR(flag_enum_t) +#ifdef __cplusplus + +#define FLAG_ATTR_IMPL(TYPE, INT_TYPE) \ +constexpr TYPE operator~ (TYPE a) { return (TYPE)~(INT_TYPE)a; } \ +constexpr TYPE operator| (TYPE a, TYPE b) { return (TYPE)((INT_TYPE)a | (INT_TYPE)b); } \ +constexpr TYPE operator& (TYPE a, TYPE b) { return (TYPE)((INT_TYPE)a & (INT_TYPE)b); } \ +constexpr TYPE operator^ (TYPE a, TYPE b) { return (TYPE)((INT_TYPE)a ^ (INT_TYPE)b); } \ +constexpr TYPE operator>> (TYPE a, int b) { return (TYPE)((INT_TYPE)a >> b); } \ +constexpr TYPE operator<< (TYPE a, int b) { return (TYPE)((INT_TYPE)a << b); } \ +TYPE& operator|=(TYPE& a, TYPE b) { a = a | b; return a; } \ +TYPE& operator&=(TYPE& a, TYPE b) { a = a & b; return a; } \ +TYPE& operator^=(TYPE& a, TYPE b) { a = a ^ b; return a; } \ +TYPE& operator>>=(TYPE& a, int b) { a >>= b; return a; } \ +TYPE& operator<<=(TYPE& a, int b) { a <<= b; return a; } + +#define FLAG_ATTR_U32(TYPE) FLAG_ATTR_IMPL(TYPE, uint32_t) +#define FLAG_ATTR FLAG_ATTR_U32 + +#else +#define FLAG_ATTR(TYPE) +#endif + // Implementation for a unique custom section // // This prevents gcc producing "x causes a section type conflict with y" diff --git a/components/soc/include/hal/timer_types.h b/components/soc/include/hal/timer_types.h index 8ab5757f2..e9bcc9985 100644 --- a/components/soc/include/hal/timer_types.h +++ b/components/soc/include/hal/timer_types.h @@ -40,7 +40,6 @@ typedef enum { TIMER_START = 1, /*!