From 004c1713b6c91dd0d7da1bd3ad418696a41121b0 Mon Sep 17 00:00:00 2001 From: morris Date: Thu, 2 Mar 2023 16:08:49 +0800 Subject: [PATCH] gptimer: test late alarm Closes https://github.com/espressif/esp-idf/issues/10877 --- .../gpio_extensions/main/test_gpio_filter.c | 4 ++ .../test_apps/gptimer/main/test_gptimer.c | 47 +++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/components/driver/test_apps/gpio_extensions/main/test_gpio_filter.c b/components/driver/test_apps/gpio_extensions/main/test_gpio_filter.c index 4d90253046..dd1580c0ce 100644 --- a/components/driver/test_apps/gpio_extensions/main/test_gpio_filter.c +++ b/components/driver/test_apps/gpio_extensions/main/test_gpio_filter.c @@ -89,9 +89,12 @@ static void test_gpio_intr_callback(void *args) // put the simulation code in the IRAM to avoid cache miss NOINLINE_ATTR IRAM_ATTR static void test_gpio_simulate_glitch_pulse(void) { + static portMUX_TYPE g_lock = portMUX_INITIALIZER_UNLOCKED; // the following code is used to generate a short glitch pulse // around 20ns @CPU160MHz, 40ns @CPU96MHz // pull high for 4 CPU cycles, to ensure the short pulse can be sampled by GPIO + // we don't want any preemption to happen during the glitch signal generation + portENTER_CRITICAL(&g_lock); asm volatile( "csrrsi zero, %0, 0x1\n" "csrrsi zero, %0, 0x1\n" @@ -100,6 +103,7 @@ NOINLINE_ATTR IRAM_ATTR static void test_gpio_simulate_glitch_pulse(void) "csrrci zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER) ); + portEXIT_CRITICAL(&g_lock); } TEST_CASE("GPIO flex glitch filter enable/disable", "[gpio_filter]") diff --git a/components/driver/test_apps/gptimer/main/test_gptimer.c b/components/driver/test_apps/gptimer/main/test_gptimer.c index ccb48ef3e3..49bfe1482d 100644 --- a/components/driver/test_apps/gptimer/main/test_gptimer.c +++ b/components/driver/test_apps/gptimer/main/test_gptimer.c @@ -549,3 +549,50 @@ TEST_CASE("gptimer_overflow", "[gptimer]") TEST_ESP_OK(gptimer_del_timer(timers[i])); } } + +TEST_ALARM_CALLBACK_ATTR static bool test_gptimer_alarm_late_callback(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data) +{ + bool *alarm_fired = (bool *)user_data; + *alarm_fired = true; + esp_rom_printf("alarm isr count=%llu\r\n", edata->count_value); + return false; +} + +TEST_CASE("gptimer_trig_alarm_with_old_count", "[gptimer]") +{ + printf("install gptimer driver\r\n"); + gptimer_config_t timer_config = { + .resolution_hz = 10 * 1000, // 10KHz, 1 tick = 0.1ms + .clk_src = GPTIMER_CLK_SRC_DEFAULT, + .direction = GPTIMER_COUNT_UP, + }; + gptimer_handle_t timer; + TEST_ESP_OK(gptimer_new_timer(&timer_config, &timer)); + + printf("register alarm callback\r\n"); + bool alarm_fired = false; + gptimer_event_callbacks_t cbs = { + .on_alarm = test_gptimer_alarm_late_callback, + }; + TEST_ESP_OK(gptimer_register_event_callbacks(timer, &cbs, &alarm_fired)); + TEST_ESP_OK(gptimer_enable(timer)); + TEST_ESP_OK(gptimer_start(timer)); + + printf("let the timer go for sometime\r\n"); + vTaskDelay(pdMS_TO_TICKS(1000)); + + printf("set alarm config with a very early count value\r\n"); + gptimer_alarm_config_t alarm_config = { + .reload_count = 0, + .alarm_count = 10, // 1ms < current count, so the alarm should fire immediately + }; + TEST_ESP_OK(gptimer_set_alarm_action(timer, &alarm_config)); + + vTaskDelay(pdMS_TO_TICKS(100)); + // check it's fired + TEST_ASSERT_TRUE(alarm_fired); + + TEST_ESP_OK(gptimer_stop(timer)); + TEST_ESP_OK(gptimer_disable(timer)); + TEST_ESP_OK(gptimer_del_timer(timer)); +}