Skip to content

Commit

Permalink
Merge branch 'feature/gptimer_c5_mp' into 'master'
Browse files Browse the repository at this point in the history
feat(gptimer): support timer group driver on c5 mp

Closes IDF-8705

See merge request espressif/esp-idf!30126
  • Loading branch information
suda-morris committed Apr 12, 2024
2 parents e32211d + a615180 commit a6fbe06
Show file tree
Hide file tree
Showing 9 changed files with 215 additions and 473 deletions.
4 changes: 3 additions & 1 deletion components/esp_driver_gptimer/include/driver/gptimer.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,11 @@ typedef struct {
/**
* @brief Set alarm event actions for GPTimer.
*
* @note This function is allowed to run within ISR context, so that user can set new alarm action immediately in the ISR callback.
* @note This function is allowed to run within ISR context, so you can update new alarm action immediately in any ISR callback.
* @note If `CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM` is enabled, this function will be placed in the IRAM by linker,
* makes it possible to execute even when the Flash Cache is disabled.
* In this case, please also ensure the `gptimer_alarm_config_t` instance is placed in the static data section
* instead of in the read-only data section. e.g.: `static gptimer_alarm_config_t alarm_config = { ... };`
*
* @param[in] timer Timer handle created by `gptimer_new_timer`
* @param[in] config Alarm configuration, especially, set config to NULL means disabling the alarm function
Expand Down
3 changes: 2 additions & 1 deletion components/esp_hw_support/port/esp32c5/rtc_time.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
}

/* Prepare calibration */
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cali_clk_sel);
// calibration clock source is set by PCR register: PCR_32K_SEL
// REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cali_clk_sel);
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING);
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles);
/* Figure out how long to wait for calibration to finish */
Expand Down
75 changes: 26 additions & 49 deletions components/hal/esp32c5/include/hal/timer_ll.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,12 @@
#pragma once

#include <stdbool.h>
#include "sdkconfig.h" // TODO: remove
#include "hal/assert.h"
#include "hal/misc.h"
#include "hal/timer_types.h"
#include "soc/timer_group_struct.h"
#include "soc/pcr_struct.h"
// TODO: [ESP32C5] IDF-8693
// #include "soc/soc_etm_source.h"
#include "soc/soc_etm_source.h"

