diff --git a/components/driver/include/driver/sigmadelta.h b/components/driver/include/driver/sigmadelta.h index 783baa142..6a6aa487a 100644 --- a/components/driver/include/driver/sigmadelta.h +++ b/components/driver/include/driver/sigmadelta.h @@ -19,7 +19,7 @@ #include "driver/gpio.h" #include "hal/sigmadelta_types.h" -#ifdef _cplusplus +#ifdef __cplusplus extern "C" { #endif @@ -81,6 +81,6 @@ esp_err_t sigmadelta_set_prescale(sigmadelta_channel_t channel, uint8_t prescale */ esp_err_t sigmadelta_set_pin(sigmadelta_channel_t channel, gpio_num_t gpio_num); -#ifdef _cplusplus +#ifdef __cplusplus } #endif diff --git a/components/driver/timer.c b/components/driver/timer.c index 567aea446..6515d6cb8 100644 --- a/components/driver/timer.c +++ b/components/driver/timer.c @@ -80,7 +80,7 @@ esp_err_t timer_get_counter_time_sec(timer_group_t group_num, timer_idx_t timer_ uint64_t timer_val; esp_err_t err = timer_get_counter_value(group_num, timer_num, &timer_val); if (err == ESP_OK) { - uint16_t div; + uint32_t div; timer_hal_get_divider(&(p_timer_obj[group_num][timer_num]->hal), &div); *time = (double)timer_val * div / rtc_clk_apb_freq_get(); #ifdef TIMER_GROUP_SUPPORTS_XTAL_CLOCK @@ -262,7 +262,7 @@ esp_err_t timer_isr_register(timer_group_t group_num, timer_idx_t timer_num, int intr_source = 0; uint32_t status_reg = 0; - int mask = 0; + uint32_t mask = 0; switch (group_num) { case TIMER_GROUP_0: default: @@ -271,8 +271,7 @@ esp_err_t timer_isr_register(timer_group_t group_num, timer_idx_t timer_num, } else { intr_source = ETS_TG0_T0_EDGE_INTR_SOURCE + timer_num; } - timer_hal_get_intr_status_reg(&(p_timer_obj[TIMER_GROUP_0][timer_num]->hal), &status_reg); - mask = 1 << timer_num; + timer_hal_get_status_reg_mask_bit(&(p_timer_obj[TIMER_GROUP_0][timer_num]->hal), &status_reg, &mask); break; case TIMER_GROUP_1: if ((intr_alloc_flags & ESP_INTR_FLAG_EDGE) == 0) { @@ -280,8 +279,7 @@ esp_err_t timer_isr_register(timer_group_t group_num, timer_idx_t timer_num, } else { intr_source = ETS_TG1_T0_EDGE_INTR_SOURCE + timer_num; } - timer_hal_get_intr_status_reg(&(p_timer_obj[TIMER_GROUP_1][timer_num]->hal), &status_reg); - mask = 1 << timer_num; + timer_hal_get_status_reg_mask_bit(&(p_timer_obj[TIMER_GROUP_1][timer_num]->hal), &status_reg, &mask); break; } return esp_intr_alloc_intrstatus(intr_source, intr_alloc_flags, status_reg, mask, fn, arg, handle); @@ -363,13 +361,9 @@ esp_err_t timer_get_config(timer_group_t group_num, timer_idx_t timer_num, timer config->counter_dir = timer_hal_get_counter_increase(&(p_timer_obj[group_num][timer_num]->hal)); config->counter_en = timer_hal_get_counter_enable(&(p_timer_obj[group_num][timer_num]->hal)); - uint16_t div; + uint32_t div; timer_hal_get_divider(&(p_timer_obj[group_num][timer_num]->hal), &div); - if (div == 0) { - config->divider = 65536; - } else { - config->divider = div; - } + config->divider = div; if (timer_hal_get_level_int_enable(&(p_timer_obj[group_num][timer_num]->hal))) { config->intr_type = TIMER_INTR_LEVEL; diff --git a/components/esp_rom/include/esp32/rom/gpio.h b/components/esp_rom/include/esp32/rom/gpio.h index 7a4c3da94..d9b3c2985 100644 --- a/components/esp_rom/include/esp32/rom/gpio.h +++ b/components/esp_rom/include/esp32/rom/gpio.h @@ -24,7 +24,7 @@ #ifdef CONFIG_LEGACY_INCLUDE_COMMON_HEADERS #include "soc/gpio_reg.h" -#include "soc/gpio_pins.h" +#include "soc/gpio_caps.h" #endif #ifdef __cplusplus diff --git a/components/freertos/test/test_suspend_scheduler.c b/components/freertos/test/test_suspend_scheduler.c index 1415c3532..1082b6d14 100644 --- a/components/freertos/test/test_suspend_scheduler.c +++ b/components/freertos/test/test_suspend_scheduler.c @@ -113,6 +113,7 @@ TEST_CASE("Scheduler disabled can handle a pending context switch on resume", "[ // When we resume scheduler, we expect the counter task // will preempt and count at least one more item esp_intr_noniram_enable(); + timer_enable_intr(TIMER_GROUP_0, TIMER_0); xTaskResumeAll(); TEST_ASSERT_NOT_EQUAL(count_config.counter, no_sched_task); diff --git a/components/soc/esp32/include/hal/timer_ll.h b/components/soc/esp32/include/hal/timer_ll.h index c6cff70f4..1c4c66f51 100644 --- a/components/soc/esp32/include/hal/timer_ll.h +++ b/components/soc/esp32/include/hal/timer_ll.h @@ -29,11 +29,6 @@ _Static_assert(TIMER_INTR_T0 == TIMG_T0_INT_CLR, "Add mapping to LL interrupt ha _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"); -typedef struct { - timg_dev_t *dev; - timer_idx_t idx; -} timer_ll_context_t; - // Get timer group instance with giving group number #define TIMER_LL_GET_HW(num) ((num == 0) ? (&TIMERG0) : (&TIMERG1)) @@ -42,12 +37,18 @@ typedef struct { * * @param hw Beginning address of the peripheral registers. * @param timer_num The timer number - * @param divider Prescale value + * @param divider Prescale value (0 and 1 are not valid) * * @return None */ -static inline void timer_ll_set_divider(timg_dev_t *hw, timer_idx_t timer_num, uint16_t divider) +static inline void timer_ll_set_divider(timg_dev_t *hw, timer_idx_t timer_num, uint32_t divider) { + // refer to TRM 18.2.1 + if (divider == 65536) { + divider = 0; + } else if (divider == 1) { + divider = 2; + } int timer_en = hw->hw_timer[timer_num].config.enable; hw->hw_timer[timer_num].config.enable = 0; hw->hw_timer[timer_num].config.divider = divider; @@ -63,9 +64,15 @@ static inline void timer_ll_set_divider(timg_dev_t *hw, timer_idx_t timer_num, u * * @return None */ -static inline void timer_ll_get_divider(timg_dev_t *hw, timer_idx_t timer_num, uint16_t *divider) +static inline void timer_ll_get_divider(timg_dev_t *hw, timer_idx_t timer_num, uint32_t *divider) { - *divider = hw->hw_timer[timer_num].config.divider; + uint32_t d = hw->hw_timer[timer_num].config.divider; + if (d == 0) { + d = 65536; + } else if (d == 1) { + d = 2; + } + *divider = d; } /** @@ -255,6 +262,7 @@ static inline bool timer_ll_get_alarm_enable(timg_dev_t *hw, timer_idx_t timer_n FORCE_INLINE_ATTR void timer_ll_intr_enable(timg_dev_t *hw, timer_idx_t timer_num) { hw->int_ena.val |= BIT(timer_num); + hw->hw_timer[timer_num].config.level_int_en = 1; } /** @@ -268,6 +276,7 @@ FORCE_INLINE_ATTR void timer_ll_intr_enable(timg_dev_t *hw, timer_idx_t timer_nu FORCE_INLINE_ATTR void timer_ll_intr_disable(timg_dev_t *hw, timer_idx_t timer_num) { hw->int_ena.val &= (~BIT(timer_num)); + hw->hw_timer[timer_num].config.level_int_en = 0; } /** @@ -372,13 +381,17 @@ static inline bool timer_ll_get_edge_int_enable(timg_dev_t *hw, timer_idx_t time * @brief Get interrupt status register address. * * @param hw Beginning address of the peripheral registers. - * @param intr_status_reg Interrupt status register address * - * @return None + * @return Interrupt status register address */ -static inline void timer_ll_get_intr_status_reg(timg_dev_t *hw, uint32_t *intr_status_reg) +static inline uint32_t timer_ll_get_intr_status_reg(timg_dev_t *hw) { - *intr_status_reg = (uint32_t)&(hw->int_st_timers.val); + return (uint32_t) & (hw->int_st_timers.val); +} + +static inline uint32_t timer_ll_get_intr_mask_bit(timg_dev_t *hw, timer_idx_t timer_num) +{ + return (1U << timer_num); } /* WDT operations */ diff --git a/components/soc/esp32s2beta/include/hal/timer_ll.h b/components/soc/esp32s2beta/include/hal/timer_ll.h index 9e7818842..421f0e58a 100644 --- a/components/soc/esp32s2beta/include/hal/timer_ll.h +++ b/components/soc/esp32s2beta/include/hal/timer_ll.h @@ -29,11 +29,6 @@ _Static_assert(TIMER_INTR_T0 == TIMG_T0_INT_CLR, "Add mapping to LL interrupt ha _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"); -typedef struct { - timg_dev_t *dev; - timer_idx_t idx; -} timer_ll_context_t; - // Get timer group instance with giving group number #define TIMER_LL_GET_HW(num) ((num == 0) ? (&TIMERG0) : (&TIMERG1)) @@ -42,12 +37,16 @@ typedef struct { * * @param hw Beginning address of the peripheral registers. * @param timer_num The timer number - * @param divider Prescale value + * @param divider Prescale value (0 is not valid) * * @return None */ -static inline void timer_ll_set_divider(timg_dev_t *hw, timer_idx_t timer_num, uint16_t divider) +static inline void timer_ll_set_divider(timg_dev_t *hw, timer_idx_t timer_num, uint32_t divider) { + // refer to TRM 12.2.1 + if (divider == 65536) { + divider = 0; + } int timer_en = hw->hw_timer[timer_num].config.enable; hw->hw_timer[timer_num].config.enable = 0; hw->hw_timer[timer_num].config.divider = divider; @@ -63,9 +62,13 @@ static inline void timer_ll_set_divider(timg_dev_t *hw, timer_idx_t timer_num, u * * @return None */ -static inline void timer_ll_get_divider(timg_dev_t *hw, timer_idx_t timer_num, uint16_t *divider) +static inline void timer_ll_get_divider(timg_dev_t *hw, timer_idx_t timer_num, uint32_t *divider) { - *divider = hw->hw_timer[timer_num].config.divider; + uint32_t d = hw->hw_timer[timer_num].config.divider; + if (d == 0) { + d = 65536; + } + *divider = d; } /** @@ -255,6 +258,7 @@ static inline bool timer_ll_get_alarm_enable(timg_dev_t *hw, timer_idx_t timer_n FORCE_INLINE_ATTR void timer_ll_intr_enable(timg_dev_t *hw, timer_idx_t timer_num) { hw->int_ena.val |= BIT(timer_num); + hw->hw_timer[timer_num].config.level_int_en = 1; } /** @@ -268,6 +272,7 @@ FORCE_INLINE_ATTR void timer_ll_intr_enable(timg_dev_t *hw, timer_idx_t timer_nu FORCE_INLINE_ATTR void timer_ll_intr_disable(timg_dev_t *hw, timer_idx_t timer_num) { hw->int_ena.val &= (~BIT(timer_num)); + hw->hw_timer[timer_num].config.level_int_en = 0; } /** @@ -372,13 +377,17 @@ static inline bool timer_ll_get_edge_int_enable(timg_dev_t *hw, timer_idx_t time * @brief Get interrupt status register address. * * @param hw Beginning address of the peripheral registers. - * @param intr_status_reg Interrupt status register address * - * @return None + * @return uint32_t Interrupt status register address */ -static inline void timer_ll_get_intr_status_reg(timg_dev_t *hw, uint32_t *intr_status_reg) +static inline uint32_t timer_ll_get_intr_status_reg(timg_dev_t *hw) { - *intr_status_reg = (uint32_t)&(hw->int_st.val); + return (uint32_t) & (hw->int_st.val); +} + +static inline uint32_t timer_ll_get_intr_mask_bit(timg_dev_t *hw, timer_idx_t timer_num) +{ + return (1U << timer_num); } /** diff --git a/components/soc/esp32s2beta/include/soc/timer_group_caps.h b/components/soc/esp32s2beta/include/soc/timer_group_caps.h index 8e4451349..f3c44bae8 100644 --- a/components/soc/esp32s2beta/include/soc/timer_group_caps.h +++ b/components/soc/esp32s2beta/include/soc/timer_group_caps.h @@ -14,4 +14,4 @@ #pragma once -#define TIMER_GROUP_SUPPORTS_XTAL_CLOCK +#define SOC_TIMER_GROUP_SUPPORT_XTAL diff --git a/components/soc/include/hal/timer_hal.h b/components/soc/include/hal/timer_hal.h index bc4dcc251..bf9ebffc1 100644 --- a/components/soc/include/hal/timer_hal.h +++ b/components/soc/include/hal/timer_hal.h @@ -50,6 +50,15 @@ typedef struct { */ void timer_hal_init(timer_hal_context_t *hal, timer_group_t group_num, timer_idx_t timer_num); +/** + * @brief Get interrupt status register address and corresponding control bits mask + * + * @param hal Context of the HAL layer + * @param status_reg[out] interrupt status register address + * @param mask_bit[out] control bits mask + */ +void timer_hal_get_status_reg_mask_bit(timer_hal_context_t *hal, uint32_t *status_reg, uint32_t *mask_bit); + /** * @brief Set timer clock prescale value * @@ -288,13 +297,12 @@ void timer_hal_init(timer_hal_context_t *hal, timer_group_t group_num, timer_idx * @brief Get interrupt status register address. * * @param hal Context of the HAL layer - * @param intr_status_reg Interrupt status register address * - * @return None + * @return Interrupt status register address */ -#define timer_hal_get_intr_status_reg(hal, intr_status_reg) timer_ll_get_intr_status_reg((hal)->dev, intr_status_reg) +#define timer_hal_get_intr_status_reg(hal) timer_ll_get_intr_status_reg((hal)->dev) -#ifdef TIMER_GROUP_SUPPORTS_XTAL_CLOCK +#ifdef SOC_TIMER_GROUP_SUPPORT_XTAL /** * @brief Set clock source. * diff --git a/components/soc/include/hal/timer_types.h b/components/soc/include/hal/timer_types.h index 09e0fcc24..343981e6d 100644 --- a/components/soc/include/hal/timer_types.h +++ b/components/soc/include/hal/timer_types.h @@ -108,7 +108,7 @@ typedef enum { TIMER_AUTORELOAD_MAX, } timer_autoreload_t; -#ifdef TIMER_GROUP_SUPPORTS_XTAL_CLOCK +#ifdef SOC_TIMER_GROUP_SUPPORT_XTAL /** * @brief Select timer source clock. */ @@ -128,7 +128,7 @@ typedef struct { timer_count_dir_t counter_dir; /*!< Counter direction */ timer_autoreload_t auto_reload; /*!< Timer auto-reload */ uint32_t divider; /*!< Counter clock divider. The divider's range is from from 2 to 65536. */ -#ifdef TIMER_GROUP_SUPPORTS_XTAL_CLOCK +#ifdef SOC_TIMER_GROUP_SUPPORT_XTAL timer_src_clk_t clk_src; /*!< Use XTAL as source clock. */ #endif } timer_config_t; diff --git a/components/soc/src/hal/timer_hal.c b/components/soc/src/hal/timer_hal.c index c35f7f70c..399a28ac5 100644 --- a/components/soc/src/hal/timer_hal.c +++ b/components/soc/src/hal/timer_hal.c @@ -20,3 +20,9 @@ void timer_hal_init(timer_hal_context_t *hal, timer_group_t group_num, timer_idx hal->dev = TIMER_LL_GET_HW(group_num); hal->idx = timer_num; } + +void timer_hal_get_status_reg_mask_bit(timer_hal_context_t *hal, uint32_t *status_reg, uint32_t *mask_bit) +{ + *status_reg = timer_ll_get_intr_status_reg(hal->dev); + *mask_bit = timer_ll_get_intr_mask_bit(hal->dev, hal->idx); +} \ No newline at end of file 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 736514df0..74c8790a6 100644 --- a/examples/peripherals/timer_group/main/timer_group_example_main.c +++ b/examples/peripherals/timer_group/main/timer_group_example_main.c @@ -41,7 +41,7 @@ xQueueHandle timer_queue; static void inline print_timer_counter(uint64_t counter_value) { printf("Counter: 0x%08x%08x\n", (uint32_t) (counter_value >> 32), - (uint32_t) (counter_value)); + (uint32_t) (counter_value)); printf("Time : %.8f s\n", (double) counter_value / TIMER_SCALE); } @@ -101,19 +101,16 @@ void IRAM_ATTR timer_group0_isr(void *para) * timer_interval_sec - the interval of alarm to set */ static void example_tg0_timer_init(int timer_idx, - bool auto_reload, double timer_interval_sec) + bool auto_reload, double timer_interval_sec) { /* Select and initialize basic parameters of the timer */ - timer_config_t config; - config.divider = TIMER_DIVIDER; - config.counter_dir = TIMER_COUNT_UP; - config.counter_en = TIMER_PAUSE; - config.alarm_en = TIMER_ALARM_EN; - config.intr_type = TIMER_INTR_LEVEL; - config.auto_reload = auto_reload; -#ifdef TIMER_GROUP_SUPPORTS_XTAL_CLOCK - config.clk_src = TIMER_SRC_CLK_APB; -#endif + timer_config_t config = { + .divider = TIMER_DIVIDER, + .counter_dir = TIMER_COUNT_UP, + .counter_en = TIMER_PAUSE, + .alarm_en = TIMER_ALARM_EN, + .auto_reload = auto_reload, + }; // default clock source is APB timer_init(TIMER_GROUP_0, timer_idx, &config); /* Timer's counter will initially start from value below. @@ -124,7 +121,7 @@ static void example_tg0_timer_init(int timer_idx, 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, - (void *) timer_idx, ESP_INTR_FLAG_IRAM, NULL); + (void *) timer_idx, ESP_INTR_FLAG_IRAM, NULL); timer_start(TIMER_GROUP_0, timer_idx); }