gptimer: bringup driver on esp32c6

pull/9803/head
morris 2022-07-13 13:17:32 +08:00
rodzic 890a84dcc4
commit a1030307f1
14 zmienionych plików z 194 dodań i 16 usunięć

Wyświetl plik

@ -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]);

Wyświetl plik

@ -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

Wyświetl plik

@ -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
*

Wyświetl plik

@ -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
*

Wyświetl plik

@ -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
*

Wyświetl plik

@ -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;
}
}
/**

Wyświetl plik

@ -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
*

Wyświetl plik

@ -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
*

Wyświetl plik

@ -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
*

Wyświetl plik

@ -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
*

Wyświetl plik

@ -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;
}

Wyświetl plik

@ -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

Wyświetl plik

@ -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;
/**

Wyświetl plik

@ -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 ---------------------------------------*/