#ifdef __cplusplus
extern "C" {
Expand All @@ -27,6 +25,31 @@ extern "C" {
#define TIMER_LL_GET_HW(group_id) ((group_id == 0) ? (&TIMERG0) : (&TIMERG1))
#define TIMER_LL_EVENT_ALARM(timer_id) (1 << (timer_id))

#define TIMER_LL_ETM_TASK_TABLE(group, timer, task) \
(uint32_t [2][1][GPTIMER_ETM_TASK_MAX]){{{ \
[GPTIMER_ETM_TASK_START_COUNT] = TIMER0_TASK_CNT_START_TIMER0, \
[GPTIMER_ETM_TASK_STOP_COUNT] = TIMER0_TASK_CNT_STOP_TIMER0, \
[GPTIMER_ETM_TASK_EN_ALARM] = TIMER0_TASK_ALARM_START_TIMER0, \
[GPTIMER_ETM_TASK_RELOAD] = TIMER0_TASK_CNT_RELOAD_TIMER0, \
[GPTIMER_ETM_TASK_CAPTURE] = TIMER0_TASK_CNT_CAP_TIMER0, \
}}, \
{{ \
[GPTIMER_ETM_TASK_START_COUNT] = TIMER1_TASK_CNT_START_TIMER0, \
[GPTIMER_ETM_TASK_STOP_COUNT] = TIMER1_TASK_CNT_STOP_TIMER0, \
[GPTIMER_ETM_TASK_EN_ALARM] = TIMER1_TASK_ALARM_START_TIMER0, \
[GPTIMER_ETM_TASK_RELOAD] = TIMER1_TASK_CNT_RELOAD_TIMER0, \
[GPTIMER_ETM_TASK_CAPTURE] = TIMER1_TASK_CNT_CAP_TIMER0, \
}}, \
}[group][timer][task]

#define TIMER_LL_ETM_EVENT_TABLE(group, timer, event) \
(uint32_t [2][1][GPTIMER_ETM_EVENT_MAX]){{{ \
[GPTIMER_ETM_EVENT_ALARM_MATCH] = TIMER0_EVT_CNT_CMP_TIMER0, \
}}, \
{{ \
[GPTIMER_ETM_EVENT_ALARM_MATCH] = TIMER1_EVT_CNT_CMP_TIMER0, \
}}, \
}[group][timer][event]

/**
* @brief Enable the bus clock for timer group module
Expand Down Expand Up @@ -134,11 +157,7 @@ __attribute__((always_inline))
static inline void timer_ll_enable_alarm(timg_dev_t *hw, uint32_t timer_num, bool en)
{
(void)timer_num;
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
hw->hw_timer[timer_num].config.tx_alarm_en = en;
#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
abort();
#endif
}

/**
Expand All @@ -154,12 +173,8 @@ static inline void timer_ll_set_clock_prescale(timg_dev_t *hw, uint32_t timer_nu
if (divider >= 65536) {
divider = 0;
}
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hw_timer[timer_num].config, tx_divider, divider);
hw->hw_timer[timer_num].config.tx_divcnt_rst = 1;
#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
abort();
#endif
}

/**
Expand All @@ -173,11 +188,7 @@ static inline void timer_ll_set_clock_prescale(timg_dev_t *hw, uint32_t timer_nu
__attribute__((always_inline))
static inline void timer_ll_enable_auto_reload(timg_dev_t *hw, uint32_t timer_num, bool en)
{
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
hw->hw_timer[timer_num].config.tx_autoreload = en;
#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
abort();
#endif
}

/**
Expand All @@ -189,11 +200,7 @@ static inline void timer_ll_enable_auto_reload(timg_dev_t *hw, uint32_t timer_nu
*/
static inline void timer_ll_set_count_direction(timg_dev_t *hw, uint32_t timer_num, gptimer_count_direction_t direction)
{
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
hw->hw_timer[timer_num].config.tx_increase = (direction == GPTIMER_COUNT_UP);
#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
abort();
#endif
}

/**
Expand All @@ -207,11 +214,7 @@ static inline void timer_ll_set_count_direction(timg_dev_t *hw, uint32_t timer_n
__attribute__((always_inline))
static inline void timer_ll_enable_counter(timg_dev_t *hw, uint32_t timer_num, bool en)
{
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
hw->hw_timer[timer_num].config.tx_en = en;
#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
abort();
#endif
}

/**
Expand All @@ -223,15 +226,11 @@ static inline void timer_ll_enable_counter(timg_dev_t *hw, uint32_t timer_num, b
__attribute__((always_inline))
static inline void timer_ll_trigger_soft_capture(timg_dev_t *hw, uint32_t timer_num)
{
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
hw->hw_timer[timer_num].update.tx_update = 1;
// Timer register is in a different clock domain from Timer hardware logic
// We need to wait for the update to take effect before fetching the count value
while (hw->hw_timer[timer_num].update.tx_update) {
}
#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
abort();
#endif
}

/**
Expand All @@ -245,12 +244,7 @@ static inline void timer_ll_trigger_soft_capture(timg_dev_t *hw, uint32_t timer_
__attribute__((always_inline))
static inline uint64_t timer_ll_get_counter_value(timg_dev_t *hw, uint32_t timer_num)
{
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
return ((uint64_t)hw->hw_timer[timer_num].hi.tx_hi << 32) | (hw->hw_timer[timer_num].lo.tx_lo);
#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
abort();
return 0;
#endif
}

/**
Expand All @@ -263,12 +257,8 @@ static inline uint64_t timer_ll_get_counter_value(timg_dev_t *hw, uint32_t timer
__attribute__((always_inline))
static inline void timer_ll_set_alarm_value(timg_dev_t *hw, uint32_t timer_num, uint64_t alarm_value)
{
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
hw->hw_timer[timer_num].alarmhi.tx_alarm_hi = (uint32_t)(alarm_value >> 32);
hw->hw_timer[timer_num].alarmlo.tx_alarm_lo = (uint32_t)alarm_value;
#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
abort();
#endif
}

/**
Expand All @@ -281,12 +271,8 @@ static inline void timer_ll_set_alarm_value(timg_dev_t *hw, uint32_t timer_num,
__attribute__((always_inline))
static inline void timer_ll_set_reload_value(timg_dev_t *hw, uint32_t timer_num, uint64_t reload_val)
{
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
hw->hw_timer[timer_num].loadhi.tx_load_hi = (uint32_t)(reload_val >> 32);
hw->hw_timer[timer_num].loadlo.tx_load_lo = (uint32_t)reload_val;
#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
abort();
#endif
}

/**
Expand All @@ -299,12 +285,7 @@ static inline void timer_ll_set_reload_value(timg_dev_t *hw, uint32_t timer_num,
__attribute__((always_inline))
static inline uint64_t timer_ll_get_reload_value(timg_dev_t *hw, uint32_t timer_num)
{
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
return ((uint64_t)hw->hw_timer[timer_num].loadhi.tx_load_hi << 32) | (hw->hw_timer[timer_num].loadlo.tx_load_lo);
#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
abort();
return 0;
#endif
}

/**
Expand All @@ -316,11 +297,7 @@ static inline uint64_t timer_ll_get_reload_value(timg_dev_t *hw, uint32_t timer_
__attribute__((always_inline))
static inline void timer_ll_trigger_soft_reload(timg_dev_t *hw, uint32_t timer_num)
{
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
hw->hw_timer[timer_num].load.tx_load = 1;
#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
abort();
#endif
}

/**
Expand Down
16 changes: 16 additions & 0 deletions components/soc/esp32c5/mp/include/soc/Kconfig.soc_caps.in
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ config SOC_UART_SUPPORTED
bool
default y

config SOC_GPTIMER_SUPPORTED
bool
default y

config SOC_SUPPORTS_SECURE_DL_MODE
bool
default y
Expand Down Expand Up @@ -275,6 +279,18 @@ config SOC_TIMER_GROUP_TIMERS_PER_GROUP
int
default 1

config SOC_TIMER_GROUP_COUNTER_BIT_WIDTH
int
default 54

config SOC_TIMER_GROUP_SUPPORT_XTAL
bool
default y

config SOC_TIMER_GROUP_TOTAL_TIMERS
int
default 2

config SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS
int
default 3
Expand Down
18 changes: 16 additions & 2 deletions components/soc/esp32c5/mp/include/soc/clk_tree_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
*/
#pragma once

#include "soc/soc_caps.h"

#ifdef __cplusplus
extern "C" {
#endif
Expand All @@ -19,7 +21,7 @@ extern "C" {
*
* 2) External 40/48MHz Crystal Clock: XTAL
*
* 3) Internal 136kHz RC Oscillator: RC_SLOW (may also referrred as SOSC in TRM or reg. description)
* 3) Internal 136kHz RC Oscillator: RC_SLOW (may also referred as SOSC in TRM or reg. description)
*
* This RC oscillator generates a ~136kHz clock signal output as the RC_SLOW_CLK. The exact frequency of this clock
* can be computed in runtime through calibration.
Expand Down Expand Up @@ -168,7 +170,11 @@ typedef enum { // TODO: [ESP32C5] IDF-8676 (inherit from C6)
* }
* @endcode
*/
#define SOC_GPTIMER_CLKS {SOC_MOD_CLK_PLL_F80M/*, SOC_MOD_CLK_RC_FAST*/, SOC_MOD_CLK_XTAL}
#if SOC_CLK_TREE_SUPPORTED
#define SOC_GPTIMER_CLKS {SOC_MOD_CLK_PLL_F80M, SOC_MOD_CLK_RC_FAST, SOC_MOD_CLK_XTAL}
#else
#define SOC_GPTIMER_CLKS {SOC_MOD_CLK_XTAL}
#endif

/**
* @brief Type of GPTimer clock source
Expand All @@ -177,7 +183,11 @@ typedef enum {
GPTIMER_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the source clock */
GPTIMER_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */
GPTIMER_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
#if SOC_CLK_TREE_SUPPORTED
GPTIMER_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the default choice */
#else
GPTIMER_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default choice */
#endif // SOC_CLK_TREE_SUPPORTED
} soc_periph_gptimer_clk_src_t;

