mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
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:
commit
3a530e3311
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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>();
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
|
||||||
if (intr_status & BIT(timer_obj->hal.idx)) {
|
|
||||||
is_awoken = timer_obj->timer_isr_fun.fn(timer_obj->timer_isr_fun.args);
|
|
||||||
//Clear intrrupt status
|
//Clear intrrupt status
|
||||||
timer_hal_clear_intr_status(&(timer_obj->hal));
|
timer_ll_clear_intr_status(hal->dev, TIMER_LL_EVENT_ALARM(timer_id));
|
||||||
//If the timer is set to auto reload, we need enable it again, so it is triggered the next time.
|
is_awoken = timer_obj->timer_isr_fun.fn(timer_obj->timer_isr_fun.args);
|
||||||
if (timer_hal_get_auto_reload(&timer_obj->hal)) {
|
//If the timer is set to auto reload, we need enable it again, so it is triggered the next time
|
||||||
timer_hal_set_alarm_enable(&(timer_obj->hal), TIMER_ALARM_EN);
|
timer_ll_enable_alarm(hal->dev, timer_id, timer_obj->auto_reload_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;
|
|
||||||
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;
|
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);
|
||||||
|
@ -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.
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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"
|
||||||
|
@ -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"
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -90,22 +83,23 @@ FORCE_INLINE_ATTR void mwdt_ll_config_stage(timg_dev_t *hw, wdt_stage_t stage, u
|
|||||||
{
|
{
|
||||||
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:
|
||||||
|
HAL_ASSERT(false && "unsupported WDT stage");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -120,18 +114,19 @@ 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:
|
||||||
|
HAL_ASSERT(false && "unsupported WDT stage");
|
||||||
break;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -192,7 +187,7 @@ FORCE_INLINE_ATTR void mwdt_ll_set_sys_reset_length(timg_dev_t *hw, wdt_reset_si
|
|||||||
*/
|
*/
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -245,7 +240,7 @@ FORCE_INLINE_ATTR void mwdt_ll_write_protect_disable(timg_dev_t *hw)
|
|||||||
*/
|
*/
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -256,7 +251,7 @@ FORCE_INLINE_ATTR void mwdt_ll_clear_intr_status(timg_dev_t* hw)
|
|||||||
*/
|
*/
|
||||||
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
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
*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].load_high = (uint32_t) (load_val >> 32);
|
hw->hw_timer[timer_num].config.tx_increase = direction == GPTIMER_COUNT_UP;
|
||||||
hw->hw_timer[timer_num].load_low = (uint32_t) load_val;
|
|
||||||
hw->hw_timer[timer_num].reload = 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].update = 1;
|
hw->hw_timer[timer_num].config.tx_en = en;
|
||||||
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 Get counter 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
|
|
||||||
*
|
*
|
||||||
* @return None
|
* @return counter value
|
||||||
*/
|
*/
|
||||||
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 uint64_t timer_ll_get_counter_value(timg_dev_t *hw, uint32_t timer_num)
|
||||||
{
|
{
|
||||||
hw->hw_timer[timer_num].config.increase = increase_en;
|
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) {
|
||||||
|
}
|
||||||
|
return ((uint64_t) hw->hw_timer[timer_num].hi.tx_hi << 32) | (hw->hw_timer[timer_num].lo.tx_lo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get 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 alarm_value When counter reaches alarm value, alarm event will be triggered
|
||||||
* @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_set_alarm_value(timg_dev_t *hw, uint32_t timer_num, uint64_t alarm_value)
|
||||||
{
|
{
|
||||||
return hw->hw_timer[timer_num].config.increase;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set counter status, enable or disable 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 counter_en True to enable counter, false to disable counter
|
* @return Counter value to trigger the alarm event
|
||||||
*
|
|
||||||
* @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 uint64_t timer_ll_get_alarm_value(timg_dev_t *hw, uint32_t timer_num)
|
||||||
{
|
{
|
||||||
hw->hw_timer[timer_num].config.enable = counter_en;
|
return ((uint64_t) hw->hw_timer[timer_num].alarmhi.tx_alarm_hi << 32) | (hw->hw_timer[timer_num].alarmlo.tx_alarm_lo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get counter status.
|
* @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 reload_val Reload counter value
|
||||||
* @return
|
|
||||||
* - 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 void timer_ll_set_reload_value(timg_dev_t *hw, uint32_t timer_num, uint64_t load_val)
|
||||||
{
|
{
|
||||||
return hw->hw_timer[timer_num].config.enable;
|
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 Set auto reload 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
|
||||||
* @param auto_reload_en True to enable auto reload mode, flase to disable auto reload mode
|
* @return reload count value
|
||||||
*
|
|
||||||
* @return None
|
|
||||||
*/
|
*/
|
||||||
static inline void timer_ll_set_auto_reload(timg_dev_t *hw, timer_idx_t timer_num, bool auto_reload_en)
|
static inline uint64_t timer_ll_get_reload_value(timg_dev_t *hw, uint32_t timer_num)
|
||||||
{
|
{
|
||||||
hw->hw_timer[timer_num].config.autoreload = auto_reload_en;
|
return ((uint64_t)hw->hw_timer[timer_num].loadhi.tx_load_hi << 32) | (hw->hw_timer[timer_num].loadlo.tx_load_lo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get auto reload mode.
|
* @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
|
|
||||||
* - 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)
|
static inline void timer_ll_trigger_soft_reload(timg_dev_t *hw, uint32_t timer_num)
|
||||||
{
|
{
|
||||||
return hw->hw_timer[timer_num].config.autoreload;
|
hw->hw_timer[timer_num].load.tx_load = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the counter value to trigger the alarm.
|
* @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 alarm_value Counter value to trigger the alarm
|
* @param en True: enable interrupt
|
||||||
*
|
* False: disable interrupt
|
||||||
* @return None
|
|
||||||
*/
|
*/
|
||||||
FORCE_INLINE_ATTR void timer_ll_set_alarm_value(timg_dev_t *hw, timer_idx_t timer_num, uint64_t alarm_value)
|
__attribute__((always_inline))
|
||||||
|
static inline void timer_ll_enable_intr(timg_dev_t *hw, uint32_t mask, bool en)
|
||||||
{
|
{
|
||||||
hw->hw_timer[timer_num].alarm_high = (uint32_t) (alarm_value >> 32);
|
if (en) {
|
||||||
hw->hw_timer[timer_num].alarm_low = (uint32_t) alarm_value;
|
hw->int_ena_timers.val |= mask;
|
||||||
|
} else {
|
||||||
|
hw->int_ena_timers.val &= ~mask;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the counter value to trigger the alarm.
|
* @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 alarm_value Pointer to accept the counter value to trigger the alarm
|
|
||||||
*
|
*
|
||||||
* @return None
|
* @return Interrupt status
|
||||||
*/
|
*/
|
||||||
static inline void timer_ll_get_alarm_value(timg_dev_t *hw, timer_idx_t timer_num, uint64_t *alarm_value)
|
__attribute__((always_inline))
|
||||||
|
static inline uint32_t timer_ll_get_intr_status(timg_dev_t *hw)
|
||||||
{
|
{
|
||||||
*alarm_value = ((uint64_t) hw->hw_timer[timer_num].alarm_high << 32) | (hw->hw_timer[timer_num].alarm_low);
|
return hw->int_st_timers.val & 0x03;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the alarm status, enable or disable the alarm.
|
* @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
|
||||||
* @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)
|
__attribute__((always_inline))
|
||||||
|
static inline void timer_ll_clear_intr_status(timg_dev_t *hw, uint32_t mask)
|
||||||
{
|
{
|
||||||
hw->hw_timer[timer_num].config.alarm_en = alarm_en;
|
hw->int_clr_timers.val = mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the alarm status.
|
* @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
|
||||||
*
|
* False: Register clock is enabled only when register operation happens
|
||||||
* @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 void timer_ll_enable_register_clock_always_on(timg_dev_t *hw, bool en)
|
||||||
{
|
{
|
||||||
return hw->hw_timer[timer_num].config.alarm_en;
|
hw->regclk.clk_en = 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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -138,6 +132,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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
*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.tn_load_hi = (uint32_t) (load_val >> 32);
|
hw->hw_timer[timer_num].config.tn_increase = (direction == GPTIMER_COUNT_UP);
|
||||||
hw->hw_timer[timer_num].loadlo.tn_load_lo = (uint32_t) load_val;
|
|
||||||
hw->hw_timer[timer_num].load.tn_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.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;
|
hw->hw_timer[timer_num].update.tn_update = 1;
|
||||||
while (hw->hw_timer[timer_num].update.tn_update) {}
|
// Timer register is in a different clock domain from Timer hardware logic
|
||||||
*timer_val = ((uint64_t) hw->hw_timer[timer_num].hi.tn_hi << 32) | (hw->hw_timer[timer_num].lo.tn_lo);
|
// We need to wait for the update to take effect before fetching the count value
|
||||||
|
while (hw->hw_timer[timer_num].update.tn_update) {
|
||||||
|
}
|
||||||
|
return ((uint64_t)hw->hw_timer[timer_num].hi.tn_hi << 32) | (hw->hw_timer[timer_num].lo.tn_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.tn_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.tn_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.tn_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.tn_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.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].alarmhi.tn_alarm_hi = (uint32_t)(alarm_value >> 32);
|
||||||
hw->hw_timer[timer_num].alarmlo.tn_alarm_lo = (uint32_t)alarm_value;
|
hw->hw_timer[timer_num].alarmlo.tn_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.tn_alarm_hi << 32) | (hw->hw_timer[timer_num].alarmlo.tn_alarm_lo);
|
return ((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.
|
* @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 reload_val)
|
||||||
{
|
{
|
||||||
hw->hw_timer[timer_num].config.tn_alarm_en = alarm_en;
|
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 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.tn_alarm_en;
|
return ((uint64_t)hw->hw_timer[timer_num].loadhi.tn_load_hi << 32) | (hw->hw_timer[timer_num].loadlo.tn_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.tn_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 & 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)
|
||||||
{
|
{
|
||||||
// Only "level" interrupts are supported on this target
|
return &hw->int_st_timers;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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);
|
|
||||||
}
|
}
|
||||||
|
@ -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__ */
|
|
||||||
|
@ -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;
|
||||||
|
/** tx_edge_int_en : R/W; bitpos: [12]; default: 0;
|
||||||
|
* When set, an alarm will generate an edge type interrupt.
|
||||||
|
*/
|
||||||
|
uint32_t tx_edge_int_en: 1;
|
||||||
|
/** tx_divider : R/W; bitpos: [28:13]; default: 1;
|
||||||
|
* Timer x clock (Tx_clk) prescaler value.
|
||||||
|
*/
|
||||||
|
uint32_t tx_divider: 16;
|
||||||
|
/** tx_autoreload : R/W; bitpos: [29]; default: 1;
|
||||||
|
* When set, timer x auto-reload at alarm is enabled.
|
||||||
|
*/
|
||||||
|
uint32_t tx_autoreload: 1;
|
||||||
|
/** tx_increase : R/W; bitpos: [30]; default: 1;
|
||||||
|
* When set, the timer x time-base counter will increment every clock tick. When
|
||||||
|
*
|
||||||
|
* cleared, the timer x time-base counter will decrement.
|
||||||
|
*/
|
||||||
|
uint32_t tx_increase: 1;
|
||||||
|
/** tx_en : R/W; bitpos: [31]; default: 0;
|
||||||
|
* When set, the timer x time-base counter is enabled.
|
||||||
|
*/
|
||||||
|
uint32_t tx_en: 1;
|
||||||
};
|
};
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
} config;
|
} timg_txconfig_reg_t;
|
||||||
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.*/
|
/** Type of txlo register
|
||||||
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)*/
|
* Timer x current value, low 32 bits
|
||||||
uint32_t alarm_low; /*Timer 0 time-base counter value lower 32 bits that will trigger the alarm*/
|
*/
|
||||||
uint32_t alarm_high; /*Timer 0 time-base counter value higher 32 bits that will trigger the alarm*/
|
typedef union {
|
||||||
uint32_t load_low; /*Lower 32 bits of the value that will load into timer 0 time-base counter*/
|
|
||||||
uint32_t load_high; /*higher 32 bits of the value that will load into timer 0 time-base counter*/
|
|
||||||
uint32_t reload; /*Write any value will trigger timer 0 time-base counter reload*/
|
|
||||||
} hw_timer[2];
|
|
||||||
union {
|
|
||||||
struct {
|
struct {
|
||||||
uint32_t reserved0: 14;
|
/** tx_lo : RO; bitpos: [31:0]; default: 0;
|
||||||
uint32_t flashboot_mod_en: 1; /*When set flash boot protection is enabled*/
|
* After writing to TIMG_TxUPDATE_REG, the low 32 bits of the time-base counter
|
||||||
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*/
|
*
|
||||||
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*/
|
* of timer x can be read here.
|
||||||
uint32_t level_int_en: 1; /*When set level type interrupt generation is enabled*/
|
*/
|
||||||
uint32_t edge_int_en: 1; /*When set edge type interrupt generation is enabled*/
|
uint32_t tx_lo: 32;
|
||||||
uint32_t stg3: 2; /*Stage 3 configuration. 0: off 1: interrupt 2: reset CPU 3: reset system*/
|
|
||||||
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 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;
|
uint32_t val;
|
||||||
} wdt_config0;
|
} timg_txlo_reg_t;
|
||||||
union {
|
|
||||||
|
/** Type of txhi register
|
||||||
|
* Timer x current value, high 32 bits
|
||||||
|
*/
|
||||||
|
typedef union {
|
||||||
struct {
|
struct {
|
||||||
uint32_t reserved0: 16;
|
/** tx_hi : RO; bitpos: [31:0]; default: 0;
|
||||||
uint32_t clk_prescale:16; /*SWDT clock prescale value. Period = 12.5ns * value stored in this register*/
|
* After writing to TIMG_TxUPDATE_REG, the high 32 bits of the time-base counter
|
||||||
|
*
|
||||||
|
* of timer x can be read here.
|
||||||
|
*/
|
||||||
|
uint32_t tx_hi: 32;
|
||||||
};
|
};
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
} wdt_config1;
|
} timg_txhi_reg_t;
|
||||||
uint32_t wdt_config2; /*Stage 0 timeout value in SWDT clock cycles*/
|
|
||||||
uint32_t wdt_config3; /*Stage 1 timeout value in SWDT clock cycles*/
|
/** Type of txupdate register
|
||||||
uint32_t wdt_config4; /*Stage 2 timeout value in SWDT clock cycles*/
|
* Write to copy current timer value to TIMGn_Tx_(LO/HI)_REG
|
||||||
uint32_t wdt_config5; /*Stage 3 timeout value in SWDT clock cycles*/
|
*/
|
||||||
uint32_t wdt_feed; /*Write any value will feed SWDT*/
|
typedef union {
|
||||||
uint32_t wdt_wprotect; /*If change its value from default then write protection is on.*/
|
|
||||||
union {
|
|
||||||
struct {
|
struct {
|
||||||
uint32_t reserved0: 12;
|
uint32_t reserved_0: 31;
|
||||||
uint32_t start_cycling: 1;
|
/** tx_update : R/W; bitpos: [31]; default: 0;
|
||||||
uint32_t clk_sel: 2;
|
* After writing 0 or 1 to TIMG_TxUPDATE_REG, the counter value is latched.
|
||||||
uint32_t rdy: 1;
|
*/
|
||||||
uint32_t max: 15;
|
uint32_t tx_update: 1;
|
||||||
uint32_t start: 1;
|
|
||||||
};
|
};
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
} rtc_cali_cfg;
|
} timg_txupdate_reg_t;
|
||||||
union {
|
|
||||||
|
/** Type of txalarmlo register
|
||||||
|
* Timer x alarm value, low 32 bits
|
||||||
|
*/
|
||||||
|
typedef union {
|
||||||
struct {
|
struct {
|
||||||
uint32_t reserved0: 7;
|
/** tx_alarm_lo : R/W; bitpos: [31:0]; default: 0;
|
||||||
uint32_t value:25;
|
* Timer x alarm trigger time-base counter value, low 32 bits.
|
||||||
|
*/
|
||||||
|
uint32_t tx_alarm_lo: 32;
|
||||||
};
|
};
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
} rtc_cali_cfg1;
|
} timg_txalarmlo_reg_t;
|
||||||
union {
|
|
||||||
|
/** Type of txalarmhi register
|
||||||
|
* Timer x alarm value, high bits
|
||||||
|
*/
|
||||||
|
typedef union {
|
||||||
struct {
|
struct {
|
||||||
uint32_t reserved0: 7;
|
/** tx_alarm_hi : R/W; bitpos: [31:0]; default: 0;
|
||||||
uint32_t rtc_only: 1;
|
*
|
||||||
uint32_t cpst_en: 1;
|
*
|
||||||
uint32_t lac_en: 1;
|
* Timer x alarm trigger time-base counter value, high 32 bits.
|
||||||
uint32_t alarm_en: 1;
|
*/
|
||||||
uint32_t level_int_en: 1;
|
uint32_t tx_alarm_hi: 32;
|
||||||
uint32_t edge_int_en: 1;
|
|
||||||
uint32_t divider: 16;
|
|
||||||
uint32_t autoreload: 1;
|
|
||||||
uint32_t increase: 1;
|
|
||||||
uint32_t en: 1;
|
|
||||||
};
|
};
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
} lactconfig;
|
} timg_txalarmhi_reg_t;
|
||||||
union {
|
|
||||||
|
/** Type of txloadlo register
|
||||||
|
* Timer x reload value, low 32 bits
|
||||||
|
*/
|
||||||
|
typedef union {
|
||||||
struct {
|
struct {
|
||||||
uint32_t reserved0: 6;
|
/** tx_load_lo : R/W; bitpos: [31:0]; default: 0;
|
||||||
uint32_t step_len:26;
|
*
|
||||||
|
*
|
||||||
|
* Low 32 bits of the value that a reload will load onto timer x time-base
|
||||||
|
*
|
||||||
|
* Counter.
|
||||||
|
*/
|
||||||
|
uint32_t tx_load_lo: 32;
|
||||||
};
|
};
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
} lactrtc;
|
} timg_txloadlo_reg_t;
|
||||||
uint32_t lactlo; /**/
|
|
||||||
uint32_t lacthi; /**/
|
/** Type of txloadhi register
|
||||||
uint32_t lactupdate; /**/
|
* Timer x reload value, high 32 bits
|
||||||
uint32_t lactalarmlo; /**/
|
*/
|
||||||
uint32_t lactalarmhi; /**/
|
typedef union {
|
||||||
uint32_t lactloadlo; /**/
|
|
||||||
uint32_t lactloadhi; /**/
|
|
||||||
uint32_t lactload; /**/
|
|
||||||
union {
|
|
||||||
struct {
|
struct {
|
||||||
uint32_t t0: 1; /*interrupt when timer0 alarm*/
|
/** tx_load_hi : R/W; bitpos: [31:0]; default: 0;
|
||||||
uint32_t t1: 1; /*interrupt when timer1 alarm*/
|
*
|
||||||
uint32_t wdt: 1; /*Interrupt when an interrupt stage timeout*/
|
*
|
||||||
uint32_t lact: 1;
|
* High 32 bits of the value that a reload will load onto timer x time-base
|
||||||
uint32_t reserved4: 28;
|
*
|
||||||
|
* counter.
|
||||||
|
*/
|
||||||
|
uint32_t tx_load_hi: 32;
|
||||||
};
|
};
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
} int_ena;
|
} timg_txloadhi_reg_t;
|
||||||
union {
|
|
||||||
|
/** Type of txload register
|
||||||
|
* Write to reload timer from TIMG_T0_(LOADLOLOADHI)_REG
|
||||||
|
*/
|
||||||
|
typedef union {
|
||||||
struct {
|
struct {
|
||||||
uint32_t t0: 1; /*interrupt when timer0 alarm*/
|
/** tx_load : WO; bitpos: [31:0]; default: 0;
|
||||||
uint32_t t1: 1; /*interrupt when timer1 alarm*/
|
*
|
||||||
uint32_t wdt: 1; /*Interrupt when an interrupt stage timeout*/
|
*
|
||||||
uint32_t lact: 1;
|
* Write any value to trigger a timer x time-base counter reload.
|
||||||
uint32_t reserved4:28;
|
*/
|
||||||
|
uint32_t tx_load: 32;
|
||||||
};
|
};
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
} int_raw;
|
} timg_txload_reg_t;
|
||||||
union {
|
|
||||||
|
|
||||||
|
/** Group: Configuration and Control Register for WDT */
|
||||||
|
/** Type of wdtconfig0 register
|
||||||
|
* Watchdog timer configuration register
|
||||||
|
*/
|
||||||
|
typedef union {
|
||||||
struct {
|
struct {
|
||||||
uint32_t t0: 1; /*interrupt when timer0 alarm*/
|
uint32_t reserved_0: 14;
|
||||||
uint32_t t1: 1; /*interrupt when timer1 alarm*/
|
/** wdt_flashboot_mod_en : R/W; bitpos: [14]; default: 1;
|
||||||
uint32_t wdt: 1; /*Interrupt when an interrupt stage timeout*/
|
* When set, Flash boot protection is enabled.
|
||||||
uint32_t lact: 1;
|
*/
|
||||||
uint32_t reserved4: 28;
|
uint32_t wdt_flashboot_mod_en: 1;
|
||||||
|
/** wdt_sys_reset_length : R/W; bitpos: [17:15]; default: 1;
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
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;
|
uint32_t val;
|
||||||
} int_st_timers;
|
} timg_wdtconfig0_reg_t;
|
||||||
union {
|
|
||||||
|
/** Type of wdtconfig1 register
|
||||||
|
* Watchdog timer prescaler register
|
||||||
|
*/
|
||||||
|
typedef union {
|
||||||
struct {
|
struct {
|
||||||
uint32_t t0: 1; /*interrupt when timer0 alarm*/
|
uint32_t reserved_0: 16;
|
||||||
uint32_t t1: 1; /*interrupt when timer1 alarm*/
|
/** wdt_clk_prescaler : R/W; bitpos: [31:16]; default: 1;
|
||||||
uint32_t wdt: 1; /*Interrupt when an interrupt stage timeout*/
|
* MWDT clock prescaler value. MWDT clock period = 12.5 ns *
|
||||||
uint32_t lact: 1;
|
*
|
||||||
uint32_t reserved4: 28;
|
* TIMG_WDT_CLK_PRESCALE.
|
||||||
|
*/
|
||||||
|
uint32_t wdt_clk_prescaler: 16;
|
||||||
};
|
};
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
} int_clr_timers;
|
} timg_wdtconfig1_reg_t;
|
||||||
uint32_t reserved_a8;
|
|
||||||
uint32_t reserved_ac;
|
/** Type of wdtconfig2 register
|
||||||
uint32_t reserved_b0;
|
* Watchdog timer stage 0 timeout value
|
||||||
uint32_t reserved_b4;
|
*/
|
||||||
uint32_t reserved_b8;
|
typedef union {
|
||||||
uint32_t reserved_bc;
|
|
||||||
uint32_t reserved_c0;
|
|
||||||
uint32_t reserved_c4;
|
|
||||||
uint32_t reserved_c8;
|
|
||||||
uint32_t reserved_cc;
|
|
||||||
uint32_t reserved_d0;
|
|
||||||
uint32_t reserved_d4;
|
|
||||||
uint32_t reserved_d8;
|
|
||||||
uint32_t reserved_dc;
|
|
||||||
uint32_t reserved_e0;
|
|
||||||
uint32_t reserved_e4;
|
|
||||||
uint32_t reserved_e8;
|
|
||||||
uint32_t reserved_ec;
|
|
||||||
uint32_t reserved_f0;
|
|
||||||
uint32_t reserved_f4;
|
|
||||||
union {
|
|
||||||
struct {
|
struct {
|
||||||
uint32_t date:28; /*Version of this regfile*/
|
/** wdt_stg0_hold : R/W; bitpos: [31:0]; default: 26000000;
|
||||||
uint32_t reserved28: 4;
|
* Stage 0 timeout value, in MWDT clock cycles.
|
||||||
|
*/
|
||||||
|
uint32_t wdt_stg0_hold: 32;
|
||||||
};
|
};
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
} timg_date;
|
} timg_wdtconfig2_reg_t;
|
||||||
union {
|
|
||||||
|
/** Type of wdtconfig3 register
|
||||||
|
* Watchdog timer stage 1 timeout value
|
||||||
|
*/
|
||||||
|
typedef union {
|
||||||
struct {
|
struct {
|
||||||
uint32_t reserved0: 31;
|
/** wdt_stg1_hold : R/W; bitpos: [31:0]; default: 134217727;
|
||||||
uint32_t en: 1; /*Force clock enable for this regfile*/
|
* Stage 1 timeout value, in MWDT clock cycles.
|
||||||
|
*/
|
||||||
|
uint32_t wdt_stg1_hold: 32;
|
||||||
};
|
};
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
} clk;
|
} 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_ */
|
|
||||||
|
@ -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,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -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;
|
||||||
|
@ -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,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -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;
|
||||||
|
@ -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,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -601,10 +601,10 @@ 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.
|
||||||
*/
|
*/
|
||||||
@ -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;
|
||||||
|
@ -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,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -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
|
||||||
|
|
||||||
@ -36,7 +27,11 @@ typedef union {
|
|||||||
* 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.
|
||||||
*/
|
*/
|
||||||
@ -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;
|
||||||
|
@ -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,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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 */
|
||||||
#if CONFIG_IDF_TARGET_ESP32C3
|
timer_group_get_intr_status_in_isr(HW_TIMER_GROUP);
|
||||||
uint32_t intr_status = TIMERG0.int_st.val;
|
timer_group_clr_intr_status_in_isr(HW_TIMER_GROUP, timer_idx);
|
||||||
TIMERG0.hw_timer[timer_idx].update.val = 1;
|
|
||||||
#elif CONFIG_IDF_TARGET_ESP32
|
|
||||||
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
|
/* After the alarm has been triggered
|
||||||
we need enable it again, so it is triggered the next time */
|
we need enable it again, so it is triggered the next time */
|
||||||
TIMERG0.hw_timer[timer_idx].config.alarm_en = TIMER_ALARM_EN;
|
timer_group_enable_alarm_in_isr(HW_TIMER_GROUP, timer_idx);
|
||||||
} 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;
|
||||||
|
@ -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 */
|
||||||
uint32_t intr_status = TIMERG0.int_st_timers.val;
|
timer_group_get_intr_status_in_isr(HW_TIMER_GROUP);
|
||||||
TIMERG0.hw_timer[timer_idx].update = 1;
|
timer_group_clr_intr_status_in_isr(HW_TIMER_GROUP, timer_idx);
|
||||||
|
|
||||||
/* Clear the interrupt */
|
|
||||||
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
|
/* After the alarm has been triggered
|
||||||
we need enable it again, so it is triggered the next time */
|
we need enable it again, so it is triggered the next time */
|
||||||
TIMERG0.hw_timer[timer_idx].config.alarm_en = TIMER_ALARM_EN;
|
timer_group_enable_alarm_in_isr(HW_TIMER_GROUP, timer_idx);
|
||||||
} 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) {
|
||||||
|
@ -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()
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
/* General Purpose Timer example
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2010-2021 Espressif Systems (Shanghai) CO LTD
|
||||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
*
|
||||||
|
* SPDX-License-Identifier: CC0-1.0
|
||||||
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"
|
||||||
|
@ -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*/
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user