#include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_system.h" #include "unity.h" #include "nvs_flash.h" #include "driver/timer.h" #define TIMER_DIVIDER 16 #define TIMER_SCALE (TIMER_BASE_CLK / TIMER_DIVIDER) /*!< used to calculate counter value */ #define TIMER_DELTA 0.001 static bool alarm_flag; // group0 interruption static void test_timer_group0_isr(void *para) { int timer_idx = (int) para; uint64_t timer_val; double time; uint64_t alarm_value; alarm_flag = true; if (TIMERG0.hw_timer[timer_idx].config.autoreload == 1) { if (timer_idx == 0) { TIMERG0.int_clr_timers.t0 = 1; } else { TIMERG0.int_clr_timers.t1 = 1; } ets_printf("This is TG0 timer[%d] reload-timer alarm!\n", timer_idx); timer_get_counter_value(TIMER_GROUP_0, timer_idx, &timer_val); timer_get_counter_time_sec(TIMER_GROUP_0, timer_idx, &time); ets_printf("time: %.8f S\n", time); } else { if (timer_idx == 0) { TIMERG0.int_clr_timers.t0 = 1; } else { TIMERG0.int_clr_timers.t1 = 1; } ets_printf("This is TG0 timer[%d] count-up-timer alarm!\n", timer_idx); timer_get_counter_value(TIMER_GROUP_0, timer_idx, &timer_val); timer_get_counter_time_sec(TIMER_GROUP_0, timer_idx, &time); timer_get_alarm_value(TIMER_GROUP_0, timer_idx, &alarm_value); ets_printf("time: %.8f S\n", time); double alarm_time = (double) alarm_value / TIMER_SCALE; ets_printf("alarm_time: %.8f S\n", alarm_time); } } // group1 interruption static void test_timer_group1_isr(void *para) { int timer_idx = (int) para; uint64_t timer_val; double time; uint64_t alarm_value; alarm_flag = true; if (TIMERG1.hw_timer[timer_idx].config.autoreload == 1) { if (timer_idx == 0) { TIMERG1.int_clr_timers.t0 = 1; } else { TIMERG1.int_clr_timers.t1 = 1; } ets_printf("This is TG1 timer[%d] reload-timer alarm!\n", timer_idx); timer_get_counter_value(TIMER_GROUP_1, timer_idx, &timer_val); timer_get_counter_time_sec(TIMER_GROUP_1, timer_idx, &time); ets_printf("time: %.8f S\n", time); } else { if (timer_idx == 0) { TIMERG1.int_clr_timers.t0 = 1; } else { TIMERG1.int_clr_timers.t1 = 1; } ets_printf("This is TG1 timer[%d] count-up-timer alarm!\n", timer_idx); timer_get_counter_value(TIMER_GROUP_1, timer_idx, &timer_val); timer_get_counter_time_sec(TIMER_GROUP_1, timer_idx, &time); timer_get_alarm_value(TIMER_GROUP_1, timer_idx, &alarm_value); ets_printf("time: %.8f S\n", time); double alarm_time = (double) alarm_value / TIMER_SCALE; ets_printf("alarm_time: %.8f S\n", alarm_time); } } // initialize exact timer group static void tg_timer_init(int timer_group, int timer_idx, double alarm_time) { timer_pause(timer_group, timer_idx); timer_set_counter_value(timer_group, timer_idx, 0x0); timer_set_alarm_value(timer_group, timer_idx, alarm_time * TIMER_SCALE); timer_enable_intr(timer_group, timer_idx); if (timer_group == 0) { timer_isr_register(timer_group, timer_idx, test_timer_group0_isr, (void *) timer_idx, ESP_INTR_FLAG_LOWMED, NULL); } else { timer_isr_register(timer_group, timer_idx, test_timer_group1_isr, (void *) timer_idx, ESP_INTR_FLAG_LOWMED, NULL); } timer_start(timer_group, timer_idx); } // initialize all timer static void all_timer_init(timer_config_t config, bool flag) { esp_err_t ret; ret = timer_init(TIMER_GROUP_0, TIMER_0, &config); if (flag) { TEST_ASSERT(ret == ESP_OK); } else { TEST_ASSERT(ret == ESP_ERR_INVALID_ARG); } ret = timer_init(TIMER_GROUP_0, TIMER_1, &config); if (flag) { TEST_ASSERT(ret == ESP_OK); } else { TEST_ASSERT(ret == ESP_ERR_INVALID_ARG); } ret = timer_init(TIMER_GROUP_1, TIMER_0, &config); if (flag) { TEST_ASSERT(ret == ESP_OK); } else { TEST_ASSERT(ret == ESP_ERR_INVALID_ARG); } ret = timer_init(TIMER_GROUP_1, TIMER_1, &config); if (flag) { TEST_ASSERT(ret == ESP_OK); } else { TEST_ASSERT(ret == ESP_ERR_INVALID_ARG); } } // start all of timer static void all_timer_start() { esp_err_t ret; ret = timer_start(TIMER_GROUP_0, TIMER_0); TEST_ASSERT(ret == ESP_OK); ret = timer_start(TIMER_GROUP_0, TIMER_1); TEST_ASSERT(ret == ESP_OK); ret = timer_start(TIMER_GROUP_1, TIMER_0); TEST_ASSERT(ret == ESP_OK); ret = timer_start(TIMER_GROUP_1, TIMER_1); TEST_ASSERT(ret == ESP_OK); } static void all_timer_set_counter_value(uint64_t set_timer_val) { esp_err_t ret; ret = timer_set_counter_value(TIMER_GROUP_0, TIMER_0, set_timer_val); TEST_ASSERT(ret == ESP_OK); ret = timer_set_counter_value(TIMER_GROUP_0, TIMER_1, set_timer_val); TEST_ASSERT(ret == ESP_OK); ret = timer_set_counter_value(TIMER_GROUP_1, TIMER_0, set_timer_val); TEST_ASSERT(ret == ESP_OK); ret = timer_set_counter_value(TIMER_GROUP_1, TIMER_1, set_timer_val); TEST_ASSERT(ret == ESP_OK); } static void all_timer_pause() { esp_err_t ret; ret = timer_pause(TIMER_GROUP_0, TIMER_0); TEST_ASSERT(ret == ESP_OK); ret = timer_pause(TIMER_GROUP_0, TIMER_1); TEST_ASSERT(ret == ESP_OK); ret = timer_pause(TIMER_GROUP_1, TIMER_0); TEST_ASSERT(ret == ESP_OK); ret = timer_pause(TIMER_GROUP_1, TIMER_1); TEST_ASSERT(ret == ESP_OK); } static void all_timer_get_counter_value(uint64_t set_timer_val, bool flag, uint64_t *counter_val) { esp_err_t ret; uint64_t time_val; ret = timer_get_counter_value(TIMER_GROUP_0, TIMER_0, &time_val); TEST_ASSERT(ret == ESP_OK); if (flag == true) { TEST_ASSERT(set_timer_val == time_val); } else { TEST_ASSERT(set_timer_val != time_val); if (counter_val != NULL) { counter_val[0] = time_val; } } ret = timer_get_counter_value(TIMER_GROUP_0, TIMER_1, &time_val); TEST_ASSERT(ret == ESP_OK); if (flag) { TEST_ASSERT(set_timer_val == time_val); } else { TEST_ASSERT(set_timer_val != time_val); if (counter_val != NULL) { counter_val[1] = time_val; } } ret = timer_get_counter_value(TIMER_GROUP_1, TIMER_0, &time_val); TEST_ASSERT(ret == ESP_OK); if (flag) { TEST_ASSERT(set_timer_val == time_val); } else { TEST_ASSERT(set_timer_val != time_val); if (counter_val != NULL) { counter_val[2] = time_val; } } ret = timer_get_counter_value(TIMER_GROUP_1, TIMER_1, &time_val); TEST_ASSERT(ret == ESP_OK); if (flag) { TEST_ASSERT(set_timer_val == time_val); } else { TEST_ASSERT(set_timer_val != time_val); if (counter_val != NULL) { counter_val[3] = time_val; } } } static void all_timer_get_counter_time_sec(bool flag, int delay_time) { double time; esp_err_t ret; ret = timer_get_counter_time_sec(TIMER_GROUP_0, TIMER_0, &time); TEST_ASSERT(ret == ESP_OK); if (!flag) { TEST_ASSERT_FLOAT_WITHIN(TIMER_DELTA, delay_time, time); } ret = timer_get_counter_time_sec(TIMER_GROUP_0, TIMER_1, &time); TEST_ASSERT(ret == ESP_OK); if (!flag) { TEST_ASSERT_FLOAT_WITHIN(TIMER_DELTA, delay_time, time); } ret = timer_get_counter_time_sec(TIMER_GROUP_1, TIMER_0, &time); TEST_ASSERT(ret == ESP_OK); if (!flag) { TEST_ASSERT_FLOAT_WITHIN(TIMER_DELTA, delay_time, time); } ret = timer_get_counter_time_sec(TIMER_GROUP_1, TIMER_1, &time); TEST_ASSERT(ret == ESP_OK); if (!flag) { TEST_ASSERT_FLOAT_WITHIN(TIMER_DELTA, delay_time, time); } } static void all_timer_set_counter_mode(timer_count_dir_t counter_dir) { esp_err_t ret; ret = timer_set_counter_mode(TIMER_GROUP_0, TIMER_0, counter_dir); TEST_ASSERT(ret == ESP_OK); ret = timer_set_counter_mode(TIMER_GROUP_0, TIMER_1, counter_dir); TEST_ASSERT(ret == ESP_OK); ret = timer_set_counter_mode(TIMER_GROUP_1, TIMER_0, counter_dir); TEST_ASSERT(ret == ESP_OK); ret = timer_set_counter_mode(TIMER_GROUP_1, TIMER_1, counter_dir); TEST_ASSERT(ret == ESP_OK); } static void all_timer_set_divider(uint32_t divider) { esp_err_t ret; ret = timer_set_divider(TIMER_GROUP_0, TIMER_0, divider); TEST_ASSERT(ret == ESP_OK); ret = timer_set_divider(TIMER_GROUP_0, TIMER_1, divider); TEST_ASSERT(ret == ESP_OK); ret = timer_set_divider(TIMER_GROUP_1, TIMER_0, divider); TEST_ASSERT(ret == ESP_OK); ret = timer_set_divider(TIMER_GROUP_1, TIMER_1, divider); TEST_ASSERT(ret == ESP_OK); } static void all_timer_set_alarm_value(double alarm_time) { esp_err_t ret; ret = timer_set_alarm_value(TIMER_GROUP_0, TIMER_0, alarm_time * TIMER_SCALE); TEST_ASSERT(ret == ESP_OK); ret = timer_set_alarm_value(TIMER_GROUP_0, TIMER_1, alarm_time * TIMER_SCALE); TEST_ASSERT(ret == ESP_OK); ret = timer_set_alarm_value(TIMER_GROUP_1, TIMER_0, alarm_time * TIMER_SCALE); TEST_ASSERT(ret == ESP_OK); ret = timer_set_alarm_value(TIMER_GROUP_1, TIMER_1, alarm_time * TIMER_SCALE); TEST_ASSERT(ret == ESP_OK); } TEST_CASE("Timer init", "[hw_timer]") { esp_err_t ret; // Test init 1:config para // empty para timer_config_t config0 = { }; all_timer_init(config0, false); // only one para timer_config_t config1 = { .auto_reload = 1 }; all_timer_init(config1, false); // lack one para timer_config_t config2 = { .auto_reload = 1, .counter_dir = TIMER_COUNT_UP, .divider = TIMER_DIVIDER, .counter_en = 1, .intr_type = TIMER_INTR_LEVEL }; all_timer_init(config2, true); config2.counter_en = 0; all_timer_init(config2, true); // error config para timer_config_t config3 = { .alarm_en = 3, //error para .auto_reload = 1, .counter_dir = TIMER_COUNT_UP, .divider = TIMER_DIVIDER, .counter_en = 1, .intr_type = TIMER_INTR_LEVEL }; all_timer_init(config3, true); timer_config_t get_config; timer_get_config(TIMER_GROUP_1, TIMER_1, &get_config); printf("Error config alarm_en is %d\n", get_config.alarm_en); TEST_ASSERT(config3.alarm_en != get_config.alarm_en); // Test init 2: init uint64_t set_timer_val = 0x0; timer_config_t config = { .alarm_en = 0, .auto_reload = 1, .counter_dir = TIMER_COUNT_UP, .divider = TIMER_DIVIDER, .counter_en = 1, .intr_type = TIMER_INTR_LEVEL }; // judge get config parameters timer_init(TIMER_GROUP_0, TIMER_0, &config); timer_get_config(TIMER_GROUP_0, TIMER_0, &get_config); TEST_ASSERT(config.alarm_en == get_config.alarm_en); TEST_ASSERT(config.auto_reload == get_config.auto_reload); TEST_ASSERT(config.counter_dir == get_config.counter_dir); TEST_ASSERT(config.counter_en == get_config.counter_en); TEST_ASSERT(config.intr_type == get_config.intr_type); TEST_ASSERT(config.divider == get_config.divider); all_timer_init(config, true); all_timer_pause(); all_timer_set_counter_value(set_timer_val); all_timer_start(); all_timer_get_counter_value(set_timer_val, false, NULL); // Test init 3: wrong para ret = timer_init(-1, TIMER_1, &config); TEST_ASSERT(ret == ESP_ERR_INVALID_ARG); ret = timer_init(TIMER_GROUP_1, 2, &config); TEST_ASSERT(ret == ESP_ERR_INVALID_ARG); ret = timer_init(TIMER_GROUP_1, -1, &config); TEST_ASSERT(ret == ESP_ERR_INVALID_ARG); ret = timer_init(2, TIMER_1, &config); TEST_ASSERT(ret == ESP_ERR_INVALID_ARG); } /** * read count case: * 1. start timer compare value * 2. pause timer compare value * 3. delay some time */ TEST_CASE("Timer read counter value", "[hw_timer]") { timer_config_t config = { .alarm_en = 1, .auto_reload = 1, .counter_dir = TIMER_COUNT_UP, .divider = TIMER_DIVIDER, .counter_en = 1, .intr_type = TIMER_INTR_LEVEL }; uint64_t set_timer_val = 0x0; all_timer_init(config, true); // Test read value 1: start timer get counter value all_timer_set_counter_value(set_timer_val); all_timer_start(); all_timer_get_counter_value(set_timer_val, false, NULL); // Test read value 2: pause timer get counter value all_timer_pause(); set_timer_val = 0x30405000ULL; all_timer_set_counter_value(set_timer_val); all_timer_get_counter_value(set_timer_val, true, NULL); // Test read value 3:delay 1s get counter value set_timer_val = 0x0; all_timer_set_counter_value(set_timer_val); all_timer_start(); vTaskDelay(1000 / portTICK_PERIOD_MS); all_timer_get_counter_time_sec(true, 1); } /** * start timer case: * 1. normal start * 2. error start para * */ TEST_CASE("Timer start", "[hw_timer]") { esp_err_t ret; timer_config_t config = { .alarm_en = 1, .auto_reload = 1, .counter_dir = TIMER_COUNT_UP, .divider = TIMER_DIVIDER, .counter_en = 1, .intr_type = TIMER_INTR_LEVEL }; uint64_t set_timer_val = 0x0; all_timer_init(config, true); //Test start 1: normal start all_timer_start(); all_timer_set_counter_value(set_timer_val); all_timer_get_counter_value(set_timer_val, false, NULL); //Test start 2:wrong para ret = timer_start(2, TIMER_1); TEST_ASSERT(ret == ESP_ERR_INVALID_ARG); ret = timer_start(-1, TIMER_1); TEST_ASSERT(ret == ESP_ERR_INVALID_ARG); ret = timer_start(TIMER_GROUP_1, 2); TEST_ASSERT(ret == ESP_ERR_INVALID_ARG); ret = timer_start(TIMER_GROUP_1, -1); TEST_ASSERT(ret == ESP_ERR_INVALID_ARG); } /** * pause timer case: * 1. normal pause, read value * 2. error pause error */ TEST_CASE("Timer pause", "[hw_timer]") { esp_err_t ret; timer_config_t config = { .alarm_en = 1, .auto_reload = 1, .counter_dir = TIMER_COUNT_UP, .divider = TIMER_DIVIDER, .counter_en = 1, .intr_type = TIMER_INTR_LEVEL }; uint64_t set_timer_val = 0x0; all_timer_init(config, true); //Test pause 1: right para all_timer_pause(); all_timer_set_counter_value(set_timer_val); all_timer_get_counter_value(set_timer_val, true, NULL); //Test pause 2: wrong para ret = timer_pause(-1, TIMER_0); TEST_ASSERT(ret == ESP_ERR_INVALID_ARG); ret = timer_pause(TIMER_GROUP_0, -1); TEST_ASSERT(ret == ESP_ERR_INVALID_ARG); ret = timer_pause(2, TIMER_0); TEST_ASSERT(ret == ESP_ERR_INVALID_ARG); ret = timer_pause(TIMER_GROUP_1, 2); TEST_ASSERT(ret == ESP_ERR_INVALID_ARG); } // positive mode and negative mode TEST_CASE("Timer counter mode (up / down)", "[hw_timer]") { esp_err_t ret; timer_config_t config = { .alarm_en = 1, .auto_reload = 1, .counter_dir = TIMER_COUNT_UP, .divider = TIMER_DIVIDER, .counter_en = 1, .intr_type = TIMER_INTR_LEVEL }; uint64_t set_timer_val = 0x0; all_timer_init(config, true); all_timer_pause(); // Test counter mode 1: TIMER_COUNT_UP all_timer_set_counter_mode(TIMER_COUNT_UP); all_timer_set_counter_value(set_timer_val); all_timer_start(); vTaskDelay(1000 / portTICK_PERIOD_MS); all_timer_get_counter_time_sec(true, 1); // Test counter mode 2: TIMER_COUNT_DOWN all_timer_pause(); set_timer_val = 0x00E4E1C0ULL; // 3s clock counter value all_timer_set_counter_mode(TIMER_COUNT_DOWN); all_timer_set_counter_value(set_timer_val); all_timer_start(); vTaskDelay(1000 / portTICK_PERIOD_MS); all_timer_get_counter_time_sec(true, 2); // Test counter mode 3 : wrong para ret = timer_set_counter_mode(TIMER_GROUP_0, TIMER_0, -1); TEST_ASSERT(ret == ESP_ERR_INVALID_ARG); ret = timer_set_counter_mode(TIMER_GROUP_0, TIMER_0, 2); TEST_ASSERT(ret == ESP_ERR_INVALID_ARG); } /** * divider case: * 1. different divider, read value * Note: divide 0 = divide max, divide 1 = divide 2 * 2. error para * * 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]") { int i; timer_config_t config = { .alarm_en = 1, .auto_reload = 1, .counter_dir = TIMER_COUNT_UP, .divider = TIMER_DIVIDER, .counter_en = 1, .intr_type = TIMER_INTR_LEVEL }; uint64_t set_timer_val = 0; uint64_t time_val[4]; uint64_t comp_time_val[4]; all_timer_init(config, true); all_timer_pause(); all_timer_set_counter_value(set_timer_val); all_timer_start(); vTaskDelay(1000 / portTICK_PERIOD_MS); 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_set_divider(8); all_timer_set_counter_value(set_timer_val); all_timer_start(); vTaskDelay(1000 / portTICK_PERIOD_MS); //delay the same time all_timer_get_counter_value(set_timer_val, false, comp_time_val); for (i = 0; i < 4; i++) { TEST_ASSERT_INT_WITHIN(5000, 5000000, time_val[i]); TEST_ASSERT_INT_WITHIN(10000, 10000000, comp_time_val[i]); } // divider is 256, value should be 2^4 all_timer_pause(); all_timer_set_divider(256); all_timer_set_counter_value(set_timer_val); all_timer_start(); vTaskDelay(1000 / portTICK_PERIOD_MS); //delay the same time all_timer_get_counter_value(set_timer_val, false, comp_time_val); for (i = 0; i < 4; i++) { TEST_ASSERT_INT_WITHIN(5000, 5000000, time_val[i]); TEST_ASSERT_INT_WITHIN(3126, 312500, comp_time_val[i]); } // extrem value test all_timer_pause(); all_timer_set_divider(2); all_timer_set_counter_value(set_timer_val); all_timer_start(); vTaskDelay(1000 / portTICK_PERIOD_MS); all_timer_get_counter_value(set_timer_val, false, comp_time_val); for (i = 0; i < 4; i++) { TEST_ASSERT_INT_WITHIN(5000, 5000000, time_val[i]); TEST_ASSERT_INT_WITHIN(40000 , 40000000, comp_time_val[i]); } all_timer_pause(); all_timer_set_divider(65536); all_timer_set_counter_value(set_timer_val); all_timer_start(); vTaskDelay(1000 / portTICK_PERIOD_MS); //delay the same time all_timer_get_counter_value(set_timer_val, false, comp_time_val); for (i = 0; i < 4; i++) { TEST_ASSERT_INT_WITHIN(5000, 5000000, time_val[i]); TEST_ASSERT_INT_WITHIN(2 , 1220, comp_time_val[i]); } // divider is 1 should be equal with 2 all_timer_pause(); TEST_ASSERT(timer_set_divider(TIMER_GROUP_0, TIMER_0, 1) == ESP_ERR_INVALID_ARG) ; TEST_ASSERT(timer_set_divider(TIMER_GROUP_1, TIMER_0, 1) == ESP_ERR_INVALID_ARG) ; TEST_ASSERT(timer_set_divider(TIMER_GROUP_0, TIMER_1, 1) == ESP_ERR_INVALID_ARG) ; TEST_ASSERT(timer_set_divider(TIMER_GROUP_1, TIMER_1, 1) == ESP_ERR_INVALID_ARG) ; all_timer_pause(); TEST_ASSERT(timer_set_divider(TIMER_GROUP_0, TIMER_0, 65537) == ESP_ERR_INVALID_ARG) ; TEST_ASSERT(timer_set_divider(TIMER_GROUP_1, TIMER_0, 65537) == ESP_ERR_INVALID_ARG) ; TEST_ASSERT(timer_set_divider(TIMER_GROUP_0, TIMER_1, 65537) == ESP_ERR_INVALID_ARG) ; TEST_ASSERT(timer_set_divider(TIMER_GROUP_1, TIMER_1, 65537) == ESP_ERR_INVALID_ARG) ; } /** * enable alarm case: * 1. enable alarm ,set alarm value and get value * 2. disable alarm ,set alarm value and get value */ TEST_CASE("Timer enable alarm", "[hw_timer]") { timer_config_t config_test = { .alarm_en = 1, .auto_reload = 1, .counter_dir = TIMER_COUNT_UP, .divider = TIMER_DIVIDER, .counter_en = 1, .intr_type = TIMER_INTR_LEVEL }; all_timer_init(config_test, true); // enable alarm alarm_flag = false; tg_timer_init(TIMER_GROUP_0, TIMER_1, 1.2); vTaskDelay(2000 / portTICK_PERIOD_MS); TEST_ASSERT(alarm_flag == true); // disable alarm alarm_flag = false; timer_set_alarm(TIMER_GROUP_0, TIMER_1, TIMER_ALARM_DIS); tg_timer_init(TIMER_GROUP_0, TIMER_1, 1.2); vTaskDelay(2000 / portTICK_PERIOD_MS); TEST_ASSERT(alarm_flag == false); // enable alarm alarm_flag = false; timer_set_alarm(TIMER_GROUP_1, TIMER_0, TIMER_ALARM_EN); tg_timer_init(TIMER_GROUP_1, TIMER_0, 1.2); vTaskDelay(2000 / portTICK_PERIOD_MS); TEST_ASSERT(alarm_flag == true); // disable alarm alarm_flag = false; timer_set_alarm(TIMER_GROUP_1, TIMER_0, TIMER_ALARM_DIS); tg_timer_init(TIMER_GROUP_1, TIMER_0, 1.2); vTaskDelay(2000 / portTICK_PERIOD_MS); TEST_ASSERT(alarm_flag == false); } /** * alarm value case: * 1. set alarm value and get value * 2. interrupt test time */ TEST_CASE("Timer set alarm value", "[hw_timer]") { esp_err_t ret; int i; uint64_t alarm_val[4]; timer_config_t config = { .alarm_en = 1, .auto_reload = TIMER_AUTORELOAD_DIS, .counter_dir = TIMER_COUNT_UP, .divider = TIMER_DIVIDER, .counter_en = 0, .intr_type = TIMER_INTR_LEVEL }; all_timer_init(config, true); // set and get alarm value all_timer_set_alarm_value(3); ret = timer_get_alarm_value(TIMER_GROUP_0, TIMER_0, &alarm_val[0]); TEST_ASSERT(ret == ESP_OK); ret = timer_get_alarm_value(TIMER_GROUP_0, TIMER_1, &alarm_val[1]); TEST_ASSERT(ret == ESP_OK); ret = timer_get_alarm_value(TIMER_GROUP_1, TIMER_0, &alarm_val[2]); TEST_ASSERT(ret == ESP_OK); ret = timer_get_alarm_value(TIMER_GROUP_1, TIMER_1, &alarm_val[3]); TEST_ASSERT(ret == ESP_OK); for (i = 0; i < 4; i++) { TEST_ASSERT_EQUAL_UINT32(alarm_val[i] , TIMER_SCALE * 3); } // set interrupt read alarm value tg_timer_init(TIMER_GROUP_0, TIMER_1, 2.4); tg_timer_init(TIMER_GROUP_1, TIMER_0, 1.4); vTaskDelay(3000 / portTICK_PERIOD_MS); } /** * auto reload case: * 1. no reload * 2. auto reload */ TEST_CASE("Timer auto reload", "[hw_timer]") { timer_config_t config = { .alarm_en = 1, .auto_reload = TIMER_AUTORELOAD_DIS, .counter_dir = TIMER_COUNT_UP, .divider = TIMER_DIVIDER, .counter_en = 1, .intr_type = TIMER_INTR_LEVEL }; all_timer_init(config, true); // test disable auto_reload tg_timer_init(TIMER_GROUP_0, TIMER_0, 1.14); tg_timer_init(TIMER_GROUP_1, TIMER_1, 1.14); vTaskDelay(2000 / portTICK_PERIOD_MS); //test enable auto_reload timer_set_auto_reload(TIMER_GROUP_0, TIMER_1, TIMER_AUTORELOAD_EN); tg_timer_init(TIMER_GROUP_0, TIMER_1, 1.4); timer_set_auto_reload(TIMER_GROUP_1, TIMER_0, TIMER_AUTORELOAD_EN); tg_timer_init(TIMER_GROUP_1, TIMER_0, 1.4); vTaskDelay(2000 / portTICK_PERIOD_MS); } /** * timer_enable_intr case: * 1. enable timer_intr * 2. disable timer_intr */ TEST_CASE("Timer enable timer interrupt", "[hw_timer]") { alarm_flag = false; timer_config_t config = { .alarm_en = 1, .auto_reload = TIMER_AUTORELOAD_DIS, .counter_dir = TIMER_COUNT_UP, .divider = TIMER_DIVIDER, .counter_en = TIMER_PAUSE, .intr_type = TIMER_INTR_LEVEL }; uint64_t set_timer_val = 0x0; all_timer_init(config, true); all_timer_pause(); all_timer_set_counter_value(set_timer_val); all_timer_set_alarm_value(1.2); // enable timer_intr0 timer_set_counter_value(TIMER_GROUP_0, TIMER_0, set_timer_val); timer_set_alarm_value(TIMER_GROUP_0, TIMER_0, 1.2 * TIMER_SCALE); timer_isr_register(TIMER_GROUP_0, TIMER_0, test_timer_group0_isr, (void *) TIMER_0, ESP_INTR_FLAG_LOWMED, NULL); timer_start(TIMER_GROUP_0, TIMER_0); vTaskDelay(2000 / portTICK_PERIOD_MS); TEST_ASSERT(alarm_flag == true) // disable timer_intr0 alarm_flag = false; timer_set_counter_value(TIMER_GROUP_0, TIMER_0, set_timer_val); timer_set_alarm_value(TIMER_GROUP_0, TIMER_0, 1.2 * TIMER_SCALE); timer_disable_intr(TIMER_GROUP_0, TIMER_0); timer_start(TIMER_GROUP_0, TIMER_0); vTaskDelay(2000 / portTICK_PERIOD_MS); TEST_ASSERT(alarm_flag == false) // enable timer_intr1 timer_set_counter_value(TIMER_GROUP_1, TIMER_1, set_timer_val); timer_set_alarm_value(TIMER_GROUP_1, TIMER_1, 1.2 * TIMER_SCALE); timer_isr_register(TIMER_GROUP_1, TIMER_1, test_timer_group1_isr, (void *) TIMER_1, ESP_INTR_FLAG_LOWMED, NULL); timer_start(TIMER_GROUP_1, TIMER_1); vTaskDelay(2000 / portTICK_PERIOD_MS); TEST_ASSERT(alarm_flag == true) // disable timer_intr1 alarm_flag = false; timer_set_counter_value(TIMER_GROUP_1, TIMER_1, set_timer_val); timer_set_alarm_value(TIMER_GROUP_1, TIMER_1, 1.2 * TIMER_SCALE); timer_disable_intr(TIMER_GROUP_1, TIMER_1); timer_start(TIMER_GROUP_1, TIMER_1); vTaskDelay(2000 / portTICK_PERIOD_MS); TEST_ASSERT(alarm_flag == false); //enable timer_intr1 again timer_init(TIMER_GROUP_1, TIMER_1, &config); timer_set_counter_value(TIMER_GROUP_1, TIMER_1, set_timer_val); timer_set_alarm_value(TIMER_GROUP_1, TIMER_1, 1.2 * TIMER_SCALE); timer_enable_intr(TIMER_GROUP_1, TIMER_1); timer_start(TIMER_GROUP_1, TIMER_1); vTaskDelay(2000 / portTICK_PERIOD_MS); TEST_ASSERT(alarm_flag == true) } /** * enable timer group case: * 1. enable timer group * 2. disable timer group */ TEST_CASE("Timer enable timer group interrupt", "[hw_timer][ignore]") { alarm_flag = false; timer_config_t config = { .alarm_en = 1, .auto_reload = TIMER_AUTORELOAD_DIS, .counter_dir = TIMER_COUNT_UP, .divider = TIMER_DIVIDER, .counter_en = 0, .intr_type = TIMER_INTR_LEVEL }; uint64_t set_timer_val = 0x0; all_timer_init(config, true); all_timer_pause(); all_timer_set_counter_value(set_timer_val); all_timer_set_alarm_value(1.2); // enable timer group timer_group_intr_enable(TIMER_GROUP_0, TIMG_T0_INT_ENA_M); timer_isr_register(TIMER_GROUP_0, TIMER_0, test_timer_group0_isr, (void *) TIMER_0, ESP_INTR_FLAG_LOWMED, NULL); timer_start(TIMER_GROUP_0, TIMER_0); vTaskDelay(2000 / portTICK_PERIOD_MS); TEST_ASSERT(alarm_flag == true); //test enable auto_reload alarm_flag = false; timer_group_intr_disable(TIMER_GROUP_0, TIMG_T0_INT_ENA_M); timer_start(TIMER_GROUP_0, TIMER_0); vTaskDelay(2000 / portTICK_PERIOD_MS); TEST_ASSERT(alarm_flag == false); timer_group_intr_enable(TIMER_GROUP_0, TIMG_T0_INT_ENA_M); timer_isr_register(TIMER_GROUP_0, TIMER_0, test_timer_group0_isr, (void *) TIMER_0, ESP_INTR_FLAG_LOWMED, NULL); timer_start(TIMER_GROUP_0, TIMER_0); vTaskDelay(2000 / portTICK_PERIOD_MS); TEST_ASSERT(alarm_flag == true); } /** * isr_register case: * Cycle register 15 times, compare the heap size to ensure no memory leaks */ TEST_CASE("Timer interrupt register", "[hw_timer]") { int i; int heap_size = 0; timer_config_t config = { .alarm_en = 1, .auto_reload = TIMER_AUTORELOAD_DIS, .counter_dir = TIMER_COUNT_UP, .divider = TIMER_DIVIDER, .counter_en = TIMER_PAUSE, .intr_type = TIMER_INTR_LEVEL }; for (i = 0; i < 15; i++) { all_timer_init(config, true); tg_timer_init(TIMER_GROUP_0, TIMER_0, 0.54); tg_timer_init(TIMER_GROUP_1, TIMER_1, 0.34); timer_set_auto_reload(TIMER_GROUP_0, TIMER_1, TIMER_AUTORELOAD_EN); tg_timer_init(TIMER_GROUP_0, TIMER_1, 0.4); timer_set_auto_reload(TIMER_GROUP_1, TIMER_0, TIMER_AUTORELOAD_EN); tg_timer_init(TIMER_GROUP_1, TIMER_0, 0.6); vTaskDelay(1000 / portTICK_PERIOD_MS); if (heap_size == 0) { heap_size = esp_get_free_heap_size(); } } TEST_ASSERT_INT_WITHIN(100, heap_size, esp_get_free_heap_size()); }