/**
Expand All @@ -186,7 +196,11 @@ typedef enum {
typedef enum {
TIMER_SRC_CLK_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< Timer group clock source is PLL_F80M */
TIMER_SRC_CLK_XTAL = SOC_MOD_CLK_XTAL, /*!< Timer group clock source is XTAL */
#if SOC_CLK_TREE_SUPPORTED
TIMER_SRC_CLK_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Timer group clock source default choice is PLL_F80M */
#else
TIMER_SRC_CLK_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Timer group clock source default choice is XTAL */
#endif // SOC_CLK_TREE_SUPPORTED
} soc_periph_tg_clk_src_legacy_t;

//////////////////////////////////////////////////RMT///////////////////////////////////////////////////////////////////
Expand Down
8 changes: 4 additions & 4 deletions components/soc/esp32c5/mp/include/soc/soc_caps.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
#define SOC_UART_SUPPORTED 1 // TODO: [ESP32C5] IDF-8722
// #define SOC_GDMA_SUPPORTED 1 // TODO: [ESP32C5] IDF-8710
// #define SOC_AHB_GDMA_SUPPORTED 1 // TODO: [ESP32C5] IDF-8710
// #define SOC_GPTIMER_SUPPORTED 1 // TODO: [ESP32C5] IDF-8705
#define SOC_GPTIMER_SUPPORTED 1
// #define SOC_PCNT_SUPPORTED 1 // TODO: [ESP32C5] IDF-8683
// #define SOC_MCPWM_SUPPORTED 1 // TODO: [ESP32C5] IDF-8709
// #define SOC_TWAI_SUPPORTED 1 // TODO: [ESP32C5] IDF-8691
Expand Down Expand Up @@ -428,10 +428,10 @@
/*--------------------------- TIMER GROUP CAPS ---------------------------------------*/
#define SOC_TIMER_GROUPS (2)
#define SOC_TIMER_GROUP_TIMERS_PER_GROUP (1U)
// #define SOC_TIMER_GROUP_COUNTER_BIT_WIDTH (54)
// #define SOC_TIMER_GROUP_SUPPORT_XTAL (1)
#define SOC_TIMER_GROUP_COUNTER_BIT_WIDTH (54)
#define SOC_TIMER_GROUP_SUPPORT_XTAL (1)
// #define SOC_TIMER_GROUP_SUPPORT_RC_FAST (1)
// #define SOC_TIMER_GROUP_TOTAL_TIMERS (2)
#define SOC_TIMER_GROUP_TOTAL_TIMERS (2)
// #define SOC_TIMER_SUPPORT_ETM (1)

/*--------------------------- WATCHDOG CAPS ---------------------------------------*/
Expand Down
Loading

0 comments on commit a6fbe06

Please sign in to comment.