mirror of
https://github.com/espressif/esp-idf
synced 2025-03-10 01:29:21 -04:00
gptimer: bringup driver on esp32c6
This commit is contained in:
parent
890a84dcc4
commit
a1030307f1
@ -359,9 +359,9 @@ esp_err_t timer_deinit(timer_group_t group_num, timer_idx_t timer_num)
|
||||
timer_hal_context_t *hal = &p_timer_obj[group_num][timer_num]->hal;
|
||||
|
||||
TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]);
|
||||
timer_ll_enable_counter(hal->dev, timer_num, false);
|
||||
timer_ll_enable_intr(hal->dev, TIMER_LL_EVENT_ALARM(timer_num), false);
|
||||
timer_ll_clear_intr_status(hal->dev, TIMER_LL_EVENT_ALARM(timer_num));
|
||||
timer_hal_deinit(hal);
|
||||
TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]);
|
||||
|
||||
free(p_timer_obj[group_num][timer_num]);
|
||||
|
@ -78,9 +78,10 @@ struct gptimer_t {
|
||||
timer_hal_context_t hal;
|
||||
gptimer_fsm_t fsm;
|
||||
intr_handle_t intr;
|
||||
portMUX_TYPE spinlock; // to protect per-timer resources concurent accessed by task and ISR handler
|
||||
portMUX_TYPE spinlock; // to protect per-timer resources concurrent accessed by task and ISR handler
|
||||
gptimer_alarm_cb_t on_alarm;
|
||||
void *user_ctx;
|
||||
gptimer_clock_source_t clk_src;
|
||||
esp_pm_lock_handle_t pm_lock; // power management lock
|
||||
#if CONFIG_PM_ENABLE
|
||||
char pm_lock_name[GPTIMER_PM_LOCK_NAME_LEN_MAX]; // pm lock name
|
||||
@ -176,10 +177,6 @@ esp_err_t gptimer_new_timer(const gptimer_config_t *config, gptimer_handle_t *re
|
||||
|
||||
// initialize HAL layer
|
||||
timer_hal_init(&timer->hal, group_id, timer_id);
|
||||
// stop counter, alarm, auto-reload
|
||||
timer_ll_enable_counter(timer->hal.dev, timer_id, false);
|
||||
timer_ll_enable_auto_reload(timer->hal.dev, timer_id, false);
|
||||
timer_ll_enable_alarm(timer->hal.dev, timer_id, false);
|
||||
// select clock source, set clock resolution
|
||||
ESP_GOTO_ON_ERROR(gptimer_select_periph_clock(timer, config->clk_src, config->resolution_hz), err, TAG, "set periph clock failed");
|
||||
// initialize counter value to zero
|
||||
@ -216,6 +213,13 @@ esp_err_t gptimer_del_timer(gptimer_handle_t timer)
|
||||
int group_id = group->group_id;
|
||||
int timer_id = timer->timer_id;
|
||||
ESP_LOGD(TAG, "del timer (%d,%d)", group_id, timer_id);
|
||||
timer_hal_deinit(&timer->hal);
|
||||
// [refactor-todo]: replace the following code with clk_tree_acquire/release, and call them in gptimer_enable/disable
|
||||
#if SOC_TIMER_GROUP_SUPPORT_RC_FAST
|
||||
if (timer->clk_src == GPTIMER_CLK_SRC_RC_FAST) {
|
||||
periph_rtc_dig_clk8m_disable();
|
||||
}
|
||||
#endif
|
||||
// recycle memory resource
|
||||
ESP_RETURN_ON_ERROR(gptimer_destory(timer), TAG, "destory gptimer failed");
|
||||
return ESP_OK;
|
||||
@ -471,11 +475,19 @@ static esp_err_t gptimer_select_periph_clock(gptimer_t *timer, gptimer_clock_sou
|
||||
counter_src_hz = esp_clk_xtal_freq();
|
||||
break;
|
||||
#endif // SOC_TIMER_GROUP_SUPPORT_XTAL
|
||||
#if SOC_TIMER_GROUP_SUPPORT_RC_FAST
|
||||
case GPTIMER_CLK_SRC_RC_FAST:
|
||||
// periph_rtc_dig_clk8m_enable must be called before periph_rtc_dig_clk8m_get_freq, to ensure a calibration is done
|
||||
periph_rtc_dig_clk8m_enable();
|
||||
periph_src_clk_hz = periph_rtc_dig_clk8m_get_freq();
|
||||
break;
|
||||
#endif // SOC_TIMER_GROUP_SUPPORT_RC_FAST
|
||||
default:
|
||||
ESP_RETURN_ON_FALSE(false, ESP_ERR_NOT_SUPPORTED, TAG, "clock source %d is not support", src_clk);
|
||||
break;
|
||||
}
|
||||
timer_ll_set_clock_source(timer->hal.dev, timer_id, src_clk);
|
||||
timer->clk_src = src_clk;
|
||||
unsigned int prescale = counter_src_hz / resolution_hz; // potential resolution loss here
|
||||
timer_ll_set_clock_prescale(timer->hal.dev, timer_id, prescale);
|
||||
timer->resolution_hz = counter_src_hz / prescale; // this is the real resolution
|
||||
|
@ -40,6 +40,22 @@ static inline void timer_ll_set_clock_source(timg_dev_t *hw, uint32_t timer_num,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable Timer Group (GPTimer) module clock
|
||||
*
|
||||
* @note This function is not optional, created for backward compatible.
|
||||
*
|
||||
* @param hw Timer Group register base address
|
||||
* @param timer_num Timer index in the group
|
||||
* @param en true to enable, false to disable
|
||||
*/
|
||||
static inline void timer_ll_enable_clock(timg_dev_t *hw, uint32_t timer_num, bool en)
|
||||
{
|
||||
(void)hw;
|
||||
(void)timer_num;
|
||||
(void)en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable alarm event
|
||||
*
|
||||
|
@ -44,6 +44,19 @@ static inline void timer_ll_set_clock_source(timg_dev_t *hw, uint32_t timer_num,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable Timer Group (GPTimer) module clock
|
||||
*
|
||||
* @param hw Timer Group register base address
|
||||
* @param timer_num Timer index in the group
|
||||
* @param en true to enable, false to disable
|
||||
*/
|
||||
static inline void timer_ll_enable_clock(timg_dev_t *hw, uint32_t timer_num, bool en)
|
||||
{
|
||||
(void)timer_num; // only one timer in the group
|
||||
hw->regclk.timer_clk_is_active = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable alarm event
|
||||
*
|
||||
|
@ -44,6 +44,19 @@ static inline void timer_ll_set_clock_source(timg_dev_t *hw, uint32_t timer_num,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable Timer Group (GPTimer) module clock
|
||||
*
|
||||
* @param hw Timer Group register base address
|
||||
* @param timer_num Timer index in the group
|
||||
* @param en true to enable, false to disable
|
||||
*/
|
||||
static inline void timer_ll_enable_clock(timg_dev_t *hw, uint32_t timer_num, bool en)
|
||||
{
|
||||
(void)timer_num; // only one timer in the group
|
||||
hw->regclk.timer_clk_is_active = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable alarm event
|
||||
*
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "hal/misc.h"
|
||||
#include "hal/timer_types.h"
|
||||
#include "soc/timer_group_struct.h"
|
||||
#include "soc/pcr_struct.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -31,17 +32,44 @@ extern "C" {
|
||||
*/
|
||||
static inline void timer_ll_set_clock_source(timg_dev_t *hw, uint32_t timer_num, gptimer_clock_source_t clk_src)
|
||||
{
|
||||
(void)timer_num; // only one timer in each group
|
||||
uint8_t clk_id = 0;
|
||||
switch (clk_src) {
|
||||
case GPTIMER_CLK_SRC_APB:
|
||||
hw->hw_timer[timer_num].config.tx_use_xtal = 0;
|
||||
break;
|
||||
case GPTIMER_CLK_SRC_XTAL:
|
||||
hw->hw_timer[timer_num].config.tx_use_xtal = 1;
|
||||
clk_id = 0;
|
||||
break;
|
||||
case GPTIMER_CLK_SRC_APB:
|
||||
clk_id = 1;
|
||||
break;
|
||||
case GPTIMER_CLK_SRC_RC_FAST:
|
||||
clk_id = 2;
|
||||
break;
|
||||
default:
|
||||
HAL_ASSERT(false && "unsupported clock source");
|
||||
HAL_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
if (hw == &TIMERG0) {
|
||||
PCR.timergroup0_timer_clk_conf.tg0_timer_clk_sel = clk_id;
|
||||
} else {
|
||||
PCR.timergroup1_timer_clk_conf.tg1_timer_clk_sel = clk_id;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable Timer Group (GPTimer) module clock
|
||||
*
|
||||
* @param hw Timer Group register base address
|
||||
* @param timer_num Timer index in the group
|
||||
* @param en true to enable, false to disable
|
||||
*/
|
||||
static inline void timer_ll_enable_clock(timg_dev_t *hw, uint32_t timer_num, bool en)
|
||||
{
|
||||
(void)timer_num; // only one timer in each group
|
||||
if (hw == &TIMERG0) {
|
||||
PCR.timergroup0_timer_clk_conf.tg0_timer_clk_en = en;
|
||||
} else {
|
||||
PCR.timergroup1_timer_clk_conf.tg1_timer_clk_en = en;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -44,6 +44,19 @@ static inline void timer_ll_set_clock_source(timg_dev_t *hw, uint32_t timer_num,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable Timer Group (GPTimer) module clock
|
||||
*
|
||||
* @param hw Timer Group register base address
|
||||
* @param timer_num Timer index in the group
|
||||
* @param en true to enable, false to disable
|
||||
*/
|
||||
static inline void timer_ll_enable_clock(timg_dev_t *hw, uint32_t timer_num, bool en)
|
||||
{
|
||||
(void)timer_num; // only one timer in the group
|
||||
hw->regclk.timer_clk_is_active = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable alarm event
|
||||
*
|
||||
|
@ -44,6 +44,22 @@ static inline void timer_ll_set_clock_source(timg_dev_t *hw, uint32_t timer_num,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable Timer Group (GPTimer) module clock
|
||||
*
|
||||
* @note This function is not optional, created for backward compatible.
|
||||
*
|
||||
* @param hw Timer Group register base address
|
||||
* @param timer_num Timer index in the group
|
||||
* @param en true to enable, false to disable
|
||||
*/
|
||||
static inline void timer_ll_enable_clock(timg_dev_t *hw, uint32_t timer_num, bool en)
|
||||
{
|
||||
(void)hw;
|
||||
(void)timer_num;
|
||||
(void)en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable alarm event
|
||||
*
|
||||
|
@ -44,6 +44,22 @@ static inline void timer_ll_set_clock_source(timg_dev_t *hw, uint32_t timer_num,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable Timer Group (GPTimer) module clock
|
||||
*
|
||||
* @note This function is not optional, created for backward compatible.
|
||||
*
|
||||
* @param hw Timer Group register base address
|
||||
* @param timer_num Timer index in the group
|
||||
* @param en true to enable, false to disable
|
||||
*/
|
||||
static inline void timer_ll_enable_clock(timg_dev_t *hw, uint32_t timer_num, bool en)
|
||||
{
|
||||
(void)hw;
|
||||
(void)timer_num;
|
||||
(void)en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable alarm event
|
||||
*
|
||||
|
@ -37,6 +37,13 @@ typedef struct {
|
||||
*/
|
||||
void timer_hal_init(timer_hal_context_t *hal, uint32_t group_num, uint32_t timer_num);
|
||||
|
||||
/**
|
||||
* @brief Deinit timer hal context.
|
||||
*
|
||||
* @param hal Context of HAL layer
|
||||
*/
|
||||
void timer_hal_deinit(timer_hal_context_t *hal);
|
||||
|
||||
/**
|
||||
* @brief Load counter value into time-base counter
|
||||
*
|
||||
|
@ -4,11 +4,37 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "hal/timer_hal.h"
|
||||
#include "hal/timer_ll.h"
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
void timer_hal_init(timer_hal_context_t *hal, uint32_t group_num, uint32_t timer_num)
|
||||
{
|
||||
hal->dev = TIMER_LL_GET_HW(group_num);
|
||||
hal->timer_id = timer_num;
|
||||
// enable peripheral clock
|
||||
timer_ll_enable_clock(hal->dev, timer_num, true);
|
||||
// stop counter, alarm, auto-reload at first place
|
||||
timer_ll_enable_counter(hal->dev, timer_num, false);
|
||||
timer_ll_enable_auto_reload(hal->dev, timer_num, false);
|
||||
timer_ll_enable_alarm(hal->dev, timer_num, false);
|
||||
// enable RTM subsystem if available
|
||||
#if SOC_TIMER_SUPPORT_ETM
|
||||
timer_ll_enable_etm(hal->dev, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
void timer_hal_deinit(timer_hal_context_t *hal)
|
||||
{
|
||||
// disable peripheral clock
|
||||
timer_ll_enable_clock(hal->dev, hal->timer_id, false);
|
||||
// ensure counter, alarm, auto-reload are disabled
|
||||
timer_ll_enable_counter(hal->dev, hal->timer_id, false);
|
||||
timer_ll_enable_auto_reload(hal->dev, hal->timer_id, false);
|
||||
timer_ll_enable_alarm(hal->dev, hal->timer_id, false);
|
||||
#if SOC_TIMER_SUPPORT_ETM
|
||||
timer_ll_enable_etm(hal->dev, false);
|
||||
#endif
|
||||
hal->dev = NULL;
|
||||
}
|
||||
|
@ -603,10 +603,18 @@ config SOC_TIMER_GROUP_SUPPORT_APB
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_TIMER_GROUP_SUPPORT_RC_FAST
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_TIMER_GROUP_TOTAL_TIMERS
|
||||
int
|
||||
default 2
|
||||
|
||||
config SOC_TIMER_SUPPORT_ETM
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_TWAI_BRP_MIN
|
||||
int
|
||||
default 2
|
||||
|
@ -128,15 +128,24 @@ typedef enum {
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
#define SOC_GPTIMER_CLKS {SOC_MOD_CLK_APB, SOC_MOD_CLK_XTAL}
|
||||
#if CONFIG_IDF_ENV_FPGA
|
||||
#define SOC_GPTIMER_CLKS {SOC_MOD_CLK_XTAL}
|
||||
#else
|
||||
#define SOC_GPTIMER_CLKS {SOC_MOD_CLK_APB, SOC_MOD_CLK_XTAL, SOC_MOD_CLK_RC_FAST}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Type of GPTimer clock source
|
||||
*/
|
||||
typedef enum {
|
||||
GPTIMER_CLK_SRC_APB = SOC_MOD_CLK_APB, /*!< Select APB as the source clock */
|
||||
GPTIMER_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
|
||||
GPTIMER_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default choice */
|
||||
GPTIMER_CLK_SRC_APB = SOC_MOD_CLK_APB, /*!< Select APB as the source clock */
|
||||
GPTIMER_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
|
||||
GPTIMER_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */
|
||||
#if CONFIG_IDF_ENV_FPGA
|
||||
GPTIMER_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default choice */
|
||||
#else
|
||||
GPTIMER_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default choice */
|
||||
#endif
|
||||
} soc_periph_gptimer_clk_src_t;
|
||||
|
||||
/**
|
||||
|
@ -322,14 +322,15 @@
|
||||
#define SOC_SYSTIMER_INT_LEVEL 1 // Systimer peripheral uses level interrupt
|
||||
#define SOC_SYSTIMER_ALARM_MISS_COMPENSATE 1 // Systimer peripheral can generate interrupt immediately if t(target) > t(current)
|
||||
|
||||
// TODO: IDF-5332 (Copy from esp32c3, need check)
|
||||
/*--------------------------- 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_SUPPORT_APB (1)
|
||||
#define SOC_TIMER_GROUP_SUPPORT_RC_FAST (1)
|
||||
#define SOC_TIMER_GROUP_TOTAL_TIMERS (2)
|
||||
#define SOC_TIMER_SUPPORT_ETM (1)
|
||||
|
||||
// TODO: IDF-5313 (Copy from esp32c3, need check)
|
||||
/*-------------------------- TWAI CAPS ---------------------------------------*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user