Merge branch 'refactor/timer_ll_hal_clean_before_ng' into 'master'

timer: clean up hal/ll for driver-ng

See merge request espressif/esp-idf!15123
This commit is contained in:
morris 2021-10-20 23:59:30 +00:00
commit 3a530e3311
45 changed files with 2545 additions and 3276 deletions

View File

@ -67,15 +67,15 @@ const static char *TAG = "esp_apptrace_test";
static void esp_apptrace_test_timer_init(int timer_group, int timer_idx, uint32_t period) static void esp_apptrace_test_timer_init(int timer_group, int timer_idx, uint32_t period)
{ {
timer_config_t config;
uint64_t alarm_val = (period * (TIMER_BASE_CLK / 1000000UL)) / 2; uint64_t alarm_val = (period * (TIMER_BASE_CLK / 1000000UL)) / 2;
timer_config_t config = {
config.alarm_en = 1; .alarm_en = 1,
config.auto_reload = 1; .auto_reload = 1,
config.counter_dir = TIMER_COUNT_UP; .counter_dir = TIMER_COUNT_UP,
config.divider = 2; //Range is 2 to 65536 .divider = 2, //Range is 2 to 65536
config.intr_type = TIMER_INTR_LEVEL; .intr_type = TIMER_INTR_LEVEL,
config.counter_en = TIMER_PAUSE; .counter_en = TIMER_PAUSE,
};
/*Configure timer*/ /*Configure timer*/
timer_init(timer_group, timer_idx, &config); timer_init(timer_group, timer_idx, &config);
/*Stop timer counter*/ /*Stop timer counter*/
@ -358,7 +358,6 @@ static uint64_t esp_apptrace_test_ts_get(void)
static void esp_apptrace_test_ts_init(int timer_group, int timer_idx) static void esp_apptrace_test_ts_init(int timer_group, int timer_idx)
{ {
timer_config_t config;
//uint64_t alarm_val = period * (TIMER_BASE_CLK / 1000000UL); //uint64_t alarm_val = period * (TIMER_BASE_CLK / 1000000UL);
ESP_APPTRACE_TEST_LOGI("Use timer%d.%d for TS", timer_group, timer_idx); ESP_APPTRACE_TEST_LOGI("Use timer%d.%d for TS", timer_group, timer_idx);
@ -366,11 +365,13 @@ static void esp_apptrace_test_ts_init(int timer_group, int timer_idx)
s_ts_timer_group = timer_group; s_ts_timer_group = timer_group;
s_ts_timer_idx = timer_idx; s_ts_timer_idx = timer_idx;
config.alarm_en = 0; timer_config_t config = {
config.auto_reload = 0; .alarm_en = 0,
config.counter_dir = TIMER_COUNT_UP; .auto_reload = 0,
config.divider = 2; //Range is 2 to 65536 .counter_dir = TIMER_COUNT_UP,
config.counter_en = 0; .divider = 2, //Range is 2 to 65536
.counter_en = 0,
};
/*Configure timer*/ /*Configure timer*/
timer_init(timer_group, timer_idx, &config); timer_init(timer_group, timer_idx, &config);
/*Load counter value */ /*Load counter value */
@ -381,13 +382,13 @@ static void esp_apptrace_test_ts_init(int timer_group, int timer_idx)
static void esp_apptrace_test_ts_cleanup(void) static void esp_apptrace_test_ts_cleanup(void)
{ {
timer_config_t config; timer_config_t config = {
.alarm_en = 0,
config.alarm_en = 0; .auto_reload = 0,
config.auto_reload = 0; .counter_dir = TIMER_COUNT_UP,
config.counter_dir = TIMER_COUNT_UP; .divider = 2, //Range is 2 to 65536
config.divider = 2; //Range is 2 to 65536 .counter_en = 0,
config.counter_en = 0; };
/*Configure timer*/ /*Configure timer*/
timer_init(s_ts_timer_group, s_ts_timer_idx, &config); timer_init(s_ts_timer_group, s_ts_timer_idx, &config);
} }

View File

@ -324,5 +324,5 @@ template<typename T> __attribute__((unused)) static void test_binary_operators()
} }
//Add more types here. If any flags cannot pass the build, use FLAG_ATTR in esp_attr.h //Add more types here. If any flags cannot pass the build, use FLAG_ATTR in esp_attr.h
#include "hal/timer_types.h" #include "driver/timer.h"
template void test_binary_operators<timer_intr_t>(); template void test_binary_operators<timer_intr_t>();

View File

@ -9,6 +9,7 @@
#include "esp_err.h" #include "esp_err.h"
#include "esp_attr.h" #include "esp_attr.h"
#include "soc/soc.h" #include "soc/soc.h"
#include "soc/soc_caps.h"
#include "soc/timer_periph.h" #include "soc/timer_periph.h"
#include "esp_intr_alloc.h" #include "esp_intr_alloc.h"
#include "hal/timer_types.h" #include "hal/timer_types.h"
@ -17,7 +18,115 @@
extern "C" { extern "C" {
#endif #endif
#define TIMER_BASE_CLK (APB_CLK_FREQ) /*!< Frequency of the clock on the input of the timer groups */ /**
* @brief Frequency of the clock on the input of the timer groups
* @note This macro is not correct for Timer Groups with multiple clock sources (e.g. APB, XTAL)
* So please don't use it in your application, we keep it here only for backward compatible
*/
#define TIMER_BASE_CLK (APB_CLK_FREQ)
/**
* @brief Selects a Timer-Group out of 2 available groups
*/
typedef enum {
TIMER_GROUP_0 = 0, /*!< Hw timer group 0 */
#if SOC_TIMER_GROUPS > 1
TIMER_GROUP_1 = 1, /*!< Hw timer group 1 */
#endif
TIMER_GROUP_MAX /*!< Maximum number of Hw timer groups */
} timer_group_t;
/**
* @brief Select a hardware timer from timer groups
*/
typedef enum {
TIMER_0 = 0, /*!<Select timer0 of GROUPx*/
#if SOC_TIMER_GROUP_TIMERS_PER_GROUP > 1
TIMER_1 = 1, /*!<Select timer1 of GROUPx*/
#endif
TIMER_MAX,
} timer_idx_t;
/**
* @brief Interrupt types of the timer.
*/
typedef enum {
TIMER_INTR_T0 = 1 << 0, /*!< interrupt of timer 0 */
#if SOC_TIMER_GROUP_TIMERS_PER_GROUP > 1
TIMER_INTR_T1 = 1 << 1, /*!< interrupt of timer 1 */
TIMER_INTR_WDT = 1 << 2, /*!< interrupt of watchdog */
#else
TIMER_INTR_WDT = 1 << 1, /*!< interrupt of watchdog */
#endif
TIMER_INTR_NONE = 0
} timer_intr_t;
FLAG_ATTR(timer_intr_t)
/**
* @brief Decides the direction of counter
*/
typedef enum {
TIMER_COUNT_DOWN = GPTIMER_COUNT_DOWN, /*!< Descending Count from cnt.high|cnt.low*/
TIMER_COUNT_UP = GPTIMER_COUNT_UP, /*!< Ascending Count from Zero*/
TIMER_COUNT_MAX /*!< Maximum number of timer count directions */
} timer_count_dir_t;
/**
* @brief Decides whether timer is on or paused
*/
typedef enum {
TIMER_PAUSE, /*!<Pause timer counter*/
TIMER_START, /*!<Start timer counter*/
} timer_start_t;
/**
* @brief Decides whether to enable alarm mode
*/
typedef enum {
TIMER_ALARM_DIS = 0, /*!< Disable timer alarm*/
TIMER_ALARM_EN = 1, /*!< Enable timer alarm*/
TIMER_ALARM_MAX
} timer_alarm_t;
/**
* @brief Select interrupt type if running in alarm mode.
*/
typedef enum {
TIMER_INTR_LEVEL = 0, /*!< Interrupt mode: level mode*/
TIMER_INTR_MAX
} timer_intr_mode_t;
/**
* @brief Select if Alarm needs to be loaded by software or automatically reload by hardware.
*/
typedef enum {
TIMER_AUTORELOAD_DIS = 0, /*!< Disable auto-reload: hardware will not load counter value after an alarm event*/
TIMER_AUTORELOAD_EN = 1, /*!< Enable auto-reload: hardware will load counter value after an alarm event*/
TIMER_AUTORELOAD_MAX,
} timer_autoreload_t;
/**
* @brief Select timer source clock.
*/
typedef enum {
TIMER_SRC_CLK_APB = GPTIMER_CLK_SRC_APB, /*!< Select APB as the source clock*/
#if SOC_TIMER_GROUP_SUPPORT_XTAL
TIMER_SRC_CLK_XTAL = GPTIMER_CLK_SRC_XTAL, /*!< Select XTAL as the source clock*/
#endif
} timer_src_clk_t;
/**
* @brief Data structure with timer's configuration settings
*/
typedef struct {
timer_alarm_t alarm_en; /*!< Timer alarm enable */
timer_start_t counter_en; /*!< Counter enable */
timer_intr_mode_t intr_type; /*!< Interrupt mode */
timer_count_dir_t counter_dir; /*!< Counter direction */
timer_autoreload_t auto_reload; /*!< Timer auto-reload */
timer_src_clk_t clk_src; /*!< Selects source clock. */
uint32_t divider; /*!< Counter clock divider */
} timer_config_t;
/** /**
* @brief Interrupt handle callback function. User need to retrun a bool value * @brief Interrupt handle callback function. User need to retrun a bool value

View File

@ -13,8 +13,11 @@
#include "driver/timer.h" #include "driver/timer.h"
#include "driver/periph_ctrl.h" #include "driver/periph_ctrl.h"
#include "hal/timer_hal.h" #include "hal/timer_hal.h"
#include "hal/timer_ll.h"
#include "hal/check.h"
#include "soc/timer_periph.h" #include "soc/timer_periph.h"
#include "soc/rtc.h" #include "soc/rtc.h"
#include "soc/timer_group_reg.h"
static const char *TIMER_TAG = "timer_group"; static const char *TIMER_TAG = "timer_group";
@ -41,6 +44,12 @@ typedef struct {
typedef struct { typedef struct {
timer_hal_context_t hal; timer_hal_context_t hal;
timer_isr_func_t timer_isr_fun; timer_isr_func_t timer_isr_fun;
gptimer_clock_source_t clk_src;
gptimer_count_direction_t direction;
uint32_t divider;
bool alarm_en;
bool auto_reload_en;
bool counter_en;
} timer_obj_t; } timer_obj_t;
static timer_obj_t *p_timer_obj[TIMER_GROUP_MAX][TIMER_MAX] = {0}; static timer_obj_t *p_timer_obj[TIMER_GROUP_MAX][TIMER_MAX] = {0};
@ -53,7 +62,7 @@ esp_err_t timer_get_counter_value(timer_group_t group_num, timer_idx_t timer_num
ESP_RETURN_ON_FALSE(timer_val != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_PARAM_ADDR_ERROR); ESP_RETURN_ON_FALSE(timer_val != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_PARAM_ADDR_ERROR);
ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR);
TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]);
timer_hal_get_counter_value(&(p_timer_obj[group_num][timer_num]->hal), timer_val); *timer_val = timer_ll_get_counter_value(p_timer_obj[group_num][timer_num]->hal.dev, timer_num);
TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]);
return ESP_OK; return ESP_OK;
} }
@ -64,19 +73,22 @@ esp_err_t timer_get_counter_time_sec(timer_group_t group_num, timer_idx_t timer_
ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR); ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR);
ESP_RETURN_ON_FALSE(time != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_PARAM_ADDR_ERROR); ESP_RETURN_ON_FALSE(time != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_PARAM_ADDR_ERROR);
ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR);
uint64_t timer_val; uint64_t timer_val = timer_ll_get_counter_value(p_timer_obj[group_num][timer_num]->hal.dev, timer_num);
esp_err_t err = timer_get_counter_value(group_num, timer_num, &timer_val); uint32_t div = p_timer_obj[group_num][timer_num]->divider;
if (err == ESP_OK) { switch (p_timer_obj[group_num][timer_num]->clk_src) {
uint32_t div; case GPTIMER_CLK_SRC_APB:
timer_hal_get_divider(&(p_timer_obj[group_num][timer_num]->hal), &div);
*time = (double)timer_val * div / rtc_clk_apb_freq_get(); *time = (double)timer_val * div / rtc_clk_apb_freq_get();
break;
#if SOC_TIMER_GROUP_SUPPORT_XTAL #if SOC_TIMER_GROUP_SUPPORT_XTAL
if (timer_hal_get_use_xtal(&(p_timer_obj[group_num][timer_num]->hal))) { case GPTIMER_CLK_SRC_XTAL:
*time = (double)timer_val * div / ((int)rtc_clk_xtal_freq_get() * 1000000); *time = (double)timer_val * div / ((int)rtc_clk_xtal_freq_get() * MHZ);
} break;
#endif #endif
default:
ESP_RETURN_ON_FALSE(false, ESP_ERR_INVALID_ARG, TIMER_TAG, "invalid clock source");
break;
} }
return err; return ESP_OK;
} }
esp_err_t timer_set_counter_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t load_val) esp_err_t timer_set_counter_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t load_val)
@ -96,7 +108,8 @@ esp_err_t timer_start(timer_group_t group_num, timer_idx_t timer_num)
ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR); ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR);
ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR);
TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]);
timer_hal_set_counter_enable(&(p_timer_obj[group_num][timer_num]->hal), TIMER_START); timer_ll_enable_counter(p_timer_obj[group_num][timer_num]->hal.dev, timer_num, true);
p_timer_obj[group_num][timer_num]->counter_en = true;
TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]);
return ESP_OK; return ESP_OK;
} }
@ -107,7 +120,8 @@ esp_err_t timer_pause(timer_group_t group_num, timer_idx_t timer_num)
ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR); ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR);
ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR);
TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]);
timer_hal_set_counter_enable(&(p_timer_obj[group_num][timer_num]->hal), TIMER_PAUSE); timer_ll_enable_counter(p_timer_obj[group_num][timer_num]->hal.dev, timer_num, false);
p_timer_obj[group_num][timer_num]->counter_en = false;
TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]);
return ESP_OK; return ESP_OK;
} }
@ -119,7 +133,7 @@ esp_err_t timer_set_counter_mode(timer_group_t group_num, timer_idx_t timer_num,
ESP_RETURN_ON_FALSE(counter_dir < TIMER_COUNT_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_COUNT_DIR_ERROR); ESP_RETURN_ON_FALSE(counter_dir < TIMER_COUNT_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_COUNT_DIR_ERROR);
ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR);
TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]);
timer_hal_set_counter_increase(&(p_timer_obj[group_num][timer_num]->hal), counter_dir); timer_ll_set_count_direction(p_timer_obj[group_num][timer_num]->hal.dev, timer_num, counter_dir);
TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]);
return ESP_OK; return ESP_OK;
} }
@ -131,7 +145,8 @@ esp_err_t timer_set_auto_reload(timer_group_t group_num, timer_idx_t timer_num,
ESP_RETURN_ON_FALSE(reload < TIMER_AUTORELOAD_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_AUTORELOAD_ERROR); ESP_RETURN_ON_FALSE(reload < TIMER_AUTORELOAD_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_AUTORELOAD_ERROR);
ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR);
TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]);
timer_hal_set_auto_reload(&(p_timer_obj[group_num][timer_num]->hal), reload); timer_ll_enable_auto_reload(p_timer_obj[group_num][timer_num]->hal.dev, timer_num, reload);
p_timer_obj[group_num][timer_num]->auto_reload_en = reload;
TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]);
return ESP_OK; return ESP_OK;
} }
@ -143,7 +158,8 @@ esp_err_t timer_set_divider(timer_group_t group_num, timer_idx_t timer_num, uint
ESP_RETURN_ON_FALSE(divider > 1 && divider < 65537, ESP_ERR_INVALID_ARG, TIMER_TAG, DIVIDER_RANGE_ERROR); ESP_RETURN_ON_FALSE(divider > 1 && divider < 65537, ESP_ERR_INVALID_ARG, TIMER_TAG, DIVIDER_RANGE_ERROR);
ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR);
TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]);
timer_hal_set_divider(&(p_timer_obj[group_num][timer_num]->hal), divider); timer_ll_set_clock_prescale(p_timer_obj[group_num][timer_num]->hal.dev, timer_num, divider);
p_timer_obj[group_num][timer_num]->divider = divider;
TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]);
return ESP_OK; return ESP_OK;
} }
@ -154,7 +170,7 @@ esp_err_t timer_set_alarm_value(timer_group_t group_num, timer_idx_t timer_num,
ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR); ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR);
ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR);
TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]);
timer_hal_set_alarm_value(&(p_timer_obj[group_num][timer_num]->hal), alarm_value); timer_ll_set_alarm_value(p_timer_obj[group_num][timer_num]->hal.dev, timer_num, alarm_value);
TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]);
return ESP_OK; return ESP_OK;
} }
@ -166,7 +182,7 @@ esp_err_t timer_get_alarm_value(timer_group_t group_num, timer_idx_t timer_num,
ESP_RETURN_ON_FALSE(alarm_value != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_PARAM_ADDR_ERROR); ESP_RETURN_ON_FALSE(alarm_value != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_PARAM_ADDR_ERROR);
ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR);
TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]);
timer_hal_get_alarm_value(&(p_timer_obj[group_num][timer_num]->hal), alarm_value); *alarm_value = timer_ll_get_alarm_value(p_timer_obj[group_num][timer_num]->hal.dev, timer_num);
TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]);
return ESP_OK; return ESP_OK;
} }
@ -178,7 +194,7 @@ esp_err_t timer_set_alarm(timer_group_t group_num, timer_idx_t timer_num, timer_
ESP_RETURN_ON_FALSE(alarm_en < TIMER_ALARM_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_ALARM_ERROR); ESP_RETURN_ON_FALSE(alarm_en < TIMER_ALARM_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_ALARM_ERROR);
ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR);
TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]);
timer_hal_set_alarm_enable(&(p_timer_obj[group_num][timer_num]->hal), alarm_en); timer_ll_enable_alarm(p_timer_obj[group_num][timer_num]->hal.dev, timer_num, alarm_en);
TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]);
return ESP_OK; return ESP_OK;
} }
@ -186,30 +202,20 @@ esp_err_t timer_set_alarm(timer_group_t group_num, timer_idx_t timer_num, timer_
static void IRAM_ATTR timer_isr_default(void *arg) static void IRAM_ATTR timer_isr_default(void *arg)
{ {
bool is_awoken = false; bool is_awoken = false;
timer_obj_t *timer_obj = (timer_obj_t *)arg; timer_obj_t *timer_obj = (timer_obj_t *)arg;
if (timer_obj == NULL) { if (timer_obj == NULL || timer_obj->timer_isr_fun.fn == NULL) {
return; return;
} }
if (timer_obj->timer_isr_fun.fn == NULL) { uint32_t timer_id = timer_obj->hal.timer_id;
return; timer_hal_context_t *hal = &timer_obj->hal;
}
TIMER_ENTER_CRITICAL(&timer_spinlock[timer_obj->timer_isr_fun.isr_timer_group]); TIMER_ENTER_CRITICAL(&timer_spinlock[timer_obj->timer_isr_fun.isr_timer_group]);
{ uint32_t intr_status = timer_ll_get_intr_status(hal->dev);
uint32_t intr_status = 0; if (intr_status & TIMER_LL_EVENT_ALARM(timer_id)) {
timer_hal_get_intr_status(&(timer_obj->hal), &intr_status); //Clear intrrupt status
if (intr_status & BIT(timer_obj->hal.idx)) { timer_ll_clear_intr_status(hal->dev, TIMER_LL_EVENT_ALARM(timer_id));
is_awoken = timer_obj->timer_isr_fun.fn(timer_obj->timer_isr_fun.args); is_awoken = timer_obj->timer_isr_fun.fn(timer_obj->timer_isr_fun.args);
//Clear intrrupt status //If the timer is set to auto reload, we need enable it again, so it is triggered the next time
timer_hal_clear_intr_status(&(timer_obj->hal)); timer_ll_enable_alarm(hal->dev, timer_id, timer_obj->auto_reload_en);
//If the timer is set to auto reload, we need enable it again, so it is triggered the next time.
if (timer_hal_get_auto_reload(&timer_obj->hal)) {
timer_hal_set_alarm_enable(&(timer_obj->hal), TIMER_ALARM_EN);
} else {
timer_hal_set_alarm_enable(&(timer_obj->hal), TIMER_ALARM_DIS);
}
}
} }
TIMER_EXIT_CRITICAL(&timer_spinlock[timer_obj->timer_isr_fun.isr_timer_group]); TIMER_EXIT_CRITICAL(&timer_spinlock[timer_obj->timer_isr_fun.isr_timer_group]);
@ -256,11 +262,11 @@ esp_err_t timer_isr_register(timer_group_t group_num, timer_idx_t timer_num,
ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR); ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR);
ESP_RETURN_ON_FALSE(fn != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_PARAM_ADDR_ERROR); ESP_RETURN_ON_FALSE(fn != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_PARAM_ADDR_ERROR);
ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR);
timer_hal_context_t *hal = &p_timer_obj[group_num][timer_num]->hal;
uint32_t status_reg = 0; return esp_intr_alloc_intrstatus(timer_group_periph_signals.groups[group_num].timer_irq_id[timer_num],
uint32_t mask = 0; intr_alloc_flags,
timer_hal_get_status_reg_mask_bit(&(p_timer_obj[group_num][timer_num]->hal), &status_reg, &mask); (uint32_t)timer_ll_get_intr_status_reg(hal->dev),
return esp_intr_alloc_intrstatus(timer_group_periph_signals.groups[group_num].t0_irq_id + timer_num, intr_alloc_flags, status_reg, mask, fn, arg, handle); TIMER_LL_EVENT_ALARM(timer_num), fn, arg, handle);
} }
esp_err_t timer_init(timer_group_t group_num, timer_idx_t timer_num, const timer_config_t *config) esp_err_t timer_init(timer_group_t group_num, timer_idx_t timer_num, const timer_config_t *config)
@ -269,33 +275,32 @@ esp_err_t timer_init(timer_group_t group_num, timer_idx_t timer_num, const timer
ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR); ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR);
ESP_RETURN_ON_FALSE(config != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_PARAM_ADDR_ERROR); ESP_RETURN_ON_FALSE(config != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_PARAM_ADDR_ERROR);
ESP_RETURN_ON_FALSE(config->divider > 1 && config->divider < 65537, ESP_ERR_INVALID_ARG, TIMER_TAG, DIVIDER_RANGE_ERROR); ESP_RETURN_ON_FALSE(config->divider > 1 && config->divider < 65537, ESP_ERR_INVALID_ARG, TIMER_TAG, DIVIDER_RANGE_ERROR);
ESP_RETURN_ON_FALSE(config->intr_type < TIMER_INTR_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, "only support Level Interrupt");
if (p_timer_obj[group_num][timer_num] == NULL) {
p_timer_obj[group_num][timer_num] = (timer_obj_t *) heap_caps_calloc(1, sizeof(timer_obj_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num], ESP_ERR_NO_MEM, TIMER_TAG, "no mem for timer object");
}
timer_hal_context_t *hal = &p_timer_obj[group_num][timer_num]->hal;
periph_module_enable(timer_group_periph_signals.groups[group_num].module); periph_module_enable(timer_group_periph_signals.groups[group_num].module);
if (p_timer_obj[group_num][timer_num] == NULL) {
p_timer_obj[group_num][timer_num] = (timer_obj_t *) heap_caps_calloc(1, sizeof(timer_obj_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
if (p_timer_obj[group_num][timer_num] == NULL) {
ESP_LOGE(TIMER_TAG, "TIMER driver malloc error");
return ESP_FAIL;
}
}
TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]);
timer_hal_init(&(p_timer_obj[group_num][timer_num]->hal), group_num, timer_num); timer_hal_init(hal, group_num, timer_num);
timer_hal_reset_periph(&(p_timer_obj[group_num][timer_num]->hal)); timer_hal_set_counter_value(hal, 0);
timer_hal_clear_intr_status(&(p_timer_obj[group_num][timer_num]->hal)); timer_ll_set_clock_source(p_timer_obj[group_num][timer_num]->hal.dev, timer_num, config->clk_src);
timer_hal_set_auto_reload(&(p_timer_obj[group_num][timer_num]->hal), config->auto_reload); timer_ll_set_clock_prescale(hal->dev, timer_num, config->divider);
timer_hal_set_divider(&(p_timer_obj[group_num][timer_num]->hal), config->divider); timer_ll_set_count_direction(p_timer_obj[group_num][timer_num]->hal.dev, timer_num, config->counter_dir);
timer_hal_set_counter_increase(&(p_timer_obj[group_num][timer_num]->hal), config->counter_dir); timer_ll_enable_intr(hal->dev, TIMER_LL_EVENT_ALARM(timer_num), false);
timer_hal_set_alarm_enable(&(p_timer_obj[group_num][timer_num]->hal), config->alarm_en); timer_ll_clear_intr_status(hal->dev, TIMER_LL_EVENT_ALARM(timer_num));
timer_hal_set_level_int_enable(&(p_timer_obj[group_num][timer_num]->hal), config->intr_type == TIMER_INTR_LEVEL); timer_ll_enable_alarm(hal->dev, timer_num, config->alarm_en);
if (config->intr_type != TIMER_INTR_LEVEL) { timer_ll_enable_auto_reload(hal->dev, timer_num, config->auto_reload);
ESP_LOGW(TIMER_TAG, "only support Level Interrupt, switch to Level Interrupt instead"); timer_ll_enable_counter(hal->dev, timer_num, config->counter_en);
} p_timer_obj[group_num][timer_num]->clk_src = config->clk_src;
timer_hal_set_counter_enable(&(p_timer_obj[group_num][timer_num]->hal), config->counter_en); p_timer_obj[group_num][timer_num]->alarm_en = config->alarm_en;
#if SOC_TIMER_GROUP_SUPPORT_XTAL p_timer_obj[group_num][timer_num]->auto_reload_en = config->auto_reload;
timer_hal_set_use_xtal(&(p_timer_obj[group_num][timer_num]->hal), config->clk_src); p_timer_obj[group_num][timer_num]->direction = config->counter_dir;
#endif p_timer_obj[group_num][timer_num]->counter_en = config->counter_en;
p_timer_obj[group_num][timer_num]->divider = config->divider;
TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]);
return ESP_OK; return ESP_OK;
@ -306,14 +311,15 @@ esp_err_t timer_deinit(timer_group_t group_num, timer_idx_t timer_num)
ESP_RETURN_ON_FALSE(group_num < TIMER_GROUP_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_GROUP_NUM_ERROR); ESP_RETURN_ON_FALSE(group_num < TIMER_GROUP_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_GROUP_NUM_ERROR);
ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR); ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR);
ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR);
timer_hal_context_t *hal = &p_timer_obj[group_num][timer_num]->hal;
TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]);
timer_hal_set_counter_enable(&(p_timer_obj[group_num][timer_num]->hal), TIMER_PAUSE); timer_ll_enable_counter(hal->dev, timer_num, false);
timer_hal_intr_disable(&(p_timer_obj[group_num][timer_num]->hal)); timer_ll_enable_intr(hal->dev, TIMER_LL_EVENT_ALARM(timer_num), false);
timer_hal_clear_intr_status(&(p_timer_obj[group_num][timer_num]->hal)); timer_ll_clear_intr_status(hal->dev, TIMER_LL_EVENT_ALARM(timer_num));
TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]);
heap_caps_free(p_timer_obj[group_num][timer_num]); free(p_timer_obj[group_num][timer_num]);
p_timer_obj[group_num][timer_num] = NULL; p_timer_obj[group_num][timer_num] = NULL;
return ESP_OK; return ESP_OK;
@ -327,20 +333,12 @@ esp_err_t timer_get_config(timer_group_t group_num, timer_idx_t timer_num, timer
ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR);
TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]);
config->alarm_en = timer_hal_get_alarm_enable(&(p_timer_obj[group_num][timer_num]->hal)); config->alarm_en = p_timer_obj[group_num][timer_num]->alarm_en;
config->auto_reload = timer_hal_get_auto_reload(&(p_timer_obj[group_num][timer_num]->hal)); config->auto_reload = p_timer_obj[group_num][timer_num]->auto_reload_en;
config->counter_dir = timer_hal_get_counter_increase(&(p_timer_obj[group_num][timer_num]->hal)); config->counter_dir = p_timer_obj[group_num][timer_num]->direction;
config->counter_en = timer_hal_get_counter_enable(&(p_timer_obj[group_num][timer_num]->hal)); config->counter_en = p_timer_obj[group_num][timer_num]->counter_en;
config->divider = p_timer_obj[group_num][timer_num]->divider;
uint32_t div; config->intr_type = TIMER_INTR_LEVEL;
timer_hal_get_divider(&(p_timer_obj[group_num][timer_num]->hal), &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;
} else {
config->intr_type = TIMER_INTR_MAX;
}
TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]);
return ESP_OK; return ESP_OK;
} }
@ -350,11 +348,7 @@ esp_err_t timer_group_intr_enable(timer_group_t group_num, timer_intr_t en_mask)
ESP_RETURN_ON_FALSE(group_num < TIMER_GROUP_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_GROUP_NUM_ERROR); ESP_RETURN_ON_FALSE(group_num < TIMER_GROUP_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_GROUP_NUM_ERROR);
ESP_RETURN_ON_FALSE(p_timer_obj[group_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); ESP_RETURN_ON_FALSE(p_timer_obj[group_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR);
TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]);
for (int i = 0; i < TIMER_MAX; i++) { timer_ll_enable_intr(p_timer_obj[group_num][0]->hal.dev, en_mask, true);
if (en_mask & BIT(i)) {
timer_hal_intr_enable(&(p_timer_obj[group_num][i]->hal));
}
}
TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]);
return ESP_OK; return ESP_OK;
} }
@ -364,11 +358,7 @@ esp_err_t timer_group_intr_disable(timer_group_t group_num, timer_intr_t disable
ESP_RETURN_ON_FALSE(group_num < TIMER_GROUP_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_GROUP_NUM_ERROR); ESP_RETURN_ON_FALSE(group_num < TIMER_GROUP_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_GROUP_NUM_ERROR);
ESP_RETURN_ON_FALSE(p_timer_obj[group_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); ESP_RETURN_ON_FALSE(p_timer_obj[group_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR);
TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]);
for (int i = 0; i < TIMER_MAX; i++) { timer_ll_enable_intr(p_timer_obj[group_num][0]->hal.dev, disable_mask, false);
if (disable_mask & BIT(i)) {
timer_hal_intr_disable(&(p_timer_obj[group_num][i]->hal));
}
}
TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]);
return ESP_OK; return ESP_OK;
} }
@ -379,7 +369,7 @@ esp_err_t timer_enable_intr(timer_group_t group_num, timer_idx_t timer_num)
ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR); ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR);
ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR);
TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]);
timer_hal_intr_enable(&(p_timer_obj[group_num][timer_num]->hal)); timer_ll_enable_intr(p_timer_obj[group_num][timer_num]->hal.dev, TIMER_LL_EVENT_ALARM(timer_num), true);
TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]);
return ESP_OK; return ESP_OK;
} }
@ -390,7 +380,7 @@ esp_err_t timer_disable_intr(timer_group_t group_num, timer_idx_t timer_num)
ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR); ESP_RETURN_ON_FALSE(timer_num < TIMER_MAX, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NUM_ERROR);
ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR); ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG, TIMER_NEVER_INIT_ERROR);
TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]);
timer_hal_intr_disable(&(p_timer_obj[group_num][timer_num]->hal)); timer_ll_enable_intr(p_timer_obj[group_num][timer_num]->hal.dev, TIMER_LL_EVENT_ALARM(timer_num), false);
TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]);
return ESP_OK; return ESP_OK;
} }
@ -398,20 +388,18 @@ esp_err_t timer_disable_intr(timer_group_t group_num, timer_idx_t timer_num)
/* This function is deprecated */ /* This function is deprecated */
timer_intr_t IRAM_ATTR timer_group_intr_get_in_isr(timer_group_t group_num) timer_intr_t IRAM_ATTR timer_group_intr_get_in_isr(timer_group_t group_num)
{ {
uint32_t intr_raw_status = 0; return timer_ll_get_intr_status(TIMER_LL_GET_HW(group_num));
timer_hal_get_intr_raw_status(group_num, &intr_raw_status);
return intr_raw_status;
} }
uint32_t IRAM_ATTR timer_group_get_intr_status_in_isr(timer_group_t group_num) uint32_t IRAM_ATTR timer_group_get_intr_status_in_isr(timer_group_t group_num)
{ {
uint32_t intr_status = 0; uint32_t intr_status = 0;
if (p_timer_obj[group_num][TIMER_0] != NULL) { if (p_timer_obj[group_num][TIMER_0] != NULL) {
timer_hal_get_intr_status(&(p_timer_obj[group_num][TIMER_0]->hal), &intr_status); intr_status = timer_ll_get_intr_status(TIMER_LL_GET_HW(group_num)) & TIMER_LL_EVENT_ALARM(0);
} }
#if SOC_TIMER_GROUP_TIMERS_PER_GROUP > 1 #if SOC_TIMER_GROUP_TIMERS_PER_GROUP > 1
else if (p_timer_obj[group_num][TIMER_1] != NULL) { else if (p_timer_obj[group_num][TIMER_1] != NULL) {
timer_hal_get_intr_status(&(p_timer_obj[group_num][TIMER_1]->hal), &intr_status); intr_status = timer_ll_get_intr_status(TIMER_LL_GET_HW(group_num)) & TIMER_LL_EVENT_ALARM(1);
} }
#endif #endif
return intr_status; return intr_status;
@ -425,29 +413,29 @@ void IRAM_ATTR timer_group_intr_clr_in_isr(timer_group_t group_num, timer_idx_t
void IRAM_ATTR timer_group_clr_intr_status_in_isr(timer_group_t group_num, timer_idx_t timer_num) void IRAM_ATTR timer_group_clr_intr_status_in_isr(timer_group_t group_num, timer_idx_t timer_num)
{ {
timer_hal_clear_intr_status(&(p_timer_obj[group_num][timer_num]->hal)); timer_ll_clear_intr_status(p_timer_obj[group_num][timer_num]->hal.dev, TIMER_LL_EVENT_ALARM(timer_num));
} }
void IRAM_ATTR timer_group_enable_alarm_in_isr(timer_group_t group_num, timer_idx_t timer_num) void IRAM_ATTR timer_group_enable_alarm_in_isr(timer_group_t group_num, timer_idx_t timer_num)
{ {
timer_hal_set_alarm_enable(&(p_timer_obj[group_num][timer_num]->hal), true); timer_ll_enable_alarm(p_timer_obj[group_num][timer_num]->hal.dev, 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 IRAM_ATTR timer_group_get_counter_value_in_isr(timer_group_t group_num, timer_idx_t timer_num)
{ {
uint64_t val; uint64_t val = timer_ll_get_counter_value(p_timer_obj[group_num][timer_num]->hal.dev, timer_num);
timer_hal_get_counter_value(&(p_timer_obj[group_num][timer_num]->hal), &val);
return 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) 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_hal_set_alarm_value(&(p_timer_obj[group_num][timer_num]->hal), alarm_val); timer_ll_set_alarm_value(p_timer_obj[group_num][timer_num]->hal.dev, 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) 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_hal_set_counter_enable(&(p_timer_obj[group_num][timer_num]->hal), counter_en); timer_ll_enable_counter(p_timer_obj[group_num][timer_num]->hal.dev, timer_num, counter_en);
p_timer_obj[group_num][timer_num]->counter_en = counter_en;
} }
/* This function is deprecated */ /* This function is deprecated */
@ -462,7 +450,7 @@ void IRAM_ATTR timer_group_clr_intr_sta_in_isr(timer_group_t group_num, timer_in
bool IRAM_ATTR timer_group_get_auto_reload_in_isr(timer_group_t group_num, timer_idx_t timer_num) bool IRAM_ATTR timer_group_get_auto_reload_in_isr(timer_group_t group_num, timer_idx_t timer_num)
{ {
return timer_hal_get_auto_reload(&(p_timer_obj[group_num][timer_num]->hal)); return p_timer_obj[group_num][timer_num]->auto_reload_en;
} }
esp_err_t IRAM_ATTR timer_spinlock_take(timer_group_t group_num) esp_err_t IRAM_ATTR timer_spinlock_take(timer_group_t group_num)
@ -478,3 +466,10 @@ esp_err_t IRAM_ATTR timer_spinlock_give(timer_group_t group_num)
TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]);
return ESP_OK; return ESP_OK;
} }
STATIC_HAL_REG_CHECK(TIMER_TAG, TIMER_INTR_T0, TIMG_T0_INT_CLR);
#if SOC_TIMER_GROUP_TIMERS_PER_GROUP > 1
STATIC_HAL_REG_CHECK(TIMER_TAG, TIMER_INTR_T1, TIMG_T1_INT_CLR);
#endif
STATIC_HAL_REG_CHECK(TIMER_TAG, TIMER_INTR_WDT, TIMG_WDT_INT_CLR);

View File

@ -2000,13 +2000,14 @@ TEST_CASE("can post events from interrupt handler", "[event]")
SemaphoreHandle_t sem = xSemaphoreCreateBinary(); SemaphoreHandle_t sem = xSemaphoreCreateBinary();
/* Select and initialize basic parameters of the timer */ /* Select and initialize basic parameters of the timer */
timer_config_t config; timer_config_t config = {
config.divider = TIMER_DIVIDER; .divider = TIMER_DIVIDER,
config.counter_dir = TIMER_COUNT_UP; .counter_dir = TIMER_COUNT_UP,
config.counter_en = TIMER_PAUSE; .counter_en = TIMER_PAUSE,
config.alarm_en = TIMER_ALARM_EN; .alarm_en = TIMER_ALARM_EN,
config.intr_type = TIMER_INTR_LEVEL; .intr_type = TIMER_INTR_LEVEL,
config.auto_reload = false; .auto_reload = false,
};
timer_init(TIMER_GROUP_0, TIMER_0, &config); timer_init(TIMER_GROUP_0, TIMER_0, &config);
/* Timer's counter will initially start from value below. /* Timer's counter will initially start from value below.

View File

@ -27,7 +27,6 @@
#include "soc/rtc.h" #include "soc/rtc.h"
#include "hal/cpu_hal.h" #include "hal/cpu_hal.h"
#include "esp_intr_alloc.h" #include "esp_intr_alloc.h"
#include "driver/timer.h"
#define MHZ (1000000) #define MHZ (1000000)
@ -347,7 +346,7 @@ TEST_CASE("BENCHMARK for DPORT access performance", "[freertos]")
uint32_t xt_highint5_read_apb; uint32_t xt_highint5_read_apb;
#ifndef CONFIG_FREERTOS_UNICORE #ifndef CONFIG_FREERTOS_UNICORE
timer_isr_handle_t inth; intr_handle_t inth;
xSemaphoreHandle sync_sema; xSemaphoreHandle sync_sema;
static void init_hi_interrupt(void *arg) static void init_hi_interrupt(void *arg)

View File

@ -401,13 +401,14 @@ static void setup_timer(void)
//Setup timer for ISR //Setup timer for ISR
int timer_group = TIMER_GROUP; int timer_group = TIMER_GROUP;
int timer_idx = TIMER_NUMBER; int timer_idx = TIMER_NUMBER;
timer_config_t config; timer_config_t config = {
config.alarm_en = 1; .alarm_en = 1,
config.auto_reload = 1; .auto_reload = 1,
config.counter_dir = TIMER_COUNT_UP; .counter_dir = TIMER_COUNT_UP,
config.divider = 10000; .divider = 10000,
config.intr_type = TIMER_INTR_LEVEL; .intr_type = TIMER_INTR_LEVEL,
config.counter_en = TIMER_PAUSE; .counter_en = TIMER_PAUSE,
};
timer_init(timer_group, timer_idx, &config); //Configure timer timer_init(timer_group, timer_idx, &config); //Configure timer
timer_pause(timer_group, timer_idx); //Stop timer counter timer_pause(timer_group, timer_idx); //Stop timer counter
timer_set_counter_value(timer_group, timer_idx, 0x00000000ULL); //Load counter value timer_set_counter_value(timer_group, timer_idx, 0x00000000ULL); //Load counter value

View File

@ -1,16 +1,8 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
@ -25,7 +17,6 @@
#include "esp_attr.h" #include "esp_attr.h"
#include "esp_freertos_hooks.h" #include "esp_freertos_hooks.h"
#include "soc/timer_periph.h" #include "soc/timer_periph.h"
#include "driver/timer.h"
#include "driver/periph_ctrl.h" #include "driver/periph_ctrl.h"
#include "esp_int_wdt.h" #include "esp_int_wdt.h"
#include "esp_private/system_internal.h" #include "esp_private/system_internal.h"

View File

@ -22,7 +22,6 @@
#include "esp_freertos_hooks.h" #include "esp_freertos_hooks.h"
#include "soc/timer_periph.h" #include "soc/timer_periph.h"
#include "esp_log.h" #include "esp_log.h"
#include "driver/timer.h"
#include "driver/periph_ctrl.h" #include "driver/periph_ctrl.h"
#include "esp_task_wdt.h" #include "esp_task_wdt.h"
#include "esp_private/system_internal.h" #include "esp_private/system_internal.h"

View File

@ -1,16 +1,7 @@
/* Copyright 2018 Espressif Systems (Shanghai) PTE LTD /*
* SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * SPDX-License-Identifier: Apache-2.0
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
/* /*
* FreeModbus Libary: ESP32 Port Demo Application * FreeModbus Libary: ESP32 Port Demo Application
@ -57,7 +48,7 @@
#define MB_US50_FREQ (20000) // 20kHz 1/20000 = 50mks #define MB_US50_FREQ (20000) // 20kHz 1/20000 = 50mks
#define MB_DISCR_TIME_US (50) // 50uS = one discreet for timer #define MB_DISCR_TIME_US (50) // 50uS = one discreet for timer
#define MB_TIMER_PRESCALLER ((TIMER_BASE_CLK / MB_US50_FREQ) - 1); #define MB_TIMER_PRESCALLER ((TIMER_BASE_CLK / MB_US50_FREQ) - 1)
#define MB_TIMER_SCALE (TIMER_BASE_CLK / TIMER_DIVIDER) // convert counter value to seconds #define MB_TIMER_SCALE (TIMER_BASE_CLK / TIMER_DIVIDER) // convert counter value to seconds
#define MB_TIMER_DIVIDER ((TIMER_BASE_CLK / 1000000UL) * MB_DISCR_TIME_US - 1) // divider for 50uS #define MB_TIMER_DIVIDER ((TIMER_BASE_CLK / 1000000UL) * MB_DISCR_TIME_US - 1) // divider for 50uS
#define MB_TIMER_WITH_RELOAD (1) #define MB_TIMER_WITH_RELOAD (1)
@ -84,13 +75,14 @@ BOOL xMBPortTimersInit(USHORT usTim1Timerout50us)
MB_PORT_CHECK((usTim1Timerout50us > 0), FALSE, MB_PORT_CHECK((usTim1Timerout50us > 0), FALSE,
"Modbus timeout discreet is incorrect."); "Modbus timeout discreet is incorrect.");
esp_err_t xErr; esp_err_t xErr;
timer_config_t config; timer_config_t config = {
config.alarm_en = TIMER_ALARM_EN; .alarm_en = TIMER_ALARM_EN,
config.auto_reload = MB_TIMER_WITH_RELOAD; .auto_reload = MB_TIMER_WITH_RELOAD,
config.counter_dir = TIMER_COUNT_UP; .counter_dir = TIMER_COUNT_UP,
config.divider = MB_TIMER_PRESCALLER; .divider = MB_TIMER_PRESCALLER,
config.intr_type = TIMER_INTR_LEVEL; .intr_type = TIMER_INTR_LEVEL,
config.counter_en = TIMER_PAUSE; .counter_en = TIMER_PAUSE,
};
// Configure timer // Configure timer
xErr = timer_init(usTimerGroupIndex, usTimerIndex, &config); xErr = timer_init(usTimerGroupIndex, usTimerIndex, &config);
MB_PORT_CHECK((xErr == ESP_OK), FALSE, MB_PORT_CHECK((xErr == ESP_OK), FALSE,

View File

@ -1,16 +1,7 @@
/* Copyright 2018 Espressif Systems (Shanghai) PTE LTD /*
* SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * SPDX-License-Identifier: Apache-2.0
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
/* /*
* FreeModbus Libary: ESP32 Port Demo Application * FreeModbus Libary: ESP32 Port Demo Application
@ -45,7 +36,7 @@
#define MB_US50_FREQ (20000) // 20kHz 1/20000 = 50mks #define MB_US50_FREQ (20000) // 20kHz 1/20000 = 50mks
#define MB_TICK_TIME_US (50) // 50uS = one tick for timer #define MB_TICK_TIME_US (50) // 50uS = one tick for timer
#define MB_TIMER_PRESCALLER ((TIMER_BASE_CLK / MB_US50_FREQ) - 1); #define MB_TIMER_PRESCALLER ((TIMER_BASE_CLK / MB_US50_FREQ) - 1)
#define MB_TIMER_SCALE (TIMER_BASE_CLK / TIMER_DIVIDER) #define MB_TIMER_SCALE (TIMER_BASE_CLK / TIMER_DIVIDER)
#define MB_TIMER_DIVIDER ((TIMER_BASE_CLK / 1000000UL) * MB_TICK_TIME_US - 1) // divider for 50uS #define MB_TIMER_DIVIDER ((TIMER_BASE_CLK / 1000000UL) * MB_TICK_TIME_US - 1) // divider for 50uS
#define MB_TIMER_WITH_RELOAD (1) #define MB_TIMER_WITH_RELOAD (1)
@ -77,13 +68,14 @@ BOOL xMBMasterPortTimersInit(USHORT usTimeOut50us)
// Save timer reload value for Modbus T35 period // Save timer reload value for Modbus T35 period
usT35TimeOut50us = usTimeOut50us; usT35TimeOut50us = usTimeOut50us;
esp_err_t xErr; esp_err_t xErr;
timer_config_t config; timer_config_t config = {
config.alarm_en = TIMER_ALARM_EN; .alarm_en = TIMER_ALARM_EN,
config.auto_reload = MB_TIMER_WITH_RELOAD; .auto_reload = MB_TIMER_WITH_RELOAD,
config.counter_dir = TIMER_COUNT_UP; .counter_dir = TIMER_COUNT_UP,
config.divider = MB_TIMER_PRESCALLER; .divider = MB_TIMER_PRESCALLER,
config.intr_type = TIMER_INTR_LEVEL; .intr_type = TIMER_INTR_LEVEL,
config.counter_en = TIMER_PAUSE; .counter_en = TIMER_PAUSE,
};
// Configure timer // Configure timer
xErr = timer_init(usTimerGroupIndex, usTimerIndex, &config); xErr = timer_init(usTimerGroupIndex, usTimerIndex, &config);
MB_PORT_CHECK((xErr == ESP_OK), FALSE, MB_PORT_CHECK((xErr == ESP_OK), FALSE,

View File

@ -168,13 +168,14 @@ static void setup_timer(void)
//Setup timer for ISR //Setup timer for ISR
int timer_group = TIMER_GROUP_0; int timer_group = TIMER_GROUP_0;
int timer_idx = TIMER_NUMBER; int timer_idx = TIMER_NUMBER;
timer_config_t config; timer_config_t config = {
config.alarm_en = 1; .alarm_en = 1,
config.auto_reload = 1; .auto_reload = 1,
config.counter_dir = TIMER_COUNT_UP; .counter_dir = TIMER_COUNT_UP,
config.divider = TIMER_DIVIDER; .divider = TIMER_DIVIDER,
config.intr_type = TIMER_INTR_LEVEL; .intr_type = TIMER_INTR_LEVEL,
config.counter_en = TIMER_PAUSE; .counter_en = TIMER_PAUSE,
};
timer_init(timer_group, timer_idx, &config); //Configure timer timer_init(timer_group, timer_idx, &config); //Configure timer
timer_pause(timer_group, timer_idx); //Stop timer counter timer_pause(timer_group, timer_idx); //Stop timer counter
timer_set_counter_value(timer_group, timer_idx, 0x00000000ULL); //Load counter value timer_set_counter_value(timer_group, timer_idx, 0x00000000ULL); //Load counter value

View File

@ -127,13 +127,14 @@ static void timerg0_init(void *isr_handle)
int timer_group = TIMER_GROUP_0; int timer_group = TIMER_GROUP_0;
int timer_idx = xPortGetCoreID(); int timer_idx = xPortGetCoreID();
timer_config_t config; timer_config_t config = {
config.alarm_en = 1; .alarm_en = 1,
config.auto_reload = 1; .auto_reload = 1,
config.counter_dir = TIMER_COUNT_UP; .counter_dir = TIMER_COUNT_UP,
config.divider = TIMER_DIVIDER; .divider = TIMER_DIVIDER,
config.intr_type = TIMER_INTR_LEVEL; .intr_type = TIMER_INTR_LEVEL,
config.counter_en = TIMER_PAUSE; .counter_en = TIMER_PAUSE,
};
/*Configure timer*/ /*Configure timer*/
timer_init(timer_group, timer_idx, &config); timer_init(timer_group, timer_idx, &config);

View File

@ -1,16 +1,8 @@
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// The LL layer for Timer Group register operations. // The LL layer for Timer Group register operations.
// Note that most of the register operations in this layer are non-atomic operations. // Note that most of the register operations in this layer are non-atomic operations.
@ -24,6 +16,7 @@ extern "C" {
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include "hal/misc.h" #include "hal/misc.h"
#include "hal/assert.h"
#include "soc/timer_periph.h" #include "soc/timer_periph.h"
#include "soc/timer_group_struct.h" #include "soc/timer_group_struct.h"
#include "hal/wdt_types.h" #include "hal/wdt_types.h"
@ -51,7 +44,7 @@ _Static_assert(WDT_RESET_SIG_LENGTH_3_2us == TIMG_WDT_RESET_LENGTH_3200_NS, "Add
*/ */
FORCE_INLINE_ATTR void mwdt_ll_enable(timg_dev_t *hw) FORCE_INLINE_ATTR void mwdt_ll_enable(timg_dev_t *hw)
{ {
hw->wdt_config0.en = 1; hw->wdtconfig0.wdt_en = 1;
} }
/** /**
@ -64,7 +57,7 @@ FORCE_INLINE_ATTR void mwdt_ll_enable(timg_dev_t *hw)
*/ */
FORCE_INLINE_ATTR void mwdt_ll_disable(timg_dev_t *hw) FORCE_INLINE_ATTR void mwdt_ll_disable(timg_dev_t *hw)
{ {
hw->wdt_config0.en = 0; hw->wdtconfig0.wdt_en = 0;
} }
/** /**
@ -75,7 +68,7 @@ FORCE_INLINE_ATTR void mwdt_ll_disable(timg_dev_t *hw)
*/ */
FORCE_INLINE_ATTR bool mwdt_ll_check_if_enabled(timg_dev_t *hw) FORCE_INLINE_ATTR bool mwdt_ll_check_if_enabled(timg_dev_t *hw)
{ {
return (hw->wdt_config0.en) ? true : false; return (hw->wdtconfig0.wdt_en) ? true : false;
} }
/** /**
@ -89,24 +82,25 @@ FORCE_INLINE_ATTR bool mwdt_ll_check_if_enabled(timg_dev_t *hw)
FORCE_INLINE_ATTR void mwdt_ll_config_stage(timg_dev_t *hw, wdt_stage_t stage, uint32_t timeout, wdt_stage_action_t behavior) FORCE_INLINE_ATTR void mwdt_ll_config_stage(timg_dev_t *hw, wdt_stage_t stage, uint32_t timeout, wdt_stage_action_t behavior)
{ {
switch (stage) { switch (stage) {
case WDT_STAGE0: case WDT_STAGE0:
hw->wdt_config0.stg0 = behavior; hw->wdtconfig0.wdt_stg0 = behavior;
hw->wdt_config2 = timeout; hw->wdtconfig2.wdt_stg0_hold = timeout;
break; break;
case WDT_STAGE1: case WDT_STAGE1:
hw->wdt_config0.stg1 = behavior; hw->wdtconfig0.wdt_stg1 = behavior;
hw->wdt_config3 = timeout; hw->wdtconfig3.wdt_stg1_hold = timeout;
break; break;
case WDT_STAGE2: case WDT_STAGE2:
hw->wdt_config0.stg2 = behavior; hw->wdtconfig0.wdt_stg2 = behavior;
hw->wdt_config4 = timeout; hw->wdtconfig4.wdt_stg2_hold = timeout;
break; break;
case WDT_STAGE3: case WDT_STAGE3:
hw->wdt_config0.stg3 = behavior; hw->wdtconfig0.wdt_stg3 = behavior;
hw->wdt_config5 = timeout; hw->wdtconfig5.wdt_stg3_hold = timeout;
break; break;
default: default:
break; HAL_ASSERT(false && "unsupported WDT stage");
break;
} }
} }
@ -119,20 +113,21 @@ FORCE_INLINE_ATTR void mwdt_ll_config_stage(timg_dev_t *hw, wdt_stage_t stage, u
FORCE_INLINE_ATTR void mwdt_ll_disable_stage(timg_dev_t *hw, uint32_t stage) FORCE_INLINE_ATTR void mwdt_ll_disable_stage(timg_dev_t *hw, uint32_t stage)
{ {
switch (stage) { switch (stage) {
case WDT_STAGE0: case WDT_STAGE0:
hw->wdt_config0.stg0 = WDT_STAGE_ACTION_OFF; hw->wdtconfig0.wdt_stg0 = WDT_STAGE_ACTION_OFF;
break; break;
case WDT_STAGE1: case WDT_STAGE1:
hw->wdt_config0.stg1 = WDT_STAGE_ACTION_OFF; hw->wdtconfig0.wdt_stg1 = WDT_STAGE_ACTION_OFF;
break; break;
case WDT_STAGE2: case WDT_STAGE2:
hw->wdt_config0.stg2 = WDT_STAGE_ACTION_OFF; hw->wdtconfig0.wdt_stg2 = WDT_STAGE_ACTION_OFF;
break; break;
case WDT_STAGE3: case WDT_STAGE3:
hw->wdt_config0.stg3 = WDT_STAGE_ACTION_OFF; hw->wdtconfig0.wdt_stg3 = WDT_STAGE_ACTION_OFF;
break; break;
default: default:
break; HAL_ASSERT(false && "unsupported WDT stage");
break;
} }
} }
@ -144,7 +139,7 @@ FORCE_INLINE_ATTR void mwdt_ll_disable_stage(timg_dev_t *hw, uint32_t stage)
*/ */
FORCE_INLINE_ATTR void mwdt_ll_set_edge_intr(timg_dev_t *hw, bool enable) FORCE_INLINE_ATTR void mwdt_ll_set_edge_intr(timg_dev_t *hw, bool enable)
{ {
hw->wdt_config0.edge_int_en = (enable) ? 1 : 0; hw->wdtconfig0.wdt_edge_int_en = enable;
} }
/** /**
@ -155,7 +150,7 @@ FORCE_INLINE_ATTR void mwdt_ll_set_edge_intr(timg_dev_t *hw, bool enable)
*/ */
FORCE_INLINE_ATTR void mwdt_ll_set_level_intr(timg_dev_t *hw, bool enable) FORCE_INLINE_ATTR void mwdt_ll_set_level_intr(timg_dev_t *hw, bool enable)
{ {
hw->wdt_config0.level_int_en = (enable) ? 1 : 0; hw->wdtconfig0.wdt_level_int_en = enable;
} }
/** /**
@ -166,7 +161,7 @@ FORCE_INLINE_ATTR void mwdt_ll_set_level_intr(timg_dev_t *hw, bool enable)
*/ */
FORCE_INLINE_ATTR void mwdt_ll_set_cpu_reset_length(timg_dev_t *hw, wdt_reset_sig_length_t length) FORCE_INLINE_ATTR void mwdt_ll_set_cpu_reset_length(timg_dev_t *hw, wdt_reset_sig_length_t length)
{ {
hw->wdt_config0.cpu_reset_length = length; hw->wdtconfig0.wdt_cpu_reset_length = length;
} }
/** /**
@ -177,7 +172,7 @@ FORCE_INLINE_ATTR void mwdt_ll_set_cpu_reset_length(timg_dev_t *hw, wdt_reset_si
*/ */
FORCE_INLINE_ATTR void mwdt_ll_set_sys_reset_length(timg_dev_t *hw, wdt_reset_sig_length_t length) FORCE_INLINE_ATTR void mwdt_ll_set_sys_reset_length(timg_dev_t *hw, wdt_reset_sig_length_t length)
{ {
hw->wdt_config0.sys_reset_length = length; hw->wdtconfig0.wdt_sys_reset_length = length;
} }
/** /**
@ -190,9 +185,9 @@ FORCE_INLINE_ATTR void mwdt_ll_set_sys_reset_length(timg_dev_t *hw, wdt_reset_si
* WDT's enable bit is set to 0. Flashboot mode for TG0 is automatically enabled * WDT's enable bit is set to 0. Flashboot mode for TG0 is automatically enabled
* on flashboot, and should be disabled by software when flashbooting completes. * on flashboot, and should be disabled by software when flashbooting completes.
*/ */
FORCE_INLINE_ATTR void mwdt_ll_set_flashboot_en(timg_dev_t* hw, bool enable) FORCE_INLINE_ATTR void mwdt_ll_set_flashboot_en(timg_dev_t *hw, bool enable)
{ {
hw->wdt_config0.flashboot_mod_en = (enable) ? 1 : 0; hw->wdtconfig0.wdt_flashboot_mod_en = (enable) ? 1 : 0;
} }
/** /**
@ -203,7 +198,7 @@ FORCE_INLINE_ATTR void mwdt_ll_set_flashboot_en(timg_dev_t* hw, bool enable)
*/ */
FORCE_INLINE_ATTR void mwdt_ll_set_prescaler(timg_dev_t *hw, uint32_t prescaler) FORCE_INLINE_ATTR void mwdt_ll_set_prescaler(timg_dev_t *hw, uint32_t prescaler)
{ {
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wdt_config1, clk_prescale, prescaler); HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wdtconfig1, wdt_clk_prescaler, prescaler);
} }
/** /**
@ -215,7 +210,7 @@ FORCE_INLINE_ATTR void mwdt_ll_set_prescaler(timg_dev_t *hw, uint32_t prescaler)
*/ */
FORCE_INLINE_ATTR void mwdt_ll_feed(timg_dev_t *hw) FORCE_INLINE_ATTR void mwdt_ll_feed(timg_dev_t *hw)
{ {
hw->wdt_feed = 1; hw->wdtfeed.wdt_feed = 1;
} }
/** /**
@ -225,7 +220,7 @@ FORCE_INLINE_ATTR void mwdt_ll_feed(timg_dev_t *hw)
*/ */
FORCE_INLINE_ATTR void mwdt_ll_write_protect_enable(timg_dev_t *hw) FORCE_INLINE_ATTR void mwdt_ll_write_protect_enable(timg_dev_t *hw)
{ {
hw->wdt_wprotect = 0; hw->wdtwprotect.wdt_wkey = 0;
} }
/** /**
@ -235,7 +230,7 @@ FORCE_INLINE_ATTR void mwdt_ll_write_protect_enable(timg_dev_t *hw)
*/ */
FORCE_INLINE_ATTR void mwdt_ll_write_protect_disable(timg_dev_t *hw) FORCE_INLINE_ATTR void mwdt_ll_write_protect_disable(timg_dev_t *hw)
{ {
hw->wdt_wprotect = TIMG_WDT_WKEY_VALUE; hw->wdtwprotect.wdt_wkey = TIMG_WDT_WKEY_VALUE;
} }
/** /**
@ -243,9 +238,9 @@ FORCE_INLINE_ATTR void mwdt_ll_write_protect_disable(timg_dev_t *hw)
* *
* @param hw Start address of the peripheral registers. * @param hw Start address of the peripheral registers.
*/ */
FORCE_INLINE_ATTR void mwdt_ll_clear_intr_status(timg_dev_t* hw) FORCE_INLINE_ATTR void mwdt_ll_clear_intr_status(timg_dev_t *hw)
{ {
hw->int_clr_timers.wdt = 1; hw->int_clr_timers.wdt_int_clr = 1;
} }
/** /**
@ -254,9 +249,9 @@ FORCE_INLINE_ATTR void mwdt_ll_clear_intr_status(timg_dev_t* hw)
* @param hw Beginning address of the peripheral registers. * @param hw Beginning address of the peripheral registers.
* @param enable Whether to enable the MWDT interrupt * @param enable Whether to enable the MWDT interrupt
*/ */
FORCE_INLINE_ATTR void mwdt_ll_set_intr_enable(timg_dev_t* hw, bool enable) FORCE_INLINE_ATTR void mwdt_ll_set_intr_enable(timg_dev_t *hw, bool enable)
{ {
hw->int_ena.wdt = (enable) ? 1 : 0; hw->int_ena_timers.wdt_int_ena = enable;
} }
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -1,382 +1,250 @@
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// The LL layer for Timer Group register operations.
// Note that most of the register operations in this layer are non-atomic operations. // Note that most of the register operations in this layer are non-atomic operations.
#pragma once #pragma once
#include <stdbool.h>
#include "hal/assert.h"
#include "hal/misc.h"
#include "hal/timer_types.h"
#include "soc/timer_group_struct.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#include <stdlib.h> // Get timer group register base address with giving group number
#include "hal/misc.h" #define TIMER_LL_GET_HW(group_id) ((group_id == 0) ? (&TIMERG0) : (&TIMERG1))
#include "hal/assert.h" #define TIMER_LL_EVENT_ALARM(timer_id) (1 << (timer_id))
#include "hal/timer_types.h"
#include "soc/timer_periph.h"
#include "soc/timer_group_struct.h"
_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");
// Get timer group instance with giving group number
#define TIMER_LL_GET_HW(num) ((num == 0) ? (&TIMERG0) : (&TIMERG1))
/** /**
* @brief Set timer clock prescale value * @brief Set clock source for timer
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
* @param divider Prescale value (0 and 1 are not valid) * @param clk_src Clock source
*
* @return None
*/ */
static inline void timer_ll_set_divider(timg_dev_t *hw, timer_idx_t timer_num, uint32_t divider) static inline void timer_ll_set_clock_source(timg_dev_t *hw, uint32_t timer_num, gptimer_clock_source_t clk_src)
{
switch (clk_src) {
case GPTIMER_CLK_SRC_APB:
break;
default:
HAL_ASSERT(false && "unsupported clock source");
break;
}
}
/**
* @brief Enable alarm event
*
* @param hw Timer Group register base address
* @param timer_num Timer number in the group
* @param en True: enable alarm
* False: disable alarm
*/
__attribute__((always_inline))
static inline void timer_ll_enable_alarm(timg_dev_t *hw, uint32_t timer_num, bool en)
{
hw->hw_timer[timer_num].config.tx_alarm_en = en;
// use level type interrupt
hw->hw_timer[timer_num].config.tx_level_int_en = en;
}
/**
* @brief Set clock prescale for timer
*
* @param hw Timer Group register base address
* @param timer_num Timer number in the group
* @param divider Prescale value (0 and 1 are not valid)
*/
static inline void timer_ll_set_clock_prescale(timg_dev_t *hw, uint32_t timer_num, uint32_t divider)
{ {
HAL_ASSERT(divider >= 2 && divider <= 65536); HAL_ASSERT(divider >= 2 && divider <= 65536);
if (divider >= 65536) { if (divider >= 65536) {
divider = 0; divider = 0;
} }
int timer_en = hw->hw_timer[timer_num].config.enable; HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hw_timer[timer_num].config, tx_divider, divider);
hw->hw_timer[timer_num].config.enable = 0;
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hw_timer[timer_num].config, divider, divider);
hw->hw_timer[timer_num].config.enable = timer_en;
} }
/** /**
* @brief Get timer clock prescale value * @brief Enable auto-reload mode
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
* @param divider Pointer to accept the prescale value * @param en True: enable auto reload mode
* * False: disable auto reload mode
* @return None
*/ */
static inline void timer_ll_get_divider(timg_dev_t *hw, timer_idx_t timer_num, uint32_t *divider) static inline void timer_ll_enable_auto_reload(timg_dev_t *hw, uint32_t timer_num, bool en)
{ {
uint32_t d = HAL_FORCE_READ_U32_REG_FIELD(hw->hw_timer[timer_num].config, divider); hw->hw_timer[timer_num].config.tx_autoreload = en;
if (d == 0) { }
d = 65536;
} else if (d == 1) { /**
d = 2; * @brief Set count direction
*
* @param hw Timer peripheral register base address
* @param timer_num Timer number in the group
* @param direction Count direction
*/
static inline void timer_ll_set_count_direction(timg_dev_t *hw, uint32_t timer_num, gptimer_count_direction_t direction)
{
hw->hw_timer[timer_num].config.tx_increase = direction == GPTIMER_COUNT_UP;
}
/**
* @brief Enable timer, start couting
*
* @param hw Timer Group register base address
* @param timer_num Timer number in the group
* @param en True: enable the counter
* False: disable the counter
*/
__attribute__((always_inline))
static inline void timer_ll_enable_counter(timg_dev_t *hw, uint32_t timer_num, bool en)
{
hw->hw_timer[timer_num].config.tx_en = en;
}
/**
* @brief Get counter value
*
* @param hw Timer Group register base address
* @param timer_num Timer number in the group
*
* @return counter value
*/
__attribute__((always_inline))
static inline uint64_t timer_ll_get_counter_value(timg_dev_t *hw, uint32_t timer_num)
{
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) {
} }
*divider = d; return ((uint64_t) hw->hw_timer[timer_num].hi.tx_hi << 32) | (hw->hw_timer[timer_num].lo.tx_lo);
} }
/** /**
* @brief Load counter value into time-base counter * @brief Set alarm value
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
* @param load_val Counter value * @param alarm_value When counter reaches alarm value, alarm event will be triggered
*
* @return None
*/ */
static inline void timer_ll_set_counter_value(timg_dev_t *hw, timer_idx_t timer_num, uint64_t load_val) __attribute__((always_inline))
static inline void timer_ll_set_alarm_value(timg_dev_t *hw, uint32_t timer_num, uint64_t alarm_value)
{ {
hw->hw_timer[timer_num].load_high = (uint32_t) (load_val >> 32); hw->hw_timer[timer_num].alarmhi.tx_alarm_hi = (uint32_t) (alarm_value >> 32);
hw->hw_timer[timer_num].load_low = (uint32_t) load_val; hw->hw_timer[timer_num].alarmlo.tx_alarm_lo = (uint32_t) alarm_value;
hw->hw_timer[timer_num].reload = 1;
} }
/** /**
* @brief Get counter value from time-base counter * @brief Get alarm value
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
* @param timer_val Pointer to accept the counter value * @return Counter value to trigger the alarm event
*
* @return None
*/ */
FORCE_INLINE_ATTR void timer_ll_get_counter_value(timg_dev_t *hw, timer_idx_t timer_num, uint64_t *timer_val) static inline uint64_t timer_ll_get_alarm_value(timg_dev_t *hw, uint32_t timer_num)
{ {
hw->hw_timer[timer_num].update = 1; return ((uint64_t) hw->hw_timer[timer_num].alarmhi.tx_alarm_hi << 32) | (hw->hw_timer[timer_num].alarmlo.tx_alarm_lo);
while (hw->hw_timer[timer_num].update) {}
*timer_val = ((uint64_t) hw->hw_timer[timer_num].cnt_high << 32) | (hw->hw_timer[timer_num].cnt_low);
} }
/** /**
* @brief Set counter mode, include increment mode and decrement mode. * @brief Set reload value
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
* @param increase_en True to increment mode, fasle to decrement mode * @param reload_val Reload counter value
*
* @return None
*/ */
static inline void timer_ll_set_counter_increase(timg_dev_t *hw, timer_idx_t timer_num, bool increase_en) static inline void timer_ll_set_reload_value(timg_dev_t *hw, uint32_t timer_num, uint64_t load_val)
{ {
hw->hw_timer[timer_num].config.increase = increase_en; hw->hw_timer[timer_num].loadhi.tx_load_hi = (uint32_t) (load_val >> 32);
hw->hw_timer[timer_num].loadlo.tx_load_lo = (uint32_t) load_val;
} }
/** /**
* @brief Get counter mode, include increment mode and decrement mode. * @brief Get reload value
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
* * @return reload count value
* @return
* - true Increment mode
* - false Decrement mode
*/ */
static inline bool timer_ll_get_counter_increase(timg_dev_t *hw, timer_idx_t timer_num) static inline uint64_t timer_ll_get_reload_value(timg_dev_t *hw, uint32_t timer_num)
{ {
return hw->hw_timer[timer_num].config.increase; return ((uint64_t)hw->hw_timer[timer_num].loadhi.tx_load_hi << 32) | (hw->hw_timer[timer_num].loadlo.tx_load_lo);
} }
/** /**
* @brief Set counter status, enable or disable counter. * @brief Trigger software reload, value set by `timer_ll_set_reload_value()` will be reflected into counter immediately
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
* @param counter_en True to enable counter, false to disable counter
*
* @return None
*/ */
FORCE_INLINE_ATTR void timer_ll_set_counter_enable(timg_dev_t *hw, timer_idx_t timer_num, bool counter_en) static inline void timer_ll_trigger_soft_reload(timg_dev_t *hw, uint32_t timer_num)
{ {
hw->hw_timer[timer_num].config.enable = counter_en; hw->hw_timer[timer_num].load.tx_load = 1;
} }
/** /**
* @brief Get counter status. * @brief Enable timer interrupt by mask
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param mask Mask of interrupt events
* * @param en True: enable interrupt
* @return * False: disable interrupt
* - true Enable counter
* - false Disable conuter
*/ */
static inline bool timer_ll_get_counter_enable(timg_dev_t *hw, timer_idx_t timer_num) __attribute__((always_inline))
static inline void timer_ll_enable_intr(timg_dev_t *hw, uint32_t mask, bool en)
{ {
return hw->hw_timer[timer_num].config.enable; if (en) {
hw->int_ena_timers.val |= mask;
} else {
hw->int_ena_timers.val &= ~mask;
}
} }
/** /**
* @brief Set auto reload mode. * @brief Get interrupt status
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number
* @param auto_reload_en True to enable auto reload mode, flase to disable auto reload mode
* *
* @return None * @return Interrupt status
*/ */
static inline void timer_ll_set_auto_reload(timg_dev_t *hw, timer_idx_t timer_num, bool auto_reload_en) __attribute__((always_inline))
static inline uint32_t timer_ll_get_intr_status(timg_dev_t *hw)
{ {
hw->hw_timer[timer_num].config.autoreload = auto_reload_en; return hw->int_st_timers.val & 0x03;
} }
/** /**
* @brief Get auto reload mode. * @brief Clear interrupt status by mask
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param mask Interrupt events mask
*
* @return
* - true Enable auto reload mode
* - false Disable auto reload mode
*/ */
FORCE_INLINE_ATTR bool timer_ll_get_auto_reload(timg_dev_t *hw, timer_idx_t timer_num) __attribute__((always_inline))
static inline void timer_ll_clear_intr_status(timg_dev_t *hw, uint32_t mask)
{ {
return hw->hw_timer[timer_num].config.autoreload; hw->int_clr_timers.val = mask;
} }
/** /**
* @brief Set the counter value to trigger the alarm. * @brief Enable the register clock forever
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param en True: Enable the register clock forever
* @param alarm_value Counter value to trigger the alarm * False: Register clock is enabled only when register operation happens
*
* @return None
*/ */
FORCE_INLINE_ATTR void timer_ll_set_alarm_value(timg_dev_t *hw, timer_idx_t timer_num, uint64_t alarm_value) static inline void timer_ll_enable_register_clock_always_on(timg_dev_t *hw, bool en)
{ {
hw->hw_timer[timer_num].alarm_high = (uint32_t) (alarm_value >> 32); hw->regclk.clk_en = en;
hw->hw_timer[timer_num].alarm_low = (uint32_t) alarm_value;
}
/**
* @brief Get the counter value to trigger the alarm.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
* @param alarm_value Pointer to accept the counter value to trigger the alarm
*
* @return None
*/
static inline void timer_ll_get_alarm_value(timg_dev_t *hw, timer_idx_t timer_num, uint64_t *alarm_value)
{
*alarm_value = ((uint64_t) hw->hw_timer[timer_num].alarm_high << 32) | (hw->hw_timer[timer_num].alarm_low);
}
/**
* @brief Set the alarm status, enable or disable the alarm.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
* @param alarm_en True to enable alarm, false to disable alarm
*
* @return None
*/
FORCE_INLINE_ATTR void timer_ll_set_alarm_enable(timg_dev_t *hw, timer_idx_t timer_num, bool alarm_en)
{
hw->hw_timer[timer_num].config.alarm_en = alarm_en;
}
/**
* @brief Get the alarm status.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return
* - true Enable alarm
* - false Disable alarm
*/
static inline bool timer_ll_get_alarm_enable(timg_dev_t *hw, timer_idx_t timer_num)
{
return hw->hw_timer[timer_num].config.alarm_en;
}
/**
* @brief Enable timer interrupt.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return None
*/
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;
}
/**
* @brief Disable timer interrupt.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return None
*/
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;
}
/**
* @brief Disable timer interrupt.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return None
*/
FORCE_INLINE_ATTR void timer_ll_clear_intr_status(timg_dev_t *hw, timer_idx_t timer_num)
{
hw->int_clr_timers.val |= BIT(timer_num);
}
/**
* @brief Get interrupt status.
*
* @param hw Beginning address of the peripheral registers.
* @param intr_status Interrupt status
*
* @return None
*/
FORCE_INLINE_ATTR void timer_ll_get_intr_status(timg_dev_t *hw, uint32_t *intr_status)
{
*intr_status = hw->int_st_timers.val & 0x03;
}
/**
* @brief Get interrupt raw status.
*
* @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
* @param intr_raw_status Interrupt raw status
*
* @return None
*/
FORCE_INLINE_ATTR void timer_ll_get_intr_raw_status(timer_group_t group_num, uint32_t *intr_raw_status)
{
timg_dev_t *hw = TIMER_LL_GET_HW(group_num);
*intr_raw_status = hw->int_raw.val & 0x03;
}
/**
* @brief Set the level interrupt status, enable or disable the level interrupt.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
* @param level_int_en True to enable level interrupt, false to disable level interrupt
*
* @return None
*/
static inline void timer_ll_set_level_int_enable(timg_dev_t *hw, timer_idx_t timer_num, bool level_int_en)
{
hw->hw_timer[timer_num].config.level_int_en = level_int_en;
}
/**
* @brief Get the level interrupt status.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return
* - true Enable level interrupt
* - false Disable level interrupt
*/
static inline bool timer_ll_get_level_int_enable(timg_dev_t *hw, timer_idx_t timer_num)
{
return hw->hw_timer[timer_num].config.level_int_en;
}
/**
* @brief Set the edge interrupt status, enable or disable the edge interrupt.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
* @param edge_int_en True to enable edge interrupt, false to disable edge interrupt
*
* @return None
*/
static inline void timer_ll_set_edge_int_enable(timg_dev_t *hw, timer_idx_t timer_num, bool edge_int_en)
{
hw->hw_timer[timer_num].config.edge_int_en = edge_int_en;
}
/**
* @brief Get the edge interrupt status.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return
* - true Enable edge interrupt
* - false Disable edge interrupt
*/
static inline bool timer_ll_get_edge_int_enable(timg_dev_t *hw, timer_idx_t timer_num)
{
return hw->hw_timer[timer_num].config.edge_int_en;
} }
/** /**
@ -386,14 +254,9 @@ static inline bool timer_ll_get_edge_int_enable(timg_dev_t *hw, timer_idx_t time
* *
* @return Interrupt status register address * @return Interrupt status register address
*/ */
static inline uint32_t timer_ll_get_intr_status_reg(timg_dev_t *hw) static inline volatile void *timer_ll_get_intr_status_reg(timg_dev_t *hw)
{ {
return (uint32_t) & (hw->int_st_timers.val); return &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);
} }
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -1,16 +1,8 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// The LL layer for Timer Group register operations. // The LL layer for Timer Group register operations.
// Note that most of the register operations in this layer are non-atomic operations. // Note that most of the register operations in this layer are non-atomic operations.
@ -26,6 +18,7 @@ extern "C" {
#include "soc/timer_periph.h" #include "soc/timer_periph.h"
#include "soc/timer_group_struct.h" #include "soc/timer_group_struct.h"
#include "hal/wdt_types.h" #include "hal/wdt_types.h"
#include "hal/assert.h"
#include "esp_attr.h" #include "esp_attr.h"
//Type check wdt_stage_action_t //Type check wdt_stage_action_t
@ -112,6 +105,7 @@ FORCE_INLINE_ATTR void mwdt_ll_config_stage(timg_dev_t *hw, wdt_stage_t stage, u
hw->wdtconfig5.wdt_stg3_hold = timeout; hw->wdtconfig5.wdt_stg3_hold = timeout;
break; break;
default: default:
HAL_ASSERT(false && "unsupported WDT stage");
break; break;
} }
//Config registers are updated asynchronously //Config registers are updated asynchronously
@ -140,6 +134,7 @@ FORCE_INLINE_ATTR void mwdt_ll_disable_stage(timg_dev_t *hw, uint32_t stage)
hw->wdtconfig0.wdt_stg3 = WDT_STAGE_ACTION_OFF; hw->wdtconfig0.wdt_stg3 = WDT_STAGE_ACTION_OFF;
break; break;
default: default:
HAL_ASSERT(false && "unsupported WDT stage");
break; break;
} }
//Config registers are updated asynchronously //Config registers are updated asynchronously

View File

@ -1,431 +1,265 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// The LL layer for Timer Group register operations.
// Note that most of the register operations in this layer are non-atomic operations. // Note that most of the register operations in this layer are non-atomic operations.
#pragma once #pragma once
#include <stdbool.h>
#include "hal/assert.h"
#include "hal/misc.h"
#include "hal/timer_types.h"
#include "soc/timer_group_struct.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#include <stdlib.h> // Get timer group register base address with giving group number
#include "hal/misc.h" #define TIMER_LL_GET_HW(group_id) ((group_id == 0) ? (&TIMERG0) : (&TIMERG1))
#include "soc/timer_periph.h" #define TIMER_LL_EVENT_ALARM(timer_id) (1 << (timer_id))
#include "soc/timer_group_struct.h"
#include "hal/timer_types.h"
#include "hal/assert.h"
_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_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))
/** /**
* @brief Set timer clock prescale value * @brief Set clock source for timer
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
* @param divider Prescale value * @param clk_src Clock source
*
* @return None
*/ */
static inline void timer_ll_set_divider(timg_dev_t *hw, timer_idx_t timer_num, uint32_t divider) static inline void timer_ll_set_clock_source(timg_dev_t *hw, uint32_t timer_num, gptimer_clock_source_t clk_src)
{
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;
break;
default:
HAL_ASSERT(false && "unsupported clock source");
break;
}
}
/**
* @brief Enable alarm event
*
* @param hw Timer Group register base address
* @param timer_num Timer number in the group
* @param en True: enable alarm
* False: disable alarm
*/
__attribute__((always_inline))
static inline void timer_ll_enable_alarm(timg_dev_t *hw, uint32_t timer_num, bool en)
{
hw->hw_timer[timer_num].config.tx_alarm_en = en;
}
/**
* @brief Set clock prescale for timer
*
* @param hw Timer Group register base address
* @param timer_num Timer number in the group
* @param divider Prescale value (0 and 1 are not valid)
*/
static inline void timer_ll_set_clock_prescale(timg_dev_t *hw, uint32_t timer_num, uint32_t divider)
{ {
HAL_ASSERT(divider >= 2 && divider <= 65536); HAL_ASSERT(divider >= 2 && divider <= 65536);
if (divider >= 65536) { if (divider >= 65536) {
divider = 0; divider = 0;
} }
int timer_en = hw->hw_timer[timer_num].config.tx_en;
hw->hw_timer[timer_num].config.tx_en = 0;
hw->hw_timer[timer_num].config.tx_divcnt_rst = 1;
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hw_timer[timer_num].config, tx_divider, divider); HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hw_timer[timer_num].config, tx_divider, divider);
hw->hw_timer[timer_num].config.tx_en = timer_en; hw->hw_timer[timer_num].config.tx_divcnt_rst = 1;
} }
/** /**
* @brief Get timer clock prescale value * @brief Enable auto-reload mode
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
* @param divider Pointer to accept the prescale value * @param en True: enable auto reload mode
* * False: disable auto reload mode
* @return None
*/ */
static inline void timer_ll_get_divider(timg_dev_t *hw, timer_idx_t timer_num, uint32_t *divider) static inline void timer_ll_enable_auto_reload(timg_dev_t *hw, uint32_t timer_num, bool en)
{ {
uint32_t d = HAL_FORCE_READ_U32_REG_FIELD(hw->hw_timer[timer_num].config, tx_divider); hw->hw_timer[timer_num].config.tx_autoreload = en;
if (d == 0) {
d = 65536;
} else if (d == 1) {
d = 2;
}
*divider = d;
} }
/** /**
* @brief Load counter value into time-base counter * @brief Set count direction
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer peripheral register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
* @param load_val Counter value * @param direction Count direction
*
* @return None
*/ */
static inline void timer_ll_set_counter_value(timg_dev_t *hw, timer_idx_t timer_num, uint64_t load_val) static inline void timer_ll_set_count_direction(timg_dev_t *hw, uint32_t timer_num, gptimer_count_direction_t direction)
{ {
hw->hw_timer[timer_num].loadhi.tx_load_hi = (uint32_t) (load_val >> 32); hw->hw_timer[timer_num].config.tx_increase = direction == GPTIMER_COUNT_UP;
hw->hw_timer[timer_num].loadlo.tx_load_lo = (uint32_t) load_val;
hw->hw_timer[timer_num].load.tx_load = 1;
} }
/** /**
* @brief Get counter value from time-base counter * @brief Enable timer, start couting
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
* @param timer_val Pointer to accept the counter value * @param en True: enable the counter
* * False: disable the counter
* @return None
*/ */
FORCE_INLINE_ATTR void timer_ll_get_counter_value(timg_dev_t *hw, timer_idx_t timer_num, uint64_t *timer_val) __attribute__((always_inline))
static inline void timer_ll_enable_counter(timg_dev_t *hw, uint32_t timer_num, bool en)
{
hw->hw_timer[timer_num].config.tx_en = en;
}
/**
* @brief Get counter value
*
* @param hw Timer Group register base address
* @param timer_num Timer number in the group
*
* @return counter value
*/
__attribute__((always_inline))
static inline uint64_t timer_ll_get_counter_value(timg_dev_t *hw, uint32_t timer_num)
{ {
hw->hw_timer[timer_num].update.tx_update = 1; hw->hw_timer[timer_num].update.tx_update = 1;
while (hw->hw_timer[timer_num].update.tx_update) {} // Timer register is in a different clock domain from Timer hardware logic
*timer_val = ((uint64_t) hw->hw_timer[timer_num].hi.tx_hi << 32) | (hw->hw_timer[timer_num].lo.tx_lo); // We need to wait for the update to take effect before fetching the count value
while (hw->hw_timer[timer_num].update.tx_update) {
}
return ((uint64_t) hw->hw_timer[timer_num].hi.tx_hi << 32) | (hw->hw_timer[timer_num].lo.tx_lo);
} }
/** /**
* @brief Set counter mode, include increment mode and decrement mode. * @brief Set alarm value
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
* @param increase_en True to increment mode, fasle to decrement mode * @param alarm_value When counter reaches alarm value, alarm event will be triggered
*
* @return None
*/ */
static inline void timer_ll_set_counter_increase(timg_dev_t *hw, timer_idx_t timer_num, bool increase_en) __attribute__((always_inline))
{ static inline void timer_ll_set_alarm_value(timg_dev_t *hw, uint32_t timer_num, uint64_t alarm_value)
hw->hw_timer[timer_num].config.tx_increase = increase_en;
}
/**
* @brief Get counter mode, include increment mode and decrement mode.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return
* - true Increment mode
* - false Decrement mode
*/
static inline bool timer_ll_get_counter_increase(timg_dev_t *hw, timer_idx_t timer_num)
{
return hw->hw_timer[timer_num].config.tx_increase;
}
/**
* @brief Set counter status, enable or disable counter.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
* @param counter_en True to enable counter, false to disable counter
*
* @return None
*/
FORCE_INLINE_ATTR void timer_ll_set_counter_enable(timg_dev_t *hw, timer_idx_t timer_num, bool counter_en)
{
hw->hw_timer[timer_num].config.tx_en = counter_en;
}
/**
* @brief Get counter status.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return
* - true Enable counter
* - false Disable conuter
*/
static inline bool timer_ll_get_counter_enable(timg_dev_t *hw, timer_idx_t timer_num)
{
return hw->hw_timer[timer_num].config.tx_en;
}
/**
* @brief Set auto reload mode.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
* @param auto_reload_en True to enable auto reload mode, flase to disable auto reload mode
*
* @return None
*/
static inline void timer_ll_set_auto_reload(timg_dev_t *hw, timer_idx_t timer_num, bool auto_reload_en)
{
hw->hw_timer[timer_num].config.tx_autoreload = auto_reload_en;
}
/**
* @brief Get auto reload mode.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return
* - true Enable auto reload mode
* - false Disable auto reload mode
*/
FORCE_INLINE_ATTR bool timer_ll_get_auto_reload(timg_dev_t *hw, timer_idx_t timer_num)
{
return hw->hw_timer[timer_num].config.tx_autoreload;
}
/**
* @brief Set the counter value to trigger the alarm.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
* @param alarm_value Counter value to trigger the alarm
*
* @return None
*/
FORCE_INLINE_ATTR void timer_ll_set_alarm_value(timg_dev_t *hw, timer_idx_t timer_num, uint64_t alarm_value)
{ {
hw->hw_timer[timer_num].alarmhi.tx_alarm_hi = (uint32_t) (alarm_value >> 32); 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; hw->hw_timer[timer_num].alarmlo.tx_alarm_lo = (uint32_t) alarm_value;
} }
/** /**
* @brief Get the counter value to trigger the alarm. * @brief Get alarm value
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
* @param alarm_value Pointer to accept the counter value to trigger the alarm * @return Counter value to trigger the alarm event
*
* @return None
*/ */
static inline void timer_ll_get_alarm_value(timg_dev_t *hw, timer_idx_t timer_num, uint64_t *alarm_value) static inline uint64_t timer_ll_get_alarm_value(timg_dev_t *hw, uint32_t timer_num)
{ {
*alarm_value = ((uint64_t) hw->hw_timer[timer_num].alarmhi.tx_alarm_hi << 32) | (hw->hw_timer[timer_num].alarmlo.tx_alarm_lo); return ((uint64_t) hw->hw_timer[timer_num].alarmhi.tx_alarm_hi << 32) | (hw->hw_timer[timer_num].alarmlo.tx_alarm_lo);
} }
/** /**
* @brief Set the alarm status, enable or disable the alarm. * @brief Set reload value
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
* @param alarm_en True to enable alarm, false to disable alarm * @param reload_val Reload counter value
*
* @return None
*/ */
FORCE_INLINE_ATTR void timer_ll_set_alarm_enable(timg_dev_t *hw, timer_idx_t timer_num, bool alarm_en) static inline void timer_ll_set_reload_value(timg_dev_t *hw, uint32_t timer_num, uint64_t load_val)
{ {
hw->hw_timer[timer_num].config.tx_alarm_en = alarm_en; hw->hw_timer[timer_num].loadhi.tx_load_hi = (uint32_t) (load_val >> 32);
hw->hw_timer[timer_num].loadlo.tx_load_lo = (uint32_t) load_val;
} }
/** /**
* @brief Get the alarm status. * @brief Get reload value
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
* * @return reload count value
* @return
* - true Enable alarm
* - false Disable alarm
*/ */
static inline bool timer_ll_get_alarm_enable(timg_dev_t *hw, timer_idx_t timer_num) static inline uint64_t timer_ll_get_reload_value(timg_dev_t *hw, uint32_t timer_num)
{ {
return hw->hw_timer[timer_num].config.tx_alarm_en; return ((uint64_t)hw->hw_timer[timer_num].loadhi.tx_load_hi << 32) | (hw->hw_timer[timer_num].loadlo.tx_load_lo);
} }
/** /**
* @brief Enable timer interrupt. * @brief Trigger software reload, value set by `timer_ll_set_reload_value()` will be reflected into counter immediately
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
*
* @return None
*/ */
FORCE_INLINE_ATTR void timer_ll_intr_enable(timg_dev_t *hw, timer_idx_t timer_num) static inline void timer_ll_trigger_soft_reload(timg_dev_t *hw, uint32_t timer_num)
{ {
hw->int_ena_timers.val |= BIT(timer_num); hw->hw_timer[timer_num].load.tx_load = 1;
} }
/** /**
* @brief Disable timer interrupt. * @brief Enable timer interrupt by mask
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param mask Mask of interrupt events
* * @param en True: enable interrupt
* @return None * False: disable interrupt
*/ */
FORCE_INLINE_ATTR void timer_ll_intr_disable(timg_dev_t *hw, timer_idx_t timer_num) __attribute__((always_inline))
static inline void timer_ll_enable_intr(timg_dev_t *hw, uint32_t mask, bool en)
{ {
hw->int_ena_timers.val &= (~BIT(timer_num)); if (en) {
hw->int_ena_timers.val |= mask;
} else {
hw->int_ena_timers.val &= ~mask;
}
} }
/** /**
* @brief Disable timer interrupt. * @brief Get interrupt status
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number
* *
* @return None * @return Interrupt status
*/ */
FORCE_INLINE_ATTR void timer_ll_clear_intr_status(timg_dev_t *hw, timer_idx_t timer_num) __attribute__((always_inline))
static inline uint32_t timer_ll_get_intr_status(timg_dev_t *hw)
{ {
hw->int_clr_timers.val |= BIT(timer_num); return hw->int_st_timers.val & 0x01;
} }
/** /**
* @brief Get interrupt status. * @brief Clear interrupt status by mask
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param intr_status Interrupt status * @param mask Interrupt events mask
*
* @return None
*/ */
FORCE_INLINE_ATTR void timer_ll_get_intr_status(timg_dev_t *hw, uint32_t *intr_status) __attribute__((always_inline))
static inline void timer_ll_clear_intr_status(timg_dev_t *hw, uint32_t mask)
{ {
*intr_status = hw->int_st_timers.val & 0x01; hw->int_clr_timers.val = mask;
} }
/** /**
* @brief Get interrupt raw status. * @brief Enable the register clock forever
* *
* @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1 * @param hw Timer Group register base address
* @param intr_raw_status Interrupt raw status * @param en True: Enable the register clock forever
* * False: Register clock is enabled only when register operation happens
* @return None
*/ */
FORCE_INLINE_ATTR void timer_ll_get_intr_raw_status(timer_group_t group_num, uint32_t *intr_raw_status) static inline void timer_ll_enable_register_clock_always_on(timg_dev_t *hw, bool en)
{ {
timg_dev_t *hw = TIMER_LL_GET_HW(group_num); hw->regclk.clk_en = en;
*intr_raw_status = hw->int_raw_timers.val & 0x01;
} }
/** /**
* @brief Set the level interrupt status, enable or disable the level interrupt. * @brief Get interrupt status register address
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number
* @param level_int_en True to enable level interrupt, false to disable level interrupt
* *
* @return None * @return Interrupt status register address
*/ */
static inline void timer_ll_set_level_int_enable(timg_dev_t *hw, timer_idx_t timer_num, bool level_int_en) static inline volatile void *timer_ll_get_intr_status_reg(timg_dev_t *hw)
{ {
// Only "level" interrupts are supported on this target return &hw->int_st_timers.val;
}
/**
* @brief Get the level interrupt status.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return
* - true Enable level interrupt
* - false Disable level interrupt
*/
static inline bool timer_ll_get_level_int_enable(timg_dev_t *hw, timer_idx_t timer_num)
{
// Only "level" interrupts are supported on this target
return true;
}
/**
* @brief Set the edge interrupt status, enable or disable the edge interrupt.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
* @param edge_int_en True to enable edge interrupt, false to disable edge interrupt
*
* @return None
*/
static inline void timer_ll_set_edge_int_enable(timg_dev_t *hw, timer_idx_t timer_num, bool edge_int_en)
{
// edge interrupt is not supported on C3
}
/**
* @brief Get the edge interrupt status.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return
* - true Enable edge interrupt
* - false Disable edge interrupt
*/
static inline bool timer_ll_get_edge_int_enable(timg_dev_t *hw, timer_idx_t timer_num)
{
// edge interrupt is not supported on C3
return false;
}
/**
* @brief Get interrupt status register address.
*
* @param hw Beginning address of the peripheral registers.
*
* @return uint32_t Interrupt status register address
*/
static inline uint32_t timer_ll_get_intr_status_reg(timg_dev_t *hw)
{
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);
}
/**
* @brief Set clock source.
*
* @param hal Context of the HAL layer
* @param use_xtal_en True to use XTAL clock, flase to use APB clock
*
* @return None
*/
static inline void timer_ll_set_use_xtal(timg_dev_t *hw, timer_idx_t timer_num, bool use_xtal_en)
{
hw->hw_timer[timer_num].config.tx_use_xtal = use_xtal_en;
}
/**
* @brief Get clock source.
*
* @param hal Context of the HAL layer
*
* @return
* - true Use XTAL clock
* - false Use APB clock
*/
static inline bool timer_ll_get_use_xtal(timg_dev_t *hw, timer_idx_t timer_num)
{
return hw->hw_timer[timer_num].config.tx_use_xtal;
} }
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -1,16 +1,8 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// The LL layer for Timer Group register operations. // The LL layer for Timer Group register operations.
// Note that most of the register operations in this layer are non-atomic operations. // Note that most of the register operations in this layer are non-atomic operations.
@ -26,6 +18,7 @@ extern "C" {
#include "soc/timer_periph.h" #include "soc/timer_periph.h"
#include "soc/timer_group_struct.h" #include "soc/timer_group_struct.h"
#include "hal/wdt_types.h" #include "hal/wdt_types.h"
#include "hal/assert.h"
#include "esp_attr.h" #include "esp_attr.h"
//Type check wdt_stage_action_t //Type check wdt_stage_action_t
@ -112,6 +105,7 @@ FORCE_INLINE_ATTR void mwdt_ll_config_stage(timg_dev_t *hw, wdt_stage_t stage, u
hw->wdtconfig5.wdt_stg3_hold = timeout; hw->wdtconfig5.wdt_stg3_hold = timeout;
break; break;
default: default:
HAL_ASSERT(false && "unsupported WDT stage");
break; break;
} }
//Config registers are updated asynchronously //Config registers are updated asynchronously
@ -140,6 +134,7 @@ FORCE_INLINE_ATTR void mwdt_ll_disable_stage(timg_dev_t *hw, uint32_t stage)
hw->wdtconfig0.wdt_stg3 = WDT_STAGE_ACTION_OFF; hw->wdtconfig0.wdt_stg3 = WDT_STAGE_ACTION_OFF;
break; break;
default: default:
HAL_ASSERT(false && "unsupported WDT stage");
break; break;
} }
//Config registers are updated asynchronously //Config registers are updated asynchronously

View File

@ -1,431 +1,265 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// The LL layer for Timer Group register operations.
// Note that most of the register operations in this layer are non-atomic operations. // Note that most of the register operations in this layer are non-atomic operations.
#pragma once #pragma once
#include <stdbool.h>
#include "hal/assert.h"
#include "hal/misc.h"
#include "hal/timer_types.h"
#include "soc/timer_group_struct.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#include <stdlib.h> // Get timer group register base address with giving group number
#include "hal/misc.h" #define TIMER_LL_GET_HW(group_id) ((group_id == 0) ? (&TIMERG0) : (&TIMERG1))
#include "soc/timer_periph.h" #define TIMER_LL_EVENT_ALARM(timer_id) (1 << (timer_id))
#include "soc/timer_group_struct.h"
#include "hal/timer_types.h"
#include "hal/assert.h"
_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_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))
/** /**
* @brief Set timer clock prescale value * @brief Set clock source for timer
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
* @param divider Prescale value * @param clk_src Clock source
*
* @return None
*/ */
static inline void timer_ll_set_divider(timg_dev_t *hw, timer_idx_t timer_num, uint32_t divider) static inline void timer_ll_set_clock_source(timg_dev_t *hw, uint32_t timer_num, gptimer_clock_source_t clk_src)
{
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;
break;
default:
HAL_ASSERT(false && "unsupported clock source");
break;
}
}
/**
* @brief Enable alarm event
*
* @param hw Timer Group register base address
* @param timer_num Timer number in the group
* @param en True: enable alarm
* False: disable alarm
*/
__attribute__((always_inline))
static inline void timer_ll_enable_alarm(timg_dev_t *hw, uint32_t timer_num, bool en)
{
hw->hw_timer[timer_num].config.tx_alarm_en = en;
}
/**
* @brief Set clock prescale for timer
*
* @param hw Timer Group register base address
* @param timer_num Timer number in the group
* @param divider Prescale value (0 and 1 are not valid)
*/
static inline void timer_ll_set_clock_prescale(timg_dev_t *hw, uint32_t timer_num, uint32_t divider)
{ {
HAL_ASSERT(divider >= 2 && divider <= 65536); HAL_ASSERT(divider >= 2 && divider <= 65536);
if (divider >= 65536) { if (divider >= 65536) {
divider = 0; divider = 0;
} }
int timer_en = hw->hw_timer[timer_num].config.tx_en;
hw->hw_timer[timer_num].config.tx_en = 0;
hw->hw_timer[timer_num].config.tx_divcnt_rst = 1;
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hw_timer[timer_num].config, tx_divider, divider); HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hw_timer[timer_num].config, tx_divider, divider);
hw->hw_timer[timer_num].config.tx_en = timer_en; hw->hw_timer[timer_num].config.tx_divcnt_rst = 1;
} }
/** /**
* @brief Get timer clock prescale value * @brief Enable auto-reload mode
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
* @param divider Pointer to accept the prescale value * @param en True: enable auto reload mode
* * False: disable auto reload mode
* @return None
*/ */
static inline void timer_ll_get_divider(timg_dev_t *hw, timer_idx_t timer_num, uint32_t *divider) static inline void timer_ll_enable_auto_reload(timg_dev_t *hw, uint32_t timer_num, bool en)
{ {
uint32_t d = HAL_FORCE_READ_U32_REG_FIELD(hw->hw_timer[timer_num].config, tx_divider); hw->hw_timer[timer_num].config.tx_autoreload = en;
if (d == 0) {
d = 65536;
} else if (d == 1) {
d = 2;
}
*divider = d;
} }
/** /**
* @brief Load counter value into time-base counter * @brief Set count direction
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer peripheral register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
* @param load_val Counter value * @param direction Count direction
*
* @return None
*/ */
static inline void timer_ll_set_counter_value(timg_dev_t *hw, timer_idx_t timer_num, uint64_t load_val) static inline void timer_ll_set_count_direction(timg_dev_t *hw, uint32_t timer_num, gptimer_count_direction_t direction)
{ {
hw->hw_timer[timer_num].loadhi.tx_load_hi = (uint32_t) (load_val >> 32); hw->hw_timer[timer_num].config.tx_increase = direction == GPTIMER_COUNT_UP;
hw->hw_timer[timer_num].loadlo.tx_load_lo = (uint32_t) load_val;
hw->hw_timer[timer_num].load.tx_load = 1;
} }
/** /**
* @brief Get counter value from time-base counter * @brief Enable timer, start couting
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
* @param timer_val Pointer to accept the counter value * @param en True: enable the counter
* * False: disable the counter
* @return None
*/ */
FORCE_INLINE_ATTR void timer_ll_get_counter_value(timg_dev_t *hw, timer_idx_t timer_num, uint64_t *timer_val) __attribute__((always_inline))
static inline void timer_ll_enable_counter(timg_dev_t *hw, uint32_t timer_num, bool en)
{
hw->hw_timer[timer_num].config.tx_en = en;
}
/**
* @brief Get counter value
*
* @param hw Timer Group register base address
* @param timer_num Timer number in the group
*
* @return counter value
*/
__attribute__((always_inline))
static inline uint64_t timer_ll_get_counter_value(timg_dev_t *hw, uint32_t timer_num)
{ {
hw->hw_timer[timer_num].update.tx_update = 1; hw->hw_timer[timer_num].update.tx_update = 1;
while (hw->hw_timer[timer_num].update.tx_update) {} // Timer register is in a different clock domain from Timer hardware logic
*timer_val = ((uint64_t) hw->hw_timer[timer_num].hi.tx_hi << 32) | (hw->hw_timer[timer_num].lo.tx_lo); // We need to wait for the update to take effect before fetching the count value
while (hw->hw_timer[timer_num].update.tx_update) {
}
return ((uint64_t) hw->hw_timer[timer_num].hi.tx_hi << 32) | (hw->hw_timer[timer_num].lo.tx_lo);
} }
/** /**
* @brief Set counter mode, include increment mode and decrement mode. * @brief Set alarm value
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
* @param increase_en True to increment mode, fasle to decrement mode * @param alarm_value When counter reaches alarm value, alarm event will be triggered
*
* @return None
*/ */
static inline void timer_ll_set_counter_increase(timg_dev_t *hw, timer_idx_t timer_num, bool increase_en) __attribute__((always_inline))
{ static inline void timer_ll_set_alarm_value(timg_dev_t *hw, uint32_t timer_num, uint64_t alarm_value)
hw->hw_timer[timer_num].config.tx_increase = increase_en;
}
/**
* @brief Get counter mode, include increment mode and decrement mode.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return
* - true Increment mode
* - false Decrement mode
*/
static inline bool timer_ll_get_counter_increase(timg_dev_t *hw, timer_idx_t timer_num)
{
return hw->hw_timer[timer_num].config.tx_increase;
}
/**
* @brief Set counter status, enable or disable counter.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
* @param counter_en True to enable counter, false to disable counter
*
* @return None
*/
FORCE_INLINE_ATTR void timer_ll_set_counter_enable(timg_dev_t *hw, timer_idx_t timer_num, bool counter_en)
{
hw->hw_timer[timer_num].config.tx_en = counter_en;
}
/**
* @brief Get counter status.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return
* - true Enable counter
* - false Disable conuter
*/
static inline bool timer_ll_get_counter_enable(timg_dev_t *hw, timer_idx_t timer_num)
{
return hw->hw_timer[timer_num].config.tx_en;
}
/**
* @brief Set auto reload mode.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
* @param auto_reload_en True to enable auto reload mode, flase to disable auto reload mode
*
* @return None
*/
static inline void timer_ll_set_auto_reload(timg_dev_t *hw, timer_idx_t timer_num, bool auto_reload_en)
{
hw->hw_timer[timer_num].config.tx_autoreload = auto_reload_en;
}
/**
* @brief Get auto reload mode.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return
* - true Enable auto reload mode
* - false Disable auto reload mode
*/
FORCE_INLINE_ATTR bool timer_ll_get_auto_reload(timg_dev_t *hw, timer_idx_t timer_num)
{
return hw->hw_timer[timer_num].config.tx_autoreload;
}
/**
* @brief Set the counter value to trigger the alarm.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
* @param alarm_value Counter value to trigger the alarm
*
* @return None
*/
FORCE_INLINE_ATTR void timer_ll_set_alarm_value(timg_dev_t *hw, timer_idx_t timer_num, uint64_t alarm_value)
{ {
hw->hw_timer[timer_num].alarmhi.tx_alarm_hi = (uint32_t) (alarm_value >> 32); 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; hw->hw_timer[timer_num].alarmlo.tx_alarm_lo = (uint32_t) alarm_value;
} }
/** /**
* @brief Get the counter value to trigger the alarm. * @brief Get alarm value
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
* @param alarm_value Pointer to accept the counter value to trigger the alarm * @return Counter value to trigger the alarm event
*
* @return None
*/ */
static inline void timer_ll_get_alarm_value(timg_dev_t *hw, timer_idx_t timer_num, uint64_t *alarm_value) static inline uint64_t timer_ll_get_alarm_value(timg_dev_t *hw, uint32_t timer_num)
{ {
*alarm_value = ((uint64_t) hw->hw_timer[timer_num].alarmhi.tx_alarm_hi << 32) | (hw->hw_timer[timer_num].alarmlo.tx_alarm_lo); return ((uint64_t) hw->hw_timer[timer_num].alarmhi.tx_alarm_hi << 32) | (hw->hw_timer[timer_num].alarmlo.tx_alarm_lo);
} }
/** /**
* @brief Set the alarm status, enable or disable the alarm. * @brief Set reload value
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
* @param alarm_en True to enable alarm, false to disable alarm * @param reload_val Reload counter value
*
* @return None
*/ */
FORCE_INLINE_ATTR void timer_ll_set_alarm_enable(timg_dev_t *hw, timer_idx_t timer_num, bool alarm_en) static inline void timer_ll_set_reload_value(timg_dev_t *hw, uint32_t timer_num, uint64_t load_val)
{ {
hw->hw_timer[timer_num].config.tx_alarm_en = alarm_en; hw->hw_timer[timer_num].loadhi.tx_load_hi = (uint32_t) (load_val >> 32);
hw->hw_timer[timer_num].loadlo.tx_load_lo = (uint32_t) load_val;
} }
/** /**
* @brief Get the alarm status. * @brief Get reload value
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
* * @return reload count value
* @return
* - true Enable alarm
* - false Disable alarm
*/ */
static inline bool timer_ll_get_alarm_enable(timg_dev_t *hw, timer_idx_t timer_num) static inline uint64_t timer_ll_get_reload_value(timg_dev_t *hw, uint32_t timer_num)
{ {
return hw->hw_timer[timer_num].config.tx_alarm_en; return ((uint64_t)hw->hw_timer[timer_num].loadhi.tx_load_hi << 32) | (hw->hw_timer[timer_num].loadlo.tx_load_lo);
} }
/** /**
* @brief Enable timer interrupt. * @brief Trigger software reload, value set by `timer_ll_set_reload_value()` will be reflected into counter immediately
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
*
* @return None
*/ */
FORCE_INLINE_ATTR void timer_ll_intr_enable(timg_dev_t *hw, timer_idx_t timer_num) static inline void timer_ll_trigger_soft_reload(timg_dev_t *hw, uint32_t timer_num)
{ {
hw->int_ena_timers.val |= BIT(timer_num); hw->hw_timer[timer_num].load.tx_load = 1;
} }
/** /**
* @brief Disable timer interrupt. * @brief Enable timer interrupt by mask
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param mask Mask of interrupt events
* * @param en True: enable interrupt
* @return None * False: disable interrupt
*/ */
FORCE_INLINE_ATTR void timer_ll_intr_disable(timg_dev_t *hw, timer_idx_t timer_num) __attribute__((always_inline))
static inline void timer_ll_enable_intr(timg_dev_t *hw, uint32_t mask, bool en)
{ {
hw->int_ena_timers.val &= (~BIT(timer_num)); if (en) {
hw->int_ena_timers.val |= mask;
} else {
hw->int_ena_timers.val &= ~mask;
}
} }
/** /**
* @brief Disable timer interrupt. * @brief Get interrupt status
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number
* *
* @return None * @return Interrupt status
*/ */
FORCE_INLINE_ATTR void timer_ll_clear_intr_status(timg_dev_t *hw, timer_idx_t timer_num) __attribute__((always_inline))
static inline uint32_t timer_ll_get_intr_status(timg_dev_t *hw)
{ {
hw->int_clr_timers.val |= BIT(timer_num); return hw->int_st_timers.val & 0x01;
} }
/** /**
* @brief Get interrupt status. * @brief Clear interrupt status by mask
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param intr_status Interrupt status * @param mask Interrupt events mask
*
* @return None
*/ */
FORCE_INLINE_ATTR void timer_ll_get_intr_status(timg_dev_t *hw, uint32_t *intr_status) __attribute__((always_inline))
static inline void timer_ll_clear_intr_status(timg_dev_t *hw, uint32_t mask)
{ {
*intr_status = hw->int_st_timers.val & 0x01; hw->int_clr_timers.val = mask;
} }
/** /**
* @brief Get interrupt raw status. * @brief Enable the register clock forever
* *
* @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1 * @param hw Timer Group register base address
* @param intr_raw_status Interrupt raw status * @param en True: Enable the register clock forever
* * False: Register clock is enabled only when register operation happens
* @return None
*/ */
FORCE_INLINE_ATTR void timer_ll_get_intr_raw_status(timer_group_t group_num, uint32_t *intr_raw_status) static inline void timer_ll_enable_register_clock_always_on(timg_dev_t *hw, bool en)
{ {
timg_dev_t *hw = TIMER_LL_GET_HW(group_num); hw->regclk.clk_en = en;
*intr_raw_status = hw->int_raw_timers.val & 0x01;
} }
/** /**
* @brief Set the level interrupt status, enable or disable the level interrupt. * @brief Get interrupt status register address
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number
* @param level_int_en True to enable level interrupt, false to disable level interrupt
* *
* @return None * @return Interrupt status register address
*/ */
static inline void timer_ll_set_level_int_enable(timg_dev_t *hw, timer_idx_t timer_num, bool level_int_en) static inline volatile void *timer_ll_get_intr_status_reg(timg_dev_t *hw)
{ {
// Only "level" interrupts are supported on this target return &hw->int_st_timers.val;
}
/**
* @brief Get the level interrupt status.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return
* - true Enable level interrupt
* - false Disable level interrupt
*/
static inline bool timer_ll_get_level_int_enable(timg_dev_t *hw, timer_idx_t timer_num)
{
// Only "level" interrupts are supported on this target
return true;
}
/**
* @brief Set the edge interrupt status, enable or disable the edge interrupt.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
* @param edge_int_en True to enable edge interrupt, false to disable edge interrupt
*
* @return None
*/
static inline void timer_ll_set_edge_int_enable(timg_dev_t *hw, timer_idx_t timer_num, bool edge_int_en)
{
// edge interrupt is not supported on H2
}
/**
* @brief Get the edge interrupt status.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return
* - true Enable edge interrupt
* - false Disable edge interrupt
*/
static inline bool timer_ll_get_edge_int_enable(timg_dev_t *hw, timer_idx_t timer_num)
{
// edge interrupt is not supported on H2
return false;
}
/**
* @brief Get interrupt status register address.
*
* @param hw Beginning address of the peripheral registers.
*
* @return uint32_t Interrupt status register address
*/
static inline uint32_t timer_ll_get_intr_status_reg(timg_dev_t *hw)
{
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);
}
/**
* @brief Set clock source.
*
* @param hal Context of the HAL layer
* @param use_xtal_en True to use XTAL clock, flase to use APB clock
*
* @return None
*/
static inline void timer_ll_set_use_xtal(timg_dev_t *hw, timer_idx_t timer_num, bool use_xtal_en)
{
hw->hw_timer[timer_num].config.tx_use_xtal = use_xtal_en;
}
/**
* @brief Get clock source.
*
* @param hal Context of the HAL layer
*
* @return
* - true Use XTAL clock
* - false Use APB clock
*/
static inline bool timer_ll_get_use_xtal(timg_dev_t *hw, timer_idx_t timer_num)
{
return hw->hw_timer[timer_num].config.tx_use_xtal;
} }
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -1,16 +1,8 @@
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// The LL layer for Timer Group register operations. // The LL layer for Timer Group register operations.
// Note that most of the register operations in this layer are non-atomic operations. // Note that most of the register operations in this layer are non-atomic operations.
@ -26,6 +18,7 @@ extern "C" {
#include "soc/timer_periph.h" #include "soc/timer_periph.h"
#include "soc/timer_group_struct.h" #include "soc/timer_group_struct.h"
#include "hal/wdt_types.h" #include "hal/wdt_types.h"
#include "hal/assert.h"
#include "esp_attr.h" #include "esp_attr.h"
//Type check wdt_stage_action_t //Type check wdt_stage_action_t
@ -95,24 +88,25 @@ FORCE_INLINE_ATTR bool mwdt_ll_check_if_enabled(timg_dev_t *hw)
FORCE_INLINE_ATTR void mwdt_ll_config_stage(timg_dev_t *hw, wdt_stage_t stage, uint32_t timeout, wdt_stage_action_t behavior) FORCE_INLINE_ATTR void mwdt_ll_config_stage(timg_dev_t *hw, wdt_stage_t stage, uint32_t timeout, wdt_stage_action_t behavior)
{ {
switch (stage) { switch (stage) {
case WDT_STAGE0: case WDT_STAGE0:
hw->wdtconfig0.wdt_stg0 = behavior; hw->wdtconfig0.wdt_stg0 = behavior;
hw->wdtconfig2.wdt_stg0_hold = timeout; hw->wdtconfig2.wdt_stg0_hold = timeout;
break; break;
case WDT_STAGE1: case WDT_STAGE1:
hw->wdtconfig0.wdt_stg1 = behavior; hw->wdtconfig0.wdt_stg1 = behavior;
hw->wdtconfig3.wdt_stg1_hold = timeout; hw->wdtconfig3.wdt_stg1_hold = timeout;
break; break;
case WDT_STAGE2: case WDT_STAGE2:
hw->wdtconfig0.wdt_stg2 = behavior; hw->wdtconfig0.wdt_stg2 = behavior;
hw->wdtconfig4.wdt_stg2_hold = timeout; hw->wdtconfig4.wdt_stg2_hold = timeout;
break; break;
case WDT_STAGE3: case WDT_STAGE3:
hw->wdtconfig0.wdt_stg3 = behavior; hw->wdtconfig0.wdt_stg3 = behavior;
hw->wdtconfig5.wdt_stg3_hold = timeout; hw->wdtconfig5.wdt_stg3_hold = timeout;
break; break;
default: default:
break; HAL_ASSERT(false && "unsupported WDT stage");
break;
} }
} }
@ -125,20 +119,21 @@ FORCE_INLINE_ATTR void mwdt_ll_config_stage(timg_dev_t *hw, wdt_stage_t stage, u
FORCE_INLINE_ATTR void mwdt_ll_disable_stage(timg_dev_t *hw, uint32_t stage) FORCE_INLINE_ATTR void mwdt_ll_disable_stage(timg_dev_t *hw, uint32_t stage)
{ {
switch (stage) { switch (stage) {
case WDT_STAGE0: case WDT_STAGE0:
hw->wdtconfig0.wdt_stg0 = WDT_STAGE_ACTION_OFF; hw->wdtconfig0.wdt_stg0 = WDT_STAGE_ACTION_OFF;
break; break;
case WDT_STAGE1: case WDT_STAGE1:
hw->wdtconfig0.wdt_stg1 = WDT_STAGE_ACTION_OFF; hw->wdtconfig0.wdt_stg1 = WDT_STAGE_ACTION_OFF;
break; break;
case WDT_STAGE2: case WDT_STAGE2:
hw->wdtconfig0.wdt_stg2 = WDT_STAGE_ACTION_OFF; hw->wdtconfig0.wdt_stg2 = WDT_STAGE_ACTION_OFF;
break; break;
case WDT_STAGE3: case WDT_STAGE3:
hw->wdtconfig0.wdt_stg3 = WDT_STAGE_ACTION_OFF; hw->wdtconfig0.wdt_stg3 = WDT_STAGE_ACTION_OFF;
break; break;
default: default:
break; HAL_ASSERT(false && "unsupported WDT stage");
break;
} }
} }
@ -196,7 +191,7 @@ FORCE_INLINE_ATTR void mwdt_ll_set_sys_reset_length(timg_dev_t *hw, wdt_reset_si
* WDT's enable bit is set to 0. Flashboot mode for TG0 is automatically enabled * WDT's enable bit is set to 0. Flashboot mode for TG0 is automatically enabled
* on flashboot, and should be disabled by software when flashbooting completes. * on flashboot, and should be disabled by software when flashbooting completes.
*/ */
FORCE_INLINE_ATTR void mwdt_ll_set_flashboot_en(timg_dev_t* hw, bool enable) FORCE_INLINE_ATTR void mwdt_ll_set_flashboot_en(timg_dev_t *hw, bool enable)
{ {
hw->wdtconfig0.wdt_flashboot_mod_en = (enable) ? 1 : 0; hw->wdtconfig0.wdt_flashboot_mod_en = (enable) ? 1 : 0;
} }
@ -253,7 +248,7 @@ FORCE_INLINE_ATTR void mwdt_ll_write_protect_disable(timg_dev_t *hw)
* *
* @param hw Start address of the peripheral registers. * @param hw Start address of the peripheral registers.
*/ */
FORCE_INLINE_ATTR void mwdt_ll_clear_intr_status(timg_dev_t* hw) FORCE_INLINE_ATTR void mwdt_ll_clear_intr_status(timg_dev_t *hw)
{ {
hw->int_clr_timers.wdt_int_clr = 1; hw->int_clr_timers.wdt_int_clr = 1;
} }
@ -264,7 +259,7 @@ FORCE_INLINE_ATTR void mwdt_ll_clear_intr_status(timg_dev_t* hw)
* @param hw Beginning address of the peripheral registers. * @param hw Beginning address of the peripheral registers.
* @param enable Whether to enable the MWDT interrupt * @param enable Whether to enable the MWDT interrupt
*/ */
FORCE_INLINE_ATTR void mwdt_ll_set_intr_enable(timg_dev_t* hw, bool enable) FORCE_INLINE_ATTR void mwdt_ll_set_intr_enable(timg_dev_t *hw, bool enable)
{ {
hw->int_ena_timers.wdt_int_ena = (enable) ? 1 : 0; hw->int_ena_timers.wdt_int_ena = (enable) ? 1 : 0;
} }

View File

@ -1,426 +1,266 @@
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// The LL layer for Timer Group register operations.
// Note that most of the register operations in this layer are non-atomic operations. // Note that most of the register operations in this layer are non-atomic operations.
#pragma once #pragma once
#include <stdbool.h>
#include "hal/assert.h"
#include "hal/misc.h"
#include "hal/timer_types.h"
#include "soc/timer_group_struct.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#include <stdlib.h> // Get timer group register base address with giving group number
#include "hal/misc.h" #define TIMER_LL_GET_HW(group_id) ((group_id == 0) ? (&TIMERG0) : (&TIMERG1))
#include "soc/timer_periph.h" #define TIMER_LL_EVENT_ALARM(timer_id) (1 << (timer_id))
#include "soc/timer_group_struct.h"
#include "hal/timer_types.h"
#include "hal/assert.h"
_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");
// Get timer group instance with giving group number
#define TIMER_LL_GET_HW(num) ((num == 0) ? (&TIMERG0) : (&TIMERG1))
/** /**
* @brief Set timer clock prescale value * @brief Set clock source for timer
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
* @param divider Prescale value (0 is not valid) * @param clk_src Clock source
*
* @return None
*/ */
static inline void timer_ll_set_divider(timg_dev_t *hw, timer_idx_t timer_num, uint32_t divider) static inline void timer_ll_set_clock_source(timg_dev_t *hw, uint32_t timer_num, gptimer_clock_source_t clk_src)
{
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;
break;
default:
HAL_ASSERT(false && "unsupported clock source");
break;
}
}
/**
* @brief Enable alarm event
*
* @param hw Timer Group register base address
* @param timer_num Timer number in the group
* @param en True: enable alarm
* False: disable alarm
*/
__attribute__((always_inline))
static inline void timer_ll_enable_alarm(timg_dev_t *hw, uint32_t timer_num, bool en)
{
hw->hw_timer[timer_num].config.tx_alarm_en = en;
// use level type interrupt
hw->hw_timer[timer_num].config.tx_level_int_en = en;
}
/**
* @brief Set clock prescale for timer
*
* @param hw Timer Group register base address
* @param timer_num Timer number in the group
* @param divider Prescale value (0 and 1 are not valid)
*/
static inline void timer_ll_set_clock_prescale(timg_dev_t *hw, uint32_t timer_num, uint32_t divider)
{ {
HAL_ASSERT(divider >= 2 && divider <= 65536); HAL_ASSERT(divider >= 2 && divider <= 65536);
if (divider >= 65536) { if (divider >= 65536) {
divider = 0; divider = 0;
} }
int timer_en = hw->hw_timer[timer_num].config.tx_en;
hw->hw_timer[timer_num].config.tx_en = 0;
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hw_timer[timer_num].config, tx_divider, divider); HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hw_timer[timer_num].config, tx_divider, divider);
hw->hw_timer[timer_num].config.tx_en = timer_en;
} }
/** /**
* @brief Get timer clock prescale value * @brief Enable auto-reload mode
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
* @param divider Pointer to accept the prescale value * @param en True: enable auto reload mode
* * False: disable auto reload mode
* @return None
*/ */
static inline void timer_ll_get_divider(timg_dev_t *hw, timer_idx_t timer_num, uint32_t *divider) static inline void timer_ll_enable_auto_reload(timg_dev_t *hw, uint32_t timer_num, bool en)
{ {
uint32_t d = HAL_FORCE_READ_U32_REG_FIELD(hw->hw_timer[timer_num].config, tx_divider); hw->hw_timer[timer_num].config.tx_autoreload = en;
if (d == 0) {
d = 65536;
} else if (d == 1) {
d = 2;
}
*divider = d;
} }
/** /**
* @brief Load counter value into time-base counter * @brief Set count direction
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer peripheral register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
* @param load_val Counter value * @param direction Count direction
*
* @return None
*/ */
static inline void timer_ll_set_counter_value(timg_dev_t *hw, timer_idx_t timer_num, uint64_t load_val) static inline void timer_ll_set_count_direction(timg_dev_t *hw, uint32_t timer_num, gptimer_count_direction_t direction)
{ {
hw->hw_timer[timer_num].loadhi.tx_load_hi = (uint32_t) (load_val >> 32); hw->hw_timer[timer_num].config.tx_increase = direction == GPTIMER_COUNT_UP;
hw->hw_timer[timer_num].loadlo.tx_load_lo = (uint32_t) load_val;
hw->hw_timer[timer_num].load.tx_load = 1;
} }
/** /**
* @brief Get counter value from time-base counter * @brief Enable timer, start couting
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
* @param timer_val Pointer to accept the counter value * @param en True: enable the counter
* * False: disable the counter
* @return None
*/ */
FORCE_INLINE_ATTR void timer_ll_get_counter_value(timg_dev_t *hw, timer_idx_t timer_num, uint64_t *timer_val) __attribute__((always_inline))
static inline void timer_ll_enable_counter(timg_dev_t *hw, uint32_t timer_num, bool en)
{
hw->hw_timer[timer_num].config.tx_en = en;
}
/**
* @brief Get counter value
*
* @param hw Timer Group register base address
* @param timer_num Timer number in the group
*
* @return counter value
*/
__attribute__((always_inline))
static inline uint64_t timer_ll_get_counter_value(timg_dev_t *hw, uint32_t timer_num)
{ {
hw->hw_timer[timer_num].update.tx_update = 1; hw->hw_timer[timer_num].update.tx_update = 1;
while (hw->hw_timer[timer_num].update.tx_update) {} // Timer register is in a different clock domain from Timer hardware logic
*timer_val = ((uint64_t) hw->hw_timer[timer_num].hi.tx_hi << 32) | (hw->hw_timer[timer_num].lo.tx_lo); // We need to wait for the update to take effect before fetching the count value
while (hw->hw_timer[timer_num].update.tx_update) {
}
return ((uint64_t) hw->hw_timer[timer_num].hi.tx_hi << 32) | (hw->hw_timer[timer_num].lo.tx_lo);
} }
/** /**
* @brief Set counter mode, include increment mode and decrement mode. * @brief Set alarm value
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
* @param increase_en True to increment mode, fasle to decrement mode * @param alarm_value When counter reaches alarm value, alarm event will be triggered
*
* @return None
*/ */
static inline void timer_ll_set_counter_increase(timg_dev_t *hw, timer_idx_t timer_num, bool increase_en) __attribute__((always_inline))
{ static inline void timer_ll_set_alarm_value(timg_dev_t *hw, uint32_t timer_num, uint64_t alarm_value)
hw->hw_timer[timer_num].config.tx_increase = increase_en;
}
/**
* @brief Get counter mode, include increment mode and decrement mode.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return
* - true Increment mode
* - false Decrement mode
*/
static inline bool timer_ll_get_counter_increase(timg_dev_t *hw, timer_idx_t timer_num)
{
return hw->hw_timer[timer_num].config.tx_increase;
}
/**
* @brief Set counter status, enable or disable counter.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
* @param counter_en True to enable counter, false to disable counter
*
* @return None
*/
FORCE_INLINE_ATTR void timer_ll_set_counter_enable(timg_dev_t *hw, timer_idx_t timer_num, bool counter_en)
{
hw->hw_timer[timer_num].config.tx_en = counter_en;
}
/**
* @brief Get counter status.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return
* - true Enable counter
* - false Disable conuter
*/
static inline bool timer_ll_get_counter_enable(timg_dev_t *hw, timer_idx_t timer_num)
{
return hw->hw_timer[timer_num].config.tx_en;
}
/**
* @brief Set auto reload mode.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
* @param auto_reload_en True to enable auto reload mode, flase to disable auto reload mode
*
* @return None
*/
static inline void timer_ll_set_auto_reload(timg_dev_t *hw, timer_idx_t timer_num, bool auto_reload_en)
{
hw->hw_timer[timer_num].config.tx_autoreload = auto_reload_en;
}
/**
* @brief Get auto reload mode.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return
* - true Enable auto reload mode
* - false Disable auto reload mode
*/
FORCE_INLINE_ATTR bool timer_ll_get_auto_reload(timg_dev_t *hw, timer_idx_t timer_num)
{
return hw->hw_timer[timer_num].config.tx_autoreload;
}
/**
* @brief Set the counter value to trigger the alarm.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
* @param alarm_value Counter value to trigger the alarm
*
* @return None
*/
FORCE_INLINE_ATTR void timer_ll_set_alarm_value(timg_dev_t *hw, timer_idx_t timer_num, uint64_t alarm_value)
{ {
hw->hw_timer[timer_num].alarmhi.tx_alarm_hi = (uint32_t) (alarm_value >> 32); 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; hw->hw_timer[timer_num].alarmlo.tx_alarm_lo = (uint32_t) alarm_value;
} }
/** /**
* @brief Get the counter value to trigger the alarm. * @brief Get alarm value
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
* @param alarm_value Pointer to accept the counter value to trigger the alarm * @return Counter value to trigger the alarm event
*
* @return None
*/ */
static inline void timer_ll_get_alarm_value(timg_dev_t *hw, timer_idx_t timer_num, uint64_t *alarm_value) static inline uint64_t timer_ll_get_alarm_value(timg_dev_t *hw, uint32_t timer_num)
{ {
*alarm_value = ((uint64_t) hw->hw_timer[timer_num].alarmhi.tx_alarm_hi << 32) | (hw->hw_timer[timer_num].alarmlo.tx_alarm_lo); return ((uint64_t) hw->hw_timer[timer_num].alarmhi.tx_alarm_hi << 32) | (hw->hw_timer[timer_num].alarmlo.tx_alarm_lo);
} }
/** /**
* @brief Set the alarm status, enable or disable the alarm. * @brief Set reload value
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
* @param alarm_en True to enable alarm, false to disable alarm * @param reload_val Reload counter value
*
* @return None
*/ */
FORCE_INLINE_ATTR void timer_ll_set_alarm_enable(timg_dev_t *hw, timer_idx_t timer_num, bool alarm_en) static inline void timer_ll_set_reload_value(timg_dev_t *hw, uint32_t timer_num, uint64_t load_val)
{ {
hw->hw_timer[timer_num].config.tx_alarm_en = alarm_en; hw->hw_timer[timer_num].loadhi.tx_load_hi = (uint32_t) (load_val >> 32);
hw->hw_timer[timer_num].loadlo.tx_load_lo = (uint32_t) load_val;
} }
/** /**
* @brief Get the alarm status. * @brief Get reload value
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
* * @return reload count value
* @return
* - true Enable alarm
* - false Disable alarm
*/ */
static inline bool timer_ll_get_alarm_enable(timg_dev_t *hw, timer_idx_t timer_num) static inline uint64_t timer_ll_get_reload_value(timg_dev_t *hw, uint32_t timer_num)
{ {
return hw->hw_timer[timer_num].config.tx_alarm_en; return ((uint64_t)hw->hw_timer[timer_num].loadhi.tx_load_hi << 32) | (hw->hw_timer[timer_num].loadlo.tx_load_lo);
} }
/** /**
* @brief Enable timer interrupt. * @brief Trigger software reload, value set by `timer_ll_set_reload_value()` will be reflected into counter immediately
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
*
* @return None
*/ */
FORCE_INLINE_ATTR void timer_ll_intr_enable(timg_dev_t *hw, timer_idx_t timer_num) static inline void timer_ll_trigger_soft_reload(timg_dev_t *hw, uint32_t timer_num)
{ {
hw->int_ena_timers.val |= BIT(timer_num); hw->hw_timer[timer_num].load.tx_load = 1;
hw->hw_timer[timer_num].config.tx_level_int_en = 1;
} }
/** /**
* @brief Disable timer interrupt. * @brief Enable timer interrupt by mask
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param mask Mask of interrupt events
* * @param en True: enable interrupt
* @return None * False: disable interrupt
*/ */
FORCE_INLINE_ATTR void timer_ll_intr_disable(timg_dev_t *hw, timer_idx_t timer_num) __attribute__((always_inline))
static inline void timer_ll_enable_intr(timg_dev_t *hw, uint32_t mask, bool en)
{ {
hw->int_ena_timers.val &= (~BIT(timer_num)); if (en) {
hw->hw_timer[timer_num].config.tx_level_int_en = 0; hw->int_ena_timers.val |= mask;
} else {
hw->int_ena_timers.val &= ~mask;
}
} }
/** /**
* @brief Disable timer interrupt. * @brief Get interrupt status
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number
* *
* @return None * @return Interrupt status
*/ */
FORCE_INLINE_ATTR void timer_ll_clear_intr_status(timg_dev_t *hw, timer_idx_t timer_num) __attribute__((always_inline))
static inline uint32_t timer_ll_get_intr_status(timg_dev_t *hw)
{ {
hw->int_clr_timers.val |= BIT(timer_num); return hw->int_st_timers.val & 0x03;
} }
/** /**
* @brief Get interrupt status. * @brief Clear interrupt status by mask
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param intr_status Interrupt status * @param mask Interrupt events mask
*
* @return None
*/ */
FORCE_INLINE_ATTR void timer_ll_get_intr_status(timg_dev_t *hw, uint32_t *intr_status) __attribute__((always_inline))
static inline void timer_ll_clear_intr_status(timg_dev_t *hw, uint32_t mask)
{ {
*intr_status = hw->int_st_timers.val & 0x03; hw->int_clr_timers.val = mask;
} }
/** /**
* @brief Get interrupt raw status. * @brief Enable the register clock forever
* *
* @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1 * @param hw Timer Group register base address
* @param intr_raw_status Interrupt raw status * @param en True: Enable the register clock forever
* * False: Register clock is enabled only when register operation happens
* @return None
*/ */
FORCE_INLINE_ATTR void timer_ll_get_intr_raw_status(timer_group_t group_num, uint32_t *intr_raw_status) static inline void timer_ll_enable_register_clock_always_on(timg_dev_t *hw, bool en)
{ {
timg_dev_t *hw = TIMER_LL_GET_HW(group_num); hw->regclk.clk_en = en;
*intr_raw_status = hw->int_raw_timers.val & 0x03;
} }
/** /**
* @brief Set the level interrupt status, enable or disable the level interrupt. * @brief Get interrupt status register address
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number
* @param level_int_en True to enable level interrupt, false to disable level interrupt
* *
* @return None * @return Interrupt status register address
*/ */
static inline void timer_ll_set_level_int_enable(timg_dev_t *hw, timer_idx_t timer_num, bool level_int_en) static inline volatile void *timer_ll_get_intr_status_reg(timg_dev_t *hw)
{ {
hw->hw_timer[timer_num].config.tx_level_int_en = level_int_en; return &hw->int_st_timers.val;
}
/**
* @brief Get the level interrupt status.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return
* - true Enable level interrupt
* - false Disable level interrupt
*/
static inline bool timer_ll_get_level_int_enable(timg_dev_t *hw, timer_idx_t timer_num)
{
return hw->hw_timer[timer_num].config.tx_level_int_en;
}
/**
* @brief Set the edge interrupt status, enable or disable the edge interrupt.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
* @param edge_int_en True to enable edge interrupt, false to disable edge interrupt
*
* @return None
*/
static inline void timer_ll_set_edge_int_enable(timg_dev_t *hw, timer_idx_t timer_num, bool edge_int_en)
{
hw->hw_timer[timer_num].config.tx_edge_int_en = edge_int_en;
}
/**
* @brief Get the edge interrupt status.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return
* - true Enable edge interrupt
* - false Disable edge interrupt
*/
static inline bool timer_ll_get_edge_int_enable(timg_dev_t *hw, timer_idx_t timer_num)
{
return hw->hw_timer[timer_num].config.tx_edge_int_en;
}
/**
* @brief Get interrupt status register address.
*
* @param hw Beginning address of the peripheral registers.
*
* @return uint32_t Interrupt status register address
*/
static inline uint32_t timer_ll_get_intr_status_reg(timg_dev_t *hw)
{
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);
}
/**
* @brief Set clock source.
*
* @param hal Context of the HAL layer
* @param use_xtal_en True to use XTAL clock, flase to use APB clock
*
* @return None
*/
static inline void timer_ll_set_use_xtal(timg_dev_t *hw, timer_idx_t timer_num, bool use_xtal_en)
{
hw->hw_timer[timer_num].config.tx_use_xtal = use_xtal_en;
}
/**
* @brief Get clock source.
*
* @param hal Context of the HAL layer
*
* @return
* - true Use XTAL clock
* - false Use APB clock
*/
static inline bool timer_ll_get_use_xtal(timg_dev_t *hw, timer_idx_t timer_num)
{
return hw->hw_timer[timer_num].config.tx_use_xtal;
} }
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -1,16 +1,8 @@
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// The LL layer for Timer Group register operations. // The LL layer for Timer Group register operations.
// Note that most of the register operations in this layer are non-atomic operations. // Note that most of the register operations in this layer are non-atomic operations.
@ -27,6 +19,7 @@ extern "C" {
#include "soc/timer_periph.h" #include "soc/timer_periph.h"
#include "soc/timer_group_struct.h" #include "soc/timer_group_struct.h"
#include "hal/wdt_types.h" #include "hal/wdt_types.h"
#include "hal/assert.h"
#include "esp_attr.h" #include "esp_attr.h"
/* The value that needs to be written to MWDT_LL_WKEY to write-enable the wdt registers */ /* The value that needs to be written to MWDT_LL_WKEY to write-enable the wdt registers */
@ -125,6 +118,7 @@ FORCE_INLINE_ATTR void mwdt_ll_config_stage(timg_dev_t *hw, wdt_stage_t stage, u
hw->wdtconfig5.wdt_stg3_hold = timeout; hw->wdtconfig5.wdt_stg3_hold = timeout;
break; break;
default: default:
HAL_ASSERT(false && "unsupported WDT stage");
break; break;
} }
} }
@ -151,6 +145,7 @@ FORCE_INLINE_ATTR void mwdt_ll_disable_stage(timg_dev_t *hw, uint32_t stage)
hw->wdtconfig0.wdt_stg3 = WDT_STAGE_ACTION_OFF; hw->wdtconfig0.wdt_stg3 = WDT_STAGE_ACTION_OFF;
break; break;
default: default:
HAL_ASSERT(false && "unsupported WDT stage");
break; break;
} }
} }

View File

@ -1,428 +1,265 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// The LL layer for Timer Group register operations.
// Note that most of the register operations in this layer are non-atomic operations. // Note that most of the register operations in this layer are non-atomic operations.
#pragma once #pragma once
#include <stdbool.h>
#include "hal/assert.h"
#include "hal/misc.h"
#include "hal/timer_types.h"
#include "soc/timer_group_struct.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#include <stdlib.h> // Get timer group register base address with giving group number
#include "hal/misc.h" #define TIMER_LL_GET_HW(group_id) ((group_id == 0) ? (&TIMERG0) : (&TIMERG1))
#include "soc/timer_periph.h" #define TIMER_LL_EVENT_ALARM(timer_id) (1 << (timer_id))
#include "soc/timer_group_struct.h"
#include "hal/timer_types.h"
#include "hal/assert.h"
_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");
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))
/** /**
* @brief Set timer clock prescale value * @brief Set clock source for timer
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
* @param divider Prescale value * @param clk_src Clock source
*
* @return None
*/ */
static inline void timer_ll_set_divider(timg_dev_t *hw, timer_idx_t timer_num, uint32_t divider) static inline void timer_ll_set_clock_source(timg_dev_t *hw, uint32_t timer_num, gptimer_clock_source_t clk_src)
{
switch (clk_src) {
case GPTIMER_CLK_SRC_APB:
hw->hw_timer[timer_num].config.tn_use_xtal = 0;
break;
case GPTIMER_CLK_SRC_XTAL:
hw->hw_timer[timer_num].config.tn_use_xtal = 1;
break;
default:
HAL_ASSERT(false && "unsupported clock source");
break;
}
}
/**
* @brief Enable alarm event
*
* @param hw Timer Group register base address
* @param timer_num Timer number in the group
* @param en True: enable alarm
* False: disable alarm
*/
__attribute__((always_inline))
static inline void timer_ll_enable_alarm(timg_dev_t *hw, uint32_t timer_num, bool en)
{
hw->hw_timer[timer_num].config.tn_alarm_en = en;
}
/**
* @brief Set clock prescale for timer
*
* @param hw Timer Group register base address
* @param timer_num Timer number in the group
* @param divider Prescale value (0 and 1 are not valid)
*/
static inline void timer_ll_set_clock_prescale(timg_dev_t *hw, uint32_t timer_num, uint32_t divider)
{ {
HAL_ASSERT(divider >= 2 && divider <= 65536); HAL_ASSERT(divider >= 2 && divider <= 65536);
if (divider >= 65536) { if (divider >= 65536) {
divider = 0; divider = 0;
} }
int timer_en = hw->hw_timer[timer_num].config.tn_en;
hw->hw_timer[timer_num].config.tn_en = 0;
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hw_timer[timer_num].config, tn_divider, divider); HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hw_timer[timer_num].config, tn_divider, divider);
hw->hw_timer[timer_num].config.tn_en = timer_en; hw->hw_timer[timer_num].config.tn_divcnt_rst = 1;
} }
/** /**
* @brief Get timer clock prescale value * @brief Enable auto-reload mode
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
* @param divider Pointer to accept the prescale value * @param en True: enable auto reload mode
* * False: disable auto reload mode
* @return None
*/ */
static inline void timer_ll_get_divider(timg_dev_t *hw, timer_idx_t timer_num, uint32_t *divider) static inline void timer_ll_enable_auto_reload(timg_dev_t *hw, uint32_t timer_num, bool en)
{ {
uint32_t d = HAL_FORCE_READ_U32_REG_FIELD(hw->hw_timer[timer_num].config, tn_divider); hw->hw_timer[timer_num].config.tn_autoreload = en;
if (d == 0) { }
d = 65536;
} else if (d == 1) { /**
d = 2; * @brief Set count direction
*
* @param hw Timer peripheral register base address
* @param timer_num Timer number in the group
* @param direction Count direction
*/
static inline void timer_ll_set_count_direction(timg_dev_t *hw, uint32_t timer_num, gptimer_count_direction_t direction)
{
hw->hw_timer[timer_num].config.tn_increase = (direction == GPTIMER_COUNT_UP);
}
/**
* @brief Enable timer, start couting
*
* @param hw Timer Group register base address
* @param timer_num Timer number in the group
* @param en True: enable the counter
* False: disable the counter
*/
__attribute__((always_inline))
static inline void timer_ll_enable_counter(timg_dev_t *hw, uint32_t timer_num, bool en)
{
hw->hw_timer[timer_num].config.tn_en = en;
}
/**
* @brief Get counter value
*
* @param hw Timer Group register base address
* @param timer_num Timer number in the group
*
* @return counter value
*/
__attribute__((always_inline))
static inline uint64_t timer_ll_get_counter_value(timg_dev_t *hw, uint32_t timer_num)
{
hw->hw_timer[timer_num].update.tn_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.tn_update) {
} }
*divider = d; return ((uint64_t)hw->hw_timer[timer_num].hi.tn_hi << 32) | (hw->hw_timer[timer_num].lo.tn_lo);
} }
/** /**
* @brief Load counter value into time-base counter * @brief Set alarm value
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param timer_num Timer number in the group
* @param load_val Counter value * @param alarm_value When counter reaches alarm value, alarm event will be triggered
*
* @return None
*/ */
static inline void timer_ll_set_counter_value(timg_dev_t *hw, timer_idx_t timer_num, uint64_t load_val) __attribute__((always_inline))
static inline void timer_ll_set_alarm_value(timg_dev_t *hw, uint32_t timer_num, uint64_t alarm_value)
{
hw->hw_timer[timer_num].alarmhi.tn_alarm_hi = (uint32_t)(alarm_value >> 32);
hw->hw_timer[timer_num].alarmlo.tn_alarm_lo = (uint32_t)alarm_value;
}
/**
* @brief Get alarm value
*
* @param hw Timer Group register base address
* @param timer_num Timer number in the group
* @return Counter value to trigger the alarm event
*/
static inline uint64_t timer_ll_get_alarm_value(timg_dev_t *hw, uint32_t timer_num)
{
return ((uint64_t)hw->hw_timer[timer_num].alarmhi.tn_alarm_hi << 32) | (hw->hw_timer[timer_num].alarmlo.tn_alarm_lo);
}
/**
* @brief Set reload value
*
* @param hw Timer Group register base address
* @param timer_num Timer number in the group
* @param reload_val Reload counter value
*/
static inline void timer_ll_set_reload_value(timg_dev_t *hw, uint32_t timer_num, uint64_t reload_val)
{
hw->hw_timer[timer_num].loadhi.tn_load_hi = (uint32_t)(reload_val >> 32);
hw->hw_timer[timer_num].loadlo.tn_load_lo = (uint32_t)reload_val;
}
/**
* @brief Get reload value
*
* @param hw Timer Group register base address
* @param timer_num Timer number in the group
* @return reload count value
*/
static inline uint64_t timer_ll_get_reload_value(timg_dev_t *hw, uint32_t timer_num)
{
return ((uint64_t)hw->hw_timer[timer_num].loadhi.tn_load_hi << 32) | (hw->hw_timer[timer_num].loadlo.tn_load_lo);
}
/**
* @brief Trigger software reload, value set by `timer_ll_set_reload_value()` will be reflected into counter immediately
*
* @param hw Timer Group register base address
* @param timer_num Timer number in the group
*/
static inline void timer_ll_trigger_soft_reload(timg_dev_t *hw, uint32_t timer_num)
{ {
hw->hw_timer[timer_num].loadhi.tn_load_hi = (uint32_t) (load_val >> 32);
hw->hw_timer[timer_num].loadlo.tn_load_lo = (uint32_t) load_val;
hw->hw_timer[timer_num].load.tn_load = 1; hw->hw_timer[timer_num].load.tn_load = 1;
} }
/** /**
* @brief Get counter value from time-base counter * @brief Enable timer interrupt by mask
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param mask Mask of interrupt events
* @param timer_val Pointer to accept the counter value * @param en True: enable interrupt
* * False: disable interrupt
* @return None
*/ */
FORCE_INLINE_ATTR void timer_ll_get_counter_value(timg_dev_t *hw, timer_idx_t timer_num, uint64_t *timer_val) __attribute__((always_inline))
static inline void timer_ll_enable_intr(timg_dev_t *hw, uint32_t mask, bool en)
{ {
hw->hw_timer[timer_num].update.tn_update = 1; if (en) {
while (hw->hw_timer[timer_num].update.tn_update) {} hw->int_ena_timers.val |= mask;
*timer_val = ((uint64_t) hw->hw_timer[timer_num].hi.tn_hi << 32) | (hw->hw_timer[timer_num].lo.tn_lo); } else {
hw->int_ena_timers.val &= ~mask;
}
} }
/** /**
* @brief Set counter mode, include increment mode and decrement mode. * @brief Get interrupt status
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number
* @param increase_en True to increment mode, fasle to decrement mode
* *
* @return None * @return Interrupt status
*/ */
static inline void timer_ll_set_counter_increase(timg_dev_t *hw, timer_idx_t timer_num, bool increase_en) __attribute__((always_inline))
static inline uint32_t timer_ll_get_intr_status(timg_dev_t *hw)
{ {
hw->hw_timer[timer_num].config.tn_increase = increase_en; return hw->int_st_timers.val & 0x03;
} }
/** /**
* @brief Get counter mode, include increment mode and decrement mode. * @brief Clear interrupt status by mask
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param mask Interrupt events mask
*
* @return
* - true Increment mode
* - false Decrement mode
*/ */
static inline bool timer_ll_get_counter_increase(timg_dev_t *hw, timer_idx_t timer_num) __attribute__((always_inline))
static inline void timer_ll_clear_intr_status(timg_dev_t *hw, uint32_t mask)
{ {
return hw->hw_timer[timer_num].config.tn_increase; hw->int_clr_timers.val = mask;
} }
/** /**
* @brief Set counter status, enable or disable counter. * @brief Enable the register clock forever
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number * @param en True: Enable the register clock forever
* @param counter_en True to enable counter, false to disable counter * False: Register clock is enabled only when register operation happens
*
* @return None
*/ */
FORCE_INLINE_ATTR void timer_ll_set_counter_enable(timg_dev_t *hw, timer_idx_t timer_num, bool counter_en) static inline void timer_ll_enable_register_clock_always_on(timg_dev_t *hw, bool en)
{ {
hw->hw_timer[timer_num].config.tn_en = counter_en; hw->regclk.clk_en = en;
} }
/** /**
* @brief Get counter status. * @brief Get interrupt status register address
* *
* @param hw Beginning address of the peripheral registers. * @param hw Timer Group register base address
* @param timer_num The timer number
* *
* @return * @return Interrupt status register address
* - true Enable counter
* - false Disable conuter
*/ */
static inline bool timer_ll_get_counter_enable(timg_dev_t *hw, timer_idx_t timer_num) static inline volatile void *timer_ll_get_intr_status_reg(timg_dev_t *hw)
{ {
return hw->hw_timer[timer_num].config.tn_en; return &hw->int_st_timers;
}
/**
* @brief Set auto reload mode.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
* @param auto_reload_en True to enable auto reload mode, flase to disable auto reload mode
*
* @return None
*/
static inline void timer_ll_set_auto_reload(timg_dev_t *hw, timer_idx_t timer_num, bool auto_reload_en)
{
hw->hw_timer[timer_num].config.tn_autoreload = auto_reload_en;
}
/**
* @brief Get auto reload mode.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return
* - true Enable auto reload mode
* - false Disable auto reload mode
*/
FORCE_INLINE_ATTR bool timer_ll_get_auto_reload(timg_dev_t *hw, timer_idx_t timer_num)
{
return hw->hw_timer[timer_num].config.tn_autoreload;
}
/**
* @brief Set the counter value to trigger the alarm.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
* @param alarm_value Counter value to trigger the alarm
*
* @return None
*/
FORCE_INLINE_ATTR void timer_ll_set_alarm_value(timg_dev_t *hw, timer_idx_t timer_num, uint64_t alarm_value)
{
hw->hw_timer[timer_num].alarmhi.tn_alarm_hi = (uint32_t) (alarm_value >> 32);
hw->hw_timer[timer_num].alarmlo.tn_alarm_lo = (uint32_t) alarm_value;
}
/**
* @brief Get the counter value to trigger the alarm.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
* @param alarm_value Pointer to accept the counter value to trigger the alarm
*
* @return None
*/
static inline void timer_ll_get_alarm_value(timg_dev_t *hw, timer_idx_t timer_num, uint64_t *alarm_value)
{
*alarm_value = ((uint64_t) hw->hw_timer[timer_num].alarmhi.tn_alarm_hi << 32) | (hw->hw_timer[timer_num].alarmlo.tn_alarm_lo);
}
/**
* @brief Set the alarm status, enable or disable the alarm.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
* @param alarm_en True to enable alarm, false to disable alarm
*
* @return None
*/
FORCE_INLINE_ATTR void timer_ll_set_alarm_enable(timg_dev_t *hw, timer_idx_t timer_num, bool alarm_en)
{
hw->hw_timer[timer_num].config.tn_alarm_en = alarm_en;
}
/**
* @brief Get the alarm status.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return
* - true Enable alarm
* - false Disable alarm
*/
static inline bool timer_ll_get_alarm_enable(timg_dev_t *hw, timer_idx_t timer_num)
{
return hw->hw_timer[timer_num].config.tn_alarm_en;
}
/**
* @brief Enable timer interrupt.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return None
*/
FORCE_INLINE_ATTR void timer_ll_intr_enable(timg_dev_t *hw, timer_idx_t timer_num)
{
hw->int_ena_timers.val |= BIT(timer_num);
}
/**
* @brief Disable timer interrupt.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return None
*/
FORCE_INLINE_ATTR void timer_ll_intr_disable(timg_dev_t *hw, timer_idx_t timer_num)
{
hw->int_ena_timers.val &= (~BIT(timer_num));
}
/**
* @brief Disable timer interrupt.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return None
*/
FORCE_INLINE_ATTR void timer_ll_clear_intr_status(timg_dev_t *hw, timer_idx_t timer_num)
{
hw->int_clr_timers.val |= BIT(timer_num);
}
/**
* @brief Get interrupt status.
*
* @param hw Beginning address of the peripheral registers.
* @param intr_status Interrupt status
*
* @return None
*/
FORCE_INLINE_ATTR void timer_ll_get_intr_status(timg_dev_t *hw, uint32_t *intr_status)
{
*intr_status = hw->int_st_timers.val & 0x03;
}
/**
* @brief Get interrupt raw status.
*
* @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
* @param intr_raw_status Interrupt raw status
*
* @return None
*/
FORCE_INLINE_ATTR void timer_ll_get_intr_raw_status(timer_group_t group_num, uint32_t *intr_raw_status)
{
timg_dev_t *hw = TIMER_LL_GET_HW(group_num);
*intr_raw_status = hw->int_raw_timers.val & 0x03;
}
/**
* @brief Set the level interrupt status, enable or disable the level interrupt.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
* @param level_int_en True to enable level interrupt, false to disable level interrupt
*
* @return None
*/
static inline void timer_ll_set_level_int_enable(timg_dev_t *hw, timer_idx_t timer_num, bool level_int_en)
{
// Only "level" interrupts are supported on this target
}
/**
* @brief Get the level interrupt status.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return
* - true Enable level interrupt
* - false Disable level interrupt
*/
static inline bool timer_ll_get_level_int_enable(timg_dev_t *hw, timer_idx_t timer_num)
{
return true;
}
/**
* @brief Set the edge interrupt status, enable or disable the edge interrupt.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
* @param edge_int_en True to enable edge interrupt, false to disable edge interrupt
*
* @return None
*/
static inline void timer_ll_set_edge_int_enable(timg_dev_t *hw, timer_idx_t timer_num, bool edge_int_en)
{
}
/**
* @brief Get the edge interrupt status.
*
* @param hw Beginning address of the peripheral registers.
* @param timer_num The timer number
*
* @return
* - true Enable edge interrupt
* - false Disable edge interrupt
*/
static inline bool timer_ll_get_edge_int_enable(timg_dev_t *hw, timer_idx_t timer_num)
{
return false;
}
/**
* @brief Get interrupt status register address.
*
* @param hw Beginning address of the peripheral registers.
*
* @return uint32_t Interrupt status register address
*/
static inline uint32_t timer_ll_get_intr_status_reg(timg_dev_t *hw)
{
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);
}
/**
* @brief Set clock source.
*
* @param hal Context of the HAL layer
* @param use_xtal_en True to use XTAL clock, flase to use APB clock
*
* @return None
*/
static inline void timer_ll_set_use_xtal(timg_dev_t *hw, timer_idx_t timer_num, bool use_xtal_en)
{
hw->hw_timer[timer_num].config.tn_use_xtal = use_xtal_en;
}
/**
* @brief Get clock source.
*
* @param hal Context of the HAL layer
*
* @return
* - true Use XTAL clock
* - false Use APB clock
*/
static inline bool timer_ll_get_use_xtal(timg_dev_t *hw, timer_idx_t timer_num)
{
return hw->hw_timer[timer_num].config.tn_use_xtal;
} }
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -1,16 +1,8 @@
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/******************************************************************************* /*******************************************************************************
* NOTICE * NOTICE
@ -18,25 +10,22 @@
* See readme.md in hal/include/hal/readme.md * See readme.md in hal/include/hal/readme.md
******************************************************************************/ ******************************************************************************/
// The HAL layer for Timer Group.
// There is no parameter check in the hal layer, so the caller must ensure the correctness of the parameters.
#pragma once #pragma once
#include <stdint.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#include "soc/soc_caps.h" typedef struct timg_dev_t *gptimer_soc_handle_t; // GPTimer SOC layer handle
#include "hal/timer_ll.h"
#include "hal/timer_types.h"
/** /**
* Context that should be maintained by both the driver and the HAL * Context that should be maintained by both the driver and the HAL
*/ */
typedef struct { typedef struct {
timg_dev_t *dev; gptimer_soc_handle_t dev; // Timer SOC layer handle (i.e. register base address)
timer_idx_t idx; uint32_t timer_id; // Timer ID (i.e. index of the timer in the group)
} timer_hal_context_t; } timer_hal_context_t;
/** /**
@ -45,294 +34,16 @@ typedef struct {
* @param hal Context of the HAL layer * @param hal Context of the HAL layer
* @param group_num The timer group number * @param group_num The timer group number
* @param timer_num The timer number * @param timer_num The timer number
*
* @return None
*/ */
void timer_hal_init(timer_hal_context_t *hal, timer_group_t group_num, timer_idx_t timer_num); void timer_hal_init(timer_hal_context_t *hal, uint32_t group_num, uint32_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 Reset timer peripheral
*
* @param hal Context of the HAL layer
*
* @return None
*/
void timer_hal_reset_periph(timer_hal_context_t *hal);
/**
* @brief Set timer clock prescale value
*
* @param hal Context of the HAL layer
* @param divider Prescale value
*
* @return None
*/
#define timer_hal_set_divider(hal, divider) timer_ll_set_divider((hal)->dev, (hal)->idx, divider)
/**
* @brief Get timer clock prescale value
*
* @param hal Context of the HAL layer
* @param divider Pointer to accept the prescale value
*
* @return None
*/
#define timer_hal_get_divider(hal, divider) timer_ll_get_divider((hal)->dev, (hal)->idx, divider)
/** /**
* @brief Load counter value into time-base counter * @brief Load counter value into time-base counter
* *
* @param hal Context of the HAL layer * @param hal Context of the HAL layer
* @param load_val Counter value * @param load_val Counter value
*
* @return None
*/ */
#define timer_hal_set_counter_value(hal, load_val) timer_ll_set_counter_value((hal)->dev, (hal)->idx, load_val) void timer_hal_set_counter_value(timer_hal_context_t *hal, uint64_t load_val);
/**
* @brief Get counter value from time-base counter
*
* @param hal Context of the HAL layer
* @param timer_val Pointer to accept the counter value
*
* @return None
*/
#define timer_hal_get_counter_value(hal, timer_val) timer_ll_get_counter_value((hal)->dev, (hal)->idx, timer_val)
/**
* @brief Set counter mode, include increment mode and decrement mode.
*
* @param hal Context of the HAL layer
* @param increase_en True to increment mode, fasle to decrement mode
*
* @return None
*/
#define timer_hal_set_counter_increase(hal, increase_en) timer_ll_set_counter_increase((hal)->dev, (hal)->idx, increase_en)
/**
* @brief Get counter mode, include increment mode and decrement mode.
*
* @param hal Context of the HAL layer
* @param counter_dir Pointer to accept the counter mode
*
* @return
* - true Increment mode
* - false Decrement mode
*/
#define timer_hal_get_counter_increase(hal) timer_ll_get_counter_increase((hal)->dev, (hal)->idx)
/**
* @brief Set counter status, enable or disable counter.
*
* @param hal Context of the HAL layer
* @param counter_en True to enable counter, false to disable counter
*
* @return None
*/
#define timer_hal_set_counter_enable(hal, counter_en) timer_ll_set_counter_enable((hal)->dev, (hal)->idx, counter_en)
/**
* @brief Get counter status.
*
* @param hal Context of the HAL layer
*
* @return
* - true Enable counter
* - false Disable conuter
*/
#define timer_hal_get_counter_enable(hal) timer_ll_get_counter_enable((hal)->dev, (hal)->idx)
/**
* @brief Set auto reload mode.
*
* @param hal Context of the HAL layer
* @param auto_reload_en True to enable auto reload mode, flase to disable auto reload mode
*
* @return None
*/
#define timer_hal_set_auto_reload(hal, auto_reload_en) timer_ll_set_auto_reload((hal)->dev, (hal)->idx, auto_reload_en)
/**
* @brief Get auto reload mode.
*
* @param hal Context of the HAL layer
*
* @return
* - true Enable auto reload mode
* - false Disable auto reload mode
*/
#define timer_hal_get_auto_reload(hal) timer_ll_get_auto_reload((hal)->dev, (hal)->idx)
/**
* @brief Set the counter value to trigger the alarm.
*
* @param hal Context of the HAL layer
* @param alarm_value Counter value to trigger the alarm
*
* @return None
*/
#define timer_hal_set_alarm_value(hal, alarm_value) timer_ll_set_alarm_value((hal)->dev, (hal)->idx, alarm_value)
/**
* @brief Get the counter value to trigger the alarm.
*
* @param hal Context of the HAL layer
* @param alarm_value Pointer to accept the counter value to trigger the alarm
*
* @return None
*/
#define timer_hal_get_alarm_value(hal, alarm_value) timer_ll_get_alarm_value((hal)->dev, (hal)->idx, alarm_value)
/**
* @brief Set the alarm status, enable or disable the alarm.
*
* @param hal Context of the HAL layer
* @param alarm_en True to enable alarm, false to disable alarm
*
* @return None
*/
#define timer_hal_set_alarm_enable(hal, alarm_en) timer_ll_set_alarm_enable((hal)->dev, (hal)->idx, alarm_en)
/**
* @brief Get the alarm status.
*
* @param hal Context of the HAL layer
*
* @return
* - true Enable alarm
* - false Disable alarm
*/
#define timer_hal_get_alarm_enable(hal) timer_ll_get_alarm_enable((hal)->dev, (hal)->idx)
/**
* @brief Set the level interrupt status, enable or disable the level interrupt.
*
* @param hal Context of the HAL layer
* @param level_int_en True to enable level interrupt, false to disable level interrupt
*
* @return None
*/
#define timer_hal_set_level_int_enable(hal, level_int_en) timer_ll_set_level_int_enable((hal)->dev, (hal)->idx, level_int_en)
/**
* @brief Get the level interrupt status.
*
* @param hal Context of the HAL layer
*
* @return
* - true Enable level interrupt
* - false Disable level interrupt
*/
#define timer_hal_get_level_int_enable(hal) timer_ll_get_level_int_enable((hal)->dev, (hal)->idx)
/**
* @brief Set the edge interrupt status, enable or disable the edge interrupt.
*
* @param hal Context of the HAL layer
* @param edge_int_en True to enable edge interrupt, false to disable edge interrupt
*
* @return None
*/
#define timer_hal_set_edge_int_enable(hal, edge_int_en) timer_ll_set_edge_int_enable((hal)->dev, (hal)->idx, edge_int_en)
/**
* @brief Get the edge interrupt status.
*
* @param hal Context of the HAL layer
*
* @return
* - true Enable edge interrupt
* - false Disable edge interrupt
*/
#define timer_hal_get_edge_int_enable(hal) timer_ll_get_edge_int_enable((hal)->dev, (hal)->idx)
/**
* @brief Enable timer interrupt.
*
* @param hal Context of the HAL layer
*
* @return None
*/
#define timer_hal_intr_enable(hal) timer_ll_intr_enable((hal)->dev, (hal)->idx)
/**
* @brief Disable timer interrupt.
*
* @param hal Context of the HAL layer
*
* @return None
*/
#define timer_hal_intr_disable(hal) timer_ll_intr_disable((hal)->dev, (hal)->idx)
/**
* @brief Clear interrupt status.
*
* @param hal Context of the HAL layer
*
* @return None
*/
#define timer_hal_clear_intr_status(hal) timer_ll_clear_intr_status((hal)->dev, (hal)->idx)
/**
* @brief Get interrupt status.
*
* @param hal Context of the HAL layer
* @param intr_status Interrupt status
*
* @return None
*/
#define timer_hal_get_intr_status(hal, intr_status) timer_ll_get_intr_status((hal)->dev, intr_status)
/**
* @brief Get interrupt raw status.
*
* @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
* @param intr_raw_status Interrupt raw status
*
* @return None
*/
#define timer_hal_get_intr_raw_status(group_num, intr_raw_status) timer_ll_get_intr_raw_status(group_num, intr_raw_status)
/**
* @brief Get interrupt status register address.
*
* @param hal Context of the HAL layer
*
* @return Interrupt status register address
*/
#define timer_hal_get_intr_status_reg(hal) timer_ll_get_intr_status_reg((hal)->dev)
#if SOC_TIMER_GROUP_SUPPORT_XTAL
/**
* @brief Set clock source.
*
* @param hal Context of the HAL layer
* @param use_xtal_en True to use XTAL clock, flase to use APB clock
*
* @return None
*/
#define timer_hal_set_use_xtal(hal, use_xtal_en) timer_ll_set_use_xtal((hal)->dev, (hal)->idx, use_xtal_en)
/**
* @brief Get clock source.
*
* @param hal Context of the HAL layer
*
* @return
* - true Use XTAL clock
* - false Use APB clock
*/
#define timer_hal_get_use_xtal(hal) timer_ll_get_use_xtal((hal)->dev, (hal)->idx)
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,16 +1,8 @@
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once #pragma once
@ -18,117 +10,39 @@
extern "C" { extern "C" {
#endif #endif
#include <stdint.h>
#include <stdbool.h>
#include <esp_bit_defs.h>
#include "esp_attr.h"
#include "soc/soc_caps.h"
/** /**
* @brief Selects a Timer-Group out of 2 available groups * @brief GPTimer clock source
* @note The clock source listed here is not supported on all targets
* @note User should select the clock source based on real requirements:
*
* GPTimer clock source Features Power Management
*
* GPTIMER_CLK_SRC_APB High resolution ESP_PM_APB_FREQ_MAX lock
*
* GPTIMER_CLK_SRC_XTAL Medium resolution, high accuracy No PM lock
*
*/ */
typedef enum { typedef enum {
TIMER_GROUP_0 = 0, /*!<Hw timer group 0*/ GPTIMER_CLK_SRC_APB, /*!< Select APB as the source clock */
#if SOC_TIMER_GROUPS > 1 GPTIMER_CLK_SRC_XTAL, /*!< Select XTAL as the source clock */
TIMER_GROUP_1 = 1, /*!<Hw timer group 1*/ } gptimer_clock_source_t;
#endif
TIMER_GROUP_MAX,
} timer_group_t;
/** /**
* @brief Select a hardware timer from timer groups * @brief GPTimer count direction
*/ */
typedef enum { typedef enum {
TIMER_0 = 0, /*!<Select timer0 of GROUPx*/ GPTIMER_COUNT_DOWN, /*!< Decrease count value */
#if SOC_TIMER_GROUP_TIMERS_PER_GROUP > 1 GPTIMER_COUNT_UP, /*!< Increase count value */
TIMER_1 = 1, /*!<Select timer1 of GROUPx*/ } gptimer_count_direction_t;
#endif
TIMER_MAX,
} timer_idx_t;
/** /**
* @brief Decides the direction of counter * @brief GPTimer actions on alarm event
*/ */
typedef enum { typedef enum {
TIMER_COUNT_DOWN = 0, /*!< Descending Count from cnt.high|cnt.low*/ GPTIMER_ALARM_ACTION_CONTINUE, /*!< Counter will pass through the alarm point and continue counting */
TIMER_COUNT_UP = 1, /*!< Ascending Count from Zero*/ GPTIMER_ALARM_ACTION_STOP, /*!< Counter will stop on alarm event */
TIMER_COUNT_MAX GPTIMER_ALARM_ACTION_RELOAD, /*!< Counter will do reload on alarm event */
} timer_count_dir_t; } gptimer_alarm_action_t;
/**
* @brief Decides whether timer is on or paused
*/
typedef enum {
TIMER_PAUSE = 0, /*!<Pause timer counter*/
TIMER_START = 1, /*!<Start timer counter*/
} 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 */
#if SOC_TIMER_GROUP_TIMERS_PER_GROUP > 1
TIMER_INTR_T1 = BIT(1), /*!< interrupt of timer 1 */
TIMER_INTR_WDT = BIT(2), /*!< interrupt of watchdog */
#else
TIMER_INTR_WDT = BIT(1), /*!< interrupt of watchdog */
#endif
TIMER_INTR_NONE = 0
} timer_intr_t;
FLAG_ATTR(timer_intr_t)
/**
* @brief Decides whether to enable alarm mode
*/
typedef enum {
TIMER_ALARM_DIS = 0, /*!< Disable timer alarm*/
TIMER_ALARM_EN = 1, /*!< Enable timer alarm*/
TIMER_ALARM_MAX
} timer_alarm_t;
/**
* @brief Select interrupt type if running in alarm mode.
*/
typedef enum {
TIMER_INTR_LEVEL = 0, /*!< Interrupt mode: level mode*/
TIMER_INTR_MAX
} timer_intr_mode_t;
/**
* @brief Select if Alarm needs to be loaded by software or automatically reload by hardware.
*/
typedef enum {
TIMER_AUTORELOAD_DIS = 0, /*!< Disable auto-reload: hardware will not load counter value after an alarm event*/
TIMER_AUTORELOAD_EN = 1, /*!< Enable auto-reload: hardware will load counter value after an alarm event*/
TIMER_AUTORELOAD_MAX,
} timer_autoreload_t;
#if SOC_TIMER_GROUP_SUPPORT_XTAL
/**
* @brief Select timer source clock.
*/
typedef enum {
TIMER_SRC_CLK_APB = 0, /*!< Select APB as the source clock*/
TIMER_SRC_CLK_XTAL = 1, /*!< Select XTAL as the source clock*/
} timer_src_clk_t;
#endif
/**
* @brief Data structure with timer's configuration settings
*/
typedef struct {
timer_alarm_t alarm_en; /*!< Timer alarm enable */
timer_start_t counter_en; /*!< Counter enable */
timer_intr_mode_t intr_type; /*!< Interrupt mode */
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. */
#if SOC_TIMER_GROUP_SUPPORT_XTAL
timer_src_clk_t clk_src; /*!< Use XTAL as source clock. */
#endif
} timer_config_t;
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,35 +1,24 @@
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "esp_attr.h"
#include "hal/timer_hal.h" #include "hal/timer_hal.h"
#include "hal/timer_ll.h"
void timer_hal_init(timer_hal_context_t *hal, timer_group_t group_num, timer_idx_t timer_num) 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->dev = TIMER_LL_GET_HW(group_num);
hal->idx = timer_num; hal->timer_id = timer_num;
} }
void timer_hal_get_status_reg_mask_bit(timer_hal_context_t *hal, uint32_t *status_reg, uint32_t *mask_bit) void timer_hal_set_counter_value(timer_hal_context_t *hal, uint64_t load_val)
{ {
*status_reg = timer_ll_get_intr_status_reg(hal->dev); // save current reload value
*mask_bit = timer_ll_get_intr_mask_bit(hal->dev, hal->idx); uint64_t old_reload = timer_ll_get_reload_value(hal->dev, hal->timer_id);
} timer_ll_set_reload_value(hal->dev, hal->timer_id, load_val);
timer_ll_trigger_soft_reload(hal->dev, hal->timer_id);
void timer_hal_reset_periph(timer_hal_context_t *hal) // restore the previous reload value
{ timer_ll_set_reload_value(hal->dev, hal->timer_id, old_reload);
timer_ll_intr_disable(hal->dev, hal->idx);
timer_ll_set_counter_enable(hal->dev, hal->idx, TIMER_PAUSE);
timer_ll_set_counter_value(hal->dev, hal->idx, 0ULL);
} }

View File

@ -1,20 +1,17 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD /**
// * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
#pragma once
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef __TIMG_REG_H__
#define __TIMG_REG_H__
#include "soc.h" #include "soc.h"
#ifdef __cplusplus
extern "C" {
#endif
/* The value that needs to be written to TIMG_WDT_WKEY to write-enable the wdt registers */ /* The value that needs to be written to TIMG_WDT_WKEY to write-enable the wdt registers */
#define TIMG_WDT_WKEY_VALUE 0x50D83AA1 #define TIMG_WDT_WKEY_VALUE 0x50D83AA1
@ -669,7 +666,6 @@
#define TIMG_CLK_EN_V 0x1 #define TIMG_CLK_EN_V 0x1
#define TIMG_CLK_EN_S 31 #define TIMG_CLK_EN_S 31
#ifdef __cplusplus
}
#endif
#endif /*__TIMG_REG_H__ */

View File

@ -1,207 +1,743 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD /**
// * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
#pragma once
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _SOC_TIMG_STRUCT_H_
#define _SOC_TIMG_STRUCT_H_
#include <stdint.h> #include <stdint.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
typedef volatile struct timg_dev_s { /** Group: Configuration and Control Register */
/** Type of txconfig register
* Timer x configuration register
*/
typedef union {
struct { struct {
union { uint32_t reserved_0: 10;
struct { /** tx_alarm_en : R/W; bitpos: [10]; default: 0;
uint32_t reserved0: 10; * When set, the alarm is enabled. This bit is automatically cleared once an
uint32_t alarm_en: 1; /*When set alarm is enabled*/ *
uint32_t level_int_en: 1; /*When set level type interrupt will be generated during alarm*/ * alarm occurs.
uint32_t edge_int_en: 1; /*When set edge type interrupt will be generated during alarm*/ */
uint32_t divider: 16; /*Timer clock (T0/1_clk) pre-scale value.*/ uint32_t tx_alarm_en: 1;
uint32_t autoreload: 1; /*When set timer 0/1 auto-reload at alarming is enabled*/ /** tx_level_int_en : R/W; bitpos: [11]; default: 0;
uint32_t increase: 1; /*When set timer 0/1 time-base counter increment. When cleared timer 0 time-base counter decrement.*/ * When set, an alarm will generate a level type interrupt.
uint32_t enable: 1; /*When set timer 0/1 time-base counter is enabled*/ */
}; uint32_t tx_level_int_en: 1;
uint32_t val; /** tx_edge_int_en : R/W; bitpos: [12]; default: 0;
} config; * When set, an alarm will generate an edge type interrupt.
uint32_t cnt_low; /*Register to store timer 0/1 time-base counter current value lower 32 bits.*/ */
uint32_t cnt_high; /*Register to store timer 0 time-base counter current value higher 32 bits.*/ uint32_t tx_edge_int_en: 1;
uint32_t update; /*Write any value will trigger a timer 0 time-base counter value update (timer 0 current value will be stored in registers above)*/ /** tx_divider : R/W; bitpos: [28:13]; default: 1;
uint32_t alarm_low; /*Timer 0 time-base counter value lower 32 bits that will trigger the alarm*/ * Timer x clock (Tx_clk) prescaler value.
uint32_t alarm_high; /*Timer 0 time-base counter value higher 32 bits that will trigger the alarm*/ */
uint32_t load_low; /*Lower 32 bits of the value that will load into timer 0 time-base counter*/ uint32_t tx_divider: 16;
uint32_t load_high; /*higher 32 bits of the value that will load into timer 0 time-base counter*/ /** tx_autoreload : R/W; bitpos: [29]; default: 1;
uint32_t reload; /*Write any value will trigger timer 0 time-base counter reload*/ * When set, timer x auto-reload at alarm is enabled.
} hw_timer[2]; */
union { uint32_t tx_autoreload: 1;
struct { /** tx_increase : R/W; bitpos: [30]; default: 1;
uint32_t reserved0: 14; * When set, the timer x time-base counter will increment every clock tick. When
uint32_t flashboot_mod_en: 1; /*When set flash boot protection is enabled*/ *
uint32_t sys_reset_length: 3; /*length of system reset selection. 0: 100ns 1: 200ns 2: 300ns 3: 400ns 4: 500ns 5: 800ns 6: 1.6us 7: 3.2us*/ * cleared, the timer x time-base counter will decrement.
uint32_t cpu_reset_length: 3; /*length of CPU reset selection. 0: 100ns 1: 200ns 2: 300ns 3: 400ns 4: 500ns 5: 800ns 6: 1.6us 7: 3.2us*/ */
uint32_t level_int_en: 1; /*When set level type interrupt generation is enabled*/ uint32_t tx_increase: 1;
uint32_t edge_int_en: 1; /*When set edge type interrupt generation is enabled*/ /** tx_en : R/W; bitpos: [31]; default: 0;
uint32_t stg3: 2; /*Stage 3 configuration. 0: off 1: interrupt 2: reset CPU 3: reset system*/ * When set, the timer x time-base counter is enabled.
uint32_t stg2: 2; /*Stage 2 configuration. 0: off 1: interrupt 2: reset CPU 3: reset system*/ */
uint32_t stg1: 2; /*Stage 1 configuration. 0: off 1: interrupt 2: reset CPU 3: reset system*/ uint32_t tx_en: 1;
uint32_t stg0: 2; /*Stage 0 configuration. 0: off 1: interrupt 2: reset CPU 3: reset system*/ };
uint32_t en: 1; /*When set SWDT is enabled*/ uint32_t val;
}; } timg_txconfig_reg_t;
uint32_t val;
} wdt_config0; /** Type of txlo register
union { * Timer x current value, low 32 bits
struct { */
uint32_t reserved0: 16; typedef union {
uint32_t clk_prescale:16; /*SWDT clock prescale value. Period = 12.5ns * value stored in this register*/ struct {
}; /** tx_lo : RO; bitpos: [31:0]; default: 0;
uint32_t val; * After writing to TIMG_TxUPDATE_REG, the low 32 bits of the time-base counter
} wdt_config1; *
uint32_t wdt_config2; /*Stage 0 timeout value in SWDT clock cycles*/ * of timer x can be read here.
uint32_t wdt_config3; /*Stage 1 timeout value in SWDT clock cycles*/ */
uint32_t wdt_config4; /*Stage 2 timeout value in SWDT clock cycles*/ uint32_t tx_lo: 32;
uint32_t wdt_config5; /*Stage 3 timeout value in SWDT clock cycles*/ };
uint32_t wdt_feed; /*Write any value will feed SWDT*/ uint32_t val;
uint32_t wdt_wprotect; /*If change its value from default then write protection is on.*/ } timg_txlo_reg_t;
union {
struct { /** Type of txhi register
uint32_t reserved0: 12; * Timer x current value, high 32 bits
uint32_t start_cycling: 1; */
uint32_t clk_sel: 2; typedef union {
uint32_t rdy: 1; struct {
uint32_t max: 15; /** tx_hi : RO; bitpos: [31:0]; default: 0;
uint32_t start: 1; * After writing to TIMG_TxUPDATE_REG, the high 32 bits of the time-base counter
}; *
uint32_t val; * of timer x can be read here.
} rtc_cali_cfg; */
union { uint32_t tx_hi: 32;
struct { };
uint32_t reserved0: 7; uint32_t val;
uint32_t value:25; } timg_txhi_reg_t;
};
uint32_t val; /** Type of txupdate register
} rtc_cali_cfg1; * Write to copy current timer value to TIMGn_Tx_(LO/HI)_REG
union { */
struct { typedef union {
uint32_t reserved0: 7; struct {
uint32_t rtc_only: 1; uint32_t reserved_0: 31;
uint32_t cpst_en: 1; /** tx_update : R/W; bitpos: [31]; default: 0;
uint32_t lac_en: 1; * After writing 0 or 1 to TIMG_TxUPDATE_REG, the counter value is latched.
uint32_t alarm_en: 1; */
uint32_t level_int_en: 1; uint32_t tx_update: 1;
uint32_t edge_int_en: 1; };
uint32_t divider: 16; uint32_t val;
uint32_t autoreload: 1; } timg_txupdate_reg_t;
uint32_t increase: 1;
uint32_t en: 1; /** Type of txalarmlo register
}; * Timer x alarm value, low 32 bits
uint32_t val; */
} lactconfig; typedef union {
union { struct {
struct { /** tx_alarm_lo : R/W; bitpos: [31:0]; default: 0;
uint32_t reserved0: 6; * Timer x alarm trigger time-base counter value, low 32 bits.
uint32_t step_len:26; */
}; uint32_t tx_alarm_lo: 32;
uint32_t val; };
} lactrtc; uint32_t val;
uint32_t lactlo; /**/ } timg_txalarmlo_reg_t;
uint32_t lacthi; /**/
uint32_t lactupdate; /**/ /** Type of txalarmhi register
uint32_t lactalarmlo; /**/ * Timer x alarm value, high bits
uint32_t lactalarmhi; /**/ */
uint32_t lactloadlo; /**/ typedef union {
uint32_t lactloadhi; /**/ struct {
uint32_t lactload; /**/ /** tx_alarm_hi : R/W; bitpos: [31:0]; default: 0;
union { *
struct { *
uint32_t t0: 1; /*interrupt when timer0 alarm*/ * Timer x alarm trigger time-base counter value, high 32 bits.
uint32_t t1: 1; /*interrupt when timer1 alarm*/ */
uint32_t wdt: 1; /*Interrupt when an interrupt stage timeout*/ uint32_t tx_alarm_hi: 32;
uint32_t lact: 1; };
uint32_t reserved4: 28; uint32_t val;
}; } timg_txalarmhi_reg_t;
uint32_t val;
} int_ena; /** Type of txloadlo register
union { * Timer x reload value, low 32 bits
struct { */
uint32_t t0: 1; /*interrupt when timer0 alarm*/ typedef union {
uint32_t t1: 1; /*interrupt when timer1 alarm*/ struct {
uint32_t wdt: 1; /*Interrupt when an interrupt stage timeout*/ /** tx_load_lo : R/W; bitpos: [31:0]; default: 0;
uint32_t lact: 1; *
uint32_t reserved4:28; *
}; * Low 32 bits of the value that a reload will load onto timer x time-base
uint32_t val; *
} int_raw; * Counter.
union { */
struct { uint32_t tx_load_lo: 32;
uint32_t t0: 1; /*interrupt when timer0 alarm*/ };
uint32_t t1: 1; /*interrupt when timer1 alarm*/ uint32_t val;
uint32_t wdt: 1; /*Interrupt when an interrupt stage timeout*/ } timg_txloadlo_reg_t;
uint32_t lact: 1;
uint32_t reserved4: 28; /** Type of txloadhi register
}; * Timer x reload value, high 32 bits
uint32_t val; */
} int_st_timers; typedef union {
union { struct {
struct { /** tx_load_hi : R/W; bitpos: [31:0]; default: 0;
uint32_t t0: 1; /*interrupt when timer0 alarm*/ *
uint32_t t1: 1; /*interrupt when timer1 alarm*/ *
uint32_t wdt: 1; /*Interrupt when an interrupt stage timeout*/ * High 32 bits of the value that a reload will load onto timer x time-base
uint32_t lact: 1; *
uint32_t reserved4: 28; * counter.
}; */
uint32_t val; uint32_t tx_load_hi: 32;
} int_clr_timers; };
uint32_t reserved_a8; uint32_t val;
uint32_t reserved_ac; } timg_txloadhi_reg_t;
uint32_t reserved_b0;
uint32_t reserved_b4; /** Type of txload register
uint32_t reserved_b8; * Write to reload timer from TIMG_T0_(LOADLOLOADHI)_REG
uint32_t reserved_bc; */
uint32_t reserved_c0; typedef union {
uint32_t reserved_c4; struct {
uint32_t reserved_c8; /** tx_load : WO; bitpos: [31:0]; default: 0;
uint32_t reserved_cc; *
uint32_t reserved_d0; *
uint32_t reserved_d4; * Write any value to trigger a timer x time-base counter reload.
uint32_t reserved_d8; */
uint32_t reserved_dc; uint32_t tx_load: 32;
uint32_t reserved_e0; };
uint32_t reserved_e4; uint32_t val;
uint32_t reserved_e8; } timg_txload_reg_t;
uint32_t reserved_ec;
uint32_t reserved_f0;
uint32_t reserved_f4; /** Group: Configuration and Control Register for WDT */
union { /** Type of wdtconfig0 register
struct { * Watchdog timer configuration register
uint32_t date:28; /*Version of this regfile*/ */
uint32_t reserved28: 4; typedef union {
}; struct {
uint32_t val; uint32_t reserved_0: 14;
} timg_date; /** wdt_flashboot_mod_en : R/W; bitpos: [14]; default: 1;
union { * When set, Flash boot protection is enabled.
struct { */
uint32_t reserved0: 31; uint32_t wdt_flashboot_mod_en: 1;
uint32_t en: 1; /*Force clock enable for this regfile*/ /** wdt_sys_reset_length : R/W; bitpos: [17:15]; default: 1;
}; * System reset signal length selection. 0: 100 ns, 1: 200 ns,
uint32_t val; *
} clk; * 2: 300 ns, 3: 400 ns, 4: 500 ns, 5: 800 ns, 6: 1.6 us, 7: 3.2 us.
*/
uint32_t wdt_sys_reset_length: 3;
/** wdt_cpu_reset_length : R/W; bitpos: [20:18]; default: 1;
* CPU reset signal length selection. 0: 100 ns, 1: 200 ns,
*
* 2: 300 ns, 3: 400 ns, 4: 500 ns, 5: 800 ns, 6: 1.6 us, 7: 3.2 us.
*/
uint32_t wdt_cpu_reset_length: 3;
/** wdt_level_int_en : R/W; bitpos: [21]; default: 0;
* When set, a level type interrupt will occur at the timeout of a stage
*
* configured to generate an interrupt.
*/
uint32_t wdt_level_int_en: 1;
/** wdt_edge_int_en : R/W; bitpos: [22]; default: 0;
* When set, an edge type interrupt will occur at the timeout of a stage
*
* configured to generate an interrupt.
*/
uint32_t wdt_edge_int_en: 1;
/** wdt_stg3 : R/W; bitpos: [24:23]; default: 0;
* Stage 3 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
*
*/
uint32_t wdt_stg3: 2;
/** wdt_stg2 : R/W; bitpos: [26:25]; default: 0;
* Stage 2 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
*
*/
uint32_t wdt_stg2: 2;
/** wdt_stg1 : R/W; bitpos: [28:27]; default: 0;
* Stage 1 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
*
*/
uint32_t wdt_stg1: 2;
/** wdt_stg0 : R/W; bitpos: [30:29]; default: 0;
* Stage 0 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
*
*/
uint32_t wdt_stg0: 2;
/** wdt_en : R/W; bitpos: [31]; default: 0;
* When set, MWDT is enabled.
*/
uint32_t wdt_en: 1;
};
uint32_t val;
} timg_wdtconfig0_reg_t;
/** Type of wdtconfig1 register
* Watchdog timer prescaler register
*/
typedef union {
struct {
uint32_t reserved_0: 16;
/** wdt_clk_prescaler : R/W; bitpos: [31:16]; default: 1;
* MWDT clock prescaler value. MWDT clock period = 12.5 ns *
*
* TIMG_WDT_CLK_PRESCALE.
*/
uint32_t wdt_clk_prescaler: 16;
};
uint32_t val;
} timg_wdtconfig1_reg_t;
/** Type of wdtconfig2 register
* Watchdog timer stage 0 timeout value
*/
typedef union {
struct {
/** wdt_stg0_hold : R/W; bitpos: [31:0]; default: 26000000;
* Stage 0 timeout value, in MWDT clock cycles.
*/
uint32_t wdt_stg0_hold: 32;
};
uint32_t val;
} timg_wdtconfig2_reg_t;
/** Type of wdtconfig3 register
* Watchdog timer stage 1 timeout value
*/
typedef union {
struct {
/** wdt_stg1_hold : R/W; bitpos: [31:0]; default: 134217727;
* Stage 1 timeout value, in MWDT clock cycles.
*/
uint32_t wdt_stg1_hold: 32;
};
uint32_t val;
} timg_wdtconfig3_reg_t;
/** Type of wdtconfig4 register
* Watchdog timer stage 2 timeout value
*/
typedef union {
struct {
/** wdt_stg2_hold : R/W; bitpos: [31:0]; default: 1048575;
* Stage 2 timeout value, in MWDT clock cycles.
*/
uint32_t wdt_stg2_hold: 32;
};
uint32_t val;
} timg_wdtconfig4_reg_t;
/** Type of wdtconfig5 register
* Watchdog timer stage 3 timeout value
*/
typedef union {
struct {
/** wdt_stg3_hold : R/W; bitpos: [31:0]; default: 1048575;
* Stage 3 timeout value, in MWDT clock cycles.
*/
uint32_t wdt_stg3_hold: 32;
};
uint32_t val;
} timg_wdtconfig5_reg_t;
/** Type of wdtfeed register
* Write to feed the watchdog timer
*/
typedef union {
struct {
/** wdt_feed : WO; bitpos: [31:0]; default: 0;
* Write any value to feed the MWDT. (WO)
*/
uint32_t wdt_feed: 32;
};
uint32_t val;
} timg_wdtfeed_reg_t;
/** Type of wdtwprotect register
* Watchdog write protect register
*/
typedef union {
struct {
/** wdt_wkey : R/W; bitpos: [31:0]; default: 1356348065;
* If the register contains a different value than its reset value, write
*
* protection is enabled.
*/
uint32_t wdt_wkey: 32;
};
uint32_t val;
} timg_wdtwprotect_reg_t;
/** Group: Configuration and Control Register for RTC CALI */
/** Type of rtccalicfg register
* RTC calibration configuration register
*/
typedef union {
struct {
uint32_t reserved_0: 12;
/** rtc_cali_start_cycling : R/W; bitpos: [12]; default: 1;
* Reserved
*/
uint32_t rtc_cali_start_cycling: 1;
/** rtc_cali_clk_sel : R/W; bitpos: [14:13]; default: 1;
* 0:rtcslowclock. 1:clk_80m. 2:xtal_32k.
*/
uint32_t rtc_cali_clk_sel: 2;
/** rtc_cali_rdy : RO; bitpos: [15]; default: 0;
* Reserved
*/
uint32_t rtc_cali_rdy: 1;
/** rtc_cali_max : R/W; bitpos: [30:16]; default: 1;
* Reserved
*/
uint32_t rtc_cali_max: 15;
/** rtc_cali_start : R/W; bitpos: [31]; default: 0;
* Reserved
*/
uint32_t rtc_cali_start: 1;
};
uint32_t val;
} timg_rtccalicfg_reg_t;
/** Type of rtccalicfg1 register
* RTC calibration configuration1 register
*/
typedef union {
struct {
uint32_t reserved_0: 7;
/** rtc_cali_value : RO; bitpos: [31:7]; default: 0;
* Reserved
*/
uint32_t rtc_cali_value: 25;
};
uint32_t val;
} timg_rtccalicfg1_reg_t;
/** Group: Configuration and Control Register for LACT */
/** Type of lactconfig register
* LACT configuration register
*/
typedef union {
struct {
uint32_t reserved_0: 7;
/** lact_rtc_only : R/W; bitpos: [7]; default: 0;
* Reserved
*/
uint32_t lact_rtc_only: 1;
/** lact_cpst_en : R/W; bitpos: [8]; default: 1;
* Reserved
*/
uint32_t lact_cpst_en: 1;
/** lact_lac_en : R/W; bitpos: [9]; default: 1;
* Reserved
*/
uint32_t lact_lac_en: 1;
/** lact_alarm_en : R/W; bitpos: [10]; default: 0;
* Reserved
*/
uint32_t lact_alarm_en: 1;
/** lact_level_int_en : R/W; bitpos: [11]; default: 0;
* Reserved
*/
uint32_t lact_level_int_en: 1;
/** lact_edge_int_en : R/W; bitpos: [12]; default: 0;
* Reserved
*/
uint32_t lact_edge_int_en: 1;
/** lact_divider : R/W; bitpos: [28:13]; default: 1;
* Reserved
*/
uint32_t lact_divider: 16;
/** lact_autoreload : R/W; bitpos: [29]; default: 1;
* Reserved
*/
uint32_t lact_autoreload: 1;
/** lact_increase : R/W; bitpos: [30]; default: 1;
* Reserved
*/
uint32_t lact_increase: 1;
/** lact_en : R/W; bitpos: [31]; default: 0;
* Reserved
*/
uint32_t lact_en: 1;
};
uint32_t val;
} timg_lactconfig_reg_t;
/** Type of lactrtc register
* LACT RTC register
*/
typedef union {
struct {
uint32_t reserved_0: 6;
/** lact_rtc_step_len : R/W; bitpos: [31:6]; default: 0;
* Reserved
*/
uint32_t lact_rtc_step_len: 26;
};
uint32_t val;
} timg_lactrtc_reg_t;
/** Type of lactlo register
* LACT low register
*/
typedef union {
struct {
/** lact_lo : RO; bitpos: [31:0]; default: 0;
* Reserved
*/
uint32_t lact_lo: 32;
};
uint32_t val;
} timg_lactlo_reg_t;
/** Type of lacthi register
* LACT high register
*/
typedef union {
struct {
/** lact_hi : RO; bitpos: [31:0]; default: 0;
* Reserved
*/
uint32_t lact_hi: 32;
};
uint32_t val;
} timg_lacthi_reg_t;
/** Type of lactupdate register
* LACT update register
*/
typedef union {
struct {
/** lact_update : WO; bitpos: [31:0]; default: 0;
* Reserved
*/
uint32_t lact_update: 32;
};
uint32_t val;
} timg_lactupdate_reg_t;
/** Type of lactalarmlo register
* LACT alarm low register
*/
typedef union {
struct {
/** lact_alarm_lo : R/W; bitpos: [31:0]; default: 0;
* Reserved
*/
uint32_t lact_alarm_lo: 32;
};
uint32_t val;
} timg_lactalarmlo_reg_t;
/** Type of lactalarmhi register
* LACT alarm high register
*/
typedef union {
struct {
/** lact_alarm_hi : R/W; bitpos: [31:0]; default: 0;
* Reserved
*/
uint32_t lact_alarm_hi: 32;
};
uint32_t val;
} timg_lactalarmhi_reg_t;
/** Type of lactloadlo register
* LACT load low register
*/
typedef union {
struct {
/** lact_load_lo : R/W; bitpos: [31:0]; default: 0;
* Reserved
*/
uint32_t lact_load_lo: 32;
};
uint32_t val;
} timg_lactloadlo_reg_t;
/** Type of lactloadhi register
* Timer LACT load high register
*/
typedef union {
struct {
/** lact_load_hi : R/W; bitpos: [31:0]; default: 0;
* Reserved
*/
uint32_t lact_load_hi: 32;
};
uint32_t val;
} timg_lactloadhi_reg_t;
/** Type of lactload register
* Timer LACT load register
*/
typedef union {
struct {
/** lact_load : WO; bitpos: [31:0]; default: 0;
* Reserved
*/
uint32_t lact_load: 32;
};
uint32_t val;
} timg_lactload_reg_t;
/** Group: Interrupt Register */
/** Type of int_ena_timers register
* Interrupt enable bits
*/
typedef union {
struct {
/** tx_int_ena : R/W; bitpos: [0]; default: 0;
* The interrupt enable bit for the TIMG_T0_INT interrupt.
*/
uint32_t t0_int_ena: 1;
/** t1_int_ena : R/W; bitpos: [1]; default: 0;
* The interrupt enable bit for the TIMG_T1_INT interrupt.
*/
uint32_t t1_int_ena: 1;
/** wdt_int_ena : R/W; bitpos: [2]; default: 0;
* The interrupt enable bit for the TIMG_WDT_INT interrupt.
*/
uint32_t wdt_int_ena: 1;
/** lact_int_ena : R/W; bitpos: [3]; default: 0;
* The interrupt enable bit for the TIMG_LACT_INT interrupt.
*/
uint32_t lact_int_ena: 1;
uint32_t reserved_4: 28;
};
uint32_t val;
} timg_int_ena_timers_reg_t;
/** Type of int_raw_timers register
* Raw interrupt status
*/
typedef union {
struct {
/** t0_int_raw : RO; bitpos: [0]; default: 0;
* The raw interrupt status bit for the TIMG_T0_INT interrupt.
*/
uint32_t t0_int_raw: 1;
/** t1_int_raw : RO; bitpos: [1]; default: 0;
* The raw interrupt status bit for the TIMG_T1_INT interrupt.
*/
uint32_t t1_int_raw: 1;
/** wdt_int_raw : RO; bitpos: [2]; default: 0;
* The raw interrupt status bit for the TIMG_WDT_INT interrupt.
*/
uint32_t wdt_int_raw: 1;
/** lact_int_raw : RO; bitpos: [3]; default: 0;
* The raw interrupt status bit for the TIMG_LACT_INT interrupt.
*/
uint32_t lact_int_raw: 1;
uint32_t reserved_4: 28;
};
uint32_t val;
} timg_int_raw_timers_reg_t;
/** Type of int_st_timers register
* Masked interrupt status
*/
typedef union {
struct {
/** t0_int_st : RO; bitpos: [0]; default: 0;
* The masked interrupt status bit for the TIMG_T0_INT interrupt.
*/
uint32_t t0_int_st: 1;
/** t1_int_st : RO; bitpos: [1]; default: 0;
* The masked interrupt status bit for the TIMG_T1_INT interrupt.
*/
uint32_t t1_int_st: 1;
/** wdt_int_st : RO; bitpos: [2]; default: 0;
* The masked interrupt status bit for the TIMG_WDT_INT interrupt.
*/
uint32_t wdt_int_st: 1;
/** lact_int_st : RO; bitpos: [3]; default: 0;
* The masked interrupt status bit for the TIMG_LACT_INT interrupt.
*/
uint32_t lact_int_st: 1;
uint32_t reserved_4: 28;
};
uint32_t val;
} timg_int_st_timers_reg_t;
/** Type of int_clr_timers register
* Interrupt clear bits
*/
typedef union {
struct {
/** t0_int_clr : WO; bitpos: [0]; default: 0;
* Set this bit to clear the TIMG_T0_INT interrupt.
*/
uint32_t t0_int_clr: 1;
/** t1_int_clr : WO; bitpos: [1]; default: 0;
* Set this bit to clear the TIMG_T1_INT interrupt.
*/
uint32_t t1_int_clr: 1;
/** wdt_int_clr : WO; bitpos: [2]; default: 0;
* Set this bit to clear the TIMG_WDT_INT interrupt.
*/
uint32_t wdt_int_clr: 1;
/** lact_int_clr : WO; bitpos: [3]; default: 0;
* Set this bit to clear the TIMG_LACT_INT interrupt.
*/
uint32_t lact_int_clr: 1;
uint32_t reserved_4: 28;
};
uint32_t val;
} timg_int_clr_timers_reg_t;
/** Group: Version Register */
/** Type of timers_date register
* Version control register
*/
typedef union {
struct {
/** timers_date : R/W; bitpos: [27:0]; default: 26243681;
* Version control register.
*/
uint32_t timers_date: 28;
uint32_t reserved_28: 4;
};
uint32_t val;
} timg_timers_date_reg_t;
/** Group: Configuration Register */
/** Type of regclk register
* Timer group clock gate register
*/
typedef union {
struct {
uint32_t reserved_0: 31;
/** clk_en : R/W; bitpos: [31]; default: 0;
* Register clock gate signal. 1: Registers can be read and written to by software. 0:
* Registers can not be read or written to by software.
*/
uint32_t clk_en: 1;
};
uint32_t val;
} timg_regclk_reg_t;
typedef struct {
volatile timg_txconfig_reg_t config;
volatile timg_txlo_reg_t lo;
volatile timg_txhi_reg_t hi;
volatile timg_txupdate_reg_t update;
volatile timg_txalarmlo_reg_t alarmlo;
volatile timg_txalarmhi_reg_t alarmhi;
volatile timg_txloadlo_reg_t loadlo;
volatile timg_txloadhi_reg_t loadhi;
volatile timg_txload_reg_t load;
} timg_hwtimer_reg_t;
typedef struct timg_dev_t {
volatile timg_hwtimer_reg_t hw_timer[2];
volatile timg_wdtconfig0_reg_t wdtconfig0;
volatile timg_wdtconfig1_reg_t wdtconfig1;
volatile timg_wdtconfig2_reg_t wdtconfig2;
volatile timg_wdtconfig3_reg_t wdtconfig3;
volatile timg_wdtconfig4_reg_t wdtconfig4;
volatile timg_wdtconfig5_reg_t wdtconfig5;
volatile timg_wdtfeed_reg_t wdtfeed;
volatile timg_wdtwprotect_reg_t wdtwprotect;
volatile timg_rtccalicfg_reg_t rtccalicfg;
volatile timg_rtccalicfg1_reg_t rtccalicfg1;
volatile timg_lactconfig_reg_t lactconfig;
volatile timg_lactrtc_reg_t lactrtc;
volatile timg_lactlo_reg_t lactlo;
volatile timg_lacthi_reg_t lacthi;
volatile timg_lactupdate_reg_t lactupdate;
volatile timg_lactalarmlo_reg_t lactalarmlo;
volatile timg_lactalarmhi_reg_t lactalarmhi;
volatile timg_lactloadlo_reg_t lactloadlo;
volatile timg_lactloadhi_reg_t lactloadhi;
volatile timg_lactload_reg_t lactload;
volatile timg_int_ena_timers_reg_t int_ena_timers;
volatile timg_int_raw_timers_reg_t int_raw_timers;
volatile timg_int_st_timers_reg_t int_st_timers;
volatile timg_int_clr_timers_reg_t int_clr_timers;
uint32_t reserved_0ac[20];
volatile timg_timers_date_reg_t timers_date;
volatile timg_regclk_reg_t regclk;
} timg_dev_t; } timg_dev_t;
extern timg_dev_t TIMERG0; extern timg_dev_t TIMERG0;
extern timg_dev_t TIMERG1; extern timg_dev_t TIMERG1;
#ifndef __cplusplus
_Static_assert(sizeof(timg_dev_t) == 0x100, "Invalid size of timg_dev_t structure");
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* _SOC_TIMG_STRUCT_H_ */

View File

@ -1,16 +1,8 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "soc/soc.h" #include "soc/soc.h"
#include "soc/timer_periph.h" #include "soc/timer_periph.h"
@ -19,11 +11,17 @@ const timer_group_signal_conn_t timer_group_periph_signals = {
.groups = { .groups = {
[0] = { [0] = {
.module = PERIPH_TIMG0_MODULE, .module = PERIPH_TIMG0_MODULE,
.t0_irq_id = ETS_TG0_T0_LEVEL_INTR_SOURCE .timer_irq_id = {
[0] = ETS_TG0_T0_LEVEL_INTR_SOURCE,
[1] = ETS_TG0_T1_LEVEL_INTR_SOURCE,
}
}, },
[1] = { [1] = {
.module = PERIPH_TIMG1_MODULE, .module = PERIPH_TIMG1_MODULE,
.t0_irq_id = ETS_TG1_T0_LEVEL_INTR_SOURCE, .timer_irq_id = {
[0] = ETS_TG1_T0_LEVEL_INTR_SOURCE,
[1] = ETS_TG1_T1_LEVEL_INTR_SOURCE,
}
} }
} }
}; };

View File

@ -1,5 +1,5 @@
/** /**
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -16,39 +16,39 @@ extern "C" {
*/ */
typedef union { typedef union {
struct { struct {
uint32_t reserved_0:9; uint32_t reserved_0: 9;
/** tx_use_xtal : R/W; bitpos: [9]; default: 0; /** tx_use_xtal : R/W; bitpos: [9]; default: 0;
* 1: Use XTAL_CLK as the source clock of timer group. 0: Use APB_CLK as the source * 1: Use XTAL_CLK as the source clock of timer group. 0: Use APB_CLK as the source
* clock of timer group. * clock of timer group.
*/ */
uint32_t tx_use_xtal:1; uint32_t tx_use_xtal: 1;
/** tx_alarm_en : R/W/SC; bitpos: [10]; default: 0; /** tx_alarm_en : R/W/SC; bitpos: [10]; default: 0;
* When set, the alarm is enabled. This bit is automatically cleared once an * When set, the alarm is enabled. This bit is automatically cleared once an
* alarm occurs. * alarm occurs.
*/ */
uint32_t tx_alarm_en:1; uint32_t tx_alarm_en: 1;
uint32_t reserved_11:1; uint32_t reserved_11: 1;
/** tx_divcnt_rst : WT; bitpos: [12]; default: 0; /** tx_divcnt_rst : WT; bitpos: [12]; default: 0;
* When set, Timer x 's clock divider counter will be reset. * When set, Timer x 's clock divider counter will be reset.
*/ */
uint32_t tx_divcnt_rst:1; uint32_t tx_divcnt_rst: 1;
/** tx_divider : R/W; bitpos: [28:13]; default: 1; /** tx_divider : R/W; bitpos: [28:13]; default: 1;
* Timer x clock (Tx_clk) prescaler value. * Timer x clock (Tx_clk) prescaler value.
*/ */
uint32_t tx_divider:16; uint32_t tx_divider: 16;
/** tx_autoreload : R/W; bitpos: [29]; default: 1; /** tx_autoreload : R/W; bitpos: [29]; default: 1;
* When set, timer x auto-reload at alarm is enabled. * When set, timer x auto-reload at alarm is enabled.
*/ */
uint32_t tx_autoreload:1; uint32_t tx_autoreload: 1;
/** tx_increase : R/W; bitpos: [30]; default: 1; /** tx_increase : R/W; bitpos: [30]; default: 1;
* When set, the timer x time-base counter will increment every clock tick. When * When set, the timer x time-base counter will increment every clock tick. When
* cleared, the timer x time-base counter will decrement. * cleared, the timer x time-base counter will decrement.
*/ */
uint32_t tx_increase:1; uint32_t tx_increase: 1;
/** tx_en : R/W; bitpos: [31]; default: 0; /** tx_en : R/W; bitpos: [31]; default: 0;
* When set, the timer x time-base counter is enabled. * When set, the timer x time-base counter is enabled.
*/ */
uint32_t tx_en:1; uint32_t tx_en: 1;
}; };
uint32_t val; uint32_t val;
} timg_txconfig_reg_t; } timg_txconfig_reg_t;
@ -62,7 +62,7 @@ typedef union {
* After writing to TIMG_TxUPDATE_REG, the low 32 bits of the time-base counter * After writing to TIMG_TxUPDATE_REG, the low 32 bits of the time-base counter
* of timer x can be read here. * of timer x can be read here.
*/ */
uint32_t tx_lo:32; uint32_t tx_lo: 32;
}; };
uint32_t val; uint32_t val;
} timg_txlo_reg_t; } timg_txlo_reg_t;
@ -76,8 +76,8 @@ typedef union {
* After writing to TIMG_T$xUPDATE_REG, the high 22 bits of the time-base counter * After writing to TIMG_T$xUPDATE_REG, the high 22 bits of the time-base counter
* of timer $x can be read here. * of timer $x can be read here.
*/ */
uint32_t tx_hi:22; uint32_t tx_hi: 22;
uint32_t reserved_22:10; uint32_t reserved_22: 10;
}; };
uint32_t val; uint32_t val;
} timg_txhi_reg_t; } timg_txhi_reg_t;
@ -87,11 +87,11 @@ typedef union {
*/ */
typedef union { typedef union {
struct { struct {
uint32_t reserved_0:31; uint32_t reserved_0: 31;
/** tx_update : R/W/SC; bitpos: [31]; default: 0; /** tx_update : R/W/SC; bitpos: [31]; default: 0;
* After writing 0 or 1 to TIMG_T$xUPDATE_REG, the counter value is latched. * After writing 0 or 1 to TIMG_T$xUPDATE_REG, the counter value is latched.
*/ */
uint32_t tx_update:1; uint32_t tx_update: 1;
}; };
uint32_t val; uint32_t val;
} timg_txupdate_reg_t; } timg_txupdate_reg_t;
@ -104,7 +104,7 @@ typedef union {
/** tx_alarm_lo : R/W; bitpos: [31:0]; default: 0; /** tx_alarm_lo : R/W; bitpos: [31:0]; default: 0;
* Timer $x alarm trigger time-base counter value, low 32 bits. * Timer $x alarm trigger time-base counter value, low 32 bits.
*/ */
uint32_t tx_alarm_lo:32; uint32_t tx_alarm_lo: 32;
}; };
uint32_t val; uint32_t val;
} timg_txalarmlo_reg_t; } timg_txalarmlo_reg_t;
@ -117,8 +117,8 @@ typedef union {
/** tx_alarm_hi : R/W; bitpos: [21:0]; default: 0; /** tx_alarm_hi : R/W; bitpos: [21:0]; default: 0;
* Timer $x alarm trigger time-base counter value, high 22 bits. * Timer $x alarm trigger time-base counter value, high 22 bits.
*/ */
uint32_t tx_alarm_hi:22; uint32_t tx_alarm_hi: 22;
uint32_t reserved_22:10; uint32_t reserved_22: 10;
}; };
uint32_t val; uint32_t val;
} timg_txalarmhi_reg_t; } timg_txalarmhi_reg_t;
@ -132,7 +132,7 @@ typedef union {
* Low 32 bits of the value that a reload will load onto timer $x time-base * Low 32 bits of the value that a reload will load onto timer $x time-base
* Counter. * Counter.
*/ */
uint32_t tx_load_lo:32; uint32_t tx_load_lo: 32;
}; };
uint32_t val; uint32_t val;
} timg_txloadlo_reg_t; } timg_txloadlo_reg_t;
@ -146,8 +146,8 @@ typedef union {
* High 22 bits of the value that a reload will load onto timer $x time-base * High 22 bits of the value that a reload will load onto timer $x time-base
* counter. * counter.
*/ */
uint32_t tx_load_hi:22; uint32_t tx_load_hi: 22;
uint32_t reserved_22:10; uint32_t reserved_22: 10;
}; };
uint32_t val; uint32_t val;
} timg_txloadhi_reg_t; } timg_txloadhi_reg_t;
@ -161,7 +161,7 @@ typedef union {
* *
* Write any value to trigger a timer $x time-base counter reload. * Write any value to trigger a timer $x time-base counter reload.
*/ */
uint32_t tx_load:32; uint32_t tx_load: 32;
}; };
uint32_t val; uint32_t val;
} timg_txload_reg_t; } timg_txload_reg_t;
@ -173,57 +173,57 @@ typedef union {
*/ */
typedef union { typedef union {
struct { struct {
uint32_t reserved_0:12; uint32_t reserved_0: 12;
/** wdt_appcpu_reset_en : R/W; bitpos: [12]; default: 0; /** wdt_appcpu_reset_en : R/W; bitpos: [12]; default: 0;
* WDT reset CPU enable. * WDT reset CPU enable.
*/ */
uint32_t wdt_appcpu_reset_en:1; uint32_t wdt_appcpu_reset_en: 1;
/** wdt_procpu_reset_en : R/W; bitpos: [13]; default: 0; /** wdt_procpu_reset_en : R/W; bitpos: [13]; default: 0;
* WDT reset CPU enable. * WDT reset CPU enable.
*/ */
uint32_t wdt_procpu_reset_en:1; uint32_t wdt_procpu_reset_en: 1;
/** wdt_flashboot_mod_en : R/W; bitpos: [14]; default: 1; /** wdt_flashboot_mod_en : R/W; bitpos: [14]; default: 1;
* When set, Flash boot protection is enabled. * When set, Flash boot protection is enabled.
*/ */
uint32_t wdt_flashboot_mod_en:1; uint32_t wdt_flashboot_mod_en: 1;
/** wdt_sys_reset_length : R/W; bitpos: [17:15]; default: 1; /** wdt_sys_reset_length : R/W; bitpos: [17:15]; default: 1;
* System reset signal length selection. 0: 100 ns, 1: 200 ns, * System reset signal length selection. 0: 100 ns, 1: 200 ns,
* 2: 300 ns, 3: 400 ns, 4: 500 ns, 5: 800 ns, 6: 1.6 us, 7: 3.2 us. * 2: 300 ns, 3: 400 ns, 4: 500 ns, 5: 800 ns, 6: 1.6 us, 7: 3.2 us.
*/ */
uint32_t wdt_sys_reset_length:3; uint32_t wdt_sys_reset_length: 3;
/** wdt_cpu_reset_length : R/W; bitpos: [20:18]; default: 1; /** wdt_cpu_reset_length : R/W; bitpos: [20:18]; default: 1;
* CPU reset signal length selection. 0: 100 ns, 1: 200 ns, * CPU reset signal length selection. 0: 100 ns, 1: 200 ns,
* 2: 300 ns, 3: 400 ns, 4: 500 ns, 5: 800 ns, 6: 1.6 us, 7: 3.2 us. * 2: 300 ns, 3: 400 ns, 4: 500 ns, 5: 800 ns, 6: 1.6 us, 7: 3.2 us.
*/ */
uint32_t wdt_cpu_reset_length:3; uint32_t wdt_cpu_reset_length: 3;
/** wdt_use_xtal : R/W; bitpos: [21]; default: 0; /** wdt_use_xtal : R/W; bitpos: [21]; default: 0;
* choose WDT clock:0-apb_clk; 1-xtal_clk. * choose WDT clock:0-apb_clk; 1-xtal_clk.
*/ */
uint32_t wdt_use_xtal:1; uint32_t wdt_use_xtal: 1;
/** wdt_conf_update_en : WT; bitpos: [22]; default: 0; /** wdt_conf_update_en : WT; bitpos: [22]; default: 0;
* update the WDT configuration registers * update the WDT configuration registers
*/ */
uint32_t wdt_conf_update_en:1; uint32_t wdt_conf_update_en: 1;
/** wdt_stg3 : R/W; bitpos: [24:23]; default: 0; /** wdt_stg3 : R/W; bitpos: [24:23]; default: 0;
* Stage 3 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system. * Stage 3 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
*/ */
uint32_t wdt_stg3:2; uint32_t wdt_stg3: 2;
/** wdt_stg2 : R/W; bitpos: [26:25]; default: 0; /** wdt_stg2 : R/W; bitpos: [26:25]; default: 0;
* Stage 2 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system. * Stage 2 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
*/ */
uint32_t wdt_stg2:2; uint32_t wdt_stg2: 2;
/** wdt_stg1 : R/W; bitpos: [28:27]; default: 0; /** wdt_stg1 : R/W; bitpos: [28:27]; default: 0;
* Stage 1 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system. * Stage 1 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
*/ */
uint32_t wdt_stg1:2; uint32_t wdt_stg1: 2;
/** wdt_stg0 : R/W; bitpos: [30:29]; default: 0; /** wdt_stg0 : R/W; bitpos: [30:29]; default: 0;
* Stage 0 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system. * Stage 0 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
*/ */
uint32_t wdt_stg0:2; uint32_t wdt_stg0: 2;
/** wdt_en : R/W; bitpos: [31]; default: 0; /** wdt_en : R/W; bitpos: [31]; default: 0;
* When set, MWDT is enabled. * When set, MWDT is enabled.
*/ */
uint32_t wdt_en:1; uint32_t wdt_en: 1;
}; };
uint32_t val; uint32_t val;
} timg_wdtconfig0_reg_t; } timg_wdtconfig0_reg_t;
@ -236,13 +236,13 @@ typedef union {
/** wdt_divcnt_rst : WT; bitpos: [0]; default: 0; /** wdt_divcnt_rst : WT; bitpos: [0]; default: 0;
* When set, WDT 's clock divider counter will be reset. * When set, WDT 's clock divider counter will be reset.
*/ */
uint32_t wdt_divcnt_rst:1; uint32_t wdt_divcnt_rst: 1;
uint32_t reserved_1:15; uint32_t reserved_1: 15;
/** wdt_clk_prescale : R/W; bitpos: [31:16]; default: 1; /** wdt_clk_prescale : R/W; bitpos: [31:16]; default: 1;
* MWDT clock prescaler value. MWDT clock period = 12.5 ns * * MWDT clock prescaler value. MWDT clock period = 12.5 ns *
* TIMG_WDT_CLK_PRESCALE. * TIMG_WDT_CLK_PRESCALE.
*/ */
uint32_t wdt_clk_prescale:16; uint32_t wdt_clk_prescale: 16;
}; };
uint32_t val; uint32_t val;
} timg_wdtconfig1_reg_t; } timg_wdtconfig1_reg_t;
@ -255,7 +255,7 @@ typedef union {
/** wdt_stg0_hold : R/W; bitpos: [31:0]; default: 26000000; /** wdt_stg0_hold : R/W; bitpos: [31:0]; default: 26000000;
* Stage 0 timeout value, in MWDT clock cycles. * Stage 0 timeout value, in MWDT clock cycles.
*/ */
uint32_t wdt_stg0_hold:32; uint32_t wdt_stg0_hold: 32;
}; };
uint32_t val; uint32_t val;
} timg_wdtconfig2_reg_t; } timg_wdtconfig2_reg_t;
@ -268,7 +268,7 @@ typedef union {
/** wdt_stg1_hold : R/W; bitpos: [31:0]; default: 134217727; /** wdt_stg1_hold : R/W; bitpos: [31:0]; default: 134217727;
* Stage 1 timeout value, in MWDT clock cycles. * Stage 1 timeout value, in MWDT clock cycles.
*/ */
uint32_t wdt_stg1_hold:32; uint32_t wdt_stg1_hold: 32;
}; };
uint32_t val; uint32_t val;
} timg_wdtconfig3_reg_t; } timg_wdtconfig3_reg_t;
@ -281,7 +281,7 @@ typedef union {
/** wdt_stg2_hold : R/W; bitpos: [31:0]; default: 1048575; /** wdt_stg2_hold : R/W; bitpos: [31:0]; default: 1048575;
* Stage 2 timeout value, in MWDT clock cycles. * Stage 2 timeout value, in MWDT clock cycles.
*/ */
uint32_t wdt_stg2_hold:32; uint32_t wdt_stg2_hold: 32;
}; };
uint32_t val; uint32_t val;
} timg_wdtconfig4_reg_t; } timg_wdtconfig4_reg_t;
@ -294,7 +294,7 @@ typedef union {
/** wdt_stg3_hold : R/W; bitpos: [31:0]; default: 1048575; /** wdt_stg3_hold : R/W; bitpos: [31:0]; default: 1048575;
* Stage 3 timeout value, in MWDT clock cycles. * Stage 3 timeout value, in MWDT clock cycles.
*/ */
uint32_t wdt_stg3_hold:32; uint32_t wdt_stg3_hold: 32;
}; };
uint32_t val; uint32_t val;
} timg_wdtconfig5_reg_t; } timg_wdtconfig5_reg_t;
@ -307,7 +307,7 @@ typedef union {
/** wdt_feed : WT; bitpos: [31:0]; default: 0; /** wdt_feed : WT; bitpos: [31:0]; default: 0;
* Write any value to feed the MWDT. (WO) * Write any value to feed the MWDT. (WO)
*/ */
uint32_t wdt_feed:32; uint32_t wdt_feed: 32;
}; };
uint32_t val; uint32_t val;
} timg_wdtfeed_reg_t; } timg_wdtfeed_reg_t;
@ -321,7 +321,7 @@ typedef union {
* If the register contains a different value than its reset value, write * If the register contains a different value than its reset value, write
* protection is enabled. * protection is enabled.
*/ */
uint32_t wdt_wkey:32; uint32_t wdt_wkey: 32;
}; };
uint32_t val; uint32_t val;
} timg_wdtwprotect_reg_t; } timg_wdtwprotect_reg_t;
@ -333,27 +333,27 @@ typedef union {
*/ */
typedef union { typedef union {
struct { struct {
uint32_t reserved_0:12; uint32_t reserved_0: 12;
/** rtc_cali_start_cycling : R/W; bitpos: [12]; default: 1; /** rtc_cali_start_cycling : R/W; bitpos: [12]; default: 1;
* Reserved * Reserved
*/ */
uint32_t rtc_cali_start_cycling:1; uint32_t rtc_cali_start_cycling: 1;
/** rtc_cali_clk_sel : R/W; bitpos: [14:13]; default: 1; /** rtc_cali_clk_sel : R/W; bitpos: [14:13]; default: 1;
* 0:rtc slow clock. 1:clk_8m, 2:xtal_32k. * 0:rtc slow clock. 1:clk_8m, 2:xtal_32k.
*/ */
uint32_t rtc_cali_clk_sel:2; uint32_t rtc_cali_clk_sel: 2;
/** rtc_cali_rdy : RO; bitpos: [15]; default: 0; /** rtc_cali_rdy : RO; bitpos: [15]; default: 0;
* Reserved * Reserved
*/ */
uint32_t rtc_cali_rdy:1; uint32_t rtc_cali_rdy: 1;
/** rtc_cali_max : R/W; bitpos: [30:16]; default: 1; /** rtc_cali_max : R/W; bitpos: [30:16]; default: 1;
* Reserved * Reserved
*/ */
uint32_t rtc_cali_max:15; uint32_t rtc_cali_max: 15;
/** rtc_cali_start : R/W; bitpos: [31]; default: 0; /** rtc_cali_start : R/W; bitpos: [31]; default: 0;
* Reserved * Reserved
*/ */
uint32_t rtc_cali_start:1; uint32_t rtc_cali_start: 1;
}; };
uint32_t val; uint32_t val;
} timg_rtccalicfg_reg_t; } timg_rtccalicfg_reg_t;
@ -366,12 +366,12 @@ typedef union {
/** rtc_cali_cycling_data_vld : RO; bitpos: [0]; default: 0; /** rtc_cali_cycling_data_vld : RO; bitpos: [0]; default: 0;
* Reserved * Reserved
*/ */
uint32_t rtc_cali_cycling_data_vld:1; uint32_t rtc_cali_cycling_data_vld: 1;
uint32_t reserved_1:6; uint32_t reserved_1: 6;
/** rtc_cali_value : RO; bitpos: [31:7]; default: 0; /** rtc_cali_value : RO; bitpos: [31:7]; default: 0;
* Reserved * Reserved
*/ */
uint32_t rtc_cali_value:25; uint32_t rtc_cali_value: 25;
}; };
uint32_t val; uint32_t val;
} timg_rtccalicfg1_reg_t; } timg_rtccalicfg1_reg_t;
@ -384,17 +384,17 @@ typedef union {
/** rtc_cali_timeout : RO; bitpos: [0]; default: 0; /** rtc_cali_timeout : RO; bitpos: [0]; default: 0;
* RTC calibration timeout indicator * RTC calibration timeout indicator
*/ */
uint32_t rtc_cali_timeout:1; uint32_t rtc_cali_timeout: 1;
uint32_t reserved_1:2; uint32_t reserved_1: 2;
/** rtc_cali_timeout_rst_cnt : R/W; bitpos: [6:3]; default: 3; /** rtc_cali_timeout_rst_cnt : R/W; bitpos: [6:3]; default: 3;
* Cycles that release calibration timeout reset * Cycles that release calibration timeout reset
*/ */
uint32_t rtc_cali_timeout_rst_cnt:4; uint32_t rtc_cali_timeout_rst_cnt: 4;
/** rtc_cali_timeout_thres : R/W; bitpos: [31:7]; default: 33554431; /** rtc_cali_timeout_thres : R/W; bitpos: [31:7]; default: 33554431;
* Threshold value for the RTC calibration timer. If the calibration timer's value * Threshold value for the RTC calibration timer. If the calibration timer's value
* exceeds this threshold, a timeout is triggered. * exceeds this threshold, a timeout is triggered.
*/ */
uint32_t rtc_cali_timeout_thres:25; uint32_t rtc_cali_timeout_thres: 25;
}; };
uint32_t val; uint32_t val;
} timg_rtccalicfg2_reg_t; } timg_rtccalicfg2_reg_t;
@ -409,12 +409,12 @@ typedef union {
/** t0_int_ena : R/W; bitpos: [0]; default: 0; /** t0_int_ena : R/W; bitpos: [0]; default: 0;
* The interrupt enable bit for the TIMG_T$x_INT interrupt. * The interrupt enable bit for the TIMG_T$x_INT interrupt.
*/ */
uint32_t t0_int_ena:1; uint32_t t0_int_ena: 1;
/** wdt_int_ena : R/W; bitpos: [1]; default: 0; /** wdt_int_ena : R/W; bitpos: [1]; default: 0;
* The interrupt enable bit for the TIMG_WDT_INT interrupt. * The interrupt enable bit for the TIMG_WDT_INT interrupt.
*/ */
uint32_t wdt_int_ena:1; uint32_t wdt_int_ena: 1;
uint32_t reserved_2:30; uint32_t reserved_2: 30;
}; };
uint32_t val; uint32_t val;
} timg_int_ena_timers_reg_t; } timg_int_ena_timers_reg_t;
@ -427,12 +427,12 @@ typedef union {
/** t0_int_raw : R/SS/WTC; bitpos: [0]; default: 0; /** t0_int_raw : R/SS/WTC; bitpos: [0]; default: 0;
* The raw interrupt status bit for the TIMG_T$x_INT interrupt. * The raw interrupt status bit for the TIMG_T$x_INT interrupt.
*/ */
uint32_t t0_int_raw:1; uint32_t t0_int_raw: 1;
/** wdt_int_raw : R/SS/WTC; bitpos: [1]; default: 0; /** wdt_int_raw : R/SS/WTC; bitpos: [1]; default: 0;
* The raw interrupt status bit for the TIMG_WDT_INT interrupt. * The raw interrupt status bit for the TIMG_WDT_INT interrupt.
*/ */
uint32_t wdt_int_raw:1; uint32_t wdt_int_raw: 1;
uint32_t reserved_2:30; uint32_t reserved_2: 30;
}; };
uint32_t val; uint32_t val;
} timg_int_raw_timers_reg_t; } timg_int_raw_timers_reg_t;
@ -445,12 +445,12 @@ typedef union {
/** t0_int_st : RO; bitpos: [0]; default: 0; /** t0_int_st : RO; bitpos: [0]; default: 0;
* The masked interrupt status bit for the TIMG_T$x_INT interrupt. * The masked interrupt status bit for the TIMG_T$x_INT interrupt.
*/ */
uint32_t t0_int_st:1; uint32_t t0_int_st: 1;
/** wdt_int_st : RO; bitpos: [1]; default: 0; /** wdt_int_st : RO; bitpos: [1]; default: 0;
* The masked interrupt status bit for the TIMG_WDT_INT interrupt. * The masked interrupt status bit for the TIMG_WDT_INT interrupt.
*/ */
uint32_t wdt_int_st:1; uint32_t wdt_int_st: 1;
uint32_t reserved_2:30; uint32_t reserved_2: 30;
}; };
uint32_t val; uint32_t val;
} timg_int_st_timers_reg_t; } timg_int_st_timers_reg_t;
@ -463,12 +463,12 @@ typedef union {
/** t0_int_clr : WT; bitpos: [0]; default: 0; /** t0_int_clr : WT; bitpos: [0]; default: 0;
* Set this bit to clear the TIMG_T$x_INT interrupt. * Set this bit to clear the TIMG_T$x_INT interrupt.
*/ */
uint32_t t0_int_clr:1; uint32_t t0_int_clr: 1;
/** wdt_int_clr : WT; bitpos: [1]; default: 0; /** wdt_int_clr : WT; bitpos: [1]; default: 0;
* Set this bit to clear the TIMG_WDT_INT interrupt. * Set this bit to clear the TIMG_WDT_INT interrupt.
*/ */
uint32_t wdt_int_clr:1; uint32_t wdt_int_clr: 1;
uint32_t reserved_2:30; uint32_t reserved_2: 30;
}; };
uint32_t val; uint32_t val;
} timg_int_clr_timers_reg_t; } timg_int_clr_timers_reg_t;
@ -483,8 +483,8 @@ typedef union {
/** ntimgs_date : R/W; bitpos: [27:0]; default: 33579409; /** ntimgs_date : R/W; bitpos: [27:0]; default: 33579409;
* Timer version control register * Timer version control register
*/ */
uint32_t ntimgs_date:28; uint32_t ntimgs_date: 28;
uint32_t reserved_28:4; uint32_t reserved_28: 4;
}; };
uint32_t val; uint32_t val;
} timg_ntimers_date_reg_t; } timg_ntimers_date_reg_t;
@ -496,20 +496,20 @@ typedef union {
*/ */
typedef union { typedef union {
struct { struct {
uint32_t reserved_0:29; uint32_t reserved_0: 29;
/** wdt_clk_is_active : R/W; bitpos: [29]; default: 1; /** wdt_clk_is_active : R/W; bitpos: [29]; default: 1;
* enable WDT's clock * enable WDT's clock
*/ */
uint32_t wdt_clk_is_active:1; uint32_t wdt_clk_is_active: 1;
/** timer_clk_is_active : R/W; bitpos: [30]; default: 1; /** timer_clk_is_active : R/W; bitpos: [30]; default: 1;
* enable Timer $x's clock * enable Timer $x's clock
*/ */
uint32_t timer_clk_is_active:1; uint32_t timer_clk_is_active: 1;
/** clk_en : R/W; bitpos: [31]; default: 0; /** clk_en : R/W; bitpos: [31]; default: 0;
* Register clock gate signal. 1: Registers can be read and written to by software. 0: * Register clock gate signal. 1: Registers can be read and written to by software. 0:
* Registers can not be read or written to by software. * Registers can not be read or written to by software.
*/ */
uint32_t clk_en:1; uint32_t clk_en: 1;
}; };
uint32_t val; uint32_t val;
} timg_regclk_reg_t; } timg_regclk_reg_t;
@ -526,7 +526,7 @@ typedef struct {
volatile timg_txload_reg_t load; volatile timg_txload_reg_t load;
} timg_hwtimer_reg_t; } timg_hwtimer_reg_t;
typedef struct { typedef struct timg_dev_t {
volatile timg_hwtimer_reg_t hw_timer[1]; volatile timg_hwtimer_reg_t hw_timer[1];
uint32_t reserved_024[9]; uint32_t reserved_024[9];
volatile timg_wdtconfig0_reg_t wdtconfig0; volatile timg_wdtconfig0_reg_t wdtconfig0;

View File

@ -1,16 +1,8 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "soc/timer_periph.h" #include "soc/timer_periph.h"
@ -18,11 +10,15 @@ const timer_group_signal_conn_t timer_group_periph_signals = {
.groups = { .groups = {
[0] = { [0] = {
.module = PERIPH_TIMG0_MODULE, .module = PERIPH_TIMG0_MODULE,
.t0_irq_id = ETS_TG0_T0_LEVEL_INTR_SOURCE .timer_irq_id = {
[0] = ETS_TG0_T0_LEVEL_INTR_SOURCE,
}
}, },
[1] = { [1] = {
.module = PERIPH_TIMG1_MODULE, .module = PERIPH_TIMG1_MODULE,
.t0_irq_id = ETS_TG1_T0_LEVEL_INTR_SOURCE, .timer_irq_id = {
[0] = ETS_TG1_T0_LEVEL_INTR_SOURCE,
}
} }
} }
}; };

View File

@ -1,5 +1,5 @@
/** /**
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -16,39 +16,39 @@ extern "C" {
*/ */
typedef union { typedef union {
struct { struct {
uint32_t reserved_0:9; uint32_t reserved_0: 9;
/** tx_use_xtal : R/W; bitpos: [9]; default: 0; /** tx_use_xtal : R/W; bitpos: [9]; default: 0;
* 1: Use XTAL_CLK as the source clock of timer group. 0: Use APB_CLK as the source * 1: Use XTAL_CLK as the source clock of timer group. 0: Use APB_CLK as the source
* clock of timer group. * clock of timer group.
*/ */
uint32_t tx_use_xtal:1; uint32_t tx_use_xtal: 1;
/** tx_alarm_en : R/W/SC; bitpos: [10]; default: 0; /** tx_alarm_en : R/W/SC; bitpos: [10]; default: 0;
* When set, the alarm is enabled. This bit is automatically cleared once an * When set, the alarm is enabled. This bit is automatically cleared once an
* alarm occurs. * alarm occurs.
*/ */
uint32_t tx_alarm_en:1; uint32_t tx_alarm_en: 1;
uint32_t reserved_11:1; uint32_t reserved_11: 1;
/** tx_divcnt_rst : WT; bitpos: [12]; default: 0; /** tx_divcnt_rst : WT; bitpos: [12]; default: 0;
* When set, Timer x 's clock divider counter will be reset. * When set, Timer x 's clock divider counter will be reset.
*/ */
uint32_t tx_divcnt_rst:1; uint32_t tx_divcnt_rst: 1;
/** tx_divider : R/W; bitpos: [28:13]; default: 1; /** tx_divider : R/W; bitpos: [28:13]; default: 1;
* Timer x clock (Tx_clk) prescaler value. * Timer x clock (Tx_clk) prescaler value.
*/ */
uint32_t tx_divider:16; uint32_t tx_divider: 16;
/** tx_autoreload : R/W; bitpos: [29]; default: 1; /** tx_autoreload : R/W; bitpos: [29]; default: 1;
* When set, timer x auto-reload at alarm is enabled. * When set, timer x auto-reload at alarm is enabled.
*/ */
uint32_t tx_autoreload:1; uint32_t tx_autoreload: 1;
/** tx_increase : R/W; bitpos: [30]; default: 1; /** tx_increase : R/W; bitpos: [30]; default: 1;
* When set, the timer x time-base counter will increment every clock tick. When * When set, the timer x time-base counter will increment every clock tick. When
* cleared, the timer x time-base counter will decrement. * cleared, the timer x time-base counter will decrement.
*/ */
uint32_t tx_increase:1; uint32_t tx_increase: 1;
/** tx_en : R/W; bitpos: [31]; default: 0; /** tx_en : R/W; bitpos: [31]; default: 0;
* When set, the timer x time-base counter is enabled. * When set, the timer x time-base counter is enabled.
*/ */
uint32_t tx_en:1; uint32_t tx_en: 1;
}; };
uint32_t val; uint32_t val;
} timg_txconfig_reg_t; } timg_txconfig_reg_t;
@ -62,7 +62,7 @@ typedef union {
* After writing to TIMG_TxUPDATE_REG, the low 32 bits of the time-base counter * After writing to TIMG_TxUPDATE_REG, the low 32 bits of the time-base counter
* of timer x can be read here. * of timer x can be read here.
*/ */
uint32_t tx_lo:32; uint32_t tx_lo: 32;
}; };
uint32_t val; uint32_t val;
} timg_txlo_reg_t; } timg_txlo_reg_t;
@ -76,8 +76,8 @@ typedef union {
* After writing to TIMG_T$xUPDATE_REG, the high 22 bits of the time-base counter * After writing to TIMG_T$xUPDATE_REG, the high 22 bits of the time-base counter
* of timer $x can be read here. * of timer $x can be read here.
*/ */
uint32_t tx_hi:22; uint32_t tx_hi: 22;
uint32_t reserved_22:10; uint32_t reserved_22: 10;
}; };
uint32_t val; uint32_t val;
} timg_txhi_reg_t; } timg_txhi_reg_t;
@ -87,11 +87,11 @@ typedef union {
*/ */
typedef union { typedef union {
struct { struct {
uint32_t reserved_0:31; uint32_t reserved_0: 31;
/** tx_update : R/W/SC; bitpos: [31]; default: 0; /** tx_update : R/W/SC; bitpos: [31]; default: 0;
* After writing 0 or 1 to TIMG_T$xUPDATE_REG, the counter value is latched. * After writing 0 or 1 to TIMG_T$xUPDATE_REG, the counter value is latched.
*/ */
uint32_t tx_update:1; uint32_t tx_update: 1;
}; };
uint32_t val; uint32_t val;
} timg_txupdate_reg_t; } timg_txupdate_reg_t;
@ -104,7 +104,7 @@ typedef union {
/** tx_alarm_lo : R/W; bitpos: [31:0]; default: 0; /** tx_alarm_lo : R/W; bitpos: [31:0]; default: 0;
* Timer $x alarm trigger time-base counter value, low 32 bits. * Timer $x alarm trigger time-base counter value, low 32 bits.
*/ */
uint32_t tx_alarm_lo:32; uint32_t tx_alarm_lo: 32;
}; };
uint32_t val; uint32_t val;
} timg_txalarmlo_reg_t; } timg_txalarmlo_reg_t;
@ -117,8 +117,8 @@ typedef union {
/** tx_alarm_hi : R/W; bitpos: [21:0]; default: 0; /** tx_alarm_hi : R/W; bitpos: [21:0]; default: 0;
* Timer $x alarm trigger time-base counter value, high 22 bits. * Timer $x alarm trigger time-base counter value, high 22 bits.
*/ */
uint32_t tx_alarm_hi:22; uint32_t tx_alarm_hi: 22;
uint32_t reserved_22:10; uint32_t reserved_22: 10;
}; };
uint32_t val; uint32_t val;
} timg_txalarmhi_reg_t; } timg_txalarmhi_reg_t;
@ -132,7 +132,7 @@ typedef union {
* Low 32 bits of the value that a reload will load onto timer $x time-base * Low 32 bits of the value that a reload will load onto timer $x time-base
* Counter. * Counter.
*/ */
uint32_t tx_load_lo:32; uint32_t tx_load_lo: 32;
}; };
uint32_t val; uint32_t val;
} timg_txloadlo_reg_t; } timg_txloadlo_reg_t;
@ -146,8 +146,8 @@ typedef union {
* High 22 bits of the value that a reload will load onto timer $x time-base * High 22 bits of the value that a reload will load onto timer $x time-base
* counter. * counter.
*/ */
uint32_t tx_load_hi:22; uint32_t tx_load_hi: 22;
uint32_t reserved_22:10; uint32_t reserved_22: 10;
}; };
uint32_t val; uint32_t val;
} timg_txloadhi_reg_t; } timg_txloadhi_reg_t;
@ -161,7 +161,7 @@ typedef union {
* *
* Write any value to trigger a timer $x time-base counter reload. * Write any value to trigger a timer $x time-base counter reload.
*/ */
uint32_t tx_load:32; uint32_t tx_load: 32;
}; };
uint32_t val; uint32_t val;
} timg_txload_reg_t; } timg_txload_reg_t;
@ -173,57 +173,57 @@ typedef union {
*/ */
typedef union { typedef union {
struct { struct {
uint32_t reserved_0:12; uint32_t reserved_0: 12;
/** wdt_appcpu_reset_en : R/W; bitpos: [12]; default: 0; /** wdt_appcpu_reset_en : R/W; bitpos: [12]; default: 0;
* WDT reset CPU enable. * WDT reset CPU enable.
*/ */
uint32_t wdt_appcpu_reset_en:1; uint32_t wdt_appcpu_reset_en: 1;
/** wdt_procpu_reset_en : R/W; bitpos: [13]; default: 0; /** wdt_procpu_reset_en : R/W; bitpos: [13]; default: 0;
* WDT reset CPU enable. * WDT reset CPU enable.
*/ */
uint32_t wdt_procpu_reset_en:1; uint32_t wdt_procpu_reset_en: 1;
/** wdt_flashboot_mod_en : R/W; bitpos: [14]; default: 1; /** wdt_flashboot_mod_en : R/W; bitpos: [14]; default: 1;
* When set, Flash boot protection is enabled. * When set, Flash boot protection is enabled.
*/ */
uint32_t wdt_flashboot_mod_en:1; uint32_t wdt_flashboot_mod_en: 1;
/** wdt_sys_reset_length : R/W; bitpos: [17:15]; default: 1; /** wdt_sys_reset_length : R/W; bitpos: [17:15]; default: 1;
* System reset signal length selection. 0: 100 ns, 1: 200 ns, * System reset signal length selection. 0: 100 ns, 1: 200 ns,
* 2: 300 ns, 3: 400 ns, 4: 500 ns, 5: 800 ns, 6: 1.6 us, 7: 3.2 us. * 2: 300 ns, 3: 400 ns, 4: 500 ns, 5: 800 ns, 6: 1.6 us, 7: 3.2 us.
*/ */
uint32_t wdt_sys_reset_length:3; uint32_t wdt_sys_reset_length: 3;
/** wdt_cpu_reset_length : R/W; bitpos: [20:18]; default: 1; /** wdt_cpu_reset_length : R/W; bitpos: [20:18]; default: 1;
* CPU reset signal length selection. 0: 100 ns, 1: 200 ns, * CPU reset signal length selection. 0: 100 ns, 1: 200 ns,
* 2: 300 ns, 3: 400 ns, 4: 500 ns, 5: 800 ns, 6: 1.6 us, 7: 3.2 us. * 2: 300 ns, 3: 400 ns, 4: 500 ns, 5: 800 ns, 6: 1.6 us, 7: 3.2 us.
*/ */
uint32_t wdt_cpu_reset_length:3; uint32_t wdt_cpu_reset_length: 3;
/** wdt_use_xtal : R/W; bitpos: [21]; default: 0; /** wdt_use_xtal : R/W; bitpos: [21]; default: 0;
* choose WDT clock:0-apb_clk; 1-xtal_clk. * choose WDT clock:0-apb_clk; 1-xtal_clk.
*/ */
uint32_t wdt_use_xtal:1; uint32_t wdt_use_xtal: 1;
/** wdt_conf_update_en : WT; bitpos: [22]; default: 0; /** wdt_conf_update_en : WT; bitpos: [22]; default: 0;
* update the WDT configuration registers * update the WDT configuration registers
*/ */
uint32_t wdt_conf_update_en:1; uint32_t wdt_conf_update_en: 1;
/** wdt_stg3 : R/W; bitpos: [24:23]; default: 0; /** wdt_stg3 : R/W; bitpos: [24:23]; default: 0;
* Stage 3 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system. * Stage 3 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
*/ */
uint32_t wdt_stg3:2; uint32_t wdt_stg3: 2;
/** wdt_stg2 : R/W; bitpos: [26:25]; default: 0; /** wdt_stg2 : R/W; bitpos: [26:25]; default: 0;
* Stage 2 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system. * Stage 2 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
*/ */
uint32_t wdt_stg2:2; uint32_t wdt_stg2: 2;
/** wdt_stg1 : R/W; bitpos: [28:27]; default: 0; /** wdt_stg1 : R/W; bitpos: [28:27]; default: 0;
* Stage 1 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system. * Stage 1 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
*/ */
uint32_t wdt_stg1:2; uint32_t wdt_stg1: 2;
/** wdt_stg0 : R/W; bitpos: [30:29]; default: 0; /** wdt_stg0 : R/W; bitpos: [30:29]; default: 0;
* Stage 0 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system. * Stage 0 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
*/ */
uint32_t wdt_stg0:2; uint32_t wdt_stg0: 2;
/** wdt_en : R/W; bitpos: [31]; default: 0; /** wdt_en : R/W; bitpos: [31]; default: 0;
* When set, MWDT is enabled. * When set, MWDT is enabled.
*/ */
uint32_t wdt_en:1; uint32_t wdt_en: 1;
}; };
uint32_t val; uint32_t val;
} timg_wdtconfig0_reg_t; } timg_wdtconfig0_reg_t;
@ -236,13 +236,13 @@ typedef union {
/** wdt_divcnt_rst : WT; bitpos: [0]; default: 0; /** wdt_divcnt_rst : WT; bitpos: [0]; default: 0;
* When set, WDT 's clock divider counter will be reset. * When set, WDT 's clock divider counter will be reset.
*/ */
uint32_t wdt_divcnt_rst:1; uint32_t wdt_divcnt_rst: 1;
uint32_t reserved_1:15; uint32_t reserved_1: 15;
/** wdt_clk_prescale : R/W; bitpos: [31:16]; default: 1; /** wdt_clk_prescale : R/W; bitpos: [31:16]; default: 1;
* MWDT clock prescaler value. MWDT clock period = 12.5 ns * * MWDT clock prescaler value. MWDT clock period = 12.5 ns *
* TIMG_WDT_CLK_PRESCALE. * TIMG_WDT_CLK_PRESCALE.
*/ */
uint32_t wdt_clk_prescale:16; uint32_t wdt_clk_prescale: 16;
}; };
uint32_t val; uint32_t val;
} timg_wdtconfig1_reg_t; } timg_wdtconfig1_reg_t;
@ -255,7 +255,7 @@ typedef union {
/** wdt_stg0_hold : R/W; bitpos: [31:0]; default: 26000000; /** wdt_stg0_hold : R/W; bitpos: [31:0]; default: 26000000;
* Stage 0 timeout value, in MWDT clock cycles. * Stage 0 timeout value, in MWDT clock cycles.
*/ */
uint32_t wdt_stg0_hold:32; uint32_t wdt_stg0_hold: 32;
}; };
uint32_t val; uint32_t val;
} timg_wdtconfig2_reg_t; } timg_wdtconfig2_reg_t;
@ -268,7 +268,7 @@ typedef union {
/** wdt_stg1_hold : R/W; bitpos: [31:0]; default: 134217727; /** wdt_stg1_hold : R/W; bitpos: [31:0]; default: 134217727;
* Stage 1 timeout value, in MWDT clock cycles. * Stage 1 timeout value, in MWDT clock cycles.
*/ */
uint32_t wdt_stg1_hold:32; uint32_t wdt_stg1_hold: 32;
}; };
uint32_t val; uint32_t val;
} timg_wdtconfig3_reg_t; } timg_wdtconfig3_reg_t;
@ -281,7 +281,7 @@ typedef union {
/** wdt_stg2_hold : R/W; bitpos: [31:0]; default: 1048575; /** wdt_stg2_hold : R/W; bitpos: [31:0]; default: 1048575;
* Stage 2 timeout value, in MWDT clock cycles. * Stage 2 timeout value, in MWDT clock cycles.
*/ */
uint32_t wdt_stg2_hold:32; uint32_t wdt_stg2_hold: 32;
}; };
uint32_t val; uint32_t val;
} timg_wdtconfig4_reg_t; } timg_wdtconfig4_reg_t;
@ -294,7 +294,7 @@ typedef union {
/** wdt_stg3_hold : R/W; bitpos: [31:0]; default: 1048575; /** wdt_stg3_hold : R/W; bitpos: [31:0]; default: 1048575;
* Stage 3 timeout value, in MWDT clock cycles. * Stage 3 timeout value, in MWDT clock cycles.
*/ */
uint32_t wdt_stg3_hold:32; uint32_t wdt_stg3_hold: 32;
}; };
uint32_t val; uint32_t val;
} timg_wdtconfig5_reg_t; } timg_wdtconfig5_reg_t;
@ -307,7 +307,7 @@ typedef union {
/** wdt_feed : WT; bitpos: [31:0]; default: 0; /** wdt_feed : WT; bitpos: [31:0]; default: 0;
* Write any value to feed the MWDT. (WO) * Write any value to feed the MWDT. (WO)
*/ */
uint32_t wdt_feed:32; uint32_t wdt_feed: 32;
}; };
uint32_t val; uint32_t val;
} timg_wdtfeed_reg_t; } timg_wdtfeed_reg_t;
@ -321,7 +321,7 @@ typedef union {
* If the register contains a different value than its reset value, write * If the register contains a different value than its reset value, write
* protection is enabled. * protection is enabled.
*/ */
uint32_t wdt_wkey:32; uint32_t wdt_wkey: 32;
}; };
uint32_t val; uint32_t val;
} timg_wdtwprotect_reg_t; } timg_wdtwprotect_reg_t;
@ -333,27 +333,27 @@ typedef union {
*/ */
typedef union { typedef union {
struct { struct {
uint32_t reserved_0:12; uint32_t reserved_0: 12;
/** rtc_cali_start_cycling : R/W; bitpos: [12]; default: 1; /** rtc_cali_start_cycling : R/W; bitpos: [12]; default: 1;
* Reserved * Reserved
*/ */
uint32_t rtc_cali_start_cycling:1; uint32_t rtc_cali_start_cycling: 1;
/** rtc_cali_clk_sel : R/W; bitpos: [14:13]; default: 1; /** rtc_cali_clk_sel : R/W; bitpos: [14:13]; default: 1;
* 0:rtc slow clock. 1:clk_8m, 2:xtal_32k. * 0:rtc slow clock. 1:clk_8m, 2:xtal_32k.
*/ */
uint32_t rtc_cali_clk_sel:2; uint32_t rtc_cali_clk_sel: 2;
/** rtc_cali_rdy : RO; bitpos: [15]; default: 0; /** rtc_cali_rdy : RO; bitpos: [15]; default: 0;
* Reserved * Reserved
*/ */
uint32_t rtc_cali_rdy:1; uint32_t rtc_cali_rdy: 1;
/** rtc_cali_max : R/W; bitpos: [30:16]; default: 1; /** rtc_cali_max : R/W; bitpos: [30:16]; default: 1;
* Reserved * Reserved
*/ */
uint32_t rtc_cali_max:15; uint32_t rtc_cali_max: 15;
/** rtc_cali_start : R/W; bitpos: [31]; default: 0; /** rtc_cali_start : R/W; bitpos: [31]; default: 0;
* Reserved * Reserved
*/ */
uint32_t rtc_cali_start:1; uint32_t rtc_cali_start: 1;
}; };
uint32_t val; uint32_t val;
} timg_rtccalicfg_reg_t; } timg_rtccalicfg_reg_t;
@ -366,12 +366,12 @@ typedef union {
/** rtc_cali_cycling_data_vld : RO; bitpos: [0]; default: 0; /** rtc_cali_cycling_data_vld : RO; bitpos: [0]; default: 0;
* Reserved * Reserved
*/ */
uint32_t rtc_cali_cycling_data_vld:1; uint32_t rtc_cali_cycling_data_vld: 1;
uint32_t reserved_1:6; uint32_t reserved_1: 6;
/** rtc_cali_value : RO; bitpos: [31:7]; default: 0; /** rtc_cali_value : RO; bitpos: [31:7]; default: 0;
* Reserved * Reserved
*/ */
uint32_t rtc_cali_value:25; uint32_t rtc_cali_value: 25;
}; };
uint32_t val; uint32_t val;
} timg_rtccalicfg1_reg_t; } timg_rtccalicfg1_reg_t;
@ -384,17 +384,17 @@ typedef union {
/** rtc_cali_timeout : RO; bitpos: [0]; default: 0; /** rtc_cali_timeout : RO; bitpos: [0]; default: 0;
* RTC calibration timeout indicator * RTC calibration timeout indicator
*/ */
uint32_t rtc_cali_timeout:1; uint32_t rtc_cali_timeout: 1;
uint32_t reserved_1:2; uint32_t reserved_1: 2;
/** rtc_cali_timeout_rst_cnt : R/W; bitpos: [6:3]; default: 3; /** rtc_cali_timeout_rst_cnt : R/W; bitpos: [6:3]; default: 3;
* Cycles that release calibration timeout reset * Cycles that release calibration timeout reset
*/ */
uint32_t rtc_cali_timeout_rst_cnt:4; uint32_t rtc_cali_timeout_rst_cnt: 4;
/** rtc_cali_timeout_thres : R/W; bitpos: [31:7]; default: 33554431; /** rtc_cali_timeout_thres : R/W; bitpos: [31:7]; default: 33554431;
* Threshold value for the RTC calibration timer. If the calibration timer's value * Threshold value for the RTC calibration timer. If the calibration timer's value
* exceeds this threshold, a timeout is triggered. * exceeds this threshold, a timeout is triggered.
*/ */
uint32_t rtc_cali_timeout_thres:25; uint32_t rtc_cali_timeout_thres: 25;
}; };
uint32_t val; uint32_t val;
} timg_rtccalicfg2_reg_t; } timg_rtccalicfg2_reg_t;
@ -409,12 +409,12 @@ typedef union {
/** t0_int_ena : R/W; bitpos: [0]; default: 0; /** t0_int_ena : R/W; bitpos: [0]; default: 0;
* The interrupt enable bit for the TIMG_T$x_INT interrupt. * The interrupt enable bit for the TIMG_T$x_INT interrupt.
*/ */
uint32_t t0_int_ena:1; uint32_t t0_int_ena: 1;
/** wdt_int_ena : R/W; bitpos: [1]; default: 0; /** wdt_int_ena : R/W; bitpos: [1]; default: 0;
* The interrupt enable bit for the TIMG_WDT_INT interrupt. * The interrupt enable bit for the TIMG_WDT_INT interrupt.
*/ */
uint32_t wdt_int_ena:1; uint32_t wdt_int_ena: 1;
uint32_t reserved_2:30; uint32_t reserved_2: 30;
}; };
uint32_t val; uint32_t val;
} timg_int_ena_timers_reg_t; } timg_int_ena_timers_reg_t;
@ -427,12 +427,12 @@ typedef union {
/** t0_int_raw : R/SS/WTC; bitpos: [0]; default: 0; /** t0_int_raw : R/SS/WTC; bitpos: [0]; default: 0;
* The raw interrupt status bit for the TIMG_T$x_INT interrupt. * The raw interrupt status bit for the TIMG_T$x_INT interrupt.
*/ */
uint32_t t0_int_raw:1; uint32_t t0_int_raw: 1;
/** wdt_int_raw : R/SS/WTC; bitpos: [1]; default: 0; /** wdt_int_raw : R/SS/WTC; bitpos: [1]; default: 0;
* The raw interrupt status bit for the TIMG_WDT_INT interrupt. * The raw interrupt status bit for the TIMG_WDT_INT interrupt.
*/ */
uint32_t wdt_int_raw:1; uint32_t wdt_int_raw: 1;
uint32_t reserved_2:30; uint32_t reserved_2: 30;
}; };
uint32_t val; uint32_t val;
} timg_int_raw_timers_reg_t; } timg_int_raw_timers_reg_t;
@ -445,12 +445,12 @@ typedef union {
/** t0_int_st : RO; bitpos: [0]; default: 0; /** t0_int_st : RO; bitpos: [0]; default: 0;
* The masked interrupt status bit for the TIMG_T$x_INT interrupt. * The masked interrupt status bit for the TIMG_T$x_INT interrupt.
*/ */
uint32_t t0_int_st:1; uint32_t t0_int_st: 1;
/** wdt_int_st : RO; bitpos: [1]; default: 0; /** wdt_int_st : RO; bitpos: [1]; default: 0;
* The masked interrupt status bit for the TIMG_WDT_INT interrupt. * The masked interrupt status bit for the TIMG_WDT_INT interrupt.
*/ */
uint32_t wdt_int_st:1; uint32_t wdt_int_st: 1;
uint32_t reserved_2:30; uint32_t reserved_2: 30;
}; };
uint32_t val; uint32_t val;
} timg_int_st_timers_reg_t; } timg_int_st_timers_reg_t;
@ -463,12 +463,12 @@ typedef union {
/** t0_int_clr : WT; bitpos: [0]; default: 0; /** t0_int_clr : WT; bitpos: [0]; default: 0;
* Set this bit to clear the TIMG_T$x_INT interrupt. * Set this bit to clear the TIMG_T$x_INT interrupt.
*/ */
uint32_t t0_int_clr:1; uint32_t t0_int_clr: 1;
/** wdt_int_clr : WT; bitpos: [1]; default: 0; /** wdt_int_clr : WT; bitpos: [1]; default: 0;
* Set this bit to clear the TIMG_WDT_INT interrupt. * Set this bit to clear the TIMG_WDT_INT interrupt.
*/ */
uint32_t wdt_int_clr:1; uint32_t wdt_int_clr: 1;
uint32_t reserved_2:30; uint32_t reserved_2: 30;
}; };
uint32_t val; uint32_t val;
} timg_int_clr_timers_reg_t; } timg_int_clr_timers_reg_t;
@ -483,8 +483,8 @@ typedef union {
/** ntimgs_date : R/W; bitpos: [27:0]; default: 33579409; /** ntimgs_date : R/W; bitpos: [27:0]; default: 33579409;
* Timer version control register * Timer version control register
*/ */
uint32_t ntimgs_date:28; uint32_t ntimgs_date: 28;
uint32_t reserved_28:4; uint32_t reserved_28: 4;
}; };
uint32_t val; uint32_t val;
} timg_ntimers_date_reg_t; } timg_ntimers_date_reg_t;
@ -496,20 +496,20 @@ typedef union {
*/ */
typedef union { typedef union {
struct { struct {
uint32_t reserved_0:29; uint32_t reserved_0: 29;
/** wdt_clk_is_active : R/W; bitpos: [29]; default: 1; /** wdt_clk_is_active : R/W; bitpos: [29]; default: 1;
* enable WDT's clock * enable WDT's clock
*/ */
uint32_t wdt_clk_is_active:1; uint32_t wdt_clk_is_active: 1;
/** timer_clk_is_active : R/W; bitpos: [30]; default: 1; /** timer_clk_is_active : R/W; bitpos: [30]; default: 1;
* enable Timer $x's clock * enable Timer $x's clock
*/ */
uint32_t timer_clk_is_active:1; uint32_t timer_clk_is_active: 1;
/** clk_en : R/W; bitpos: [31]; default: 0; /** clk_en : R/W; bitpos: [31]; default: 0;
* Register clock gate signal. 1: Registers can be read and written to by software. 0: * Register clock gate signal. 1: Registers can be read and written to by software. 0:
* Registers can not be read or written to by software. * Registers can not be read or written to by software.
*/ */
uint32_t clk_en:1; uint32_t clk_en: 1;
}; };
uint32_t val; uint32_t val;
} timg_regclk_reg_t; } timg_regclk_reg_t;
@ -526,7 +526,7 @@ typedef struct {
volatile timg_txload_reg_t load; volatile timg_txload_reg_t load;
} timg_hwtimer_reg_t; } timg_hwtimer_reg_t;
typedef struct { typedef struct timg_dev_t {
volatile timg_hwtimer_reg_t hw_timer[1]; volatile timg_hwtimer_reg_t hw_timer[1];
uint32_t reserved_024[9]; uint32_t reserved_024[9];
volatile timg_wdtconfig0_reg_t wdtconfig0; volatile timg_wdtconfig0_reg_t wdtconfig0;

View File

@ -1,16 +1,8 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "soc/timer_periph.h" #include "soc/timer_periph.h"
@ -18,11 +10,15 @@ const timer_group_signal_conn_t timer_group_periph_signals = {
.groups = { .groups = {
[0] = { [0] = {
.module = PERIPH_TIMG0_MODULE, .module = PERIPH_TIMG0_MODULE,
.t0_irq_id = ETS_TG0_T0_LEVEL_INTR_SOURCE .timer_irq_id = {
[0] = ETS_TG0_T0_LEVEL_INTR_SOURCE,
}
}, },
[1] = { [1] = {
.module = PERIPH_TIMG1_MODULE, .module = PERIPH_TIMG1_MODULE,
.t0_irq_id = ETS_TG1_T0_LEVEL_INTR_SOURCE, .timer_irq_id = {
[0] = ETS_TG1_T0_LEVEL_INTR_SOURCE,
}
} }
} }
}; };

View File

@ -1,5 +1,5 @@
/** /**
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -16,44 +16,44 @@ extern "C" {
*/ */
typedef union { typedef union {
struct { struct {
uint32_t reserved_0:9; uint32_t reserved_0: 9;
/** tx_use_xtal : R/W; bitpos: [9]; default: 0; /** tx_use_xtal : R/W; bitpos: [9]; default: 0;
* 1: Use XTAL_CLK as the source clock of timer group. 0: Use APB_CLK as the source * 1: Use XTAL_CLK as the source clock of timer group. 0: Use APB_CLK as the source
* clock of timer group. * clock of timer group.
*/ */
uint32_t tx_use_xtal:1; uint32_t tx_use_xtal: 1;
/** tx_alarm_en : R/W; bitpos: [10]; default: 0; /** tx_alarm_en : R/W; bitpos: [10]; default: 0;
* When set, the alarm is enabled. This bit is automatically cleared once an * When set, the alarm is enabled. This bit is automatically cleared once an
* *
* alarm occurs. * alarm occurs.
*/ */
uint32_t tx_alarm_en:1; uint32_t tx_alarm_en: 1;
/** tx_level_int_en : R/W; bitpos: [11]; default: 0; /** tx_level_int_en : R/W; bitpos: [11]; default: 0;
* When set, an alarm will generate a level type interrupt. * When set, an alarm will generate a level type interrupt.
*/ */
uint32_t tx_level_int_en:1; uint32_t tx_level_int_en: 1;
/** tx_edge_int_en : R/W; bitpos: [12]; default: 0; /** tx_edge_int_en : R/W; bitpos: [12]; default: 0;
* When set, an alarm will generate an edge type interrupt. * When set, an alarm will generate an edge type interrupt.
*/ */
uint32_t tx_edge_int_en:1; uint32_t tx_edge_int_en: 1;
/** tx_divider : R/W; bitpos: [28:13]; default: 1; /** tx_divider : R/W; bitpos: [28:13]; default: 1;
* Timer x clock (Tx_clk) prescaler value. * Timer x clock (Tx_clk) prescaler value.
*/ */
uint32_t tx_divider:16; uint32_t tx_divider: 16;
/** tx_autoreload : R/W; bitpos: [29]; default: 1; /** tx_autoreload : R/W; bitpos: [29]; default: 1;
* When set, timer x auto-reload at alarm is enabled. * When set, timer x auto-reload at alarm is enabled.
*/ */
uint32_t tx_autoreload:1; uint32_t tx_autoreload: 1;
/** tx_increase : R/W; bitpos: [30]; default: 1; /** tx_increase : R/W; bitpos: [30]; default: 1;
* When set, the timer x time-base counter will increment every clock tick. When * When set, the timer x time-base counter will increment every clock tick. When
* *
* cleared, the timer x time-base counter will decrement. * cleared, the timer x time-base counter will decrement.
*/ */
uint32_t tx_increase:1; uint32_t tx_increase: 1;
/** tx_en : R/W; bitpos: [31]; default: 0; /** tx_en : R/W; bitpos: [31]; default: 0;
* When set, the timer x time-base counter is enabled. * When set, the timer x time-base counter is enabled.
*/ */
uint32_t tx_en:1; uint32_t tx_en: 1;
}; };
uint32_t val; uint32_t val;
} timg_txconfig_reg_t; } timg_txconfig_reg_t;
@ -68,7 +68,7 @@ typedef union {
* *
* of timer x can be read here. * of timer x can be read here.
*/ */
uint32_t tx_lo:32; uint32_t tx_lo: 32;
}; };
uint32_t val; uint32_t val;
} timg_txlo_reg_t; } timg_txlo_reg_t;
@ -83,7 +83,7 @@ typedef union {
* *
* of timer x can be read here. * of timer x can be read here.
*/ */
uint32_t tx_hi:32; uint32_t tx_hi: 32;
}; };
uint32_t val; uint32_t val;
} timg_txhi_reg_t; } timg_txhi_reg_t;
@ -93,11 +93,11 @@ typedef union {
*/ */
typedef union { typedef union {
struct { struct {
uint32_t reserved_0:31; uint32_t reserved_0: 31;
/** tx_update : R/W; bitpos: [31]; default: 0; /** tx_update : R/W; bitpos: [31]; default: 0;
* After writing 0 or 1 to TIMG_TxUPDATE_REG, the counter value is latched. * After writing 0 or 1 to TIMG_TxUPDATE_REG, the counter value is latched.
*/ */
uint32_t tx_update:1; uint32_t tx_update: 1;
}; };
uint32_t val; uint32_t val;
} timg_txupdate_reg_t; } timg_txupdate_reg_t;
@ -110,7 +110,7 @@ typedef union {
/** tx_alarm_lo : R/W; bitpos: [31:0]; default: 0; /** tx_alarm_lo : R/W; bitpos: [31:0]; default: 0;
* Timer x alarm trigger time-base counter value, low 32 bits. * Timer x alarm trigger time-base counter value, low 32 bits.
*/ */
uint32_t tx_alarm_lo:32; uint32_t tx_alarm_lo: 32;
}; };
uint32_t val; uint32_t val;
} timg_txalarmlo_reg_t; } timg_txalarmlo_reg_t;
@ -125,7 +125,7 @@ typedef union {
* *
* Timer x alarm trigger time-base counter value, high 32 bits. * Timer x alarm trigger time-base counter value, high 32 bits.
*/ */
uint32_t tx_alarm_hi:32; uint32_t tx_alarm_hi: 32;
}; };
uint32_t val; uint32_t val;
} timg_txalarmhi_reg_t; } timg_txalarmhi_reg_t;
@ -142,7 +142,7 @@ typedef union {
* *
* Counter. * Counter.
*/ */
uint32_t tx_load_lo:32; uint32_t tx_load_lo: 32;
}; };
uint32_t val; uint32_t val;
} timg_txloadlo_reg_t; } timg_txloadlo_reg_t;
@ -159,7 +159,7 @@ typedef union {
* *
* counter. * counter.
*/ */
uint32_t tx_load_hi:32; uint32_t tx_load_hi: 32;
}; };
uint32_t val; uint32_t val;
} timg_txloadhi_reg_t; } timg_txloadhi_reg_t;
@ -174,7 +174,7 @@ typedef union {
* *
* Write any value to trigger a timer x time-base counter reload. * Write any value to trigger a timer x time-base counter reload.
*/ */
uint32_t tx_load:32; uint32_t tx_load: 32;
}; };
uint32_t val; uint32_t val;
} timg_txload_reg_t; } timg_txload_reg_t;
@ -186,67 +186,67 @@ typedef union {
*/ */
typedef union { typedef union {
struct { struct {
uint32_t reserved_0:12; uint32_t reserved_0: 12;
/** wdt_appcpu_reset_en : R/W; bitpos: [12]; default: 0; /** wdt_appcpu_reset_en : R/W; bitpos: [12]; default: 0;
* Reserved * Reserved
*/ */
uint32_t wdt_appcpu_reset_en:1; uint32_t wdt_appcpu_reset_en: 1;
/** wdt_procpu_reset_en : R/W; bitpos: [13]; default: 0; /** wdt_procpu_reset_en : R/W; bitpos: [13]; default: 0;
* WDT reset CPU enable. * WDT reset CPU enable.
*/ */
uint32_t wdt_procpu_reset_en:1; uint32_t wdt_procpu_reset_en: 1;
/** wdt_flashboot_mod_en : R/W; bitpos: [14]; default: 1; /** wdt_flashboot_mod_en : R/W; bitpos: [14]; default: 1;
* When set, Flash boot protection is enabled. * When set, Flash boot protection is enabled.
*/ */
uint32_t wdt_flashboot_mod_en:1; uint32_t wdt_flashboot_mod_en: 1;
/** wdt_sys_reset_length : R/W; bitpos: [17:15]; default: 1; /** wdt_sys_reset_length : R/W; bitpos: [17:15]; default: 1;
* System reset signal length selection. 0: 100 ns, 1: 200 ns, * System reset signal length selection. 0: 100 ns, 1: 200 ns,
* *
* 2: 300 ns, 3: 400 ns, 4: 500 ns, 5: 800 ns, 6: 1.6 us, 7: 3.2 us. * 2: 300 ns, 3: 400 ns, 4: 500 ns, 5: 800 ns, 6: 1.6 us, 7: 3.2 us.
*/ */
uint32_t wdt_sys_reset_length:3; uint32_t wdt_sys_reset_length: 3;
/** wdt_cpu_reset_length : R/W; bitpos: [20:18]; default: 1; /** wdt_cpu_reset_length : R/W; bitpos: [20:18]; default: 1;
* CPU reset signal length selection. 0: 100 ns, 1: 200 ns, * CPU reset signal length selection. 0: 100 ns, 1: 200 ns,
* *
* 2: 300 ns, 3: 400 ns, 4: 500 ns, 5: 800 ns, 6: 1.6 us, 7: 3.2 us. * 2: 300 ns, 3: 400 ns, 4: 500 ns, 5: 800 ns, 6: 1.6 us, 7: 3.2 us.
*/ */
uint32_t wdt_cpu_reset_length:3; uint32_t wdt_cpu_reset_length: 3;
/** wdt_level_int_en : R/W; bitpos: [21]; default: 0; /** wdt_level_int_en : R/W; bitpos: [21]; default: 0;
* When set, a level type interrupt will occur at the timeout of a stage * When set, a level type interrupt will occur at the timeout of a stage
* *
* configured to generate an interrupt. * configured to generate an interrupt.
*/ */
uint32_t wdt_level_int_en:1; uint32_t wdt_level_int_en: 1;
/** wdt_edge_int_en : R/W; bitpos: [22]; default: 0; /** wdt_edge_int_en : R/W; bitpos: [22]; default: 0;
* When set, an edge type interrupt will occur at the timeout of a stage * When set, an edge type interrupt will occur at the timeout of a stage
* *
* configured to generate an interrupt. * configured to generate an interrupt.
*/ */
uint32_t wdt_edge_int_en:1; uint32_t wdt_edge_int_en: 1;
/** wdt_stg3 : R/W; bitpos: [24:23]; default: 0; /** wdt_stg3 : R/W; bitpos: [24:23]; default: 0;
* Stage 3 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system. * Stage 3 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
* *
*/ */
uint32_t wdt_stg3:2; uint32_t wdt_stg3: 2;
/** wdt_stg2 : R/W; bitpos: [26:25]; default: 0; /** wdt_stg2 : R/W; bitpos: [26:25]; default: 0;
* Stage 2 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system. * Stage 2 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
* *
*/ */
uint32_t wdt_stg2:2; uint32_t wdt_stg2: 2;
/** wdt_stg1 : R/W; bitpos: [28:27]; default: 0; /** wdt_stg1 : R/W; bitpos: [28:27]; default: 0;
* Stage 1 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system. * Stage 1 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
* *
*/ */
uint32_t wdt_stg1:2; uint32_t wdt_stg1: 2;
/** wdt_stg0 : R/W; bitpos: [30:29]; default: 0; /** wdt_stg0 : R/W; bitpos: [30:29]; default: 0;
* Stage 0 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system. * Stage 0 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
* *
*/ */
uint32_t wdt_stg0:2; uint32_t wdt_stg0: 2;
/** wdt_en : R/W; bitpos: [31]; default: 0; /** wdt_en : R/W; bitpos: [31]; default: 0;
* When set, MWDT is enabled. * When set, MWDT is enabled.
*/ */
uint32_t wdt_en:1; uint32_t wdt_en: 1;
}; };
uint32_t val; uint32_t val;
} timg_wdtconfig0_reg_t; } timg_wdtconfig0_reg_t;
@ -256,13 +256,13 @@ typedef union {
*/ */
typedef union { typedef union {
struct { struct {
uint32_t reserved_0:16; uint32_t reserved_0: 16;
/** wdt_clk_prescaler : R/W; bitpos: [31:16]; default: 1; /** wdt_clk_prescaler : R/W; bitpos: [31:16]; default: 1;
* MWDT clock prescaler value. MWDT clock period = 12.5 ns * * MWDT clock prescaler value. MWDT clock period = 12.5 ns *
* *
* TIMG_WDT_CLK_PRESCALE. * TIMG_WDT_CLK_PRESCALE.
*/ */
uint32_t wdt_clk_prescaler:16; uint32_t wdt_clk_prescaler: 16;
}; };
uint32_t val; uint32_t val;
} timg_wdtconfig1_reg_t; } timg_wdtconfig1_reg_t;
@ -275,7 +275,7 @@ typedef union {
/** wdt_stg0_hold : R/W; bitpos: [31:0]; default: 26000000; /** wdt_stg0_hold : R/W; bitpos: [31:0]; default: 26000000;
* Stage 0 timeout value, in MWDT clock cycles. * Stage 0 timeout value, in MWDT clock cycles.
*/ */
uint32_t wdt_stg0_hold:32; uint32_t wdt_stg0_hold: 32;
}; };
uint32_t val; uint32_t val;
} timg_wdtconfig2_reg_t; } timg_wdtconfig2_reg_t;
@ -288,7 +288,7 @@ typedef union {
/** wdt_stg1_hold : R/W; bitpos: [31:0]; default: 134217727; /** wdt_stg1_hold : R/W; bitpos: [31:0]; default: 134217727;
* Stage 1 timeout value, in MWDT clock cycles. * Stage 1 timeout value, in MWDT clock cycles.
*/ */
uint32_t wdt_stg1_hold:32; uint32_t wdt_stg1_hold: 32;
}; };
uint32_t val; uint32_t val;
} timg_wdtconfig3_reg_t; } timg_wdtconfig3_reg_t;
@ -301,7 +301,7 @@ typedef union {
/** wdt_stg2_hold : R/W; bitpos: [31:0]; default: 1048575; /** wdt_stg2_hold : R/W; bitpos: [31:0]; default: 1048575;
* Stage 2 timeout value, in MWDT clock cycles. * Stage 2 timeout value, in MWDT clock cycles.
*/ */
uint32_t wdt_stg2_hold:32; uint32_t wdt_stg2_hold: 32;
}; };
uint32_t val; uint32_t val;
} timg_wdtconfig4_reg_t; } timg_wdtconfig4_reg_t;
@ -314,7 +314,7 @@ typedef union {
/** wdt_stg3_hold : R/W; bitpos: [31:0]; default: 1048575; /** wdt_stg3_hold : R/W; bitpos: [31:0]; default: 1048575;
* Stage 3 timeout value, in MWDT clock cycles. * Stage 3 timeout value, in MWDT clock cycles.
*/ */
uint32_t wdt_stg3_hold:32; uint32_t wdt_stg3_hold: 32;
}; };
uint32_t val; uint32_t val;
} timg_wdtconfig5_reg_t; } timg_wdtconfig5_reg_t;
@ -327,7 +327,7 @@ typedef union {
/** wdt_feed : WO; bitpos: [31:0]; default: 0; /** wdt_feed : WO; bitpos: [31:0]; default: 0;
* Write any value to feed the MWDT. (WO) * Write any value to feed the MWDT. (WO)
*/ */
uint32_t wdt_feed:32; uint32_t wdt_feed: 32;
}; };
uint32_t val; uint32_t val;
} timg_wdtfeed_reg_t; } timg_wdtfeed_reg_t;
@ -342,7 +342,7 @@ typedef union {
* *
* protection is enabled. * protection is enabled.
*/ */
uint32_t wdt_wkey:32; uint32_t wdt_wkey: 32;
}; };
uint32_t val; uint32_t val;
} timg_wdtwprotect_reg_t; } timg_wdtwprotect_reg_t;
@ -354,27 +354,27 @@ typedef union {
*/ */
typedef union { typedef union {
struct { struct {
uint32_t reserved_0:12; uint32_t reserved_0: 12;
/** rtc_cali_start_cycling : R/W; bitpos: [12]; default: 1; /** rtc_cali_start_cycling : R/W; bitpos: [12]; default: 1;
* Reserved * Reserved
*/ */
uint32_t rtc_cali_start_cycling:1; uint32_t rtc_cali_start_cycling: 1;
/** rtc_cali_clk_sel : R/W; bitpos: [14:13]; default: 1; /** rtc_cali_clk_sel : R/W; bitpos: [14:13]; default: 1;
* 0:rtcslowclock. 1:clk_80m. 2:xtal_32k. * 0:rtcslowclock. 1:clk_80m. 2:xtal_32k.
*/ */
uint32_t rtc_cali_clk_sel:2; uint32_t rtc_cali_clk_sel: 2;
/** rtc_cali_rdy : RO; bitpos: [15]; default: 0; /** rtc_cali_rdy : RO; bitpos: [15]; default: 0;
* Reserved * Reserved
*/ */
uint32_t rtc_cali_rdy:1; uint32_t rtc_cali_rdy: 1;
/** rtc_cali_max : R/W; bitpos: [30:16]; default: 1; /** rtc_cali_max : R/W; bitpos: [30:16]; default: 1;
* Reserved * Reserved
*/ */
uint32_t rtc_cali_max:15; uint32_t rtc_cali_max: 15;
/** rtc_cali_start : R/W; bitpos: [31]; default: 0; /** rtc_cali_start : R/W; bitpos: [31]; default: 0;
* Reserved * Reserved
*/ */
uint32_t rtc_cali_start:1; uint32_t rtc_cali_start: 1;
}; };
uint32_t val; uint32_t val;
} timg_rtccalicfg_reg_t; } timg_rtccalicfg_reg_t;
@ -387,12 +387,12 @@ typedef union {
/** rtc_cali_cycling_data_vld : RO; bitpos: [0]; default: 0; /** rtc_cali_cycling_data_vld : RO; bitpos: [0]; default: 0;
* Reserved * Reserved
*/ */
uint32_t rtc_cali_cycling_data_vld:1; uint32_t rtc_cali_cycling_data_vld: 1;
uint32_t reserved_1:6; uint32_t reserved_1: 6;
/** rtc_cali_value : RO; bitpos: [31:7]; default: 0; /** rtc_cali_value : RO; bitpos: [31:7]; default: 0;
* Reserved * Reserved
*/ */
uint32_t rtc_cali_value:25; uint32_t rtc_cali_value: 25;
}; };
uint32_t val; uint32_t val;
} timg_rtccalicfg1_reg_t; } timg_rtccalicfg1_reg_t;
@ -405,17 +405,17 @@ typedef union {
/** rtc_cali_timeout : RO; bitpos: [0]; default: 0; /** rtc_cali_timeout : RO; bitpos: [0]; default: 0;
* RTC calibration timeout indicator * RTC calibration timeout indicator
*/ */
uint32_t rtc_cali_timeout:1; uint32_t rtc_cali_timeout: 1;
uint32_t reserved_1:2; uint32_t reserved_1: 2;
/** rtc_cali_timeout_rst_cnt : R/W; bitpos: [6:3]; default: 3; /** rtc_cali_timeout_rst_cnt : R/W; bitpos: [6:3]; default: 3;
* Cycles that release calibration timeout reset * Cycles that release calibration timeout reset
*/ */
uint32_t rtc_cali_timeout_rst_cnt:4; uint32_t rtc_cali_timeout_rst_cnt: 4;
/** rtc_cali_timeout_thres : R/W; bitpos: [31:7]; default: 33554431; /** rtc_cali_timeout_thres : R/W; bitpos: [31:7]; default: 33554431;
* Threshold value for the RTC calibration timer. If the calibration timer's value * Threshold value for the RTC calibration timer. If the calibration timer's value
* exceeds this threshold, a timeout is triggered. * exceeds this threshold, a timeout is triggered.
*/ */
uint32_t rtc_cali_timeout_thres:25; uint32_t rtc_cali_timeout_thres: 25;
}; };
uint32_t val; uint32_t val;
} timg_rtccalicfg2_reg_t; } timg_rtccalicfg2_reg_t;
@ -427,51 +427,51 @@ typedef union {
*/ */
typedef union { typedef union {
struct { struct {
uint32_t reserved_0:6; uint32_t reserved_0: 6;
/** lact_use_reftick : R/W; bitpos: [6]; default: 0; /** lact_use_reftick : R/W; bitpos: [6]; default: 0;
* Reserved * Reserved
*/ */
uint32_t lact_use_reftick:1; uint32_t lact_use_reftick: 1;
/** lact_rtc_only : R/W; bitpos: [7]; default: 0; /** lact_rtc_only : R/W; bitpos: [7]; default: 0;
* Reserved * Reserved
*/ */
uint32_t lact_rtc_only:1; uint32_t lact_rtc_only: 1;
/** lact_cpst_en : R/W; bitpos: [8]; default: 1; /** lact_cpst_en : R/W; bitpos: [8]; default: 1;
* Reserved * Reserved
*/ */
uint32_t lact_cpst_en:1; uint32_t lact_cpst_en: 1;
/** lact_lac_en : R/W; bitpos: [9]; default: 1; /** lact_lac_en : R/W; bitpos: [9]; default: 1;
* Reserved * Reserved
*/ */
uint32_t lact_lac_en:1; uint32_t lact_lac_en: 1;
/** lact_alarm_en : R/W; bitpos: [10]; default: 0; /** lact_alarm_en : R/W; bitpos: [10]; default: 0;
* Reserved * Reserved
*/ */
uint32_t lact_alarm_en:1; uint32_t lact_alarm_en: 1;
/** lact_level_int_en : R/W; bitpos: [11]; default: 0; /** lact_level_int_en : R/W; bitpos: [11]; default: 0;
* Reserved * Reserved
*/ */
uint32_t lact_level_int_en:1; uint32_t lact_level_int_en: 1;
/** lact_edge_int_en : R/W; bitpos: [12]; default: 0; /** lact_edge_int_en : R/W; bitpos: [12]; default: 0;
* Reserved * Reserved
*/ */
uint32_t lact_edge_int_en:1; uint32_t lact_edge_int_en: 1;
/** lact_divider : R/W; bitpos: [28:13]; default: 1; /** lact_divider : R/W; bitpos: [28:13]; default: 1;
* Reserved * Reserved
*/ */
uint32_t lact_divider:16; uint32_t lact_divider: 16;
/** lact_autoreload : R/W; bitpos: [29]; default: 1; /** lact_autoreload : R/W; bitpos: [29]; default: 1;
* Reserved * Reserved
*/ */
uint32_t lact_autoreload:1; uint32_t lact_autoreload: 1;
/** lact_increase : R/W; bitpos: [30]; default: 1; /** lact_increase : R/W; bitpos: [30]; default: 1;
* Reserved * Reserved
*/ */
uint32_t lact_increase:1; uint32_t lact_increase: 1;
/** lact_en : R/W; bitpos: [31]; default: 0; /** lact_en : R/W; bitpos: [31]; default: 0;
* Reserved * Reserved
*/ */
uint32_t lact_en:1; uint32_t lact_en: 1;
}; };
uint32_t val; uint32_t val;
} timg_lactconfig_reg_t; } timg_lactconfig_reg_t;
@ -481,11 +481,11 @@ typedef union {
*/ */
typedef union { typedef union {
struct { struct {
uint32_t reserved_0:6; uint32_t reserved_0: 6;
/** lact_rtc_step_len : R/W; bitpos: [31:6]; default: 0; /** lact_rtc_step_len : R/W; bitpos: [31:6]; default: 0;
* Reserved * Reserved
*/ */
uint32_t lact_rtc_step_len:26; uint32_t lact_rtc_step_len: 26;
}; };
uint32_t val; uint32_t val;
} timg_lactrtc_reg_t; } timg_lactrtc_reg_t;
@ -498,7 +498,7 @@ typedef union {
/** lact_lo : RO; bitpos: [31:0]; default: 0; /** lact_lo : RO; bitpos: [31:0]; default: 0;
* Reserved * Reserved
*/ */
uint32_t lact_lo:32; uint32_t lact_lo: 32;
}; };
uint32_t val; uint32_t val;
} timg_lactlo_reg_t; } timg_lactlo_reg_t;
@ -511,7 +511,7 @@ typedef union {
/** lact_hi : RO; bitpos: [31:0]; default: 0; /** lact_hi : RO; bitpos: [31:0]; default: 0;
* Reserved * Reserved
*/ */
uint32_t lact_hi:32; uint32_t lact_hi: 32;
}; };
uint32_t val; uint32_t val;
} timg_lacthi_reg_t; } timg_lacthi_reg_t;
@ -524,7 +524,7 @@ typedef union {
/** lact_update : WO; bitpos: [31:0]; default: 0; /** lact_update : WO; bitpos: [31:0]; default: 0;
* Reserved * Reserved
*/ */
uint32_t lact_update:32; uint32_t lact_update: 32;
}; };
uint32_t val; uint32_t val;
} timg_lactupdate_reg_t; } timg_lactupdate_reg_t;
@ -537,7 +537,7 @@ typedef union {
/** lact_alarm_lo : R/W; bitpos: [31:0]; default: 0; /** lact_alarm_lo : R/W; bitpos: [31:0]; default: 0;
* Reserved * Reserved
*/ */
uint32_t lact_alarm_lo:32; uint32_t lact_alarm_lo: 32;
}; };
uint32_t val; uint32_t val;
} timg_lactalarmlo_reg_t; } timg_lactalarmlo_reg_t;
@ -550,7 +550,7 @@ typedef union {
/** lact_alarm_hi : R/W; bitpos: [31:0]; default: 0; /** lact_alarm_hi : R/W; bitpos: [31:0]; default: 0;
* Reserved * Reserved
*/ */
uint32_t lact_alarm_hi:32; uint32_t lact_alarm_hi: 32;
}; };
uint32_t val; uint32_t val;
} timg_lactalarmhi_reg_t; } timg_lactalarmhi_reg_t;
@ -563,7 +563,7 @@ typedef union {
/** lact_load_lo : R/W; bitpos: [31:0]; default: 0; /** lact_load_lo : R/W; bitpos: [31:0]; default: 0;
* Reserved * Reserved
*/ */
uint32_t lact_load_lo:32; uint32_t lact_load_lo: 32;
}; };
uint32_t val; uint32_t val;
} timg_lactloadlo_reg_t; } timg_lactloadlo_reg_t;
@ -576,7 +576,7 @@ typedef union {
/** lact_load_hi : R/W; bitpos: [31:0]; default: 0; /** lact_load_hi : R/W; bitpos: [31:0]; default: 0;
* Reserved * Reserved
*/ */
uint32_t lact_load_hi:32; uint32_t lact_load_hi: 32;
}; };
uint32_t val; uint32_t val;
} timg_lactloadhi_reg_t; } timg_lactloadhi_reg_t;
@ -589,7 +589,7 @@ typedef union {
/** lact_load : WO; bitpos: [31:0]; default: 0; /** lact_load : WO; bitpos: [31:0]; default: 0;
* Reserved * Reserved
*/ */
uint32_t lact_load:32; uint32_t lact_load: 32;
}; };
uint32_t val; uint32_t val;
} timg_lactload_reg_t; } timg_lactload_reg_t;
@ -601,23 +601,23 @@ typedef union {
*/ */
typedef union { typedef union {
struct { struct {
/** tx_int_ena : R/W; bitpos: [0]; default: 0; /** t0_int_ena : R/W; bitpos: [0]; default: 0;
* The interrupt enable bit for the TIMG_T0_INT interrupt. * The interrupt enable bit for the TIMG_T0_INT interrupt.
*/ */
uint32_t tx_int_ena:1; uint32_t t0_int_ena: 1;
/** t1_int_ena : R/W; bitpos: [1]; default: 0; /** t1_int_ena : R/W; bitpos: [1]; default: 0;
* The interrupt enable bit for the TIMG_T1_INT interrupt. * The interrupt enable bit for the TIMG_T1_INT interrupt.
*/ */
uint32_t t1_int_ena:1; uint32_t t1_int_ena: 1;
/** wdt_int_ena : R/W; bitpos: [2]; default: 0; /** wdt_int_ena : R/W; bitpos: [2]; default: 0;
* The interrupt enable bit for the TIMG_WDT_INT interrupt. * The interrupt enable bit for the TIMG_WDT_INT interrupt.
*/ */
uint32_t wdt_int_ena:1; uint32_t wdt_int_ena: 1;
/** lact_int_ena : R/W; bitpos: [3]; default: 0; /** lact_int_ena : R/W; bitpos: [3]; default: 0;
* The interrupt enable bit for the TIMG_LACT_INT interrupt. * The interrupt enable bit for the TIMG_LACT_INT interrupt.
*/ */
uint32_t lact_int_ena:1; uint32_t lact_int_ena: 1;
uint32_t reserved_4:28; uint32_t reserved_4: 28;
}; };
uint32_t val; uint32_t val;
} timg_int_ena_timers_reg_t; } timg_int_ena_timers_reg_t;
@ -630,20 +630,20 @@ typedef union {
/** t0_int_raw : RO; bitpos: [0]; default: 0; /** t0_int_raw : RO; bitpos: [0]; default: 0;
* The raw interrupt status bit for the TIMG_T0_INT interrupt. * The raw interrupt status bit for the TIMG_T0_INT interrupt.
*/ */
uint32_t t0_int_raw:1; uint32_t t0_int_raw: 1;
/** t1_int_raw : RO; bitpos: [1]; default: 0; /** t1_int_raw : RO; bitpos: [1]; default: 0;
* The raw interrupt status bit for the TIMG_T1_INT interrupt. * The raw interrupt status bit for the TIMG_T1_INT interrupt.
*/ */
uint32_t t1_int_raw:1; uint32_t t1_int_raw: 1;
/** wdt_int_raw : RO; bitpos: [2]; default: 0; /** wdt_int_raw : RO; bitpos: [2]; default: 0;
* The raw interrupt status bit for the TIMG_WDT_INT interrupt. * The raw interrupt status bit for the TIMG_WDT_INT interrupt.
*/ */
uint32_t wdt_int_raw:1; uint32_t wdt_int_raw: 1;
/** lact_int_raw : RO; bitpos: [3]; default: 0; /** lact_int_raw : RO; bitpos: [3]; default: 0;
* The raw interrupt status bit for the TIMG_LACT_INT interrupt. * The raw interrupt status bit for the TIMG_LACT_INT interrupt.
*/ */
uint32_t lact_int_raw:1; uint32_t lact_int_raw: 1;
uint32_t reserved_4:28; uint32_t reserved_4: 28;
}; };
uint32_t val; uint32_t val;
} timg_int_raw_timers_reg_t; } timg_int_raw_timers_reg_t;
@ -656,20 +656,20 @@ typedef union {
/** t0_int_st : RO; bitpos: [0]; default: 0; /** t0_int_st : RO; bitpos: [0]; default: 0;
* The masked interrupt status bit for the TIMG_T0_INT interrupt. * The masked interrupt status bit for the TIMG_T0_INT interrupt.
*/ */
uint32_t t0_int_st:1; uint32_t t0_int_st: 1;
/** t1_int_st : RO; bitpos: [1]; default: 0; /** t1_int_st : RO; bitpos: [1]; default: 0;
* The masked interrupt status bit for the TIMG_T1_INT interrupt. * The masked interrupt status bit for the TIMG_T1_INT interrupt.
*/ */
uint32_t t1_int_st:1; uint32_t t1_int_st: 1;
/** wdt_int_st : RO; bitpos: [2]; default: 0; /** wdt_int_st : RO; bitpos: [2]; default: 0;
* The masked interrupt status bit for the TIMG_WDT_INT interrupt. * The masked interrupt status bit for the TIMG_WDT_INT interrupt.
*/ */
uint32_t wdt_int_st:1; uint32_t wdt_int_st: 1;
/** lact_int_st : RO; bitpos: [3]; default: 0; /** lact_int_st : RO; bitpos: [3]; default: 0;
* The masked interrupt status bit for the TIMG_LACT_INT interrupt. * The masked interrupt status bit for the TIMG_LACT_INT interrupt.
*/ */
uint32_t lact_int_st:1; uint32_t lact_int_st: 1;
uint32_t reserved_4:28; uint32_t reserved_4: 28;
}; };
uint32_t val; uint32_t val;
} timg_int_st_timers_reg_t; } timg_int_st_timers_reg_t;
@ -682,20 +682,20 @@ typedef union {
/** t0_int_clr : WO; bitpos: [0]; default: 0; /** t0_int_clr : WO; bitpos: [0]; default: 0;
* Set this bit to clear the TIMG_T0_INT interrupt. * Set this bit to clear the TIMG_T0_INT interrupt.
*/ */
uint32_t t0_int_clr:1; uint32_t t0_int_clr: 1;
/** t1_int_clr : WO; bitpos: [1]; default: 0; /** t1_int_clr : WO; bitpos: [1]; default: 0;
* Set this bit to clear the TIMG_T1_INT interrupt. * Set this bit to clear the TIMG_T1_INT interrupt.
*/ */
uint32_t t1_int_clr:1; uint32_t t1_int_clr: 1;
/** wdt_int_clr : WO; bitpos: [2]; default: 0; /** wdt_int_clr : WO; bitpos: [2]; default: 0;
* Set this bit to clear the TIMG_WDT_INT interrupt. * Set this bit to clear the TIMG_WDT_INT interrupt.
*/ */
uint32_t wdt_int_clr:1; uint32_t wdt_int_clr: 1;
/** lact_int_clr : WO; bitpos: [3]; default: 0; /** lact_int_clr : WO; bitpos: [3]; default: 0;
* Set this bit to clear the TIMG_LACT_INT interrupt. * Set this bit to clear the TIMG_LACT_INT interrupt.
*/ */
uint32_t lact_int_clr:1; uint32_t lact_int_clr: 1;
uint32_t reserved_4:28; uint32_t reserved_4: 28;
}; };
uint32_t val; uint32_t val;
} timg_int_clr_timers_reg_t; } timg_int_clr_timers_reg_t;
@ -710,8 +710,8 @@ typedef union {
/** timers_date : R/W; bitpos: [27:0]; default: 26243681; /** timers_date : R/W; bitpos: [27:0]; default: 26243681;
* Version control register. * Version control register.
*/ */
uint32_t timers_date:28; uint32_t timers_date: 28;
uint32_t reserved_28:4; uint32_t reserved_28: 4;
}; };
uint32_t val; uint32_t val;
} timg_timers_date_reg_t; } timg_timers_date_reg_t;
@ -723,12 +723,12 @@ typedef union {
*/ */
typedef union { typedef union {
struct { struct {
uint32_t reserved_0:31; uint32_t reserved_0: 31;
/** clk_en : R/W; bitpos: [31]; default: 0; /** clk_en : R/W; bitpos: [31]; default: 0;
* Register clock gate signal. 1: Registers can be read and written to by software. 0: * Register clock gate signal. 1: Registers can be read and written to by software. 0:
* Registers can not be read or written to by software. * Registers can not be read or written to by software.
*/ */
uint32_t clk_en:1; uint32_t clk_en: 1;
}; };
uint32_t val; uint32_t val;
} timg_regclk_reg_t; } timg_regclk_reg_t;
@ -745,7 +745,7 @@ typedef struct {
volatile timg_txload_reg_t load; volatile timg_txload_reg_t load;
} timg_hwtimer_reg_t; } timg_hwtimer_reg_t;
typedef struct { typedef struct timg_dev_t {
volatile timg_hwtimer_reg_t hw_timer[2]; volatile timg_hwtimer_reg_t hw_timer[2];
volatile timg_wdtconfig0_reg_t wdtconfig0; volatile timg_wdtconfig0_reg_t wdtconfig0;
volatile timg_wdtconfig1_reg_t wdtconfig1; volatile timg_wdtconfig1_reg_t wdtconfig1;

View File

@ -1,16 +1,8 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "soc/timer_periph.h" #include "soc/timer_periph.h"
@ -18,11 +10,17 @@ const timer_group_signal_conn_t timer_group_periph_signals = {
.groups = { .groups = {
[0] = { [0] = {
.module = PERIPH_TIMG0_MODULE, .module = PERIPH_TIMG0_MODULE,
.t0_irq_id = ETS_TG0_T0_LEVEL_INTR_SOURCE .timer_irq_id = {
[0] = ETS_TG0_T0_LEVEL_INTR_SOURCE,
[1] = ETS_TG0_T1_LEVEL_INTR_SOURCE,
}
}, },
[1] = { [1] = {
.module = PERIPH_TIMG1_MODULE, .module = PERIPH_TIMG1_MODULE,
.t0_irq_id = ETS_TG1_T0_LEVEL_INTR_SOURCE, .timer_irq_id = {
[0] = ETS_TG1_T0_LEVEL_INTR_SOURCE,
[1] = ETS_TG1_T1_LEVEL_INTR_SOURCE,
}
} }
} }
}; };

View File

@ -1,16 +1,7 @@
/** Copyright 2021 Espressif Systems (Shanghai) PTE LTD /**
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * SPDX-License-Identifier: Apache-2.0
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#pragma once #pragma once
@ -25,35 +16,39 @@ extern "C" {
*/ */
typedef union { typedef union {
struct { struct {
uint32_t reserved_0:9; uint32_t reserved_0: 9;
/** tn_use_xtal : R/W; bitpos: [9]; default: 0; /** tn_use_xtal : R/W; bitpos: [9]; default: 0;
* 1: Use XTAL_CLK as the source clock of timer group. 0: Use APB_CLK as the source * 1: Use XTAL_CLK as the source clock of timer group. 0: Use APB_CLK as the source
* clock of timer group. * clock of timer group.
*/ */
uint32_t tn_use_xtal:1; uint32_t tn_use_xtal: 1;
/** tn_alarm_en : R/W/SC; bitpos: [10]; default: 0; /** tn_alarm_en : R/W/SC; bitpos: [10]; default: 0;
* When set, the alarm is enabled. This bit is automatically cleared once an * When set, the alarm is enabled. This bit is automatically cleared once an
* alarm occurs. * alarm occurs.
*/ */
uint32_t tn_alarm_en:1; uint32_t tn_alarm_en: 1;
uint32_t reserved_11:2; uint32_t reserved_11: 1;
/** tn_divcnt_rst : WT; bitpos: [12]; default: 0;
* When set, Timer n 's clock divider counter will be reset.
*/
uint32_t tn_divcnt_rst: 1;
/** tn_divider : R/W; bitpos: [28:13]; default: 1; /** tn_divider : R/W; bitpos: [28:13]; default: 1;
* Timer n clock (Tn_clk) prescaler value. * Timer n clock (Tn_clk) prescaler value.
*/ */
uint32_t tn_divider:16; uint32_t tn_divider: 16;
/** tn_autoreload : R/W; bitpos: [29]; default: 1; /** tn_autoreload : R/W; bitpos: [29]; default: 1;
* When set, timer n auto-reload at alarm is enabled. * When set, timer n auto-reload at alarm is enabled.
*/ */
uint32_t tn_autoreload:1; uint32_t tn_autoreload: 1;
/** tn_increase : R/W; bitpos: [30]; default: 1; /** tn_increase : R/W; bitpos: [30]; default: 1;
* When set, the timer n time-base counter will increment every clock tick. When * When set, the timer n time-base counter will increment every clock tick. When
* cleared, the timer n time-base counter will decrement. * cleared, the timer n time-base counter will decrement.
*/ */
uint32_t tn_increase:1; uint32_t tn_increase: 1;
/** tn_en : R/W; bitpos: [31]; default: 0; /** tn_en : R/W; bitpos: [31]; default: 0;
* When set, the timer n time-base counter is enabled. * When set, the timer n time-base counter is enabled.
*/ */
uint32_t tn_en:1; uint32_t tn_en: 1;
}; };
uint32_t val; uint32_t val;
} timg_tnconfig_reg_t; } timg_tnconfig_reg_t;
@ -67,7 +62,7 @@ typedef union {
* After writing to TIMG_TnUPDATE_REG, the low 32 bits of the time-base counter * After writing to TIMG_TnUPDATE_REG, the low 32 bits of the time-base counter
* of timer n can be read here. * of timer n can be read here.
*/ */
uint32_t tn_lo:32; uint32_t tn_lo: 32;
}; };
uint32_t val; uint32_t val;
} timg_tnlo_reg_t; } timg_tnlo_reg_t;
@ -81,8 +76,8 @@ typedef union {
* After writing to TIMG_TnUPDATE_REG, the high 22 bits of the time-base counter * After writing to TIMG_TnUPDATE_REG, the high 22 bits of the time-base counter
* of timer n can be read here. * of timer n can be read here.
*/ */
uint32_t tn_hi:22; uint32_t tn_hi: 22;
uint32_t reserved_22:10; uint32_t reserved_22: 10;
}; };
uint32_t val; uint32_t val;
} timg_tnhi_reg_t; } timg_tnhi_reg_t;
@ -92,11 +87,11 @@ typedef union {
*/ */
typedef union { typedef union {
struct { struct {
uint32_t reserved_0:31; uint32_t reserved_0: 31;
/** tn_update : R/W/SC; bitpos: [31]; default: 0; /** tn_update : R/W/SC; bitpos: [31]; default: 0;
* After writing 0 or 1 to TIMG_TnUPDATE_REG, the counter value is latched. * After writing 0 or 1 to TIMG_TnUPDATE_REG, the counter value is latched.
*/ */
uint32_t tn_update:1; uint32_t tn_update: 1;
}; };
uint32_t val; uint32_t val;
} timg_tnupdate_reg_t; } timg_tnupdate_reg_t;
@ -109,7 +104,7 @@ typedef union {
/** tn_alarm_lo : R/W; bitpos: [31:0]; default: 0; /** tn_alarm_lo : R/W; bitpos: [31:0]; default: 0;
* Timer n alarm trigger time-base counter value, low 32 bits. * Timer n alarm trigger time-base counter value, low 32 bits.
*/ */
uint32_t tn_alarm_lo:32; uint32_t tn_alarm_lo: 32;
}; };
uint32_t val; uint32_t val;
} timg_tnalarmlo_reg_t; } timg_tnalarmlo_reg_t;
@ -122,8 +117,8 @@ typedef union {
/** tn_alarm_hi : R/W; bitpos: [21:0]; default: 0; /** tn_alarm_hi : R/W; bitpos: [21:0]; default: 0;
* Timer n alarm trigger time-base counter value, high 22 bits. * Timer n alarm trigger time-base counter value, high 22 bits.
*/ */
uint32_t tn_alarm_hi:22; uint32_t tn_alarm_hi: 22;
uint32_t reserved_22:10; uint32_t reserved_22: 10;
}; };
uint32_t val; uint32_t val;
} timg_tnalarmhi_reg_t; } timg_tnalarmhi_reg_t;
@ -137,7 +132,7 @@ typedef union {
* Low 32 bits of the value that a reload will load onto timer n time-base * Low 32 bits of the value that a reload will load onto timer n time-base
* Counter. * Counter.
*/ */
uint32_t tn_load_lo:32; uint32_t tn_load_lo: 32;
}; };
uint32_t val; uint32_t val;
} timg_tnloadlo_reg_t; } timg_tnloadlo_reg_t;
@ -151,8 +146,8 @@ typedef union {
* High 22 bits of the value that a reload will load onto timer n time-base * High 22 bits of the value that a reload will load onto timer n time-base
* counter. * counter.
*/ */
uint32_t tn_load_hi:22; uint32_t tn_load_hi: 22;
uint32_t reserved_22:10; uint32_t reserved_22: 10;
}; };
uint32_t val; uint32_t val;
} timg_tnloadhi_reg_t; } timg_tnloadhi_reg_t;
@ -166,7 +161,7 @@ typedef union {
* *
* Write any value to trigger a timer n time-base counter reload. * Write any value to trigger a timer n time-base counter reload.
*/ */
uint32_t tn_load:32; uint32_t tn_load: 32;
}; };
uint32_t val; uint32_t val;
} timg_tnload_reg_t; } timg_tnload_reg_t;
@ -178,50 +173,50 @@ typedef union {
*/ */
typedef union { typedef union {
struct { struct {
uint32_t reserved_0:12; uint32_t reserved_0: 12;
/** wdt_appcpu_reset_en : R/W; bitpos: [12]; default: 0; /** wdt_appcpu_reset_en : R/W; bitpos: [12]; default: 0;
* Reserved * Reserved
*/ */
uint32_t wdt_appcpu_reset_en:1; uint32_t wdt_appcpu_reset_en: 1;
/** wdt_procpu_reset_en : R/W; bitpos: [13]; default: 0; /** wdt_procpu_reset_en : R/W; bitpos: [13]; default: 0;
* WDT reset CPU enable. * WDT reset CPU enable.
*/ */
uint32_t wdt_procpu_reset_en:1; uint32_t wdt_procpu_reset_en: 1;
/** wdt_flashboot_mod_en : R/W; bitpos: [14]; default: 1; /** wdt_flashboot_mod_en : R/W; bitpos: [14]; default: 1;
* When set, Flash boot protection is enabled. * When set, Flash boot protection is enabled.
*/ */
uint32_t wdt_flashboot_mod_en:1; uint32_t wdt_flashboot_mod_en: 1;
/** wdt_sys_reset_length : R/W; bitpos: [17:15]; default: 1; /** wdt_sys_reset_length : R/W; bitpos: [17:15]; default: 1;
* System reset signal length selection. 0: 100 ns, 1: 200 ns, * System reset signal length selection. 0: 100 ns, 1: 200 ns,
* 2: 300 ns, 3: 400 ns, 4: 500 ns, 5: 800 ns, 6: 1.6 us, 7: 3.2 us. * 2: 300 ns, 3: 400 ns, 4: 500 ns, 5: 800 ns, 6: 1.6 us, 7: 3.2 us.
*/ */
uint32_t wdt_sys_reset_length:3; uint32_t wdt_sys_reset_length: 3;
/** wdt_cpu_reset_length : R/W; bitpos: [20:18]; default: 1; /** wdt_cpu_reset_length : R/W; bitpos: [20:18]; default: 1;
* CPU reset signal length selection. 0: 100 ns, 1: 200 ns, * CPU reset signal length selection. 0: 100 ns, 1: 200 ns,
* 2: 300 ns, 3: 400 ns, 4: 500 ns, 5: 800 ns, 6: 1.6 us, 7: 3.2 us. * 2: 300 ns, 3: 400 ns, 4: 500 ns, 5: 800 ns, 6: 1.6 us, 7: 3.2 us.
*/ */
uint32_t wdt_cpu_reset_length:3; uint32_t wdt_cpu_reset_length: 3;
uint32_t reserved_21:2; uint32_t reserved_21: 2;
/** wdt_stg3 : R/W; bitpos: [24:23]; default: 0; /** wdt_stg3 : R/W; bitpos: [24:23]; default: 0;
* Stage 3 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system. * Stage 3 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
*/ */
uint32_t wdt_stg3:2; uint32_t wdt_stg3: 2;
/** wdt_stg2 : R/W; bitpos: [26:25]; default: 0; /** wdt_stg2 : R/W; bitpos: [26:25]; default: 0;
* Stage 2 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system. * Stage 2 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
*/ */
uint32_t wdt_stg2:2; uint32_t wdt_stg2: 2;
/** wdt_stg1 : R/W; bitpos: [28:27]; default: 0; /** wdt_stg1 : R/W; bitpos: [28:27]; default: 0;
* Stage 1 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system. * Stage 1 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
*/ */
uint32_t wdt_stg1:2; uint32_t wdt_stg1: 2;
/** wdt_stg0 : R/W; bitpos: [30:29]; default: 0; /** wdt_stg0 : R/W; bitpos: [30:29]; default: 0;
* Stage 0 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system. * Stage 0 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
*/ */
uint32_t wdt_stg0:2; uint32_t wdt_stg0: 2;
/** wdt_en : R/W; bitpos: [31]; default: 0; /** wdt_en : R/W; bitpos: [31]; default: 0;
* When set, MWDT is enabled. * When set, MWDT is enabled.
*/ */
uint32_t wdt_en:1; uint32_t wdt_en: 1;
}; };
uint32_t val; uint32_t val;
} timg_wdtconfig0_reg_t; } timg_wdtconfig0_reg_t;
@ -231,12 +226,12 @@ typedef union {
*/ */
typedef union { typedef union {
struct { struct {
uint32_t reserved_0:16; uint32_t reserved_0: 16;
/** wdt_clk_prescale : R/W; bitpos: [31:16]; default: 1; /** wdt_clk_prescale : R/W; bitpos: [31:16]; default: 1;
* MWDT clock prescaler value. MWDT clock period = 12.5 ns * * MWDT clock prescaler value. MWDT clock period = 12.5 ns *
* TIMG_WDT_CLK_PRESCALE. * TIMG_WDT_CLK_PRESCALE.
*/ */
uint32_t wdt_clk_prescale:16; uint32_t wdt_clk_prescale: 16;
}; };
uint32_t val; uint32_t val;
} timg_wdtconfig1_reg_t; } timg_wdtconfig1_reg_t;
@ -249,7 +244,7 @@ typedef union {
/** wdt_stg0_hold : R/W; bitpos: [31:0]; default: 26000000; /** wdt_stg0_hold : R/W; bitpos: [31:0]; default: 26000000;
* Stage 0 timeout value, in MWDT clock cycles. * Stage 0 timeout value, in MWDT clock cycles.
*/ */
uint32_t wdt_stg0_hold:32; uint32_t wdt_stg0_hold: 32;
}; };
uint32_t val; uint32_t val;
} timg_wdtconfig2_reg_t; } timg_wdtconfig2_reg_t;
@ -262,7 +257,7 @@ typedef union {
/** wdt_stg1_hold : R/W; bitpos: [31:0]; default: 134217727; /** wdt_stg1_hold : R/W; bitpos: [31:0]; default: 134217727;
* Stage 1 timeout value, in MWDT clock cycles. * Stage 1 timeout value, in MWDT clock cycles.
*/ */
uint32_t wdt_stg1_hold:32; uint32_t wdt_stg1_hold: 32;
}; };
uint32_t val; uint32_t val;
} timg_wdtconfig3_reg_t; } timg_wdtconfig3_reg_t;
@ -275,7 +270,7 @@ typedef union {
/** wdt_stg2_hold : R/W; bitpos: [31:0]; default: 1048575; /** wdt_stg2_hold : R/W; bitpos: [31:0]; default: 1048575;
* Stage 2 timeout value, in MWDT clock cycles. * Stage 2 timeout value, in MWDT clock cycles.
*/ */
uint32_t wdt_stg2_hold:32; uint32_t wdt_stg2_hold: 32;
}; };
uint32_t val; uint32_t val;
} timg_wdtconfig4_reg_t; } timg_wdtconfig4_reg_t;
@ -288,7 +283,7 @@ typedef union {
/** wdt_stg3_hold : R/W; bitpos: [31:0]; default: 1048575; /** wdt_stg3_hold : R/W; bitpos: [31:0]; default: 1048575;
* Stage 3 timeout value, in MWDT clock cycles. * Stage 3 timeout value, in MWDT clock cycles.
*/ */
uint32_t wdt_stg3_hold:32; uint32_t wdt_stg3_hold: 32;
}; };
uint32_t val; uint32_t val;
} timg_wdtconfig5_reg_t; } timg_wdtconfig5_reg_t;
@ -301,7 +296,7 @@ typedef union {
/** wdt_feed : WT; bitpos: [31:0]; default: 0; /** wdt_feed : WT; bitpos: [31:0]; default: 0;
* Write any value to feed the MWDT. (WO) * Write any value to feed the MWDT. (WO)
*/ */
uint32_t wdt_feed:32; uint32_t wdt_feed: 32;
}; };
uint32_t val; uint32_t val;
} timg_wdtfeed_reg_t; } timg_wdtfeed_reg_t;
@ -315,7 +310,7 @@ typedef union {
* If the register contains a different value than its reset value, write * If the register contains a different value than its reset value, write
* protection is enabled. * protection is enabled.
*/ */
uint32_t wdt_wkey:32; uint32_t wdt_wkey: 32;
}; };
uint32_t val; uint32_t val;
} timg_wdtwprotect_reg_t; } timg_wdtwprotect_reg_t;
@ -327,27 +322,27 @@ typedef union {
*/ */
typedef union { typedef union {
struct { struct {
uint32_t reserved_0:12; uint32_t reserved_0: 12;
/** rtc_cali_start_cycling : R/W; bitpos: [12]; default: 1; /** rtc_cali_start_cycling : R/W; bitpos: [12]; default: 1;
* Reserved * Reserved
*/ */
uint32_t rtc_cali_start_cycling:1; uint32_t rtc_cali_start_cycling: 1;
/** rtc_cali_clk_sel : R/W; bitpos: [14:13]; default: 1; /** rtc_cali_clk_sel : R/W; bitpos: [14:13]; default: 1;
* 0:rtc slow clock. 1:clk_80m. 2:xtal_32k. * 0:rtc slow clock. 1:clk_80m. 2:xtal_32k.
*/ */
uint32_t rtc_cali_clk_sel:2; uint32_t rtc_cali_clk_sel: 2;
/** rtc_cali_rdy : RO; bitpos: [15]; default: 0; /** rtc_cali_rdy : RO; bitpos: [15]; default: 0;
* Reserved * Reserved
*/ */
uint32_t rtc_cali_rdy:1; uint32_t rtc_cali_rdy: 1;
/** rtc_cali_max : R/W; bitpos: [30:16]; default: 1; /** rtc_cali_max : R/W; bitpos: [30:16]; default: 1;
* Reserved * Reserved
*/ */
uint32_t rtc_cali_max:15; uint32_t rtc_cali_max: 15;
/** rtc_cali_start : R/W; bitpos: [31]; default: 0; /** rtc_cali_start : R/W; bitpos: [31]; default: 0;
* Reserved * Reserved
*/ */
uint32_t rtc_cali_start:1; uint32_t rtc_cali_start: 1;
}; };
uint32_t val; uint32_t val;
} timg_rtccalicfg_reg_t; } timg_rtccalicfg_reg_t;
@ -360,12 +355,12 @@ typedef union {
/** rtc_cali_cycling_data_vld : RO; bitpos: [0]; default: 0; /** rtc_cali_cycling_data_vld : RO; bitpos: [0]; default: 0;
* Reserved * Reserved
*/ */
uint32_t rtc_cali_cycling_data_vld:1; uint32_t rtc_cali_cycling_data_vld: 1;
uint32_t reserved_1:6; uint32_t reserved_1: 6;
/** rtc_cali_value : RO; bitpos: [31:7]; default: 0; /** rtc_cali_value : RO; bitpos: [31:7]; default: 0;
* Reserved * Reserved
*/ */
uint32_t rtc_cali_value:25; uint32_t rtc_cali_value: 25;
}; };
uint32_t val; uint32_t val;
} timg_rtccalicfg1_reg_t; } timg_rtccalicfg1_reg_t;
@ -378,17 +373,17 @@ typedef union {
/** rtc_cali_timeout : RO; bitpos: [0]; default: 0; /** rtc_cali_timeout : RO; bitpos: [0]; default: 0;
* RTC calibration timeout indicator * RTC calibration timeout indicator
*/ */
uint32_t rtc_cali_timeout:1; uint32_t rtc_cali_timeout: 1;
uint32_t reserved_1:2; uint32_t reserved_1: 2;
/** rtc_cali_timeout_rst_cnt : R/W; bitpos: [6:3]; default: 3; /** rtc_cali_timeout_rst_cnt : R/W; bitpos: [6:3]; default: 3;
* Cycles that release calibration timeout reset * Cycles that release calibration timeout reset
*/ */
uint32_t rtc_cali_timeout_rst_cnt:4; uint32_t rtc_cali_timeout_rst_cnt: 4;
/** rtc_cali_timeout_thres : R/W; bitpos: [31:7]; default: 33554431; /** rtc_cali_timeout_thres : R/W; bitpos: [31:7]; default: 33554431;
* Threshold value for the RTC calibration timer. If the calibration timer's value * Threshold value for the RTC calibration timer. If the calibration timer's value
* exceeds this threshold, a timeout is triggered. * exceeds this threshold, a timeout is triggered.
*/ */
uint32_t rtc_cali_timeout_thres:25; uint32_t rtc_cali_timeout_thres: 25;
}; };
uint32_t val; uint32_t val;
} timg_rtccalicfg2_reg_t; } timg_rtccalicfg2_reg_t;
@ -403,16 +398,16 @@ typedef union {
/** t0_int_ena : R/W; bitpos: [0]; default: 0; /** t0_int_ena : R/W; bitpos: [0]; default: 0;
* The interrupt enable bit for the TIMG_T0_INT interrupt. * The interrupt enable bit for the TIMG_T0_INT interrupt.
*/ */
uint32_t t0_int_ena:1; uint32_t t0_int_ena: 1;
/** t1_int_ena : R/W; bitpos: [1]; default: 0; /** t1_int_ena : R/W; bitpos: [1]; default: 0;
* The interrupt enable bit for the TIMG_T1_INT interrupt. * The interrupt enable bit for the TIMG_T1_INT interrupt.
*/ */
uint32_t t1_int_ena:1; uint32_t t1_int_ena: 1;
/** wdt_int_ena : R/W; bitpos: [2]; default: 0; /** wdt_int_ena : R/W; bitpos: [2]; default: 0;
* The interrupt enable bit for the TIMG_WDT_INT interrupt. * The interrupt enable bit for the TIMG_WDT_INT interrupt.
*/ */
uint32_t wdt_int_ena:1; uint32_t wdt_int_ena: 1;
uint32_t reserved_3:29; uint32_t reserved_3: 29;
}; };
uint32_t val; uint32_t val;
} timg_int_ena_timers_reg_t; } timg_int_ena_timers_reg_t;
@ -425,16 +420,16 @@ typedef union {
/** t0_int_raw : R/WTC/SS; bitpos: [0]; default: 0; /** t0_int_raw : R/WTC/SS; bitpos: [0]; default: 0;
* The raw interrupt status bit for the TIMG_T0_INT interrupt. * The raw interrupt status bit for the TIMG_T0_INT interrupt.
*/ */
uint32_t t0_int_raw:1; uint32_t t0_int_raw: 1;
/** t1_int_raw : R/WTC/SS; bitpos: [1]; default: 0; /** t1_int_raw : R/WTC/SS; bitpos: [1]; default: 0;
* The raw interrupt status bit for the TIMG_T1_INT interrupt. * The raw interrupt status bit for the TIMG_T1_INT interrupt.
*/ */
uint32_t t1_int_raw:1; uint32_t t1_int_raw: 1;
/** wdt_int_raw : R/WTC/SS; bitpos: [2]; default: 0; /** wdt_int_raw : R/WTC/SS; bitpos: [2]; default: 0;
* The raw interrupt status bit for the TIMG_WDT_INT interrupt. * The raw interrupt status bit for the TIMG_WDT_INT interrupt.
*/ */
uint32_t wdt_int_raw:1; uint32_t wdt_int_raw: 1;
uint32_t reserved_3:29; uint32_t reserved_3: 29;
}; };
uint32_t val; uint32_t val;
} timg_int_raw_timers_reg_t; } timg_int_raw_timers_reg_t;
@ -447,16 +442,16 @@ typedef union {
/** t0_int_st : RO; bitpos: [0]; default: 0; /** t0_int_st : RO; bitpos: [0]; default: 0;
* The masked interrupt status bit for the TIMG_T0_INT interrupt. * The masked interrupt status bit for the TIMG_T0_INT interrupt.
*/ */
uint32_t t0_int_st:1; uint32_t t0_int_st: 1;
/** t1_int_st : RO; bitpos: [1]; default: 0; /** t1_int_st : RO; bitpos: [1]; default: 0;
* The masked interrupt status bit for the TIMG_T1_INT interrupt. * The masked interrupt status bit for the TIMG_T1_INT interrupt.
*/ */
uint32_t t1_int_st:1; uint32_t t1_int_st: 1;
/** wdt_int_st : RO; bitpos: [2]; default: 0; /** wdt_int_st : RO; bitpos: [2]; default: 0;
* The masked interrupt status bit for the TIMG_WDT_INT interrupt. * The masked interrupt status bit for the TIMG_WDT_INT interrupt.
*/ */
uint32_t wdt_int_st:1; uint32_t wdt_int_st: 1;
uint32_t reserved_3:29; uint32_t reserved_3: 29;
}; };
uint32_t val; uint32_t val;
} timg_int_st_timers_reg_t; } timg_int_st_timers_reg_t;
@ -469,16 +464,16 @@ typedef union {
/** t0_int_clr : WT; bitpos: [0]; default: 0; /** t0_int_clr : WT; bitpos: [0]; default: 0;
* Set this bit to clear the TIMG_T0_INT interrupt. * Set this bit to clear the TIMG_T0_INT interrupt.
*/ */
uint32_t t0_int_clr:1; uint32_t t0_int_clr: 1;
/** t1_int_clr : WT; bitpos: [1]; default: 0; /** t1_int_clr : WT; bitpos: [1]; default: 0;
* Set this bit to clear the TIMG_T1_INT interrupt. * Set this bit to clear the TIMG_T1_INT interrupt.
*/ */
uint32_t t1_int_clr:1; uint32_t t1_int_clr: 1;
/** wdt_int_clr : WT; bitpos: [2]; default: 0; /** wdt_int_clr : WT; bitpos: [2]; default: 0;
* Set this bit to clear the TIMG_WDT_INT interrupt. * Set this bit to clear the TIMG_WDT_INT interrupt.
*/ */
uint32_t wdt_int_clr:1; uint32_t wdt_int_clr: 1;
uint32_t reserved_3:29; uint32_t reserved_3: 29;
}; };
uint32_t val; uint32_t val;
} timg_int_clr_timers_reg_t; } timg_int_clr_timers_reg_t;
@ -493,8 +488,8 @@ typedef union {
/** ntimers_date : R/W; bitpos: [27:0]; default: 33566833; /** ntimers_date : R/W; bitpos: [27:0]; default: 33566833;
* Timer version control register * Timer version control register
*/ */
uint32_t ntimers_date:28; uint32_t ntimers_date: 28;
uint32_t reserved_28:4; uint32_t reserved_28: 4;
}; };
uint32_t val; uint32_t val;
} timg_ntimers_date_reg_t; } timg_ntimers_date_reg_t;
@ -504,13 +499,13 @@ typedef union {
*/ */
typedef union { typedef union {
struct { struct {
uint32_t reserved_0:31; uint32_t reserved_0: 31;
/** clk_en : R/W; bitpos: [31]; default: 0; /** clk_en : R/W; bitpos: [31]; default: 0;
* Register clock gate signal. 1: The clock for software to read and write registers * Register clock gate signal. 1: The clock for software to read and write registers
* is always on. 0: The clock for software to read and write registers only exits when * is always on. 0: The clock for software to read and write registers only exits when
* the operation happens. * the operation happens.
*/ */
uint32_t clk_en:1; uint32_t clk_en: 1;
}; };
uint32_t val; uint32_t val;
} timg_regclk_reg_t; } timg_regclk_reg_t;
@ -527,7 +522,7 @@ typedef struct {
volatile timg_tnload_reg_t load; volatile timg_tnload_reg_t load;
} timg_hwtimer_reg_t; } timg_hwtimer_reg_t;
typedef struct { typedef struct timg_dev_t {
volatile timg_hwtimer_reg_t hw_timer[2]; volatile timg_hwtimer_reg_t hw_timer[2];
volatile timg_wdtconfig0_reg_t wdtconfig0; volatile timg_wdtconfig0_reg_t wdtconfig0;
volatile timg_wdtconfig1_reg_t wdtconfig1; volatile timg_wdtconfig1_reg_t wdtconfig1;

View File

@ -1,16 +1,8 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "soc/timer_periph.h" #include "soc/timer_periph.h"
@ -18,11 +10,17 @@ const timer_group_signal_conn_t timer_group_periph_signals = {
.groups = { .groups = {
[0] = { [0] = {
.module = PERIPH_TIMG0_MODULE, .module = PERIPH_TIMG0_MODULE,
.t0_irq_id = ETS_TG0_T0_LEVEL_INTR_SOURCE .timer_irq_id = {
[0] = ETS_TG0_T0_LEVEL_INTR_SOURCE,
[1] = ETS_TG0_T1_LEVEL_INTR_SOURCE,
}
}, },
[1] = { [1] = {
.module = PERIPH_TIMG1_MODULE, .module = PERIPH_TIMG1_MODULE,
.t0_irq_id = ETS_TG1_T0_LEVEL_INTR_SOURCE, .timer_irq_id = {
[0] = ETS_TG1_T0_LEVEL_INTR_SOURCE,
[1] = ETS_TG1_T1_LEVEL_INTR_SOURCE,
}
} }
} }
}; };

View File

@ -1,16 +1,8 @@
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once #pragma once
@ -27,7 +19,7 @@ extern "C" {
typedef struct { typedef struct {
struct { struct {
const periph_module_t module; // Peripheral module const periph_module_t module; // Peripheral module
const int t0_irq_id; // Interrupt ID of the first timer in the group const int timer_irq_id[SOC_TIMER_GROUP_TIMERS_PER_GROUP]; // interrupt source ID
} groups[SOC_TIMER_GROUPS]; } groups[SOC_TIMER_GROUPS];
} timer_group_signal_conn_t; } timer_group_signal_conn_t;

View File

@ -1,16 +1,8 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -59,25 +51,19 @@ static const char *TAG = "iot_light";
static DRAM_ATTR iot_light_t *g_light_config = NULL; static DRAM_ATTR iot_light_t *g_light_config = NULL;
static DRAM_ATTR uint16_t *g_gamma_table = NULL; static DRAM_ATTR uint16_t *g_gamma_table = NULL;
static DRAM_ATTR bool g_hw_timer_started = false; static DRAM_ATTR bool g_hw_timer_started = false;
static DRAM_ATTR timg_dev_t *TG[2] = {&TIMERG0, &TIMERG1};
static IRAM_ATTR esp_err_t _timer_pause(timer_group_t group_num, timer_idx_t timer_num)
{
TG[group_num]->hw_timer[timer_num].config.enable = 0;
return ESP_OK;
}
static void iot_timer_create(hw_timer_idx_t *timer_id, bool auto_reload, static void iot_timer_create(hw_timer_idx_t *timer_id, bool auto_reload,
uint32_t timer_interval_ms, void *isr_handle) uint32_t timer_interval_ms, void *isr_handle)
{ {
/* Select and initialize basic parameters of the timer */ /* Select and initialize basic parameters of the timer */
timer_config_t config; timer_config_t config = {
config.divider = HW_TIMER_DIVIDER; .divider = HW_TIMER_DIVIDER,
config.counter_dir = TIMER_COUNT_UP; .counter_dir = TIMER_COUNT_UP,
config.counter_en = TIMER_PAUSE; .counter_en = TIMER_PAUSE,
config.alarm_en = TIMER_ALARM_EN; .alarm_en = TIMER_ALARM_EN,
config.intr_type = TIMER_INTR_LEVEL; .intr_type = TIMER_INTR_LEVEL,
config.auto_reload = auto_reload; .auto_reload = auto_reload,
};
timer_init(timer_id->timer_group, timer_id->timer_id, &config); timer_init(timer_id->timer_group, timer_id->timer_id, &config);
/* Timer's counter will initially start from value below. /* Timer's counter will initially start from value below.
@ -99,7 +85,7 @@ static void iot_timer_start(hw_timer_idx_t *timer_id)
static IRAM_ATTR void iot_timer_stop(hw_timer_idx_t *timer_id) static IRAM_ATTR void iot_timer_stop(hw_timer_idx_t *timer_id)
{ {
_timer_pause(timer_id->timer_group, timer_id->timer_id); timer_group_set_counter_enable_in_isr(timer_id->timer_group, timer_id->timer_id, TIMER_PAUSE);
g_hw_timer_started = false; g_hw_timer_started = false;
} }
@ -284,51 +270,12 @@ static IRAM_ATTR void fade_timercb(void *para)
int timer_idx = (int) para; int timer_idx = (int) para;
int idle_channel_num = 0; int idle_channel_num = 0;
if (HW_TIMER_GROUP == TIMER_GROUP_0) { /* Retrieve the interrupt status */
/* Retrieve the interrupt status */ timer_group_get_intr_status_in_isr(HW_TIMER_GROUP);
#if CONFIG_IDF_TARGET_ESP32C3 timer_group_clr_intr_status_in_isr(HW_TIMER_GROUP, timer_idx);
uint32_t intr_status = TIMERG0.int_st.val; /* After the alarm has been triggered
TIMERG0.hw_timer[timer_idx].update.val = 1; we need enable it again, so it is triggered the next time */
#elif CONFIG_IDF_TARGET_ESP32 timer_group_enable_alarm_in_isr(HW_TIMER_GROUP, timer_idx);
uint32_t intr_status = TIMERG0.int_st_timers.val;
TIMERG0.hw_timer[timer_idx].update = 1;
#endif
/* Clear the interrupt */
if ((intr_status & BIT(timer_idx)) && timer_idx == TIMER_0) {
#if CONFIG_IDF_TARGET_ESP32C3
TIMERG0.int_clr.t0 = 1;
#elif CONFIG_IDF_TARGET_ESP32
TIMERG0.int_clr_timers.t0 = 1;
} else if ((intr_status & BIT(timer_idx)) && timer_idx == TIMER_1) {
TIMERG0.int_clr_timers.t1 = 1;
#endif
}
/* 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;
} else if (HW_TIMER_GROUP == TIMER_GROUP_1) {
#if CONFIG_IDF_TARGET_ESP32C3
uint32_t intr_status = TIMERG1.int_st.val;
TIMERG1.hw_timer[timer_idx].update.val = 1;
#elif CONFIG_IDF_TARGET_ESP32
uint32_t intr_status = TIMERG1.int_st_timers.val;
TIMERG1.hw_timer[timer_idx].update = 1;
#endif
if ((intr_status & BIT(timer_idx)) && timer_idx == TIMER_0) {
#if CONFIG_IDF_TARGET_ESP32C3
TIMERG1.int_clr.t0 = 1;
#elif CONFIG_IDF_TARGET_ESP32
TIMERG1.int_clr_timers.t0 = 1;
} else if ((intr_status & BIT(timer_idx)) && timer_idx == TIMER_1) {
TIMERG1.int_clr_timers.t1 = 1;
#endif
}
TIMERG1.hw_timer[timer_idx].config.alarm_en = TIMER_ALARM_EN;
}
for (int channel = 0; channel < LEDC_CHANNEL_MAX; channel++) { for (int channel = 0; channel < LEDC_CHANNEL_MAX; channel++) {
ledc_fade_data_t *fade_data = g_light_config->fade_data + channel; ledc_fade_data_t *fade_data = g_light_config->fade_data + channel;
@ -349,7 +296,7 @@ static IRAM_ATTR void fade_timercb(void *para)
_iot_update_duty(g_light_config->speed_mode, channel); _iot_update_duty(g_light_config->speed_mode, channel);
} else { } else {
iot_ledc_set_duty(g_light_config->speed_mode,channel,gamma_value_to_duty(fade_data->cur)); iot_ledc_set_duty(g_light_config->speed_mode, channel, gamma_value_to_duty(fade_data->cur));
_iot_update_duty(g_light_config->speed_mode, channel); _iot_update_duty(g_light_config->speed_mode, channel);
} }
} else if (fade_data->cycle) { } else if (fade_data->cycle) {
@ -497,7 +444,7 @@ esp_err_t iot_led_set_channel(ledc_channel_t channel, uint8_t value, uint32_t fa
fade_data->step *= -1; fade_data->step *= -1;
} }
if (fade_data->cycle != 0){ if (fade_data->cycle != 0) {
fade_data->cycle = 0; fade_data->cycle = 0;
} }

View File

@ -1,16 +1,8 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdio.h> #include <stdio.h>
#include "math.h" #include "math.h"
@ -83,13 +75,14 @@ static esp_err_t iot_light_duty_set(light_handle_t light_handle, uint8_t channel
static void iot_timer_create(hw_timer_idx_t *timer_id, bool auto_reload, double timer_interval_sec, timer_isr_handle_t *isr_handle) static void iot_timer_create(hw_timer_idx_t *timer_id, bool auto_reload, double timer_interval_sec, timer_isr_handle_t *isr_handle)
{ {
/* Select and initialize basic parameters of the timer */ /* Select and initialize basic parameters of the timer */
timer_config_t config; timer_config_t config = {
config.divider = HW_TIMER_DIVIDER; .divider = HW_TIMER_DIVIDER,
config.counter_dir = TIMER_COUNT_UP; .counter_dir = TIMER_COUNT_UP,
config.counter_en = TIMER_PAUSE; .counter_en = TIMER_PAUSE,
config.alarm_en = TIMER_ALARM_EN; .alarm_en = TIMER_ALARM_EN,
config.intr_type = TIMER_INTR_LEVEL; .intr_type = TIMER_INTR_LEVEL,
config.auto_reload = auto_reload; .auto_reload = auto_reload,
};
timer_init(timer_id->timer_group, timer_id->timer_id, &config); timer_init(timer_id->timer_group, timer_id->timer_id, &config);
/* Timer's counter will initially start from value below. /* Timer's counter will initially start from value below.
@ -167,33 +160,12 @@ static IRAM_ATTR void breath_timer_callback(void *para)
{ {
int timer_idx = (int) para; int timer_idx = (int) para;
if (HW_TIMER_GROUP == TIMER_GROUP_0) { /* Retrieve the interrupt status */
/* Retrieve the interrupt status */ timer_group_get_intr_status_in_isr(HW_TIMER_GROUP);
uint32_t intr_status = TIMERG0.int_st_timers.val; timer_group_clr_intr_status_in_isr(HW_TIMER_GROUP, timer_idx);
TIMERG0.hw_timer[timer_idx].update = 1; /* After the alarm has been triggered
we need enable it again, so it is triggered the next time */
/* Clear the interrupt */ timer_group_enable_alarm_in_isr(HW_TIMER_GROUP, timer_idx);
if ((intr_status & BIT(timer_idx)) && timer_idx == TIMER_0) {
TIMERG0.int_clr_timers.t0 = 1;
} else if ((intr_status & BIT(timer_idx)) && timer_idx == TIMER_1) {
TIMERG0.int_clr_timers.t1 = 1;
}
/* 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;
} else if (HW_TIMER_GROUP == TIMER_GROUP_1) {
uint32_t intr_status = TIMERG1.int_st_timers.val;
TIMERG1.hw_timer[timer_idx].update = 1;
if ((intr_status & BIT(timer_idx)) && timer_idx == TIMER_0) {
TIMERG1.int_clr_timers.t0 = 1;
} else if ((intr_status & BIT(timer_idx)) && timer_idx == TIMER_1) {
TIMERG1.int_clr_timers.t1 = 1;
}
TIMERG1.hw_timer[timer_idx].config.alarm_en = TIMER_ALARM_EN;
}
for (int i = 0; i < LIGHT_NUM_MAX; i++) { for (int i = 0; i < LIGHT_NUM_MAX; i++) {
if (g_light_group[i] != NULL) { if (g_light_group[i] != NULL) {

View File

@ -1,3 +1,10 @@
#!/usr/bin/env python
#
# SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
#
# SPDX-License-Identifier: CC0-1.0
#
from __future__ import unicode_literals from __future__ import unicode_literals
import re import re
@ -6,7 +13,7 @@ from typing import Any
import ttfw_idf import ttfw_idf
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32', 'esp32c3']) @ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32', 'esp32s2', 'esp32c3'])
def test_examples_timergroup(env, extra_data): # type: (Any, Any) -> None def test_examples_timergroup(env, extra_data): # type: (Any, Any) -> None
dut = env.get_dut('timer_group', 'examples/peripherals/timer_group') dut = env.get_dut('timer_group', 'examples/peripherals/timer_group')
dut.start_app() dut.start_app()

View File

@ -1,11 +1,9 @@
/* General Purpose Timer example /*
* SPDX-FileCopyrightText: 2010-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h> #include <stdio.h>
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"

View File

@ -86,15 +86,16 @@ static void example_sysview_event_send(uint32_t id, uint32_t val)
static void example_timer_init(int timer_group, int timer_idx, uint32_t period) static void example_timer_init(int timer_group, int timer_idx, uint32_t period)
{ {
timer_config_t config;
uint64_t alarm_val = (period * (TIMER_BASE_CLK / 1000000UL)) / 2; uint64_t alarm_val = (period * (TIMER_BASE_CLK / 1000000UL)) / 2;
config.alarm_en = 1; timer_config_t config = {
config.auto_reload = 1; .alarm_en = 1,
config.counter_dir = TIMER_COUNT_UP; .auto_reload = 1,
config.divider = 2; //Range is 2 to 65536 .counter_dir = TIMER_COUNT_UP,
config.intr_type = TIMER_INTR_LEVEL; .divider = 2, //Range is 2 to 65536
config.counter_en = TIMER_PAUSE; .intr_type = TIMER_INTR_LEVEL,
.counter_en = TIMER_PAUSE,
};
/*Configure timer*/ /*Configure timer*/
timer_init(timer_group, timer_idx, &config); timer_init(timer_group, timer_idx, &config);
/*Stop timer counter*/ /*Stop timer counter*/

View File

@ -1116,7 +1116,6 @@ components/esp_system/include/esp_private/usb_console.h
components/esp_system/include/esp_system.h components/esp_system/include/esp_system.h
components/esp_system/include/esp_task.h components/esp_system/include/esp_task.h
components/esp_system/include/esp_task_wdt.h components/esp_system/include/esp_task_wdt.h
components/esp_system/int_wdt.c
components/esp_system/panic.c components/esp_system/panic.c
components/esp_system/port/arch/riscv/expression_with_stack.c components/esp_system/port/arch/riscv/expression_with_stack.c
components/esp_system/port/arch/xtensa/debug_helpers.c components/esp_system/port/arch/xtensa/debug_helpers.c
@ -1327,8 +1326,6 @@ components/freemodbus/port/portother.c
components/freemodbus/port/portother_m.c components/freemodbus/port/portother_m.c
components/freemodbus/port/portserial.c components/freemodbus/port/portserial.c
components/freemodbus/port/portserial_m.c components/freemodbus/port/portserial_m.c
components/freemodbus/port/porttimer.c
components/freemodbus/port/porttimer_m.c
components/freemodbus/serial_master/modbus_controller/mbc_serial_master.c components/freemodbus/serial_master/modbus_controller/mbc_serial_master.c
components/freemodbus/serial_master/modbus_controller/mbc_serial_master.h components/freemodbus/serial_master/modbus_controller/mbc_serial_master.h
components/freemodbus/serial_master/port/port_serial_master.h components/freemodbus/serial_master/port/port_serial_master.h
@ -1446,7 +1443,6 @@ components/hal/esp32/include/hal/interrupt_controller_ll.h
components/hal/esp32/include/hal/ledc_ll.h components/hal/esp32/include/hal/ledc_ll.h
components/hal/esp32/include/hal/mcpwm_ll.h components/hal/esp32/include/hal/mcpwm_ll.h
components/hal/esp32/include/hal/mpu_ll.h components/hal/esp32/include/hal/mpu_ll.h
components/hal/esp32/include/hal/mwdt_ll.h
components/hal/esp32/include/hal/pcnt_ll.h components/hal/esp32/include/hal/pcnt_ll.h
components/hal/esp32/include/hal/rmt_ll.h components/hal/esp32/include/hal/rmt_ll.h
components/hal/esp32/include/hal/rtc_cntl_ll.h components/hal/esp32/include/hal/rtc_cntl_ll.h
@ -1458,7 +1454,6 @@ components/hal/esp32/include/hal/soc_ll.h
components/hal/esp32/include/hal/spi_flash_encrypted_ll.h components/hal/esp32/include/hal/spi_flash_encrypted_ll.h
components/hal/esp32/include/hal/spi_flash_ll.h components/hal/esp32/include/hal/spi_flash_ll.h
components/hal/esp32/include/hal/spi_ll.h components/hal/esp32/include/hal/spi_ll.h
components/hal/esp32/include/hal/timer_ll.h
components/hal/esp32/include/hal/touch_sensor_hal.h components/hal/esp32/include/hal/touch_sensor_hal.h
components/hal/esp32/include/hal/touch_sensor_ll.h components/hal/esp32/include/hal/touch_sensor_ll.h
components/hal/esp32/include/hal/trace_ll.h components/hal/esp32/include/hal/trace_ll.h
@ -1485,7 +1480,6 @@ components/hal/esp32c3/include/hal/interrupt_controller_ll.h
components/hal/esp32c3/include/hal/ledc_ll.h components/hal/esp32c3/include/hal/ledc_ll.h
components/hal/esp32c3/include/hal/memprot_ll.h components/hal/esp32c3/include/hal/memprot_ll.h
components/hal/esp32c3/include/hal/mpu_ll.h components/hal/esp32c3/include/hal/mpu_ll.h
components/hal/esp32c3/include/hal/mwdt_ll.h
components/hal/esp32c3/include/hal/rtc_cntl_ll.h components/hal/esp32c3/include/hal/rtc_cntl_ll.h
components/hal/esp32c3/include/hal/rwdt_ll.h components/hal/esp32c3/include/hal/rwdt_ll.h
components/hal/esp32c3/include/hal/sha_ll.h components/hal/esp32c3/include/hal/sha_ll.h
@ -1496,7 +1490,6 @@ components/hal/esp32c3/include/hal/spi_flash_ll.h
components/hal/esp32c3/include/hal/spi_ll.h components/hal/esp32c3/include/hal/spi_ll.h
components/hal/esp32c3/include/hal/spimem_flash_ll.h components/hal/esp32c3/include/hal/spimem_flash_ll.h
components/hal/esp32c3/include/hal/systimer_ll.h components/hal/esp32c3/include/hal/systimer_ll.h
components/hal/esp32c3/include/hal/timer_ll.h
components/hal/esp32c3/include/hal/twai_ll.h components/hal/esp32c3/include/hal/twai_ll.h
components/hal/esp32c3/include/hal/uart_ll.h components/hal/esp32c3/include/hal/uart_ll.h
components/hal/esp32c3/include/hal/uhci_ll.h components/hal/esp32c3/include/hal/uhci_ll.h
@ -1521,7 +1514,6 @@ components/hal/esp32h2/include/hal/interrupt_controller_ll.h
components/hal/esp32h2/include/hal/ledc_ll.h components/hal/esp32h2/include/hal/ledc_ll.h
components/hal/esp32h2/include/hal/memprot_ll.h components/hal/esp32h2/include/hal/memprot_ll.h
components/hal/esp32h2/include/hal/mpu_ll.h components/hal/esp32h2/include/hal/mpu_ll.h
components/hal/esp32h2/include/hal/mwdt_ll.h
components/hal/esp32h2/include/hal/rtc_cntl_ll.h components/hal/esp32h2/include/hal/rtc_cntl_ll.h
components/hal/esp32h2/include/hal/rwdt_ll.h components/hal/esp32h2/include/hal/rwdt_ll.h
components/hal/esp32h2/include/hal/sha_ll.h components/hal/esp32h2/include/hal/sha_ll.h
@ -1532,7 +1524,6 @@ components/hal/esp32h2/include/hal/spi_flash_ll.h
components/hal/esp32h2/include/hal/spi_ll.h components/hal/esp32h2/include/hal/spi_ll.h
components/hal/esp32h2/include/hal/spimem_flash_ll.h components/hal/esp32h2/include/hal/spimem_flash_ll.h
components/hal/esp32h2/include/hal/systimer_ll.h components/hal/esp32h2/include/hal/systimer_ll.h
components/hal/esp32h2/include/hal/timer_ll.h
components/hal/esp32h2/include/hal/twai_ll.h components/hal/esp32h2/include/hal/twai_ll.h
components/hal/esp32h2/include/hal/uart_ll.h components/hal/esp32h2/include/hal/uart_ll.h
components/hal/esp32h2/include/hal/uhci_ll.h components/hal/esp32h2/include/hal/uhci_ll.h
@ -1563,7 +1554,6 @@ components/hal/esp32s2/include/hal/ledc_ll.h
components/hal/esp32s2/include/hal/memprot_ll.h components/hal/esp32s2/include/hal/memprot_ll.h
components/hal/esp32s2/include/hal/memprot_peri_ll.h components/hal/esp32s2/include/hal/memprot_peri_ll.h
components/hal/esp32s2/include/hal/mpu_ll.h components/hal/esp32s2/include/hal/mpu_ll.h
components/hal/esp32s2/include/hal/mwdt_ll.h
components/hal/esp32s2/include/hal/pcnt_ll.h components/hal/esp32s2/include/hal/pcnt_ll.h
components/hal/esp32s2/include/hal/rtc_cntl_ll.h components/hal/esp32s2/include/hal/rtc_cntl_ll.h
components/hal/esp32s2/include/hal/rtc_io_ll.h components/hal/esp32s2/include/hal/rtc_io_ll.h
@ -1576,7 +1566,6 @@ components/hal/esp32s2/include/hal/spi_flash_ll.h
components/hal/esp32s2/include/hal/spi_ll.h components/hal/esp32s2/include/hal/spi_ll.h
components/hal/esp32s2/include/hal/spimem_flash_ll.h components/hal/esp32s2/include/hal/spimem_flash_ll.h
components/hal/esp32s2/include/hal/systimer_ll.h components/hal/esp32s2/include/hal/systimer_ll.h
components/hal/esp32s2/include/hal/timer_ll.h
components/hal/esp32s2/include/hal/touch_sensor_hal.h components/hal/esp32s2/include/hal/touch_sensor_hal.h
components/hal/esp32s2/include/hal/touch_sensor_ll.h components/hal/esp32s2/include/hal/touch_sensor_ll.h
components/hal/esp32s2/include/hal/trace_ll.h components/hal/esp32s2/include/hal/trace_ll.h
@ -1598,7 +1587,6 @@ components/hal/esp32s3/include/hal/ledc_ll.h
components/hal/esp32s3/include/hal/mcpwm_ll.h components/hal/esp32s3/include/hal/mcpwm_ll.h
components/hal/esp32s3/include/hal/memprot_ll.h components/hal/esp32s3/include/hal/memprot_ll.h
components/hal/esp32s3/include/hal/mpu_ll.h components/hal/esp32s3/include/hal/mpu_ll.h
components/hal/esp32s3/include/hal/mwdt_ll.h
components/hal/esp32s3/include/hal/pcnt_ll.h components/hal/esp32s3/include/hal/pcnt_ll.h
components/hal/esp32s3/include/hal/rtc_cntl_ll.h components/hal/esp32s3/include/hal/rtc_cntl_ll.h
components/hal/esp32s3/include/hal/rwdt_ll.h components/hal/esp32s3/include/hal/rwdt_ll.h
@ -1610,7 +1598,6 @@ components/hal/esp32s3/include/hal/spi_flash_ll.h
components/hal/esp32s3/include/hal/spi_ll.h components/hal/esp32s3/include/hal/spi_ll.h
components/hal/esp32s3/include/hal/spimem_flash_ll.h components/hal/esp32s3/include/hal/spimem_flash_ll.h
components/hal/esp32s3/include/hal/systimer_ll.h components/hal/esp32s3/include/hal/systimer_ll.h
components/hal/esp32s3/include/hal/timer_ll.h
components/hal/esp32s3/include/hal/trace_ll.h components/hal/esp32s3/include/hal/trace_ll.h
components/hal/esp32s3/include/hal/twai_ll.h components/hal/esp32s3/include/hal/twai_ll.h
components/hal/esp32s3/include/hal/uart_ll.h components/hal/esp32s3/include/hal/uart_ll.h
@ -1675,8 +1662,6 @@ components/hal/include/hal/spi_slave_hd_hal.h
components/hal/include/hal/spi_types.h components/hal/include/hal/spi_types.h
components/hal/include/hal/systimer_hal.h components/hal/include/hal/systimer_hal.h
components/hal/include/hal/systimer_types.h components/hal/include/hal/systimer_types.h
components/hal/include/hal/timer_hal.h
components/hal/include/hal/timer_types.h
components/hal/include/hal/touch_sensor_hal.h components/hal/include/hal/touch_sensor_hal.h
components/hal/include/hal/twai_hal.h components/hal/include/hal/twai_hal.h
components/hal/include/hal/twai_types.h components/hal/include/hal/twai_types.h
@ -1716,7 +1701,6 @@ components/hal/spi_slave_hal_iram.c
components/hal/spi_slave_hd_hal.c components/hal/spi_slave_hd_hal.c
components/hal/systimer_hal.c components/hal/systimer_hal.c
components/hal/test/test_mpu.c components/hal/test/test_mpu.c
components/hal/timer_hal.c
components/hal/touch_sensor_hal.c components/hal/touch_sensor_hal.c
components/hal/twai_hal.c components/hal/twai_hal.c
components/hal/twai_hal_iram.c components/hal/twai_hal_iram.c
@ -2222,8 +2206,6 @@ components/soc/esp32/include/soc/spi_reg.h
components/soc/esp32/include/soc/spi_struct.h components/soc/esp32/include/soc/spi_struct.h
components/soc/esp32/include/soc/syscon_reg.h components/soc/esp32/include/soc/syscon_reg.h
components/soc/esp32/include/soc/syscon_struct.h components/soc/esp32/include/soc/syscon_struct.h
components/soc/esp32/include/soc/timer_group_reg.h
components/soc/esp32/include/soc/timer_group_struct.h
components/soc/esp32/include/soc/touch_sensor_channel.h components/soc/esp32/include/soc/touch_sensor_channel.h
components/soc/esp32/include/soc/twai_struct.h components/soc/esp32/include/soc/twai_struct.h
components/soc/esp32/include/soc/uart_channel.h components/soc/esp32/include/soc/uart_channel.h
@ -2243,7 +2225,6 @@ components/soc/esp32/sdio_slave_periph.c
components/soc/esp32/sdmmc_periph.c components/soc/esp32/sdmmc_periph.c
components/soc/esp32/sigmadelta_periph.c components/soc/esp32/sigmadelta_periph.c
components/soc/esp32/spi_periph.c components/soc/esp32/spi_periph.c
components/soc/esp32/timer_periph.c
components/soc/esp32/touch_sensor_periph.c components/soc/esp32/touch_sensor_periph.c
components/soc/esp32/uart_periph.c components/soc/esp32/uart_periph.c
components/soc/esp32c3/adc_periph.c components/soc/esp32c3/adc_periph.c
@ -2329,7 +2310,6 @@ components/soc/esp32c3/ledc_periph.c
components/soc/esp32c3/rmt_periph.c components/soc/esp32c3/rmt_periph.c
components/soc/esp32c3/sigmadelta_periph.c components/soc/esp32c3/sigmadelta_periph.c
components/soc/esp32c3/spi_periph.c components/soc/esp32c3/spi_periph.c
components/soc/esp32c3/timer_periph.c
components/soc/esp32c3/uart_periph.c components/soc/esp32c3/uart_periph.c
components/soc/esp32h2/adc_periph.c components/soc/esp32h2/adc_periph.c
components/soc/esp32h2/gdma_periph.c components/soc/esp32h2/gdma_periph.c
@ -2417,7 +2397,6 @@ components/soc/esp32h2/ledc_periph.c
components/soc/esp32h2/rmt_periph.c components/soc/esp32h2/rmt_periph.c
components/soc/esp32h2/sigmadelta_periph.c components/soc/esp32h2/sigmadelta_periph.c
components/soc/esp32h2/spi_periph.c components/soc/esp32h2/spi_periph.c
components/soc/esp32h2/timer_periph.c
components/soc/esp32h2/uart_periph.c components/soc/esp32h2/uart_periph.c
components/soc/esp32s2/adc_periph.c components/soc/esp32s2/adc_periph.c
components/soc/esp32s2/dac_periph.c components/soc/esp32s2/dac_periph.c
@ -2523,7 +2502,6 @@ components/soc/esp32s2/rmt_periph.c
components/soc/esp32s2/rtc_io_periph.c components/soc/esp32s2/rtc_io_periph.c
components/soc/esp32s2/sigmadelta_periph.c components/soc/esp32s2/sigmadelta_periph.c
components/soc/esp32s2/spi_periph.c components/soc/esp32s2/spi_periph.c
components/soc/esp32s2/timer_periph.c
components/soc/esp32s2/touch_sensor_periph.c components/soc/esp32s2/touch_sensor_periph.c
components/soc/esp32s2/uart_periph.c components/soc/esp32s2/uart_periph.c
components/soc/esp32s2/usb_periph.c components/soc/esp32s2/usb_periph.c
@ -2623,8 +2601,6 @@ components/soc/esp32s3/include/soc/system_reg.h
components/soc/esp32s3/include/soc/system_struct.h components/soc/esp32s3/include/soc/system_struct.h
components/soc/esp32s3/include/soc/systimer_reg.h components/soc/esp32s3/include/soc/systimer_reg.h
components/soc/esp32s3/include/soc/systimer_struct.h components/soc/esp32s3/include/soc/systimer_struct.h
components/soc/esp32s3/include/soc/timer_group_reg.h
components/soc/esp32s3/include/soc/timer_group_struct.h
components/soc/esp32s3/include/soc/touch_channel.h components/soc/esp32s3/include/soc/touch_channel.h
components/soc/esp32s3/include/soc/touch_sensor_caps.h components/soc/esp32s3/include/soc/touch_sensor_caps.h
components/soc/esp32s3/include/soc/twai_caps.h components/soc/esp32s3/include/soc/twai_caps.h
@ -2660,7 +2636,6 @@ components/soc/esp32s3/sdio_slave_periph.c
components/soc/esp32s3/sdmmc_periph.c components/soc/esp32s3/sdmmc_periph.c
components/soc/esp32s3/sigmadelta_periph.c components/soc/esp32s3/sigmadelta_periph.c
components/soc/esp32s3/spi_periph.c components/soc/esp32s3/spi_periph.c
components/soc/esp32s3/timer_periph.c
components/soc/esp32s3/uart_periph.c components/soc/esp32s3/uart_periph.c
components/soc/esp32s3/usb_periph.c components/soc/esp32s3/usb_periph.c
components/soc/esp32s3/usb_periph.h components/soc/esp32s3/usb_periph.h
@ -2690,7 +2665,6 @@ components/soc/include/soc/sigmadelta_periph.h
components/soc/include/soc/soc_memory_types.h components/soc/include/soc/soc_memory_types.h
components/soc/include/soc/spi_periph.h components/soc/include/soc/spi_periph.h
components/soc/include/soc/syscon_periph.h components/soc/include/soc/syscon_periph.h
components/soc/include/soc/timer_periph.h
components/soc/include/soc/touch_sensor_periph.h components/soc/include/soc/touch_sensor_periph.h
components/soc/include/soc/twai_periph.h components/soc/include/soc/twai_periph.h
components/soc/include/soc/uart_periph.h components/soc/include/soc/uart_periph.h
@ -3375,8 +3349,6 @@ examples/bluetooth/esp_ble_mesh/common_components/fast_provisioning/ble_mesh_fas
examples/bluetooth/esp_ble_mesh/common_components/light_driver/include/iot_led.h examples/bluetooth/esp_ble_mesh/common_components/light_driver/include/iot_led.h
examples/bluetooth/esp_ble_mesh/common_components/light_driver/include/iot_light.h examples/bluetooth/esp_ble_mesh/common_components/light_driver/include/iot_light.h
examples/bluetooth/esp_ble_mesh/common_components/light_driver/include/light_driver.h examples/bluetooth/esp_ble_mesh/common_components/light_driver/include/light_driver.h
examples/bluetooth/esp_ble_mesh/common_components/light_driver/iot_led.c
examples/bluetooth/esp_ble_mesh/common_components/light_driver/iot_light.c
examples/bluetooth/esp_ble_mesh/common_components/light_driver/light_driver.c examples/bluetooth/esp_ble_mesh/common_components/light_driver/light_driver.c
examples/bluetooth/esp_hid_device/main/esp_hid_device_main.c examples/bluetooth/esp_hid_device/main/esp_hid_device_main.c
examples/bluetooth/esp_hid_device/main/esp_hid_gap.c examples/bluetooth/esp_hid_device/main/esp_hid_gap.c
@ -3595,8 +3567,6 @@ examples/peripherals/spi_slave_hd/append_mode/slave/main/app_main.c
examples/peripherals/spi_slave_hd/segment_mode/seg_master/main/app_main.c examples/peripherals/spi_slave_hd/segment_mode/seg_master/main/app_main.c
examples/peripherals/spi_slave_hd/segment_mode/seg_slave/main/app_main.c examples/peripherals/spi_slave_hd/segment_mode/seg_slave/main/app_main.c
examples/peripherals/temp_sensor/main/temp_sensor_main.c examples/peripherals/temp_sensor/main/temp_sensor_main.c
examples/peripherals/timer_group/example_test.py
examples/peripherals/timer_group/main/timer_group_example_main.c
examples/peripherals/touch_element/touch_button/main/touch_button_example_main.c examples/peripherals/touch_element/touch_button/main/touch_button_example_main.c
examples/peripherals/touch_element/touch_element_waterproof/main/waterproof_example_main.c examples/peripherals/touch_element/touch_element_waterproof/main/waterproof_example_main.c
examples/peripherals/touch_element/touch_elements_combination/main/touch_elements_example_main.c examples/peripherals/touch_element/touch_elements_combination/main/touch_elements_example_main.c
@ -4159,7 +4129,6 @@ tools/unit-test-app/components/test_utils/include/ccomp_timer.h
tools/unit-test-app/components/test_utils/include/test_utils.h tools/unit-test-app/components/test_utils/include/test_utils.h
tools/unit-test-app/components/test_utils/private_include/ccomp_timer_impl.h tools/unit-test-app/components/test_utils/private_include/ccomp_timer_impl.h
tools/unit-test-app/components/test_utils/ref_clock_impl_rmt_pcnt.c tools/unit-test-app/components/test_utils/ref_clock_impl_rmt_pcnt.c
tools/unit-test-app/components/test_utils/ref_clock_impl_timergroup.c
tools/unit-test-app/components/test_utils/test/ccomp_timer_test_api.c tools/unit-test-app/components/test_utils/test/ccomp_timer_test_api.c
tools/unit-test-app/components/test_utils/test/ccomp_timer_test_data.c tools/unit-test-app/components/test_utils/test/ccomp_timer_test_data.c
tools/unit-test-app/components/test_utils/test/ccomp_timer_test_inst.c tools/unit-test-app/components/test_utils/test/ccomp_timer_test_inst.c

View File

@ -1,21 +1,14 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "test_utils.h" #include "test_utils.h"
#include "driver/periph_ctrl.h" #include "driver/periph_ctrl.h"
#include "soc/periph_defs.h" #include "soc/periph_defs.h"
#include "hal/timer_hal.h" #include "hal/timer_hal.h"
#include "hal/timer_ll.h"
#define TIMER_GROUP_ID (1) #define TIMER_GROUP_ID (1)
#define TIMER_ID (0) #define TIMER_ID (0)
@ -25,26 +18,24 @@ void ref_clock_init(void)
{ {
periph_module_enable(PERIPH_TIMG1_MODULE); periph_module_enable(PERIPH_TIMG1_MODULE);
timer_hal_init(&timer_hal, TIMER_GROUP_ID, TIMER_ID); timer_hal_init(&timer_hal, TIMER_GROUP_ID, TIMER_ID);
timer_hal_set_use_xtal(&timer_hal, true); // Select XTAL, so ref_clock is independent of the APL clock timer_ll_set_clock_source(timer_hal.dev, TIMER_ID, GPTIMER_CLK_SRC_XTAL); // Select XTAL, so ref_clock is independent of the APL clock
timer_hal_set_divider(&timer_hal, 40); // Resolution is configured to 1MHz timer_ll_enable_counter(timer_hal.dev, TIMER_ID, false); // stop timer from running
timer_hal_set_counter_increase(&timer_hal, true); // increase mode timer_ll_set_clock_prescale(timer_hal.dev, TIMER_ID, 40); // Resolution is configured to 1MHz
timer_hal_set_counter_enable(&timer_hal, false); // stop timer from running timer_ll_set_count_direction(timer_hal.dev, timer_hal.timer_id, GPTIMER_COUNT_UP); // increase mode
timer_hal_set_counter_value(&timer_hal, 0); // initial count value to zero timer_hal_set_counter_value(&timer_hal, 0); // initial count value to zero
timer_hal_intr_disable(&timer_hal); // disable interrupt timer_ll_enable_intr(timer_hal.dev, TIMER_LL_EVENT_ALARM(TIMER_ID), false); // disable interrupt
timer_hal_set_alarm_enable(&timer_hal, false); // we don't need to generate any interrupt timer_ll_enable_alarm(timer_hal.dev, TIMER_ID, false); // alarm event is not needed
timer_hal_set_auto_reload(&timer_hal, false); timer_ll_enable_auto_reload(timer_hal.dev, TIMER_ID, false);
timer_hal_set_counter_enable(&timer_hal, true); // start counter timer_ll_enable_counter(timer_hal.dev, TIMER_ID, true); // start counter
} }
void ref_clock_deinit(void) void ref_clock_deinit(void)
{ {
timer_hal_set_counter_enable(&timer_hal, false); // stop timer from running timer_ll_enable_counter(timer_hal.dev, TIMER_ID, false); // stop timer from running
periph_module_disable(PERIPH_TIMG1_MODULE); periph_module_disable(PERIPH_TIMG1_MODULE);
} }
uint64_t ref_clock_get(void) uint64_t ref_clock_get(void)
{ {
uint64_t count_value = 0; return timer_ll_get_counter_value(timer_hal.dev, timer_hal.timer_id);
timer_hal_get_counter_value(&timer_hal, &count_value);
return count_value;
} }