forked from espressif/esp-idf
Merge branch 'bugfix/alarm_update_invalid' into 'master'
timer: stop alarm if the alarm target value hasn't changed && 8684 support Closes IDFGH-6435, IDFGH-5229, IDF-3825, and IDF-4220 See merge request espressif/esp-idf!16429
This commit is contained in:
@@ -15,12 +15,9 @@
|
|||||||
#include "soc/soc_caps.h"
|
#include "soc/soc_caps.h"
|
||||||
#include "esp_rom_sys.h"
|
#include "esp_rom_sys.h"
|
||||||
|
|
||||||
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP8684)
|
#define TEST_TIMER_RESOLUTION_HZ 1000000 // 1MHz resolution
|
||||||
// TODO: Timer support IDF-3825
|
|
||||||
|
|
||||||
#define TIMER_DIVIDER 16
|
|
||||||
#define TIMER_SCALE (TIMER_BASE_CLK / TIMER_DIVIDER) /*!< used to calculate counter value */
|
|
||||||
#define TIMER_DELTA 0.001
|
#define TIMER_DELTA 0.001
|
||||||
|
|
||||||
static bool alarm_flag;
|
static bool alarm_flag;
|
||||||
static xQueueHandle timer_queue;
|
static xQueueHandle timer_queue;
|
||||||
|
|
||||||
@@ -39,14 +36,16 @@ typedef struct {
|
|||||||
#define TIMER_INFO_INIT(TG, TID) {.timer_group = (TG), .timer_idx = (TID),}
|
#define TIMER_INFO_INIT(TG, TID) {.timer_group = (TG), .timer_idx = (TID),}
|
||||||
|
|
||||||
static timer_info_t timer_info[] = {
|
static timer_info_t timer_info[] = {
|
||||||
#if !CONFIG_IDF_TARGET_ESP32C3
|
#if SOC_TIMER_GROUP_TOTAL_TIMERS >= 4
|
||||||
TIMER_INFO_INIT(TIMER_GROUP_0, TIMER_0),
|
TIMER_INFO_INIT(TIMER_GROUP_0, TIMER_0),
|
||||||
TIMER_INFO_INIT(TIMER_GROUP_0, TIMER_1),
|
TIMER_INFO_INIT(TIMER_GROUP_0, TIMER_1),
|
||||||
TIMER_INFO_INIT(TIMER_GROUP_1, TIMER_0),
|
TIMER_INFO_INIT(TIMER_GROUP_1, TIMER_0),
|
||||||
TIMER_INFO_INIT(TIMER_GROUP_1, TIMER_1),
|
TIMER_INFO_INIT(TIMER_GROUP_1, TIMER_1),
|
||||||
#else
|
#elif SOC_TIMER_GROUP_TOTAL_TIMERS >= 2
|
||||||
TIMER_INFO_INIT(TIMER_GROUP_0, TIMER_0),
|
TIMER_INFO_INIT(TIMER_GROUP_0, TIMER_0),
|
||||||
TIMER_INFO_INIT(TIMER_GROUP_1, TIMER_0),
|
TIMER_INFO_INIT(TIMER_GROUP_1, TIMER_0),
|
||||||
|
#else
|
||||||
|
TIMER_INFO_INIT(TIMER_GROUP_0, TIMER_0),
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -248,7 +247,7 @@ static void timer_intr_enable_and_start(int timer_group, int timer_idx, double a
|
|||||||
{
|
{
|
||||||
TEST_ESP_OK(timer_pause(timer_group, timer_idx));
|
TEST_ESP_OK(timer_pause(timer_group, timer_idx));
|
||||||
TEST_ESP_OK(timer_set_counter_value(timer_group, timer_idx, 0x0));
|
TEST_ESP_OK(timer_set_counter_value(timer_group, timer_idx, 0x0));
|
||||||
TEST_ESP_OK(timer_set_alarm_value(timer_group, timer_idx, alarm_time * TIMER_SCALE));
|
TEST_ESP_OK(timer_set_alarm_value(timer_group, timer_idx, alarm_time * TEST_TIMER_RESOLUTION_HZ));
|
||||||
TEST_ESP_OK(timer_set_alarm(timer_group, timer_idx, TIMER_ALARM_EN));
|
TEST_ESP_OK(timer_set_alarm(timer_group, timer_idx, TIMER_ALARM_EN));
|
||||||
TEST_ESP_OK(timer_enable_intr(timer_group, timer_idx));
|
TEST_ESP_OK(timer_enable_intr(timer_group, timer_idx));
|
||||||
TEST_ESP_OK(timer_start(timer_group, timer_idx));
|
TEST_ESP_OK(timer_start(timer_group, timer_idx));
|
||||||
@@ -300,9 +299,10 @@ TEST_CASE("Timer init", "[hw_timer]")
|
|||||||
|
|
||||||
// lack one parameter
|
// lack one parameter
|
||||||
timer_config_t config2 = {
|
timer_config_t config2 = {
|
||||||
|
.clk_src = TIMER_SRC_CLK_APB,
|
||||||
|
.divider = APB_CLK_FREQ / TEST_TIMER_RESOLUTION_HZ,
|
||||||
.auto_reload = TIMER_AUTORELOAD_EN,
|
.auto_reload = TIMER_AUTORELOAD_EN,
|
||||||
.counter_dir = TIMER_COUNT_UP,
|
.counter_dir = TIMER_COUNT_UP,
|
||||||
.divider = TIMER_DIVIDER,
|
|
||||||
.counter_en = TIMER_START,
|
.counter_en = TIMER_START,
|
||||||
.intr_type = TIMER_INTR_LEVEL
|
.intr_type = TIMER_INTR_LEVEL
|
||||||
};
|
};
|
||||||
@@ -311,33 +311,20 @@ TEST_CASE("Timer init", "[hw_timer]")
|
|||||||
config2.counter_en = TIMER_PAUSE;
|
config2.counter_en = TIMER_PAUSE;
|
||||||
all_timer_init(&config2, true);
|
all_timer_init(&config2, true);
|
||||||
|
|
||||||
// error config parameter
|
|
||||||
timer_config_t config3 = {
|
|
||||||
.alarm_en = 3, //error parameter
|
|
||||||
.auto_reload = TIMER_AUTORELOAD_EN,
|
|
||||||
.counter_dir = TIMER_COUNT_UP,
|
|
||||||
.divider = TIMER_DIVIDER,
|
|
||||||
.counter_en = TIMER_START,
|
|
||||||
.intr_type = TIMER_INTR_LEVEL
|
|
||||||
};
|
|
||||||
all_timer_init(&config3, true);
|
|
||||||
timer_config_t get_config;
|
|
||||||
TEST_ESP_OK(timer_get_config(TIMER_GROUP_1, TIMER_0, &get_config));
|
|
||||||
printf("Error config alarm_en is %d\n", get_config.alarm_en);
|
|
||||||
TEST_ASSERT_NOT_EQUAL(config3.alarm_en, get_config.alarm_en);
|
|
||||||
|
|
||||||
// Test init 2: init
|
// Test init 2: init
|
||||||
uint64_t set_timer_val = 0x0;
|
uint64_t set_timer_val = 0x0;
|
||||||
timer_config_t config = {
|
timer_config_t config = {
|
||||||
|
.clk_src = TIMER_SRC_CLK_APB,
|
||||||
|
.divider = APB_CLK_FREQ / TEST_TIMER_RESOLUTION_HZ,
|
||||||
.alarm_en = TIMER_ALARM_DIS,
|
.alarm_en = TIMER_ALARM_DIS,
|
||||||
.auto_reload = TIMER_AUTORELOAD_EN,
|
.auto_reload = TIMER_AUTORELOAD_EN,
|
||||||
.counter_dir = TIMER_COUNT_UP,
|
.counter_dir = TIMER_COUNT_UP,
|
||||||
.divider = TIMER_DIVIDER,
|
|
||||||
.counter_en = TIMER_START,
|
.counter_en = TIMER_START,
|
||||||
.intr_type = TIMER_INTR_LEVEL
|
.intr_type = TIMER_INTR_LEVEL
|
||||||
};
|
};
|
||||||
|
|
||||||
// judge get config parameters
|
// judge get config parameters
|
||||||
|
timer_config_t get_config;
|
||||||
TEST_ESP_OK(timer_init(TIMER_GROUP_0, TIMER_0, &config));
|
TEST_ESP_OK(timer_init(TIMER_GROUP_0, TIMER_0, &config));
|
||||||
TEST_ESP_OK(timer_get_config(TIMER_GROUP_0, TIMER_0, &get_config));
|
TEST_ESP_OK(timer_get_config(TIMER_GROUP_0, TIMER_0, &get_config));
|
||||||
TEST_ASSERT_EQUAL(config.alarm_en, get_config.alarm_en);
|
TEST_ASSERT_EQUAL(config.alarm_en, get_config.alarm_en);
|
||||||
@@ -355,8 +342,8 @@ TEST_CASE("Timer init", "[hw_timer]")
|
|||||||
|
|
||||||
// Test init 3: wrong parameter
|
// Test init 3: wrong parameter
|
||||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_init(-1, TIMER_0, &config));
|
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_init(-1, TIMER_0, &config));
|
||||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_init(TIMER_GROUP_1, 2, &config));
|
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_init(TIMER_GROUP_0, 2, &config));
|
||||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_init(TIMER_GROUP_1, -1, &config));
|
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_init(TIMER_GROUP_0, -1, &config));
|
||||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_init(2, TIMER_0, &config));
|
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_init(2, TIMER_0, &config));
|
||||||
all_timer_deinit();
|
all_timer_deinit();
|
||||||
}
|
}
|
||||||
@@ -369,10 +356,11 @@ TEST_CASE("Timer init", "[hw_timer]")
|
|||||||
TEST_CASE("Timer read counter value", "[hw_timer]")
|
TEST_CASE("Timer read counter value", "[hw_timer]")
|
||||||
{
|
{
|
||||||
timer_config_t config = {
|
timer_config_t config = {
|
||||||
|
.clk_src = TIMER_SRC_CLK_APB,
|
||||||
|
.divider = APB_CLK_FREQ / TEST_TIMER_RESOLUTION_HZ,
|
||||||
.alarm_en = TIMER_ALARM_EN,
|
.alarm_en = TIMER_ALARM_EN,
|
||||||
.auto_reload = TIMER_AUTORELOAD_EN,
|
.auto_reload = TIMER_AUTORELOAD_EN,
|
||||||
.counter_dir = TIMER_COUNT_UP,
|
.counter_dir = TIMER_COUNT_UP,
|
||||||
.divider = TIMER_DIVIDER,
|
|
||||||
.counter_en = TIMER_START,
|
.counter_en = TIMER_START,
|
||||||
.intr_type = TIMER_INTR_LEVEL
|
.intr_type = TIMER_INTR_LEVEL
|
||||||
};
|
};
|
||||||
@@ -408,10 +396,11 @@ TEST_CASE("Timer read counter value", "[hw_timer]")
|
|||||||
TEST_CASE("Timer start", "[hw_timer]")
|
TEST_CASE("Timer start", "[hw_timer]")
|
||||||
{
|
{
|
||||||
timer_config_t config = {
|
timer_config_t config = {
|
||||||
|
.clk_src = TIMER_SRC_CLK_APB,
|
||||||
|
.divider = APB_CLK_FREQ / TEST_TIMER_RESOLUTION_HZ,
|
||||||
.alarm_en = TIMER_ALARM_EN,
|
.alarm_en = TIMER_ALARM_EN,
|
||||||
.auto_reload = TIMER_AUTORELOAD_EN,
|
.auto_reload = TIMER_AUTORELOAD_EN,
|
||||||
.counter_dir = TIMER_COUNT_UP,
|
.counter_dir = TIMER_COUNT_UP,
|
||||||
.divider = TIMER_DIVIDER,
|
|
||||||
.counter_en = TIMER_START,
|
.counter_en = TIMER_START,
|
||||||
.intr_type = TIMER_INTR_LEVEL
|
.intr_type = TIMER_INTR_LEVEL
|
||||||
};
|
};
|
||||||
@@ -426,8 +415,8 @@ TEST_CASE("Timer start", "[hw_timer]")
|
|||||||
//Test start 2:wrong parameter
|
//Test start 2:wrong parameter
|
||||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_start(2, TIMER_0));
|
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_start(2, TIMER_0));
|
||||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_start(-1, TIMER_0));
|
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_start(-1, TIMER_0));
|
||||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_start(TIMER_GROUP_1, 2));
|
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_start(TIMER_GROUP_0, 2));
|
||||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_start(TIMER_GROUP_1, -1));
|
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_start(TIMER_GROUP_0, -1));
|
||||||
all_timer_deinit();
|
all_timer_deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -439,10 +428,11 @@ TEST_CASE("Timer start", "[hw_timer]")
|
|||||||
TEST_CASE("Timer pause", "[hw_timer]")
|
TEST_CASE("Timer pause", "[hw_timer]")
|
||||||
{
|
{
|
||||||
timer_config_t config = {
|
timer_config_t config = {
|
||||||
|
.clk_src = TIMER_SRC_CLK_APB,
|
||||||
|
.divider = APB_CLK_FREQ / TEST_TIMER_RESOLUTION_HZ,
|
||||||
.alarm_en = TIMER_ALARM_EN,
|
.alarm_en = TIMER_ALARM_EN,
|
||||||
.auto_reload = TIMER_AUTORELOAD_EN,
|
.auto_reload = TIMER_AUTORELOAD_EN,
|
||||||
.counter_dir = TIMER_COUNT_UP,
|
.counter_dir = TIMER_COUNT_UP,
|
||||||
.divider = TIMER_DIVIDER,
|
|
||||||
.counter_en = TIMER_START,
|
.counter_en = TIMER_START,
|
||||||
.intr_type = TIMER_INTR_LEVEL
|
.intr_type = TIMER_INTR_LEVEL
|
||||||
};
|
};
|
||||||
@@ -458,7 +448,7 @@ TEST_CASE("Timer pause", "[hw_timer]")
|
|||||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_pause(-1, TIMER_0));
|
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_pause(-1, TIMER_0));
|
||||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_pause(TIMER_GROUP_0, -1));
|
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_pause(TIMER_GROUP_0, -1));
|
||||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_pause(2, TIMER_0));
|
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_pause(2, TIMER_0));
|
||||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_pause(TIMER_GROUP_1, 2));
|
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_pause(TIMER_GROUP_0, 2));
|
||||||
all_timer_deinit();
|
all_timer_deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -466,10 +456,11 @@ TEST_CASE("Timer pause", "[hw_timer]")
|
|||||||
TEST_CASE("Timer counter mode (up / down)", "[hw_timer]")
|
TEST_CASE("Timer counter mode (up / down)", "[hw_timer]")
|
||||||
{
|
{
|
||||||
timer_config_t config = {
|
timer_config_t config = {
|
||||||
|
.clk_src = TIMER_SRC_CLK_APB,
|
||||||
|
.divider = APB_CLK_FREQ / TEST_TIMER_RESOLUTION_HZ,
|
||||||
.alarm_en = TIMER_ALARM_EN,
|
.alarm_en = TIMER_ALARM_EN,
|
||||||
.auto_reload = TIMER_AUTORELOAD_EN,
|
.auto_reload = TIMER_AUTORELOAD_EN,
|
||||||
.counter_dir = TIMER_COUNT_UP,
|
.counter_dir = TIMER_COUNT_UP,
|
||||||
.divider = TIMER_DIVIDER,
|
|
||||||
.counter_en = TIMER_START,
|
.counter_en = TIMER_START,
|
||||||
.intr_type = TIMER_INTR_LEVEL
|
.intr_type = TIMER_INTR_LEVEL
|
||||||
};
|
};
|
||||||
@@ -486,7 +477,7 @@ TEST_CASE("Timer counter mode (up / down)", "[hw_timer]")
|
|||||||
|
|
||||||
// Test counter mode 2: TIMER_COUNT_DOWN
|
// Test counter mode 2: TIMER_COUNT_DOWN
|
||||||
all_timer_pause();
|
all_timer_pause();
|
||||||
set_timer_val = 0x00E4E1C0ULL; // 3s clock counter value
|
set_timer_val = TEST_TIMER_RESOLUTION_HZ * 3; // 3s clock counter value
|
||||||
all_timer_set_counter_mode(TIMER_COUNT_DOWN);
|
all_timer_set_counter_mode(TIMER_COUNT_DOWN);
|
||||||
all_timer_set_counter_value(set_timer_val);
|
all_timer_set_counter_value(set_timer_val);
|
||||||
all_timer_start();
|
all_timer_start();
|
||||||
@@ -499,24 +490,14 @@ TEST_CASE("Timer counter mode (up / down)", "[hw_timer]")
|
|||||||
all_timer_deinit();
|
all_timer_deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* divider case:
|
|
||||||
* 1. different divider, read value
|
|
||||||
* Note: divide 0 = divide max, divide 1 = divide 2
|
|
||||||
* 2. error parameter
|
|
||||||
*
|
|
||||||
* the frequency(timer counts in one sec):
|
|
||||||
* 80M/divider = 800*100000
|
|
||||||
* max divider value is 65536, its frequency is 1220 (nearly about 1KHz)
|
|
||||||
*/
|
|
||||||
TEST_CASE("Timer divider", "[hw_timer]")
|
TEST_CASE("Timer divider", "[hw_timer]")
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
timer_config_t config = {
|
timer_config_t config = {
|
||||||
|
.clk_src = TIMER_SRC_CLK_APB,
|
||||||
|
.divider = APB_CLK_FREQ / TEST_TIMER_RESOLUTION_HZ,
|
||||||
.alarm_en = TIMER_ALARM_EN,
|
.alarm_en = TIMER_ALARM_EN,
|
||||||
.auto_reload = TIMER_AUTORELOAD_EN,
|
.auto_reload = TIMER_AUTORELOAD_EN,
|
||||||
.counter_dir = TIMER_COUNT_UP,
|
.counter_dir = TIMER_COUNT_UP,
|
||||||
.divider = TIMER_DIVIDER,
|
|
||||||
.counter_en = TIMER_START,
|
.counter_en = TIMER_START,
|
||||||
.intr_type = TIMER_INTR_LEVEL
|
.intr_type = TIMER_INTR_LEVEL
|
||||||
};
|
};
|
||||||
@@ -532,41 +513,36 @@ TEST_CASE("Timer divider", "[hw_timer]")
|
|||||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||||
all_timer_get_counter_value(set_timer_val, false, time_val);
|
all_timer_get_counter_value(set_timer_val, false, time_val);
|
||||||
|
|
||||||
// compare divider 16 and 8, value should be double
|
|
||||||
all_timer_pause();
|
all_timer_pause();
|
||||||
all_timer_set_divider(8);
|
all_timer_set_divider(config.divider / 2); // half of original divider
|
||||||
all_timer_set_counter_value(set_timer_val);
|
all_timer_set_counter_value(set_timer_val);
|
||||||
|
|
||||||
all_timer_start();
|
all_timer_start();
|
||||||
vTaskDelay(1000 / portTICK_PERIOD_MS); //delay the same time
|
vTaskDelay(1000 / portTICK_PERIOD_MS); //delay the same time
|
||||||
all_timer_get_counter_value(set_timer_val, false, comp_time_val);
|
all_timer_get_counter_value(set_timer_val, false, comp_time_val);
|
||||||
for (i = 0; i < TIMER_GROUP_MAX * TIMER_MAX; i++) {
|
for (int i = 0; i < TIMER_GROUP_MAX * TIMER_MAX; i++) {
|
||||||
TEST_ASSERT_INT_WITHIN(5000, 5000000, time_val[i]);
|
TEST_ASSERT_INT_WITHIN(2000, 1000000, time_val[i]);
|
||||||
TEST_ASSERT_INT_WITHIN(10000, 10000000, comp_time_val[i]);
|
TEST_ASSERT_INT_WITHIN(2000, 2000000, comp_time_val[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// divider is 256, value should be 2^4
|
|
||||||
all_timer_pause();
|
all_timer_pause();
|
||||||
all_timer_set_divider(256);
|
all_timer_set_divider(256);
|
||||||
all_timer_set_counter_value(set_timer_val);
|
all_timer_set_counter_value(set_timer_val);
|
||||||
all_timer_start();
|
all_timer_start();
|
||||||
vTaskDelay(1000 / portTICK_PERIOD_MS); //delay the same time
|
vTaskDelay(1000 / portTICK_PERIOD_MS); //delay the same time
|
||||||
all_timer_get_counter_value(set_timer_val, false, comp_time_val);
|
all_timer_get_counter_value(set_timer_val, false, comp_time_val);
|
||||||
for (i = 0; i < TIMER_GROUP_MAX * TIMER_MAX; i++) {
|
for (int i = 0; i < TIMER_GROUP_MAX * TIMER_MAX; i++) {
|
||||||
TEST_ASSERT_INT_WITHIN(5000, 5000000, time_val[i]);
|
TEST_ASSERT_INT_WITHIN(100, APB_CLK_FREQ / 256, comp_time_val[i]);
|
||||||
TEST_ASSERT_INT_WITHIN(3126, 312500, comp_time_val[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// extrem value test
|
|
||||||
all_timer_pause();
|
all_timer_pause();
|
||||||
all_timer_set_divider(2);
|
all_timer_set_divider(2);
|
||||||
all_timer_set_counter_value(set_timer_val);
|
all_timer_set_counter_value(set_timer_val);
|
||||||
all_timer_start();
|
all_timer_start();
|
||||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||||
all_timer_get_counter_value(set_timer_val, false, comp_time_val);
|
all_timer_get_counter_value(set_timer_val, false, comp_time_val);
|
||||||
for (i = 0; i < TIMER_GROUP_MAX * TIMER_MAX; i++) {
|
for (int i = 0; i < TIMER_GROUP_MAX * TIMER_MAX; i++) {
|
||||||
TEST_ASSERT_INT_WITHIN(5000, 5000000, time_val[i]);
|
TEST_ASSERT_INT_WITHIN(5000, APB_CLK_FREQ / 2, comp_time_val[i]);
|
||||||
TEST_ASSERT_INT_WITHIN(40000, 40000000, comp_time_val[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
all_timer_pause();
|
all_timer_pause();
|
||||||
@@ -575,19 +551,13 @@ TEST_CASE("Timer divider", "[hw_timer]")
|
|||||||
all_timer_start();
|
all_timer_start();
|
||||||
vTaskDelay(1000 / portTICK_PERIOD_MS); //delay the same time
|
vTaskDelay(1000 / portTICK_PERIOD_MS); //delay the same time
|
||||||
all_timer_get_counter_value(set_timer_val, false, comp_time_val);
|
all_timer_get_counter_value(set_timer_val, false, comp_time_val);
|
||||||
for (i = 0; i < TIMER_GROUP_MAX * TIMER_MAX; i++) {
|
for (int i = 0; i < TIMER_GROUP_MAX * TIMER_MAX; i++) {
|
||||||
TEST_ASSERT_INT_WITHIN(5000, 5000000, time_val[i]);
|
TEST_ASSERT_INT_WITHIN(10, APB_CLK_FREQ / 65536, comp_time_val[i]);
|
||||||
TEST_ASSERT_INT_WITHIN(2, 1220, comp_time_val[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// divider is 1 should be equal with 2
|
|
||||||
all_timer_pause();
|
all_timer_pause();
|
||||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_set_divider(TIMER_GROUP_0, TIMER_0, 1));
|
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_set_divider(TIMER_GROUP_0, TIMER_0, 1));
|
||||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_set_divider(TIMER_GROUP_1, TIMER_0, 1));
|
|
||||||
|
|
||||||
all_timer_pause();
|
|
||||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_set_divider(TIMER_GROUP_0, TIMER_0, 65537));
|
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_set_divider(TIMER_GROUP_0, TIMER_0, 65537));
|
||||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, timer_set_divider(TIMER_GROUP_1, TIMER_0, 65537));
|
|
||||||
all_timer_deinit();
|
all_timer_deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -599,10 +569,11 @@ TEST_CASE("Timer divider", "[hw_timer]")
|
|||||||
TEST_CASE("Timer enable alarm", "[hw_timer]")
|
TEST_CASE("Timer enable alarm", "[hw_timer]")
|
||||||
{
|
{
|
||||||
timer_config_t config_test = {
|
timer_config_t config_test = {
|
||||||
|
.clk_src = TIMER_SRC_CLK_APB,
|
||||||
|
.divider = APB_CLK_FREQ / TEST_TIMER_RESOLUTION_HZ,
|
||||||
.alarm_en = TIMER_ALARM_DIS,
|
.alarm_en = TIMER_ALARM_DIS,
|
||||||
.auto_reload = TIMER_AUTORELOAD_DIS,
|
.auto_reload = TIMER_AUTORELOAD_DIS,
|
||||||
.counter_dir = TIMER_COUNT_UP,
|
.counter_dir = TIMER_COUNT_UP,
|
||||||
.divider = TIMER_DIVIDER,
|
|
||||||
.counter_en = TIMER_PAUSE,
|
.counter_en = TIMER_PAUSE,
|
||||||
.intr_type = TIMER_INTR_LEVEL
|
.intr_type = TIMER_INTR_LEVEL
|
||||||
};
|
};
|
||||||
@@ -613,7 +584,7 @@ TEST_CASE("Timer enable alarm", "[hw_timer]")
|
|||||||
alarm_flag = false;
|
alarm_flag = false;
|
||||||
TEST_ESP_OK(timer_set_alarm(TIMER_GROUP_0, TIMER_0, TIMER_ALARM_EN));
|
TEST_ESP_OK(timer_set_alarm(TIMER_GROUP_0, TIMER_0, TIMER_ALARM_EN));
|
||||||
timer_intr_enable_and_start(TIMER_GROUP_0, TIMER_0, 1.2);
|
timer_intr_enable_and_start(TIMER_GROUP_0, TIMER_0, 1.2);
|
||||||
timer_isr_check(TIMER_GROUP_0, TIMER_0, TIMER_AUTORELOAD_DIS, 1.2 * TIMER_SCALE);
|
timer_isr_check(TIMER_GROUP_0, TIMER_0, TIMER_AUTORELOAD_DIS, 1.2 * TEST_TIMER_RESOLUTION_HZ);
|
||||||
TEST_ASSERT_EQUAL(true, alarm_flag);
|
TEST_ASSERT_EQUAL(true, alarm_flag);
|
||||||
|
|
||||||
// disable alarm of tg0_timer1
|
// disable alarm of tg0_timer1
|
||||||
@@ -623,11 +594,12 @@ TEST_CASE("Timer enable alarm", "[hw_timer]")
|
|||||||
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
||||||
TEST_ASSERT_EQUAL(false, alarm_flag);
|
TEST_ASSERT_EQUAL(false, alarm_flag);
|
||||||
|
|
||||||
|
#if SOC_TIMER_GROUPS > 1
|
||||||
// enable alarm of tg1_timer0
|
// enable alarm of tg1_timer0
|
||||||
alarm_flag = false;
|
alarm_flag = false;
|
||||||
TEST_ESP_OK(timer_set_alarm(TIMER_GROUP_1, TIMER_0, TIMER_ALARM_EN));
|
TEST_ESP_OK(timer_set_alarm(TIMER_GROUP_1, TIMER_0, TIMER_ALARM_EN));
|
||||||
timer_intr_enable_and_start(TIMER_GROUP_1, TIMER_0, 1.2);
|
timer_intr_enable_and_start(TIMER_GROUP_1, TIMER_0, 1.2);
|
||||||
timer_isr_check(TIMER_GROUP_1, TIMER_0, TIMER_AUTORELOAD_DIS, 1.2 * TIMER_SCALE);
|
timer_isr_check(TIMER_GROUP_1, TIMER_0, TIMER_AUTORELOAD_DIS, 1.2 * TEST_TIMER_RESOLUTION_HZ);
|
||||||
TEST_ASSERT_EQUAL(true, alarm_flag);
|
TEST_ASSERT_EQUAL(true, alarm_flag);
|
||||||
|
|
||||||
// disable alarm of tg1_timer0
|
// disable alarm of tg1_timer0
|
||||||
@@ -636,6 +608,7 @@ TEST_CASE("Timer enable alarm", "[hw_timer]")
|
|||||||
TEST_ESP_OK(timer_set_alarm(TIMER_GROUP_1, TIMER_0, TIMER_ALARM_DIS));
|
TEST_ESP_OK(timer_set_alarm(TIMER_GROUP_1, TIMER_0, TIMER_ALARM_DIS));
|
||||||
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
||||||
TEST_ASSERT_EQUAL(false, alarm_flag);
|
TEST_ASSERT_EQUAL(false, alarm_flag);
|
||||||
|
#endif
|
||||||
all_timer_isr_unreg();
|
all_timer_isr_unreg();
|
||||||
all_timer_deinit();
|
all_timer_deinit();
|
||||||
}
|
}
|
||||||
@@ -649,10 +622,11 @@ TEST_CASE("Timer set alarm value", "[hw_timer]")
|
|||||||
{
|
{
|
||||||
uint64_t alarm_val[SOC_TIMER_GROUP_TOTAL_TIMERS];
|
uint64_t alarm_val[SOC_TIMER_GROUP_TOTAL_TIMERS];
|
||||||
timer_config_t config = {
|
timer_config_t config = {
|
||||||
|
.clk_src = TIMER_SRC_CLK_APB,
|
||||||
|
.divider = APB_CLK_FREQ / TEST_TIMER_RESOLUTION_HZ,
|
||||||
.alarm_en = TIMER_ALARM_EN,
|
.alarm_en = TIMER_ALARM_EN,
|
||||||
.auto_reload = TIMER_AUTORELOAD_DIS,
|
.auto_reload = TIMER_AUTORELOAD_DIS,
|
||||||
.counter_dir = TIMER_COUNT_UP,
|
.counter_dir = TIMER_COUNT_UP,
|
||||||
.divider = TIMER_DIVIDER,
|
|
||||||
.counter_en = TIMER_PAUSE,
|
.counter_en = TIMER_PAUSE,
|
||||||
.intr_type = TIMER_INTR_LEVEL
|
.intr_type = TIMER_INTR_LEVEL
|
||||||
};
|
};
|
||||||
@@ -660,17 +634,19 @@ TEST_CASE("Timer set alarm value", "[hw_timer]")
|
|||||||
all_timer_isr_reg();
|
all_timer_isr_reg();
|
||||||
|
|
||||||
// set and get alarm value
|
// set and get alarm value
|
||||||
all_timer_set_alarm_value(3 * TIMER_SCALE);
|
all_timer_set_alarm_value(3 * TEST_TIMER_RESOLUTION_HZ);
|
||||||
all_timer_get_alarm_value(alarm_val);
|
all_timer_get_alarm_value(alarm_val);
|
||||||
for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
|
for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
|
||||||
TEST_ASSERT_EQUAL_UINT32(3 * TIMER_SCALE, (uint32_t)alarm_val[i]);
|
TEST_ASSERT_EQUAL_UINT32(3 * TEST_TIMER_RESOLUTION_HZ, (uint32_t)alarm_val[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set interrupt read alarm value
|
// set interrupt read alarm value
|
||||||
timer_intr_enable_and_start(TIMER_GROUP_0, TIMER_0, 2.4);
|
timer_intr_enable_and_start(TIMER_GROUP_0, TIMER_0, 2.4);
|
||||||
timer_isr_check(TIMER_GROUP_0, TIMER_0, TIMER_AUTORELOAD_DIS, 2.4 * TIMER_SCALE);
|
timer_isr_check(TIMER_GROUP_0, TIMER_0, TIMER_AUTORELOAD_DIS, 2.4 * TEST_TIMER_RESOLUTION_HZ);
|
||||||
|
#if SOC_TIMER_GROUPS > 1
|
||||||
timer_intr_enable_and_start(TIMER_GROUP_1, TIMER_0, 1.4);
|
timer_intr_enable_and_start(TIMER_GROUP_1, TIMER_0, 1.4);
|
||||||
timer_isr_check(TIMER_GROUP_1, TIMER_0, TIMER_AUTORELOAD_DIS, 1.4 * TIMER_SCALE);
|
timer_isr_check(TIMER_GROUP_1, TIMER_0, TIMER_AUTORELOAD_DIS, 1.4 * TEST_TIMER_RESOLUTION_HZ);
|
||||||
|
#endif
|
||||||
all_timer_isr_unreg();
|
all_timer_isr_unreg();
|
||||||
all_timer_deinit();
|
all_timer_deinit();
|
||||||
}
|
}
|
||||||
@@ -683,10 +659,11 @@ TEST_CASE("Timer set alarm value", "[hw_timer]")
|
|||||||
TEST_CASE("Timer auto reload", "[hw_timer]")
|
TEST_CASE("Timer auto reload", "[hw_timer]")
|
||||||
{
|
{
|
||||||
timer_config_t config = {
|
timer_config_t config = {
|
||||||
|
.clk_src = TIMER_SRC_CLK_APB,
|
||||||
|
.divider = APB_CLK_FREQ / TEST_TIMER_RESOLUTION_HZ,
|
||||||
.alarm_en = TIMER_ALARM_EN,
|
.alarm_en = TIMER_ALARM_EN,
|
||||||
.auto_reload = TIMER_AUTORELOAD_DIS,
|
.auto_reload = TIMER_AUTORELOAD_DIS,
|
||||||
.counter_dir = TIMER_COUNT_UP,
|
.counter_dir = TIMER_COUNT_UP,
|
||||||
.divider = TIMER_DIVIDER,
|
|
||||||
.counter_en = TIMER_PAUSE,
|
.counter_en = TIMER_PAUSE,
|
||||||
.intr_type = TIMER_INTR_LEVEL
|
.intr_type = TIMER_INTR_LEVEL
|
||||||
};
|
};
|
||||||
@@ -695,17 +672,21 @@ TEST_CASE("Timer auto reload", "[hw_timer]")
|
|||||||
|
|
||||||
// test disable auto_reload
|
// test disable auto_reload
|
||||||
timer_intr_enable_and_start(TIMER_GROUP_0, TIMER_0, 1.14);
|
timer_intr_enable_and_start(TIMER_GROUP_0, TIMER_0, 1.14);
|
||||||
timer_isr_check(TIMER_GROUP_0, TIMER_0, TIMER_AUTORELOAD_DIS, 1.14 * TIMER_SCALE);
|
timer_isr_check(TIMER_GROUP_0, TIMER_0, TIMER_AUTORELOAD_DIS, 1.14 * TEST_TIMER_RESOLUTION_HZ);
|
||||||
|
#if SOC_TIMER_GROUPS > 1
|
||||||
timer_intr_enable_and_start(TIMER_GROUP_1, TIMER_0, 1.14);
|
timer_intr_enable_and_start(TIMER_GROUP_1, TIMER_0, 1.14);
|
||||||
timer_isr_check(TIMER_GROUP_1, TIMER_0, TIMER_AUTORELOAD_DIS, 1.14 * TIMER_SCALE);
|
timer_isr_check(TIMER_GROUP_1, TIMER_0, TIMER_AUTORELOAD_DIS, 1.14 * TEST_TIMER_RESOLUTION_HZ);
|
||||||
|
#endif
|
||||||
|
|
||||||
//test enable auto_reload
|
//test enable auto_reload
|
||||||
TEST_ESP_OK(timer_set_auto_reload(TIMER_GROUP_0, TIMER_0, TIMER_AUTORELOAD_EN));
|
TEST_ESP_OK(timer_set_auto_reload(TIMER_GROUP_0, TIMER_0, TIMER_AUTORELOAD_EN));
|
||||||
timer_intr_enable_and_start(TIMER_GROUP_0, TIMER_0, 1.4);
|
timer_intr_enable_and_start(TIMER_GROUP_0, TIMER_0, 1.4);
|
||||||
timer_isr_check(TIMER_GROUP_0, TIMER_0, TIMER_AUTORELOAD_EN, 0);
|
timer_isr_check(TIMER_GROUP_0, TIMER_0, TIMER_AUTORELOAD_EN, 0);
|
||||||
|
#if SOC_TIMER_GROUPS > 1
|
||||||
TEST_ESP_OK(timer_set_auto_reload(TIMER_GROUP_1, TIMER_0, TIMER_AUTORELOAD_EN));
|
TEST_ESP_OK(timer_set_auto_reload(TIMER_GROUP_1, TIMER_0, TIMER_AUTORELOAD_EN));
|
||||||
timer_intr_enable_and_start(TIMER_GROUP_1, TIMER_0, 1.4);
|
timer_intr_enable_and_start(TIMER_GROUP_1, TIMER_0, 1.4);
|
||||||
timer_isr_check(TIMER_GROUP_1, TIMER_0, TIMER_AUTORELOAD_EN, 0);
|
timer_isr_check(TIMER_GROUP_1, TIMER_0, TIMER_AUTORELOAD_EN, 0);
|
||||||
|
#endif
|
||||||
all_timer_isr_unreg();
|
all_timer_isr_unreg();
|
||||||
all_timer_deinit();
|
all_timer_deinit();
|
||||||
}
|
}
|
||||||
@@ -718,30 +699,33 @@ TEST_CASE("Timer auto reload", "[hw_timer]")
|
|||||||
TEST_CASE("Timer enable timer interrupt", "[hw_timer]")
|
TEST_CASE("Timer enable timer interrupt", "[hw_timer]")
|
||||||
{
|
{
|
||||||
timer_config_t config = {
|
timer_config_t config = {
|
||||||
|
.clk_src = TIMER_SRC_CLK_APB,
|
||||||
|
.divider = APB_CLK_FREQ / TEST_TIMER_RESOLUTION_HZ,
|
||||||
.alarm_en = TIMER_ALARM_DIS,
|
.alarm_en = TIMER_ALARM_DIS,
|
||||||
.counter_dir = TIMER_COUNT_UP,
|
.counter_dir = TIMER_COUNT_UP,
|
||||||
.auto_reload = TIMER_AUTORELOAD_DIS,
|
.auto_reload = TIMER_AUTORELOAD_DIS,
|
||||||
.divider = TIMER_DIVIDER,
|
|
||||||
.counter_en = TIMER_PAUSE,
|
.counter_en = TIMER_PAUSE,
|
||||||
.intr_type = TIMER_INTR_LEVEL
|
.intr_type = TIMER_INTR_LEVEL
|
||||||
};
|
};
|
||||||
|
|
||||||
all_timer_init(&config, true);
|
all_timer_init(&config, true);
|
||||||
all_timer_pause();
|
all_timer_pause();
|
||||||
all_timer_set_alarm_value(1.2 * TIMER_SCALE);
|
all_timer_set_alarm_value(1.2 * TEST_TIMER_RESOLUTION_HZ);
|
||||||
all_timer_set_counter_value(0);
|
all_timer_set_counter_value(0);
|
||||||
all_timer_isr_reg();
|
all_timer_isr_reg();
|
||||||
timer_intr_enable_disable_test(TIMER_GROUP_0, TIMER_0, 1.2 * TIMER_SCALE);
|
timer_intr_enable_disable_test(TIMER_GROUP_0, TIMER_0, 1.2 * TEST_TIMER_RESOLUTION_HZ);
|
||||||
timer_intr_enable_disable_test(TIMER_GROUP_1, TIMER_0, 1.2 * TIMER_SCALE);
|
#if SOC_TIMER_GROUPS > 1
|
||||||
|
timer_intr_enable_disable_test(TIMER_GROUP_1, TIMER_0, 1.2 * TEST_TIMER_RESOLUTION_HZ);
|
||||||
|
#endif
|
||||||
|
|
||||||
// enable interrupt of tg1_timer0 again
|
// enable interrupt of tg0_timer0 again
|
||||||
alarm_flag = false;
|
alarm_flag = false;
|
||||||
TEST_ESP_OK(timer_pause(TIMER_GROUP_1, TIMER_0));
|
TEST_ESP_OK(timer_pause(TIMER_GROUP_0, TIMER_0));
|
||||||
TEST_ESP_OK(timer_set_counter_value(TIMER_GROUP_1, TIMER_0, 0));
|
TEST_ESP_OK(timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0));
|
||||||
TEST_ESP_OK(timer_set_alarm(TIMER_GROUP_1, TIMER_0, TIMER_ALARM_EN));
|
TEST_ESP_OK(timer_set_alarm(TIMER_GROUP_0, TIMER_0, TIMER_ALARM_EN));
|
||||||
TEST_ESP_OK(timer_enable_intr(TIMER_GROUP_1, TIMER_0));
|
TEST_ESP_OK(timer_enable_intr(TIMER_GROUP_0, TIMER_0));
|
||||||
TEST_ESP_OK(timer_start(TIMER_GROUP_1, TIMER_0));
|
TEST_ESP_OK(timer_start(TIMER_GROUP_0, TIMER_0));
|
||||||
timer_isr_check(TIMER_GROUP_1, TIMER_0, TIMER_AUTORELOAD_DIS, 1.2 * TIMER_SCALE);
|
timer_isr_check(TIMER_GROUP_0, TIMER_0, TIMER_AUTORELOAD_DIS, 1.2 * TEST_TIMER_RESOLUTION_HZ);
|
||||||
TEST_ASSERT_EQUAL(true, alarm_flag);
|
TEST_ASSERT_EQUAL(true, alarm_flag);
|
||||||
all_timer_isr_unreg();
|
all_timer_isr_unreg();
|
||||||
all_timer_deinit();
|
all_timer_deinit();
|
||||||
@@ -757,10 +741,11 @@ TEST_CASE("Timer enable timer group interrupt", "[hw_timer][ignore]")
|
|||||||
intr_handle_t isr_handle = NULL;
|
intr_handle_t isr_handle = NULL;
|
||||||
alarm_flag = false;
|
alarm_flag = false;
|
||||||
timer_config_t config = {
|
timer_config_t config = {
|
||||||
|
.clk_src = TIMER_SRC_CLK_APB,
|
||||||
|
.divider = APB_CLK_FREQ / TEST_TIMER_RESOLUTION_HZ,
|
||||||
.alarm_en = TIMER_ALARM_EN,
|
.alarm_en = TIMER_ALARM_EN,
|
||||||
.auto_reload = TIMER_AUTORELOAD_DIS,
|
.auto_reload = TIMER_AUTORELOAD_DIS,
|
||||||
.counter_dir = TIMER_COUNT_UP,
|
.counter_dir = TIMER_COUNT_UP,
|
||||||
.divider = TIMER_DIVIDER,
|
|
||||||
.counter_en = TIMER_PAUSE,
|
.counter_en = TIMER_PAUSE,
|
||||||
.intr_type = TIMER_INTR_LEVEL
|
.intr_type = TIMER_INTR_LEVEL
|
||||||
};
|
};
|
||||||
@@ -768,14 +753,14 @@ TEST_CASE("Timer enable timer group interrupt", "[hw_timer][ignore]")
|
|||||||
all_timer_init(&config, true);
|
all_timer_init(&config, true);
|
||||||
all_timer_pause();
|
all_timer_pause();
|
||||||
all_timer_set_counter_value(set_timer_val);
|
all_timer_set_counter_value(set_timer_val);
|
||||||
all_timer_set_alarm_value(1.2 * TIMER_SCALE);
|
all_timer_set_alarm_value(1.2 * TEST_TIMER_RESOLUTION_HZ);
|
||||||
|
|
||||||
// enable interrupt of tg0_timer0
|
// enable interrupt of tg0_timer0
|
||||||
TEST_ESP_OK(timer_group_intr_enable(TIMER_GROUP_0, TIMER_INTR_T0));
|
TEST_ESP_OK(timer_group_intr_enable(TIMER_GROUP_0, TIMER_INTR_T0));
|
||||||
TEST_ESP_OK(timer_isr_register(TIMER_GROUP_0, TIMER_0, test_timer_group_isr,
|
TEST_ESP_OK(timer_isr_register(TIMER_GROUP_0, TIMER_0, test_timer_group_isr,
|
||||||
GET_TIMER_INFO(TIMER_GROUP_0, TIMER_0), ESP_INTR_FLAG_LOWMED, &isr_handle));
|
GET_TIMER_INFO(TIMER_GROUP_0, TIMER_0), ESP_INTR_FLAG_LOWMED, &isr_handle));
|
||||||
TEST_ESP_OK(timer_start(TIMER_GROUP_0, TIMER_0));
|
TEST_ESP_OK(timer_start(TIMER_GROUP_0, TIMER_0));
|
||||||
timer_isr_check(TIMER_GROUP_0, TIMER_0, TIMER_AUTORELOAD_DIS, 1.2 * TIMER_SCALE);
|
timer_isr_check(TIMER_GROUP_0, TIMER_0, TIMER_AUTORELOAD_DIS, 1.2 * TEST_TIMER_RESOLUTION_HZ);
|
||||||
TEST_ASSERT_EQUAL(true, alarm_flag);
|
TEST_ASSERT_EQUAL(true, alarm_flag);
|
||||||
|
|
||||||
// disable interrupt of tg0_timer0
|
// disable interrupt of tg0_timer0
|
||||||
@@ -795,10 +780,11 @@ TEST_CASE("Timer enable timer group interrupt", "[hw_timer][ignore]")
|
|||||||
TEST_CASE("Timer interrupt register", "[hw_timer]")
|
TEST_CASE("Timer interrupt register", "[hw_timer]")
|
||||||
{
|
{
|
||||||
timer_config_t config = {
|
timer_config_t config = {
|
||||||
|
.clk_src = TIMER_SRC_CLK_APB,
|
||||||
|
.divider = APB_CLK_FREQ / TEST_TIMER_RESOLUTION_HZ,
|
||||||
.alarm_en = TIMER_ALARM_DIS,
|
.alarm_en = TIMER_ALARM_DIS,
|
||||||
.auto_reload = TIMER_AUTORELOAD_DIS,
|
.auto_reload = TIMER_AUTORELOAD_DIS,
|
||||||
.counter_dir = TIMER_COUNT_UP,
|
.counter_dir = TIMER_COUNT_UP,
|
||||||
.divider = TIMER_DIVIDER,
|
|
||||||
.counter_en = TIMER_PAUSE,
|
.counter_en = TIMER_PAUSE,
|
||||||
.intr_type = TIMER_INTR_LEVEL
|
.intr_type = TIMER_INTR_LEVEL
|
||||||
};
|
};
|
||||||
@@ -815,15 +801,19 @@ TEST_CASE("Timer interrupt register", "[hw_timer]")
|
|||||||
|
|
||||||
TEST_ESP_OK(timer_set_alarm(TIMER_GROUP_0, TIMER_0, TIMER_ALARM_EN));
|
TEST_ESP_OK(timer_set_alarm(TIMER_GROUP_0, TIMER_0, TIMER_ALARM_EN));
|
||||||
timer_intr_enable_and_start(TIMER_GROUP_0, TIMER_0, 0.54);
|
timer_intr_enable_and_start(TIMER_GROUP_0, TIMER_0, 0.54);
|
||||||
|
#if SOC_TIMER_GROUPS > 1
|
||||||
TEST_ESP_OK(timer_set_alarm(TIMER_GROUP_1, TIMER_0, TIMER_ALARM_EN));
|
TEST_ESP_OK(timer_set_alarm(TIMER_GROUP_1, TIMER_0, TIMER_ALARM_EN));
|
||||||
timer_intr_enable_and_start(TIMER_GROUP_1, TIMER_0, 0.34);
|
timer_intr_enable_and_start(TIMER_GROUP_1, TIMER_0, 0.34);
|
||||||
|
#endif
|
||||||
|
|
||||||
TEST_ESP_OK(timer_set_auto_reload(TIMER_GROUP_0, TIMER_0, TIMER_AUTORELOAD_EN));
|
TEST_ESP_OK(timer_set_auto_reload(TIMER_GROUP_0, TIMER_0, TIMER_AUTORELOAD_EN));
|
||||||
TEST_ESP_OK(timer_set_alarm(TIMER_GROUP_0, TIMER_0, TIMER_ALARM_EN));
|
TEST_ESP_OK(timer_set_alarm(TIMER_GROUP_0, TIMER_0, TIMER_ALARM_EN));
|
||||||
timer_intr_enable_and_start(TIMER_GROUP_0, TIMER_0, 0.4);
|
timer_intr_enable_and_start(TIMER_GROUP_0, TIMER_0, 0.4);
|
||||||
|
#if SOC_TIMER_GROUPS > 1
|
||||||
TEST_ESP_OK(timer_set_auto_reload(TIMER_GROUP_1, TIMER_0, TIMER_AUTORELOAD_EN));
|
TEST_ESP_OK(timer_set_auto_reload(TIMER_GROUP_1, TIMER_0, TIMER_AUTORELOAD_EN));
|
||||||
TEST_ESP_OK(timer_set_alarm(TIMER_GROUP_1, TIMER_0, TIMER_ALARM_EN));
|
TEST_ESP_OK(timer_set_alarm(TIMER_GROUP_1, TIMER_0, TIMER_ALARM_EN));
|
||||||
timer_intr_enable_and_start(TIMER_GROUP_1, TIMER_0, 0.6);
|
timer_intr_enable_and_start(TIMER_GROUP_1, TIMER_0, 0.6);
|
||||||
|
#endif
|
||||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||||
|
|
||||||
// ISR hanlde function should be free before next ISR register.
|
// ISR hanlde function should be free before next ISR register.
|
||||||
@@ -845,34 +835,37 @@ TEST_CASE("Timer interrupt register", "[hw_timer]")
|
|||||||
TEST_CASE("Timer clock source", "[hw_timer]")
|
TEST_CASE("Timer clock source", "[hw_timer]")
|
||||||
{
|
{
|
||||||
// configure clock source as APB clock
|
// configure clock source as APB clock
|
||||||
uint32_t timer_scale = rtc_clk_apb_freq_get() / TIMER_DIVIDER;
|
|
||||||
timer_config_t config = {
|
timer_config_t config = {
|
||||||
|
.clk_src = TIMER_SRC_CLK_APB,
|
||||||
|
.divider = APB_CLK_FREQ / TEST_TIMER_RESOLUTION_HZ,
|
||||||
.alarm_en = TIMER_ALARM_DIS,
|
.alarm_en = TIMER_ALARM_DIS,
|
||||||
.auto_reload = TIMER_AUTORELOAD_DIS,
|
.auto_reload = TIMER_AUTORELOAD_DIS,
|
||||||
.counter_dir = TIMER_COUNT_UP,
|
.counter_dir = TIMER_COUNT_UP,
|
||||||
.divider = TIMER_DIVIDER,
|
|
||||||
.counter_en = TIMER_PAUSE,
|
.counter_en = TIMER_PAUSE,
|
||||||
.intr_type = TIMER_INTR_LEVEL,
|
.intr_type = TIMER_INTR_LEVEL,
|
||||||
.clk_src = TIMER_SRC_CLK_APB
|
|
||||||
};
|
};
|
||||||
all_timer_init(&config, true);
|
all_timer_init(&config, true);
|
||||||
all_timer_pause();
|
all_timer_pause();
|
||||||
all_timer_set_alarm_value(1.2 * timer_scale);
|
all_timer_set_alarm_value(1.2 * TEST_TIMER_RESOLUTION_HZ);
|
||||||
all_timer_set_counter_value(0);
|
all_timer_set_counter_value(0);
|
||||||
all_timer_isr_reg();
|
all_timer_isr_reg();
|
||||||
|
|
||||||
timer_intr_enable_disable_test(TIMER_GROUP_0, TIMER_0, 1.2 * timer_scale);
|
timer_intr_enable_disable_test(TIMER_GROUP_0, TIMER_0, 1.2 * TEST_TIMER_RESOLUTION_HZ);
|
||||||
timer_intr_enable_disable_test(TIMER_GROUP_1, TIMER_0, 1.2 * timer_scale );
|
#if SOC_TIMER_GROUPS > 1
|
||||||
|
timer_intr_enable_disable_test(TIMER_GROUP_1, TIMER_0, 1.2 * TEST_TIMER_RESOLUTION_HZ);
|
||||||
|
#endif
|
||||||
|
|
||||||
// configure clock source as XTAL clock
|
// configure clock source as XTAL clock
|
||||||
all_timer_pause();
|
all_timer_pause();
|
||||||
timer_scale = rtc_clk_xtal_freq_get() * 1000000 / TIMER_DIVIDER;
|
|
||||||
config.clk_src = TIMER_SRC_CLK_XTAL;
|
config.clk_src = TIMER_SRC_CLK_XTAL;
|
||||||
|
config.divider = rtc_clk_xtal_freq_get() * 1000000 / TEST_TIMER_RESOLUTION_HZ;
|
||||||
all_timer_init(&config, true);
|
all_timer_init(&config, true);
|
||||||
all_timer_set_alarm_value(1.2 * timer_scale);
|
all_timer_set_alarm_value(1.2 * TEST_TIMER_RESOLUTION_HZ);
|
||||||
|
|
||||||
timer_intr_enable_disable_test(TIMER_GROUP_0, TIMER_0, 1.2 * timer_scale);
|
timer_intr_enable_disable_test(TIMER_GROUP_0, TIMER_0, 1.2 * TEST_TIMER_RESOLUTION_HZ);
|
||||||
timer_intr_enable_disable_test(TIMER_GROUP_1, TIMER_0, 1.2 * timer_scale );
|
#if SOC_TIMER_GROUPS > 1
|
||||||
|
timer_intr_enable_disable_test(TIMER_GROUP_1, TIMER_0, 1.2 * TEST_TIMER_RESOLUTION_HZ);
|
||||||
|
#endif
|
||||||
|
|
||||||
all_timer_isr_unreg();
|
all_timer_isr_unreg();
|
||||||
all_timer_deinit();
|
all_timer_deinit();
|
||||||
@@ -886,15 +879,15 @@ TEST_CASE("Timer ISR callback", "[hw_timer]")
|
|||||||
{
|
{
|
||||||
alarm_flag = false;
|
alarm_flag = false;
|
||||||
timer_config_t config = {
|
timer_config_t config = {
|
||||||
|
.clk_src = TIMER_SRC_CLK_APB,
|
||||||
|
.divider = APB_CLK_FREQ / TEST_TIMER_RESOLUTION_HZ,
|
||||||
.alarm_en = TIMER_ALARM_EN,
|
.alarm_en = TIMER_ALARM_EN,
|
||||||
.auto_reload = TIMER_AUTORELOAD_DIS,
|
.auto_reload = TIMER_AUTORELOAD_DIS,
|
||||||
.counter_dir = TIMER_COUNT_UP,
|
.counter_dir = TIMER_COUNT_UP,
|
||||||
.divider = TIMER_DIVIDER,
|
|
||||||
.counter_en = TIMER_PAUSE,
|
.counter_en = TIMER_PAUSE,
|
||||||
.intr_type = TIMER_INTR_LEVEL,
|
.intr_type = TIMER_INTR_LEVEL,
|
||||||
};
|
};
|
||||||
uint32_t timer_scale = rtc_clk_apb_freq_get() / TIMER_DIVIDER;
|
uint64_t alarm_cnt_val = 1.2 * TEST_TIMER_RESOLUTION_HZ;
|
||||||
uint64_t alarm_cnt_val = 1.2 * timer_scale;
|
|
||||||
uint64_t set_timer_val = 0x0;
|
uint64_t set_timer_val = 0x0;
|
||||||
all_timer_init(&config, true);
|
all_timer_init(&config, true);
|
||||||
all_timer_pause();
|
all_timer_pause();
|
||||||
@@ -918,6 +911,7 @@ TEST_CASE("Timer ISR callback", "[hw_timer]")
|
|||||||
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
||||||
TEST_ASSERT_EQUAL(false, alarm_flag);
|
TEST_ASSERT_EQUAL(false, alarm_flag);
|
||||||
|
|
||||||
|
#if SOC_TIMER_GROUPS > 1
|
||||||
// add isr callback for tg1_timer0
|
// add isr callback for tg1_timer0
|
||||||
TEST_ESP_OK(timer_pause(TIMER_GROUP_1, TIMER_0));
|
TEST_ESP_OK(timer_pause(TIMER_GROUP_1, TIMER_0));
|
||||||
TEST_ESP_OK(timer_isr_callback_add(TIMER_GROUP_1, TIMER_0, test_timer_group_isr_cb,
|
TEST_ESP_OK(timer_isr_callback_add(TIMER_GROUP_1, TIMER_0, test_timer_group_isr_cb,
|
||||||
@@ -935,19 +929,21 @@ TEST_CASE("Timer ISR callback", "[hw_timer]")
|
|||||||
TEST_ESP_OK(timer_start(TIMER_GROUP_1, TIMER_0));
|
TEST_ESP_OK(timer_start(TIMER_GROUP_1, TIMER_0));
|
||||||
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
||||||
TEST_ASSERT_EQUAL(false, alarm_flag);
|
TEST_ASSERT_EQUAL(false, alarm_flag);
|
||||||
|
#endif
|
||||||
all_timer_deinit();
|
all_timer_deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Timer memory test
|
* Timer memory test
|
||||||
*/
|
*/
|
||||||
TEST_CASE("Timer memory test", "[hw_timer]")
|
TEST_CASE("Timer init/deinit stress test", "[hw_timer]")
|
||||||
{
|
{
|
||||||
timer_config_t config = {
|
timer_config_t config = {
|
||||||
|
.clk_src = TIMER_SRC_CLK_APB,
|
||||||
|
.divider = APB_CLK_FREQ / TEST_TIMER_RESOLUTION_HZ,
|
||||||
.alarm_en = TIMER_ALARM_EN,
|
.alarm_en = TIMER_ALARM_EN,
|
||||||
.auto_reload = TIMER_AUTORELOAD_EN,
|
.auto_reload = TIMER_AUTORELOAD_EN,
|
||||||
.counter_dir = TIMER_COUNT_UP,
|
.counter_dir = TIMER_COUNT_UP,
|
||||||
.divider = TIMER_DIVIDER,
|
|
||||||
.counter_en = TIMER_PAUSE,
|
.counter_en = TIMER_PAUSE,
|
||||||
.intr_type = TIMER_INTR_LEVEL,
|
.intr_type = TIMER_INTR_LEVEL,
|
||||||
};
|
};
|
||||||
@@ -964,10 +960,10 @@ TEST_CASE("Timer memory test", "[hw_timer]")
|
|||||||
static void timer_group_test_init(void)
|
static void timer_group_test_init(void)
|
||||||
{
|
{
|
||||||
static const uint32_t time_ms = 100; // Alarm value 100ms.
|
static const uint32_t time_ms = 100; // Alarm value 100ms.
|
||||||
static const uint16_t timer_div = TIMER_DIVIDER; // Timer prescaler
|
static const uint32_t ste_val = time_ms * TEST_TIMER_RESOLUTION_HZ / 1000;
|
||||||
static const uint32_t ste_val = time_ms * (TIMER_BASE_CLK / timer_div / 1000);
|
|
||||||
timer_config_t config = {
|
timer_config_t config = {
|
||||||
.divider = timer_div,
|
.clk_src = TIMER_SRC_CLK_APB,
|
||||||
|
.divider = APB_CLK_FREQ / TEST_TIMER_RESOLUTION_HZ,
|
||||||
.counter_dir = TIMER_COUNT_UP,
|
.counter_dir = TIMER_COUNT_UP,
|
||||||
.counter_en = TIMER_PAUSE,
|
.counter_en = TIMER_PAUSE,
|
||||||
.alarm_en = TIMER_ALARM_EN,
|
.alarm_en = TIMER_ALARM_EN,
|
||||||
@@ -1028,7 +1024,8 @@ TEST_CASE("Timer check reinitialization sequence", "[hw_timer]")
|
|||||||
// 3 - deinit timer driver
|
// 3 - deinit timer driver
|
||||||
TEST_ESP_OK(timer_deinit(TIMER_GROUP_0, TIMER_0));
|
TEST_ESP_OK(timer_deinit(TIMER_GROUP_0, TIMER_0));
|
||||||
timer_config_t config = {
|
timer_config_t config = {
|
||||||
.divider = TIMER_DIVIDER,
|
.clk_src = TIMER_SRC_CLK_APB,
|
||||||
|
.divider = APB_CLK_FREQ / TEST_TIMER_RESOLUTION_HZ,
|
||||||
.counter_dir = TIMER_COUNT_UP,
|
.counter_dir = TIMER_COUNT_UP,
|
||||||
.counter_en = TIMER_START,
|
.counter_en = TIMER_START,
|
||||||
.alarm_en = TIMER_ALARM_EN,
|
.alarm_en = TIMER_ALARM_EN,
|
||||||
@@ -1043,5 +1040,3 @@ TEST_CASE("Timer check reinitialization sequence", "[hw_timer]")
|
|||||||
// The pending timer interrupt should not be triggered
|
// The pending timer interrupt should not be triggered
|
||||||
TEST_ASSERT_EQUAL(0, timer_group_get_intr_status_in_isr(TIMER_GROUP_0) & TIMER_INTR_T0);
|
TEST_ASSERT_EQUAL(0, timer_group_get_intr_status_in_isr(TIMER_GROUP_0) & TIMER_INTR_T0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP8684)
|
|
||||||
|
@@ -47,6 +47,7 @@ typedef struct {
|
|||||||
gptimer_clock_source_t clk_src;
|
gptimer_clock_source_t clk_src;
|
||||||
gptimer_count_direction_t direction;
|
gptimer_count_direction_t direction;
|
||||||
uint32_t divider;
|
uint32_t divider;
|
||||||
|
uint64_t alarm_value;
|
||||||
bool alarm_en;
|
bool alarm_en;
|
||||||
bool auto_reload_en;
|
bool auto_reload_en;
|
||||||
bool counter_en;
|
bool counter_en;
|
||||||
@@ -171,6 +172,7 @@ esp_err_t timer_set_alarm_value(timer_group_t group_num, timer_idx_t timer_num,
|
|||||||
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_ll_set_alarm_value(p_timer_obj[group_num][timer_num]->hal.dev, timer_num, alarm_value);
|
timer_ll_set_alarm_value(p_timer_obj[group_num][timer_num]->hal.dev, timer_num, alarm_value);
|
||||||
|
p_timer_obj[group_num][timer_num]->alarm_value = alarm_value;
|
||||||
TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]);
|
TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]);
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
@@ -182,7 +184,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]);
|
||||||
*alarm_value = timer_ll_get_alarm_value(p_timer_obj[group_num][timer_num]->hal.dev, timer_num);
|
*alarm_value = p_timer_obj[group_num][timer_num]->alarm_value;
|
||||||
TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]);
|
TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]);
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
@@ -210,12 +212,16 @@ static void IRAM_ATTR timer_isr_default(void *arg)
|
|||||||
timer_hal_context_t *hal = &timer_obj->hal;
|
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 = timer_ll_get_intr_status(hal->dev);
|
||||||
|
uint64_t old_alarm_value = timer_obj->alarm_value;
|
||||||
if (intr_status & TIMER_LL_EVENT_ALARM(timer_id)) {
|
if (intr_status & TIMER_LL_EVENT_ALARM(timer_id)) {
|
||||||
//Clear intrrupt status
|
// Clear interrupt status
|
||||||
timer_ll_clear_intr_status(hal->dev, TIMER_LL_EVENT_ALARM(timer_id));
|
timer_ll_clear_intr_status(hal->dev, TIMER_LL_EVENT_ALARM(timer_id));
|
||||||
|
// call user registered callback
|
||||||
is_awoken = timer_obj->timer_isr_fun.fn(timer_obj->timer_isr_fun.args);
|
is_awoken = timer_obj->timer_isr_fun.fn(timer_obj->timer_isr_fun.args);
|
||||||
//If the timer is set to auto reload, we need enable it again, so it is triggered the next time
|
// reenable alarm if required
|
||||||
timer_ll_enable_alarm(hal->dev, timer_id, timer_obj->auto_reload_en);
|
uint64_t new_alarm_value = timer_obj->alarm_value;
|
||||||
|
bool reenable_alarm = (new_alarm_value != old_alarm_value) || timer_obj->auto_reload_en;
|
||||||
|
timer_ll_enable_alarm(hal->dev, timer_id, reenable_alarm);
|
||||||
}
|
}
|
||||||
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]);
|
||||||
|
|
||||||
@@ -430,6 +436,7 @@ uint64_t IRAM_ATTR timer_group_get_counter_value_in_isr(timer_group_t group_num,
|
|||||||
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_ll_set_alarm_value(p_timer_obj[group_num][timer_num]->hal.dev, timer_num, alarm_val);
|
timer_ll_set_alarm_value(p_timer_obj[group_num][timer_num]->hal.dev, timer_num, alarm_val);
|
||||||
|
p_timer_obj[group_num][timer_num]->alarm_value = 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)
|
||||||
|
@@ -144,18 +144,6 @@ static inline void timer_ll_set_alarm_value(timg_dev_t *hw, uint32_t timer_num,
|
|||||||
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 alarm value
|
|
||||||
*
|
|
||||||
* @param hw Timer Group register base address
|
|
||||||
* @param timer_num Timer number in the group
|
|
||||||
* @return Counter value to trigger the alarm event
|
|
||||||
*/
|
|
||||||
static inline uint64_t timer_ll_get_alarm_value(timg_dev_t *hw, uint32_t timer_num)
|
|
||||||
{
|
|
||||||
return ((uint64_t) hw->hw_timer[timer_num].alarmhi.tx_alarm_hi << 32) | (hw->hw_timer[timer_num].alarmlo.tx_alarm_lo);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set reload value
|
* @brief Set reload value
|
||||||
*
|
*
|
||||||
|
@@ -147,18 +147,6 @@ static inline void timer_ll_set_alarm_value(timg_dev_t *hw, uint32_t timer_num,
|
|||||||
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 alarm value
|
|
||||||
*
|
|
||||||
* @param hw Timer Group register base address
|
|
||||||
* @param timer_num Timer number in the group
|
|
||||||
* @return Counter value to trigger the alarm event
|
|
||||||
*/
|
|
||||||
static inline uint64_t timer_ll_get_alarm_value(timg_dev_t *hw, uint32_t timer_num)
|
|
||||||
{
|
|
||||||
return ((uint64_t) hw->hw_timer[timer_num].alarmhi.tx_alarm_hi << 32) | (hw->hw_timer[timer_num].alarmlo.tx_alarm_lo);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set reload value
|
* @brief Set reload value
|
||||||
*
|
*
|
||||||
|
@@ -147,18 +147,6 @@ static inline void timer_ll_set_alarm_value(timg_dev_t *hw, uint32_t timer_num,
|
|||||||
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 alarm value
|
|
||||||
*
|
|
||||||
* @param hw Timer Group register base address
|
|
||||||
* @param timer_num Timer number in the group
|
|
||||||
* @return Counter value to trigger the alarm event
|
|
||||||
*/
|
|
||||||
static inline uint64_t timer_ll_get_alarm_value(timg_dev_t *hw, uint32_t timer_num)
|
|
||||||
{
|
|
||||||
return ((uint64_t) hw->hw_timer[timer_num].alarmhi.tx_alarm_hi << 32) | (hw->hw_timer[timer_num].alarmlo.tx_alarm_lo);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set reload value
|
* @brief Set reload value
|
||||||
*
|
*
|
||||||
|
@@ -148,18 +148,6 @@ static inline void timer_ll_set_alarm_value(timg_dev_t *hw, uint32_t timer_num,
|
|||||||
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 alarm value
|
|
||||||
*
|
|
||||||
* @param hw Timer Group register base address
|
|
||||||
* @param timer_num Timer number in the group
|
|
||||||
* @return Counter value to trigger the alarm event
|
|
||||||
*/
|
|
||||||
static inline uint64_t timer_ll_get_alarm_value(timg_dev_t *hw, uint32_t timer_num)
|
|
||||||
{
|
|
||||||
return ((uint64_t) hw->hw_timer[timer_num].alarmhi.tx_alarm_hi << 32) | (hw->hw_timer[timer_num].alarmlo.tx_alarm_lo);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set reload value
|
* @brief Set reload value
|
||||||
*
|
*
|
||||||
|
@@ -147,18 +147,6 @@ static inline void timer_ll_set_alarm_value(timg_dev_t *hw, uint32_t timer_num,
|
|||||||
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 alarm value
|
|
||||||
*
|
|
||||||
* @param hw Timer Group register base address
|
|
||||||
* @param timer_num Timer number in the group
|
|
||||||
* @return Counter value to trigger the alarm event
|
|
||||||
*/
|
|
||||||
static inline uint64_t timer_ll_get_alarm_value(timg_dev_t *hw, uint32_t timer_num)
|
|
||||||
{
|
|
||||||
return ((uint64_t)hw->hw_timer[timer_num].alarmhi.tn_alarm_hi << 32) | (hw->hw_timer[timer_num].alarmlo.tn_alarm_lo);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set reload value
|
* @brief Set reload value
|
||||||
*
|
*
|
||||||
|
@@ -12,7 +12,6 @@
|
|||||||
#include "hal/assert.h"
|
#include "hal/assert.h"
|
||||||
#include "hal/misc.h"
|
#include "hal/misc.h"
|
||||||
#include "hal/timer_types.h"
|
#include "hal/timer_types.h"
|
||||||
#include "soc/timer_periph.h"
|
|
||||||
#include "soc/timer_group_struct.h"
|
#include "soc/timer_group_struct.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@@ -148,18 +147,6 @@ static inline void timer_ll_set_alarm_value(timg_dev_t *hw, uint32_t timer_num,
|
|||||||
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 alarm value
|
|
||||||
*
|
|
||||||
* @param hw Timer Group register base address
|
|
||||||
* @param timer_num Timer number in the group
|
|
||||||
* @return Counter value to trigger the alarm event
|
|
||||||
*/
|
|
||||||
static inline uint64_t timer_ll_get_alarm_value(timg_dev_t *hw, uint32_t timer_num)
|
|
||||||
{
|
|
||||||
return ((uint64_t) hw->hw_timer[timer_num].alarmhi.tx_alarm_hi << 32) | (hw->hw_timer[timer_num].alarmlo.tx_alarm_lo);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set reload value
|
* @brief Set reload value
|
||||||
*
|
*
|
||||||
|
@@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "soc/soc_caps.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@@ -14,17 +16,21 @@ extern "C" {
|
|||||||
* @brief GPTimer clock source
|
* @brief GPTimer clock source
|
||||||
* @note The clock source listed here is not supported on all targets
|
* @note The clock source listed here is not supported on all targets
|
||||||
* @note User should select the clock source based on real requirements:
|
* @note User should select the clock source based on real requirements:
|
||||||
* ╔══════════════════════╦══════════════════════════════════╦══════════════════════════╗
|
* @verbatim embed:rst:leading-asterisk
|
||||||
* ║ GPTimer clock source ║ Features ║ Power Management ║
|
* +----------------------+----------------------------------+--------------------------+
|
||||||
* ╠══════════════════════╬══════════════════════════════════╬══════════════════════════╣
|
* | GPTimer clock source | Features | Power Management |
|
||||||
* ║ GPTIMER_CLK_SRC_APB ║ High resolution ║ ESP_PM_APB_FREQ_MAX lock ║
|
* +======================+==================================+==========================+
|
||||||
* ╠══════════════════════╬══════════════════════════════════╬══════════════════════════╣
|
* | GPTIMER_CLK_SRC_APB | High resolution | ESP_PM_APB_FREQ_MAX lock |
|
||||||
* ║ GPTIMER_CLK_SRC_XTAL ║ Medium resolution, high accuracy ║ No PM lock ║
|
* +----------------------+----------------------------------+--------------------------+
|
||||||
* ╚══════════════════════╩══════════════════════════════════╩══════════════════════════╝
|
* | GPTIMER_CLK_SRC_XTAL | Medium resolution, high accuracy | No PM lock |
|
||||||
|
* +----------------------+----------------------------------+--------------------------+
|
||||||
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
GPTIMER_CLK_SRC_APB, /*!< Select APB as the source clock */
|
GPTIMER_CLK_SRC_APB, /*!< Select APB as the source clock */
|
||||||
|
#if SOC_TIMER_GROUP_SUPPORT_XTAL
|
||||||
GPTIMER_CLK_SRC_XTAL, /*!< Select XTAL as the source clock */
|
GPTIMER_CLK_SRC_XTAL, /*!< Select XTAL as the source clock */
|
||||||
|
#endif
|
||||||
} gptimer_clock_source_t;
|
} gptimer_clock_source_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -35,15 +41,6 @@ typedef enum {
|
|||||||
GPTIMER_COUNT_UP, /*!< Increase count value */
|
GPTIMER_COUNT_UP, /*!< Increase count value */
|
||||||
} gptimer_count_direction_t;
|
} gptimer_count_direction_t;
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief GPTimer actions on alarm event
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
GPTIMER_ALARM_ACTION_CONTINUE, /*!< Counter will pass through the alarm point and continue counting */
|
|
||||||
GPTIMER_ALARM_ACTION_STOP, /*!< Counter will stop on alarm event */
|
|
||||||
GPTIMER_ALARM_ACTION_RELOAD, /*!< Counter will do reload on alarm event */
|
|
||||||
} gptimer_alarm_action_t;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -431,6 +431,10 @@ config SOC_TIMER_GROUP_COUNTER_BIT_WIDTH
|
|||||||
int
|
int
|
||||||
default 64
|
default 64
|
||||||
|
|
||||||
|
config SOC_TIMER_GROUP_TOTAL_TIMERS
|
||||||
|
int
|
||||||
|
default 4
|
||||||
|
|
||||||
config SOC_TOUCH_VERSION_1
|
config SOC_TOUCH_VERSION_1
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
@@ -249,7 +249,7 @@
|
|||||||
#define SOC_TIMER_GROUPS (2)
|
#define SOC_TIMER_GROUPS (2)
|
||||||
#define SOC_TIMER_GROUP_TIMERS_PER_GROUP (2)
|
#define SOC_TIMER_GROUP_TIMERS_PER_GROUP (2)
|
||||||
#define SOC_TIMER_GROUP_COUNTER_BIT_WIDTH (64)
|
#define SOC_TIMER_GROUP_COUNTER_BIT_WIDTH (64)
|
||||||
#define SOC_TIMER_GROUP_TOTAL_TIMERS (SOC_TIMER_GROUPS * SOC_TIMER_GROUP_TIMERS_PER_GROUP)
|
#define SOC_TIMER_GROUP_TOTAL_TIMERS (4)
|
||||||
|
|
||||||
/*-------------------------- TOUCH SENSOR CAPS -------------------------------*/
|
/*-------------------------- TOUCH SENSOR CAPS -------------------------------*/
|
||||||
#define SOC_TOUCH_VERSION_1 (1) /*!<Hardware version of touch sensor */
|
#define SOC_TOUCH_VERSION_1 (1) /*!<Hardware version of touch sensor */
|
||||||
|
@@ -528,8 +528,8 @@ config SOC_TIMER_GROUPS
|
|||||||
default 2
|
default 2
|
||||||
|
|
||||||
config SOC_TIMER_GROUP_TIMERS_PER_GROUP
|
config SOC_TIMER_GROUP_TIMERS_PER_GROUP
|
||||||
bool
|
int
|
||||||
default y
|
default 1
|
||||||
|
|
||||||
config SOC_TIMER_GROUP_COUNTER_BIT_WIDTH
|
config SOC_TIMER_GROUP_COUNTER_BIT_WIDTH
|
||||||
int
|
int
|
||||||
@@ -539,6 +539,10 @@ config SOC_TIMER_GROUP_SUPPORT_XTAL
|
|||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
config SOC_TIMER_GROUP_TOTAL_TIMERS
|
||||||
|
int
|
||||||
|
default 2
|
||||||
|
|
||||||
config SOC_TOUCH_SENSOR_NUM
|
config SOC_TOUCH_SENSOR_NUM
|
||||||
bool
|
bool
|
||||||
default n
|
default n
|
||||||
|
@@ -264,10 +264,10 @@
|
|||||||
|
|
||||||
/*--------------------------- TIMER GROUP CAPS ---------------------------------------*/
|
/*--------------------------- TIMER GROUP CAPS ---------------------------------------*/
|
||||||
#define SOC_TIMER_GROUPS (2)
|
#define SOC_TIMER_GROUPS (2)
|
||||||
#define SOC_TIMER_GROUP_TIMERS_PER_GROUP (1)
|
#define SOC_TIMER_GROUP_TIMERS_PER_GROUP (1U)
|
||||||
#define SOC_TIMER_GROUP_COUNTER_BIT_WIDTH (54)
|
#define SOC_TIMER_GROUP_COUNTER_BIT_WIDTH (54)
|
||||||
#define SOC_TIMER_GROUP_SUPPORT_XTAL (1)
|
#define SOC_TIMER_GROUP_SUPPORT_XTAL (1)
|
||||||
#define SOC_TIMER_GROUP_TOTAL_TIMERS (SOC_TIMER_GROUPS * SOC_TIMER_GROUP_TIMERS_PER_GROUP)
|
#define SOC_TIMER_GROUP_TOTAL_TIMERS (2)
|
||||||
|
|
||||||
/*-------------------------- TOUCH SENSOR CAPS -------------------------------*/
|
/*-------------------------- TOUCH SENSOR CAPS -------------------------------*/
|
||||||
#define SOC_TOUCH_SENSOR_NUM (0) /*! No touch sensors on ESP32-C3 */
|
#define SOC_TOUCH_SENSOR_NUM (0) /*! No touch sensors on ESP32-C3 */
|
||||||
|
@@ -508,8 +508,8 @@ config SOC_TIMER_GROUPS
|
|||||||
default 2
|
default 2
|
||||||
|
|
||||||
config SOC_TIMER_GROUP_TIMERS_PER_GROUP
|
config SOC_TIMER_GROUP_TIMERS_PER_GROUP
|
||||||
bool
|
int
|
||||||
default y
|
default 1
|
||||||
|
|
||||||
config SOC_TIMER_GROUP_COUNTER_BIT_WIDTH
|
config SOC_TIMER_GROUP_COUNTER_BIT_WIDTH
|
||||||
int
|
int
|
||||||
@@ -519,6 +519,10 @@ config SOC_TIMER_GROUP_SUPPORT_XTAL
|
|||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
config SOC_TIMER_GROUP_TOTAL_TIMERS
|
||||||
|
int
|
||||||
|
default 2
|
||||||
|
|
||||||
config SOC_TOUCH_SENSOR_NUM
|
config SOC_TOUCH_SENSOR_NUM
|
||||||
bool
|
bool
|
||||||
default n
|
default n
|
||||||
|
@@ -258,10 +258,10 @@
|
|||||||
|
|
||||||
/*--------------------------- TIMER GROUP CAPS ---------------------------------------*/
|
/*--------------------------- TIMER GROUP CAPS ---------------------------------------*/
|
||||||
#define SOC_TIMER_GROUPS (2)
|
#define SOC_TIMER_GROUPS (2)
|
||||||
#define SOC_TIMER_GROUP_TIMERS_PER_GROUP (1)
|
#define SOC_TIMER_GROUP_TIMERS_PER_GROUP (1U)
|
||||||
#define SOC_TIMER_GROUP_COUNTER_BIT_WIDTH (54)
|
#define SOC_TIMER_GROUP_COUNTER_BIT_WIDTH (54)
|
||||||
#define SOC_TIMER_GROUP_SUPPORT_XTAL (1)
|
#define SOC_TIMER_GROUP_SUPPORT_XTAL (1)
|
||||||
#define SOC_TIMER_GROUP_TOTAL_TIMERS (SOC_TIMER_GROUPS * SOC_TIMER_GROUP_TIMERS_PER_GROUP)
|
#define SOC_TIMER_GROUP_TOTAL_TIMERS (2)
|
||||||
|
|
||||||
/*-------------------------- TOUCH SENSOR CAPS -------------------------------*/
|
/*-------------------------- TOUCH SENSOR CAPS -------------------------------*/
|
||||||
#define SOC_TOUCH_SENSOR_NUM (0) /*! No touch sensors on ESP32-C3 */
|
#define SOC_TOUCH_SENSOR_NUM (0) /*! No touch sensors on ESP32-C3 */
|
||||||
|
@@ -507,10 +507,6 @@ config SOC_SYSTIMER_BIT_WIDTH_HI
|
|||||||
int
|
int
|
||||||
default 32
|
default 32
|
||||||
|
|
||||||
config SOC_TIMER_GROUP_COUNTER_BIT_WIDTH
|
|
||||||
int
|
|
||||||
default 64
|
|
||||||
|
|
||||||
config SOC_TIMER_GROUPS
|
config SOC_TIMER_GROUPS
|
||||||
int
|
int
|
||||||
default 2
|
default 2
|
||||||
@@ -519,10 +515,18 @@ config SOC_TIMER_GROUP_TIMERS_PER_GROUP
|
|||||||
int
|
int
|
||||||
default 2
|
default 2
|
||||||
|
|
||||||
|
config SOC_TIMER_GROUP_COUNTER_BIT_WIDTH
|
||||||
|
int
|
||||||
|
default 64
|
||||||
|
|
||||||
config SOC_TIMER_GROUP_SUPPORT_XTAL
|
config SOC_TIMER_GROUP_SUPPORT_XTAL
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
config SOC_TIMER_GROUP_TOTAL_TIMERS
|
||||||
|
int
|
||||||
|
default 4
|
||||||
|
|
||||||
config SOC_TOUCH_VERSION_2
|
config SOC_TOUCH_VERSION_2
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
@@ -248,11 +248,11 @@
|
|||||||
#define SOC_SYSTIMER_BIT_WIDTH_HI (32) // Bit width of systimer high part
|
#define SOC_SYSTIMER_BIT_WIDTH_HI (32) // Bit width of systimer high part
|
||||||
|
|
||||||
/*-------------------------- TIMER GROUP CAPS --------------------------------*/
|
/*-------------------------- TIMER GROUP CAPS --------------------------------*/
|
||||||
#define SOC_TIMER_GROUP_COUNTER_BIT_WIDTH (64)
|
|
||||||
#define SOC_TIMER_GROUPS (2)
|
#define SOC_TIMER_GROUPS (2)
|
||||||
#define SOC_TIMER_GROUP_TIMERS_PER_GROUP (2)
|
#define SOC_TIMER_GROUP_TIMERS_PER_GROUP (2)
|
||||||
|
#define SOC_TIMER_GROUP_COUNTER_BIT_WIDTH (64)
|
||||||
#define SOC_TIMER_GROUP_SUPPORT_XTAL (1)
|
#define SOC_TIMER_GROUP_SUPPORT_XTAL (1)
|
||||||
#define SOC_TIMER_GROUP_TOTAL_TIMERS (SOC_TIMER_GROUPS * SOC_TIMER_GROUP_TIMERS_PER_GROUP)
|
#define SOC_TIMER_GROUP_TOTAL_TIMERS (4)
|
||||||
|
|
||||||
/*-------------------------- TOUCH SENSOR CAPS -------------------------------*/
|
/*-------------------------- TOUCH SENSOR CAPS -------------------------------*/
|
||||||
#define SOC_TOUCH_VERSION_2 (1) /*!<Hardware version of touch sensor */
|
#define SOC_TOUCH_VERSION_2 (1) /*!<Hardware version of touch sensor */
|
||||||
|
@@ -643,6 +643,10 @@ config SOC_TIMER_GROUP_SUPPORT_XTAL
|
|||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
config SOC_TIMER_GROUP_TOTAL_TIMERS
|
||||||
|
int
|
||||||
|
default 4
|
||||||
|
|
||||||
config SOC_TOUCH_SENSOR_NUM
|
config SOC_TOUCH_SENSOR_NUM
|
||||||
int
|
int
|
||||||
default 15
|
default 15
|
||||||
|
@@ -238,7 +238,7 @@
|
|||||||
#define SOC_TIMER_GROUP_TIMERS_PER_GROUP (2)
|
#define SOC_TIMER_GROUP_TIMERS_PER_GROUP (2)
|
||||||
#define SOC_TIMER_GROUP_COUNTER_BIT_WIDTH (54)
|
#define SOC_TIMER_GROUP_COUNTER_BIT_WIDTH (54)
|
||||||
#define SOC_TIMER_GROUP_SUPPORT_XTAL (1)
|
#define SOC_TIMER_GROUP_SUPPORT_XTAL (1)
|
||||||
#define SOC_TIMER_GROUP_TOTAL_TIMERS (SOC_TIMER_GROUPS * SOC_TIMER_GROUP_TIMERS_PER_GROUP)
|
#define SOC_TIMER_GROUP_TOTAL_TIMERS (4)
|
||||||
|
|
||||||
/*-------------------------- TOUCH SENSOR CAPS -------------------------------*/
|
/*-------------------------- TOUCH SENSOR CAPS -------------------------------*/
|
||||||
#define SOC_TOUCH_SENSOR_NUM (15) /*! 15 Touch channels */
|
#define SOC_TOUCH_SENSOR_NUM (15) /*! 15 Touch channels */
|
||||||
|
@@ -411,6 +411,10 @@ config SOC_TIMER_GROUP_SUPPORT_XTAL
|
|||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
config SOC_TIMER_GROUP_TOTAL_TIMERS
|
||||||
|
int
|
||||||
|
default 1
|
||||||
|
|
||||||
config SOC_TOUCH_SENSOR_NUM
|
config SOC_TOUCH_SENSOR_NUM
|
||||||
int
|
int
|
||||||
default 0
|
default 0
|
||||||
|
@@ -211,7 +211,7 @@
|
|||||||
#define SOC_TIMER_GROUP_TIMERS_PER_GROUP (1U)
|
#define SOC_TIMER_GROUP_TIMERS_PER_GROUP (1U)
|
||||||
#define SOC_TIMER_GROUP_COUNTER_BIT_WIDTH (54)
|
#define SOC_TIMER_GROUP_COUNTER_BIT_WIDTH (54)
|
||||||
#define SOC_TIMER_GROUP_SUPPORT_XTAL (1)
|
#define SOC_TIMER_GROUP_SUPPORT_XTAL (1)
|
||||||
#define SOC_TIMER_GROUP_TOTAL_TIMERS (SOC_TIMER_GROUPS * SOC_TIMER_GROUP_TIMERS_PER_GROUP)
|
#define SOC_TIMER_GROUP_TOTAL_TIMERS (1U)
|
||||||
|
|
||||||
/*-------------------------- TOUCH SENSOR CAPS -------------------------------*/
|
/*-------------------------- TOUCH SENSOR CAPS -------------------------------*/
|
||||||
#define SOC_TOUCH_SENSOR_NUM (0U) /*! No touch sensors on ESP8684 */
|
#define SOC_TOUCH_SENSOR_NUM (0U) /*! No touch sensors on ESP8684 */
|
||||||
|
@@ -102,7 +102,6 @@ api-reference/storage/index
|
|||||||
api-reference/peripherals/adc
|
api-reference/peripherals/adc
|
||||||
api-reference/peripherals/usb_host
|
api-reference/peripherals/usb_host
|
||||||
api-reference/peripherals/sigmadelta
|
api-reference/peripherals/sigmadelta
|
||||||
api-reference/peripherals/timer
|
|
||||||
api-reference/peripherals/twai
|
api-reference/peripherals/twai
|
||||||
api-reference/peripherals/hmac
|
api-reference/peripherals/hmac
|
||||||
api-reference/peripherals/usb_device
|
api-reference/peripherals/usb_device
|
||||||
|
@@ -4,13 +4,14 @@ General Purpose Timer
|
|||||||
:link_to_translation:`zh_CN:[中文]`
|
:link_to_translation:`zh_CN:[中文]`
|
||||||
|
|
||||||
{IDF_TARGET_TIMER_COUNTER_BIT_WIDTH:default="54", esp32="64", esp32s2="64"}
|
{IDF_TARGET_TIMER_COUNTER_BIT_WIDTH:default="54", esp32="64", esp32s2="64"}
|
||||||
{IDF_TARGET_TIMERS_PER_GROUP:default="two", esp32c3="one"}
|
{IDF_TARGET_TIMER_GROUPS:default="two", esp8684="one"}
|
||||||
{IDF_TARGET_TIMERS_TOTAL:default="four", esp32c3="two"}
|
{IDF_TARGET_TIMERS_PER_GROUP:default="two", esp32c3="one", esp8684="one"}
|
||||||
|
{IDF_TARGET_TIMERS_TOTAL:default="four", esp32c3="two", esp8684="one"}
|
||||||
|
|
||||||
Introduction
|
Introduction
|
||||||
------------
|
------------
|
||||||
|
|
||||||
The {IDF_TARGET_NAME} chip contains two hardware timer groups. Each group has {IDF_TARGET_TIMERS_PER_GROUP} general-purpose hardware timer(s). They are all {IDF_TARGET_TIMER_COUNTER_BIT_WIDTH}-bit generic timers based on 16-bit pre-scalers and {IDF_TARGET_TIMER_COUNTER_BIT_WIDTH}-bit up / down counters which are capable of being auto-reloaded.
|
The {IDF_TARGET_NAME} chip contains {IDF_TARGET_TIMER_GROUPS} hardware timer group(s). Each group has {IDF_TARGET_TIMERS_PER_GROUP} general-purpose hardware timer(s). They are all {IDF_TARGET_TIMER_COUNTER_BIT_WIDTH}-bit generic timers based on 16-bit pre-scalers and {IDF_TARGET_TIMER_COUNTER_BIT_WIDTH}-bit up / down counters which are capable of being auto-reloaded.
|
||||||
|
|
||||||
|
|
||||||
Functional Overview
|
Functional Overview
|
||||||
@@ -29,7 +30,7 @@ The following sections of this document cover the typical steps to configure and
|
|||||||
Timer Initialization
|
Timer Initialization
|
||||||
^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
The two {IDF_TARGET_NAME} timer groups, with {IDF_TARGET_TIMERS_PER_GROUP} timer(s) in each, provide the total of {IDF_TARGET_TIMERS_TOTAL} individual timers for use. An {IDF_TARGET_NAME} timer group should be identified using :cpp:type:`timer_group_t`. An individual timer in a group should be identified with :cpp:type:`timer_idx_t`.
|
The {IDF_TARGET_TIMER_GROUPS} {IDF_TARGET_NAME} timer group(s), with {IDF_TARGET_TIMERS_PER_GROUP} timer(s) in each, provide the total of {IDF_TARGET_TIMERS_TOTAL} individual timers for use. An {IDF_TARGET_NAME} timer group should be identified using :cpp:type:`timer_group_t`. An individual timer in a group should be identified with :cpp:type:`timer_idx_t`.
|
||||||
|
|
||||||
First of all, the timer should be initialized by calling the function :cpp:func:`timer_init` and passing a structure :cpp:type:`timer_config_t` to it to define how the timer should operate. In particular, the following timer parameters can be set:
|
First of all, the timer should be initialized by calling the function :cpp:func:`timer_init` and passing a structure :cpp:type:`timer_config_t` to it to define how the timer should operate. In particular, the following timer parameters can be set:
|
||||||
|
|
||||||
|
@@ -19,40 +19,27 @@ See the [ESP-IDF Getting Started Guide](https://idf.espressif.com/) for all the
|
|||||||
## Example Output
|
## Example Output
|
||||||
|
|
||||||
```
|
```
|
||||||
Timer Group with auto reload
|
I (0) cpu_start: Starting scheduler on APP CPU.
|
||||||
Group[0], timer[0] alarm event
|
I (325) example: Init timer with auto-reload
|
||||||
------- EVENT TIME --------
|
I (835) example: Timer auto reloaded, count value in ISR: 3
|
||||||
Counter: 0x0000000000000008
|
I (1335) example: Timer auto reloaded, count value in ISR: 3
|
||||||
Time : 0.00000160 s
|
I (1835) example: Timer auto reloaded, count value in ISR: 3
|
||||||
-------- TASK TIME --------
|
I (2335) example: Timer auto reloaded, count value in ISR: 3
|
||||||
Counter: 0x0000000000004ed8
|
I (2335) example: Init timer without auto-reload
|
||||||
Time : 0.00403680 s
|
I (2835) example: Timer alarmed at 500003
|
||||||
Timer Group without auto reload
|
I (3335) example: Timer alarmed at 1000003
|
||||||
Group[1], timer[0] alarm event
|
I (3835) example: Timer alarmed at 1500003
|
||||||
------- EVENT TIME --------
|
I (4335) example: Timer alarmed at 2000003
|
||||||
Counter: 0x00000000017d7848
|
|
||||||
Time : 5.00000160 s
|
|
||||||
-------- TASK TIME --------
|
|
||||||
Counter: 0x00000000017dcb32
|
|
||||||
Time : 5.00424680 s
|
|
||||||
Timer Group with auto reload
|
|
||||||
Group[0], timer[0] alarm event
|
|
||||||
------- EVENT TIME --------
|
|
||||||
Counter: 0x0000000000000008
|
|
||||||
Time : 0.00000160 s
|
|
||||||
-------- TASK TIME --------
|
|
||||||
Counter: 0x0000000000004dd4
|
|
||||||
Time : 0.00398480 s
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Functionality Overview
|
## Functionality Overview
|
||||||
|
|
||||||
* Two timers are configured
|
* Configure one timer with auto-reload enabled, alarm period set to 0.5s
|
||||||
* Each timer is set with some sample alarm interval
|
* On reaching the interval value the timer will generate an alarm
|
||||||
* On reaching the interval value each timer will generate an alarm
|
* The timer will reload with initial count value on alarm, by hardware
|
||||||
* One of the timers is configured to automatically reload it's counter value on the alarm
|
* Reconfigure the timer with auto-reload disabled, initial alarm value set to 0.5s
|
||||||
* The other timer is configured to keep incrementing and is reloaded by the application each time the alarm happens
|
* The timer keeps incrementing and in the alarm callback, the software reconfigures its alarm value by increasing 0.5s
|
||||||
* Alarms trigger subsequent interrupts, that is tracked with messages printed on the terminal:
|
* The main task will print the count value that captured in the alarm callback
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
|
@@ -1,42 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
#
|
|
||||||
# SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: CC0-1.0
|
|
||||||
#
|
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import re
|
|
||||||
from typing import Any
|
|
||||||
|
|
||||||
import ttfw_idf
|
|
||||||
|
|
||||||
|
|
||||||
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32', 'esp32s2', 'esp32c3'])
|
|
||||||
def test_examples_timergroup(env, extra_data): # type: (Any, Any) -> None
|
|
||||||
dut = env.get_dut('timer_group', 'examples/peripherals/timer_group')
|
|
||||||
dut.start_app()
|
|
||||||
|
|
||||||
# check auto reload function
|
|
||||||
with_auto_reload = dut.expect(re.compile(r'Timer Group (\S+) auto reload'), timeout=30)[0]
|
|
||||||
assert with_auto_reload == 'with'
|
|
||||||
select_groups = dut.expect(re.compile(r'Group\[(\d)\], timer\[(\d)\] alarm event'))
|
|
||||||
timer_group_num = int(select_groups[0])
|
|
||||||
timer_instance_num = int(select_groups[1])
|
|
||||||
assert timer_group_num == 0 and timer_instance_num == 0
|
|
||||||
dut.expect('EVENT TIME')
|
|
||||||
counter_value = dut.expect(re.compile(r'Counter:\s+(0x\d+)'))[0]
|
|
||||||
counter_value = int(counter_value, 16)
|
|
||||||
print('counter value at auto reload event: ', counter_value)
|
|
||||||
assert counter_value < 20
|
|
||||||
|
|
||||||
# check timer interval
|
|
||||||
dut.expect('Timer Group without auto reload', timeout=5)
|
|
||||||
dut.expect('EVENT TIME')
|
|
||||||
event_time0 = dut.expect(re.compile(r'Time\s+:\s+(\d+\.\d+)\s+s'))[0]
|
|
||||||
print('event0={}'.format(event_time0))
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
test_examples_timergroup()
|
|
@@ -9,131 +9,119 @@
|
|||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
#include "freertos/queue.h"
|
#include "freertos/queue.h"
|
||||||
#include "driver/timer.h"
|
#include "driver/timer.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
|
||||||
#define TIMER_DIVIDER (16) // Hardware timer clock divider
|
#define TIMER_RESOLUTION_HZ 1000000 // 1MHz resolution
|
||||||
#define TIMER_SCALE (TIMER_BASE_CLK / TIMER_DIVIDER) // convert counter value to seconds
|
#define TIMER_ALARM_PERIOD_S 0.5 // Alarm period 0.5s
|
||||||
|
|
||||||
typedef struct {
|
static const char *TAG = "example";
|
||||||
int timer_group;
|
|
||||||
int timer_idx;
|
|
||||||
int alarm_interval;
|
|
||||||
bool auto_reload;
|
|
||||||
} example_timer_info_t;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A sample structure to pass events from the timer ISR to task
|
* @brief A sample structure to pass events from the timer ISR to task
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
example_timer_info_t info;
|
uint64_t timer_count_value;
|
||||||
uint64_t timer_counter_value;
|
|
||||||
} example_timer_event_t;
|
} example_timer_event_t;
|
||||||
|
|
||||||
static xQueueHandle s_timer_queue;
|
/**
|
||||||
|
* @brief Timer user data, will be pass to timer alarm callback
|
||||||
/*
|
|
||||||
* A simple helper function to print the raw timer counter value
|
|
||||||
* and the counter value converted to seconds
|
|
||||||
*/
|
*/
|
||||||
static void inline print_timer_counter(uint64_t counter_value)
|
typedef struct {
|
||||||
{
|
xQueueHandle user_queue;
|
||||||
printf("Counter: 0x%08x%08x\r\n", (uint32_t) (counter_value >> 32),
|
int timer_group;
|
||||||
(uint32_t) (counter_value));
|
int timer_idx;
|
||||||
printf("Time : %.8f s\r\n", (double) counter_value / TIMER_SCALE);
|
int alarm_value;
|
||||||
}
|
bool auto_reload;
|
||||||
|
} example_timer_user_data_t;
|
||||||
|
|
||||||
static bool IRAM_ATTR timer_group_isr_callback(void *args)
|
static bool IRAM_ATTR timer_group_isr_callback(void *args)
|
||||||
{
|
{
|
||||||
BaseType_t high_task_awoken = pdFALSE;
|
BaseType_t high_task_awoken = pdFALSE;
|
||||||
example_timer_info_t *info = (example_timer_info_t *) args;
|
example_timer_user_data_t *user_data = (example_timer_user_data_t *) args;
|
||||||
|
// fetch current count value
|
||||||
uint64_t timer_counter_value = timer_group_get_counter_value_in_isr(info->timer_group, info->timer_idx);
|
uint64_t timer_count_value = timer_group_get_counter_value_in_isr(user_data->timer_group, user_data->timer_idx);
|
||||||
|
|
||||||
/* Prepare basic event data that will be then sent back to task */
|
|
||||||
example_timer_event_t evt = {
|
example_timer_event_t evt = {
|
||||||
.info.timer_group = info->timer_group,
|
.timer_count_value = timer_count_value,
|
||||||
.info.timer_idx = info->timer_idx,
|
|
||||||
.info.auto_reload = info->auto_reload,
|
|
||||||
.info.alarm_interval = info->alarm_interval,
|
|
||||||
.timer_counter_value = timer_counter_value
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!info->auto_reload) {
|
// set new alarm value if necessary
|
||||||
timer_counter_value += info->alarm_interval * TIMER_SCALE;
|
if (!user_data->auto_reload) {
|
||||||
timer_group_set_alarm_value_in_isr(info->timer_group, info->timer_idx, timer_counter_value);
|
user_data->alarm_value += TIMER_ALARM_PERIOD_S * TIMER_RESOLUTION_HZ;
|
||||||
|
timer_group_set_alarm_value_in_isr(user_data->timer_group, user_data->timer_idx, user_data->alarm_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now just send the event data back to the main program task */
|
// Send the event data back to the main program task
|
||||||
xQueueSendFromISR(s_timer_queue, &evt, &high_task_awoken);
|
xQueueSendFromISR(user_data->user_queue, &evt, &high_task_awoken);
|
||||||
|
|
||||||
return high_task_awoken == pdTRUE; // return whether we need to yield at the end of ISR
|
return high_task_awoken == pdTRUE; // return whether a task switch is needed
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static void example_tg_timer_init(example_timer_user_data_t *user_data)
|
||||||
* @brief Initialize selected timer of timer group
|
|
||||||
*
|
|
||||||
* @param group Timer Group number, index from 0
|
|
||||||
* @param timer timer ID, index from 0
|
|
||||||
* @param auto_reload whether auto-reload on alarm event
|
|
||||||
* @param timer_interval_sec interval of alarm
|
|
||||||
*/
|
|
||||||
static void example_tg_timer_init(int group, int timer, bool auto_reload, int timer_interval_sec)
|
|
||||||
{
|
{
|
||||||
/* Select and initialize basic parameters of the timer */
|
int group = user_data->timer_group;
|
||||||
|
int timer = user_data->timer_idx;
|
||||||
|
|
||||||
timer_config_t config = {
|
timer_config_t config = {
|
||||||
.divider = TIMER_DIVIDER,
|
.clk_src = TIMER_SRC_CLK_APB,
|
||||||
|
.divider = APB_CLK_FREQ / TIMER_RESOLUTION_HZ,
|
||||||
.counter_dir = TIMER_COUNT_UP,
|
.counter_dir = TIMER_COUNT_UP,
|
||||||
.counter_en = TIMER_PAUSE,
|
.counter_en = TIMER_PAUSE,
|
||||||
.alarm_en = TIMER_ALARM_EN,
|
.alarm_en = TIMER_ALARM_EN,
|
||||||
.auto_reload = auto_reload,
|
.auto_reload = user_data->auto_reload,
|
||||||
}; // default clock source is APB
|
};
|
||||||
timer_init(group, timer, &config);
|
ESP_ERROR_CHECK(timer_init(group, timer, &config));
|
||||||
|
|
||||||
/* Timer's counter will initially start from value below.
|
// For the timer counter to a initial value
|
||||||
Also, if auto_reload is set, this value will be automatically reload on alarm */
|
ESP_ERROR_CHECK(timer_set_counter_value(group, timer, 0));
|
||||||
timer_set_counter_value(group, timer, 0);
|
// Set alarm value and enable alarm interrupt
|
||||||
|
ESP_ERROR_CHECK(timer_set_alarm_value(group, timer, user_data->alarm_value));
|
||||||
|
ESP_ERROR_CHECK(timer_enable_intr(group, timer));
|
||||||
|
// Hook interrupt callback
|
||||||
|
ESP_ERROR_CHECK(timer_isr_callback_add(group, timer, timer_group_isr_callback, user_data, 0));
|
||||||
|
// Start timer
|
||||||
|
ESP_ERROR_CHECK(timer_start(group, timer));
|
||||||
|
}
|
||||||
|
|
||||||
/* Configure the alarm value and the interrupt on alarm. */
|
static void example_tg_timer_deinit(int group, int timer)
|
||||||
timer_set_alarm_value(group, timer, timer_interval_sec * TIMER_SCALE);
|
{
|
||||||
timer_enable_intr(group, timer);
|
ESP_ERROR_CHECK(timer_isr_callback_remove(group, timer));
|
||||||
|
ESP_ERROR_CHECK(timer_deinit(group, timer));
|
||||||
example_timer_info_t *timer_info = calloc(1, sizeof(example_timer_info_t));
|
|
||||||
timer_info->timer_group = group;
|
|
||||||
timer_info->timer_idx = timer;
|
|
||||||
timer_info->auto_reload = auto_reload;
|
|
||||||
timer_info->alarm_interval = timer_interval_sec;
|
|
||||||
timer_isr_callback_add(group, timer, timer_group_isr_callback, timer_info, 0);
|
|
||||||
|
|
||||||
timer_start(group, timer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void app_main(void)
|
void app_main(void)
|
||||||
{
|
{
|
||||||
s_timer_queue = xQueueCreate(10, sizeof(example_timer_event_t));
|
example_timer_user_data_t *user_data = calloc(1, sizeof(example_timer_user_data_t));
|
||||||
|
assert(user_data);
|
||||||
|
user_data->user_queue = xQueueCreate(10, sizeof(example_timer_event_t));
|
||||||
|
assert(user_data->user_queue);
|
||||||
|
user_data->timer_group = 0;
|
||||||
|
user_data->timer_idx = 0;
|
||||||
|
user_data->alarm_value = TIMER_ALARM_PERIOD_S * TIMER_RESOLUTION_HZ;
|
||||||
|
|
||||||
example_tg_timer_init(TIMER_GROUP_0, TIMER_0, true, 3);
|
|
||||||
example_tg_timer_init(TIMER_GROUP_1, TIMER_0, false, 5);
|
|
||||||
|
|
||||||
while (1) {
|
ESP_LOGI(TAG, "Init timer with auto-reload");
|
||||||
example_timer_event_t evt;
|
user_data->auto_reload = true;
|
||||||
xQueueReceive(s_timer_queue, &evt, portMAX_DELAY);
|
example_tg_timer_init(user_data);
|
||||||
|
|
||||||
/* Print information that the timer reported an event */
|
example_timer_event_t evt;
|
||||||
if (evt.info.auto_reload) {
|
uint32_t test_count = 4;
|
||||||
printf("Timer Group with auto reload\n");
|
while (test_count--) {
|
||||||
} else {
|
xQueueReceive(user_data->user_queue, &evt, portMAX_DELAY);
|
||||||
printf("Timer Group without auto reload\n");
|
ESP_LOGI(TAG, "Timer auto reloaded, count value in ISR: %llu", evt.timer_count_value);
|
||||||
}
|
|
||||||
printf("Group[%d], timer[%d] alarm event\n", evt.info.timer_group, evt.info.timer_idx);
|
|
||||||
|
|
||||||
/* Print the timer values passed by event */
|
|
||||||
printf("------- EVENT TIME --------\n");
|
|
||||||
print_timer_counter(evt.timer_counter_value);
|
|
||||||
|
|
||||||
/* Print the timer values as visible by this task */
|
|
||||||
printf("-------- TASK TIME --------\n");
|
|
||||||
uint64_t task_counter_value;
|
|
||||||
timer_get_counter_value(evt.info.timer_group, evt.info.timer_idx, &task_counter_value);
|
|
||||||
print_timer_counter(task_counter_value);
|
|
||||||
}
|
}
|
||||||
|
example_tg_timer_deinit(user_data->timer_group, user_data->timer_idx);
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Init timer without auto-reload");
|
||||||
|
user_data->auto_reload = false;
|
||||||
|
example_tg_timer_init(user_data);
|
||||||
|
|
||||||
|
test_count = 4;
|
||||||
|
while (test_count--) {
|
||||||
|
xQueueReceive(user_data->user_queue, &evt, portMAX_DELAY);
|
||||||
|
ESP_LOGI(TAG, "Timer alarmed at %llu", evt.timer_count_value);
|
||||||
|
}
|
||||||
|
example_tg_timer_deinit(user_data->timer_group, user_data->timer_idx);
|
||||||
|
|
||||||
|
vQueueDelete(user_data->user_queue);
|
||||||
|
free(user_data);
|
||||||
}
|
}
|
||||||
|
24
examples/peripherals/timer_group/pytest_timer_group.py
Normal file
24
examples/peripherals/timer_group/pytest_timer_group.py
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from pytest_embedded.dut import Dut
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.esp32
|
||||||
|
@pytest.mark.esp32s2
|
||||||
|
@pytest.mark.esp32s3
|
||||||
|
@pytest.mark.esp32c3
|
||||||
|
@pytest.mark.generic
|
||||||
|
def test_timer_group_example(dut: Dut): # type: ignore
|
||||||
|
dut.expect(r'Init timer with auto-reload', timeout=5)
|
||||||
|
res = dut.expect(r'Timer auto reloaded, count value in ISR: (\d+)', timeout=5)
|
||||||
|
reloaded_count = res.group(1).decode('utf8')
|
||||||
|
assert 0 <= int(reloaded_count) < 10
|
||||||
|
|
||||||
|
alarm_increase_step = 500000
|
||||||
|
dut.expect(r'Init timer without auto-reload')
|
||||||
|
for i in range(1, 5):
|
||||||
|
res = dut.expect(r'Timer alarmed at (\d+)', timeout=3)
|
||||||
|
alarm_count = res.group(1).decode('utf8')
|
||||||
|
assert (i * alarm_increase_step - 10) < int(alarm_count) < (i * alarm_increase_step + 10)
|
Reference in New Issue
Block a user