Skip to content

Commit

Permalink
unit_tests: replace legacy timer group with gptimer
Browse files Browse the repository at this point in the history
  • Loading branch information
suda-morris committed Jan 7, 2022
1 parent 6bf3af7 commit 705788a
Show file tree
Hide file tree
Showing 18 changed files with 414 additions and 662 deletions.
4 changes: 2 additions & 2 deletions components/cxx/test/test_cxx.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -324,5 +324,5 @@ template<typename T> __attribute__((unused)) static void test_binary_operators()
}

//Add more types here. If any flags cannot pass the build, use FLAG_ATTR in esp_attr.h
#include "driver/timer.h"
#include "driver/timer_types_legacy.h"
template void test_binary_operators<timer_intr_t>();
2 changes: 0 additions & 2 deletions components/esp_event/test/test_default_loop.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "esp_private/periph_ctrl.h"
#include "driver/timer.h"

#include "esp_event.h"
#include "esp_event_private.h"
Expand Down
63 changes: 23 additions & 40 deletions components/esp_event/test/test_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "esp_private/periph_ctrl.h"
#include "driver/timer.h"
#include "driver/gptimer.h"

#include "esp_event.h"
#include "esp_event_private.h"
Expand Down Expand Up @@ -302,10 +301,6 @@ static void test_teardown(void)
TEST_ESP_OK(esp_event_loop_delete_default());
}

#define TIMER_DIVIDER 16 // Hardware timer clock divider
#define TIMER_SCALE (TIMER_BASE_CLK / TIMER_DIVIDER) // convert counter value to seconds
#define TIMER_INTERVAL0_SEC (2.0) // sample test interval for the first timer

TEST_CASE("can create and delete event loops", "[event]")
{
/* this test aims to verify that:
Expand Down Expand Up @@ -1973,63 +1968,51 @@ static void test_handler_post_from_isr(void* event_handler_arg, esp_event_base_t
xSemaphoreGive(*sem);
}

void IRAM_ATTR test_event_on_timer_alarm(void* para)
bool test_event_on_timer_alarm(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_ctx)
{
/* Retrieve the interrupt status and the counter value
from the timer that reported the interrupt */
uint64_t timer_counter_value =
timer_group_get_counter_value_in_isr(TIMER_GROUP_0, TIMER_0);
timer_group_clr_intr_status_in_isr(TIMER_GROUP_0, TIMER_0);
timer_counter_value += (uint64_t) (TIMER_INTERVAL0_SEC * TIMER_SCALE);
timer_group_set_alarm_value_in_isr(TIMER_GROUP_0, TIMER_0, timer_counter_value);

int data = (int) para;
int data = (int)user_ctx;
gptimer_stop(timer);
// Posting events with data more than 4 bytes should fail.
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_event_isr_post(s_test_base1, TEST_EVENT_BASE1_EV1, &data, 5, NULL));
// This should succeedd, as data is int-sized. The handler for the event checks that the passed event data
// is correct.
BaseType_t task_unblocked;
TEST_ESP_OK(esp_event_isr_post(s_test_base1, TEST_EVENT_BASE1_EV1, &data, sizeof(data), &task_unblocked));
if (task_unblocked == pdTRUE) {
portYIELD_FROM_ISR();
}
return task_unblocked == pdTRUE;
}

TEST_CASE("can post events from interrupt handler", "[event]")
{
SemaphoreHandle_t sem = xSemaphoreCreateBinary();

gptimer_handle_t gptimer = NULL;
/* Select and initialize basic parameters of the timer */
timer_config_t config = {
.divider = TIMER_DIVIDER,
.counter_dir = TIMER_COUNT_UP,
.counter_en = TIMER_PAUSE,
.alarm_en = TIMER_ALARM_EN,
.intr_type = TIMER_INTR_LEVEL,
.auto_reload = false,
gptimer_config_t config = {
.clk_src = GPTIMER_CLK_SRC_APB,
.direction = GPTIMER_COUNT_UP,
.resolution_hz = 1000000, // 1MHz, 1 tick = 1us
};
timer_init(TIMER_GROUP_0, TIMER_0, &config);

/* Timer's counter will initially start from value below.
Also, if auto_reload is set, this value will be automatically reload on alarm */
timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0x00000000ULL);
TEST_ESP_OK(gptimer_new_timer(&config, &gptimer));

/* Configure the alarm value and the interrupt on alarm. */
timer_set_alarm_value(TIMER_GROUP_0, TIMER_0, TIMER_INTERVAL0_SEC * TIMER_SCALE);
timer_enable_intr(TIMER_GROUP_0, TIMER_0);
timer_isr_register(TIMER_GROUP_0, TIMER_0, test_event_on_timer_alarm,
(void *) sem, ESP_INTR_FLAG_IRAM, NULL);

timer_start(TIMER_GROUP_0, TIMER_0);
gptimer_alarm_config_t alarm_config = {
.reload_count = 0,
.alarm_count = 500000,
};
gptimer_event_callbacks_t cbs = {
.on_alarm = test_event_on_timer_alarm
};
TEST_ESP_OK(gptimer_register_event_callbacks(gptimer, &cbs, sem));
TEST_ESP_OK(gptimer_set_alarm_action(gptimer, &alarm_config));
TEST_ESP_OK(gptimer_start(gptimer));

TEST_SETUP();

TEST_ESP_OK(esp_event_handler_register(s_test_base1, TEST_EVENT_BASE1_EV1,
test_handler_post_from_isr, &sem));
test_handler_post_from_isr, &sem));

xSemaphoreTake(sem, portMAX_DELAY);

TEST_TEARDOWN();
TEST_ESP_OK(gptimer_del_timer(gptimer));
}

#endif // CONFIG_ESP_EVENT_POST_FROM_ISR
148 changes: 43 additions & 105 deletions components/esp_hw_support/test/test_intr_alloc.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand All @@ -8,6 +8,7 @@
*/

#include <stdio.h>
#include "sdkconfig.h"
#include "esp_types.h"
#include "esp_rom_sys.h"
#include "freertos/FreeRTOS.h"
Expand All @@ -16,84 +17,52 @@
#include "freertos/queue.h"
#include "unity.h"
#include "esp_intr_alloc.h"
#include "esp_private/periph_ctrl.h"
#include "driver/timer.h"
#include "driver/gptimer.h"
#include "soc/soc_caps.h"
#include "soc/spi_periph.h"
#include "hal/spi_ll.h"
#include "sdkconfig.h"

#define TIMER_DIVIDER (16) /*!< Hardware timer clock divider */
#define TIMER_SCALE (APB_CLK_FREQ / TIMER_DIVIDER) /*!< used to calculate counter value */
#define TIMER_INTERVAL0_SEC (3) /*!< test interval for timer 0 */
#define TIMER_INTERVAL1_SEC (5) /*!< test interval for timer 1 */

static void my_timer_init(int timer_group, int timer_idx, uint64_t alarm_value)
{
timer_config_t config = {
.alarm_en = 1,
.auto_reload = 1,
.counter_dir = TIMER_COUNT_UP,
.divider = TIMER_DIVIDER,
};
/*Configure timer*/
timer_init(timer_group, timer_idx, &config);
/*Stop timer counter*/
timer_pause(timer_group, timer_idx);
/*Load counter value */
timer_set_counter_value(timer_group, timer_idx, 0);
/*Set alarm value*/
timer_set_alarm_value(timer_group, timer_idx, alarm_value);
/*Enable timer interrupt*/
timer_enable_intr(timer_group, timer_idx);
}

static volatile int count[SOC_TIMER_GROUP_TOTAL_TIMERS] = {0};
#include "esp_private/periph_ctrl.h"
#include "esp_private/gptimer.h"

static void timer_isr(void *arg)
static bool on_timer_alarm(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_ctx)
{
int timer_idx = (int)arg;
int group_id = timer_idx / SOC_TIMER_GROUP_TIMERS_PER_GROUP;
int timer_id = timer_idx % SOC_TIMER_GROUP_TIMERS_PER_GROUP;
count[timer_idx]++;

timer_group_clr_intr_status_in_isr(group_id, timer_id);
timer_group_enable_alarm_in_isr(group_id, timer_id);
volatile int *count = (volatile int *)user_ctx;
(*count)++;
return false;
}

static void timer_test(int flags)
{
timer_isr_handle_t inth[SOC_TIMER_GROUP_TOTAL_TIMERS];
for (int i = 0; i < SOC_TIMER_GROUPS; i++) {
for (int j = 0; j < SOC_TIMER_GROUP_TIMERS_PER_GROUP; j++) {
my_timer_init(i, j, 100000 + 10000 * (i * SOC_TIMER_GROUP_TIMERS_PER_GROUP + j + 1));
}
}
timer_isr_register(0, 0, timer_isr, (void *)0, flags | ESP_INTR_FLAG_INTRDISABLED, &inth[0]);
printf("Interrupts allocated: %d (dis)\r\n", esp_intr_get_intno(inth[0]));

for (int j = 1; j < SOC_TIMER_GROUP_TIMERS_PER_GROUP; j++) {
timer_isr_register(0, j, timer_isr, (void *)1, flags, &inth[j]);
printf("Interrupts allocated: %d\r\n", esp_intr_get_intno(inth[j]));
}
for (int i = 1; i < SOC_TIMER_GROUPS; i++) {
for (int j = 0; j < SOC_TIMER_GROUP_TIMERS_PER_GROUP; j++) {
timer_isr_register(i, j, timer_isr, (void *)(i * SOC_TIMER_GROUP_TIMERS_PER_GROUP + j), flags, &inth[i * SOC_TIMER_GROUP_TIMERS_PER_GROUP + j]);
printf("Interrupts allocated: %d\r\n", esp_intr_get_intno(inth[i * SOC_TIMER_GROUP_TIMERS_PER_GROUP + j]));
}
}
for (int i = 0; i < SOC_TIMER_GROUPS; i++) {
for (int j = 0; j < SOC_TIMER_GROUP_TIMERS_PER_GROUP; j++) {
timer_start(i, j);
}
static int count[SOC_TIMER_GROUP_TOTAL_TIMERS] = {0};
gptimer_handle_t gptimers[SOC_TIMER_GROUP_TOTAL_TIMERS];
intr_handle_t inth[SOC_TIMER_GROUP_TOTAL_TIMERS];

gptimer_config_t config = {
.clk_src = GPTIMER_CLK_SRC_APB,
.direction = GPTIMER_COUNT_UP,
.resolution_hz = 1000000,
.flags.intr_shared = (flags & ESP_INTR_FLAG_SHARED) == ESP_INTR_FLAG_SHARED,
};
for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
TEST_ESP_OK(gptimer_new_timer(&config, &gptimers[i]));
}
gptimer_alarm_config_t alarm_config = {
.reload_count = 0,
.alarm_count = 100000,
.flags.auto_reload_on_alarm = true,
};
gptimer_event_callbacks_t cbs = {
.on_alarm = on_timer_alarm,
};

printf("Timer values on start:");
for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
count[i] = 0;
printf(" %d", count[i]);
TEST_ESP_OK(gptimer_register_event_callbacks(gptimers[i], &cbs, &count[i]));
alarm_config.alarm_count += 10000 * i;
TEST_ESP_OK(gptimer_set_alarm_action(gptimers[i], &alarm_config));
TEST_ESP_OK(gptimer_start(gptimers[i]));
TEST_ESP_OK(gptimer_get_intr_handle(gptimers[i], &inth[i]));
printf("Interrupts allocated: %d\r\n", esp_intr_get_intno(inth[i]));
}
printf("\r\n");

vTaskDelay(1000 / portTICK_PERIOD_MS);
printf("Timer values after 1 sec:");
Expand All @@ -102,19 +71,13 @@ static void timer_test(int flags)
}
printf("\r\n");

TEST_ASSERT(count[0] == 0);
for (int i = 1; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
TEST_ASSERT(count[i] != 0);
for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
TEST_ASSERT_NOT_EQUAL(0, count[i]);
}

printf("Disabling half of timers' interrupt...\r\n");
for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS / 2; i++) {
esp_intr_disable(inth[i]);
}
for (int i = SOC_TIMER_GROUP_TOTAL_TIMERS / 2; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
esp_intr_enable(inth[i]);
}
printf("Disabling timers' interrupt...\r\n");
for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
esp_intr_disable(inth[i]);
count[i] = 0;
}

Expand All @@ -124,38 +87,13 @@ static void timer_test(int flags)
printf(" %d", count[i]);
}
printf("\r\n");
for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS / 2; i++) {
TEST_ASSERT(count[i] == 0);
}
for (int i = SOC_TIMER_GROUP_TOTAL_TIMERS / 2; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
TEST_ASSERT(count[i] != 0);
}

printf("Disabling another half...\r\n");
for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS / 2; i++) {
esp_intr_enable(inth[i]);
}
for (int i = SOC_TIMER_GROUP_TOTAL_TIMERS / 2; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
esp_intr_disable(inth[i]);
}
for (int x = 0; x < SOC_TIMER_GROUP_TOTAL_TIMERS; x++) {
count[x] = 0;
}
vTaskDelay(1000 / portTICK_PERIOD_MS);
printf("Timer values after 1 sec:");
for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
printf(" %d", count[i]);
TEST_ASSERT_EQUAL(0, count[i]);
}
printf("\r\n");
for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS / 2; i++) {
TEST_ASSERT(count[i] != 0);
}
for (int i = SOC_TIMER_GROUP_TOTAL_TIMERS / 2; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
TEST_ASSERT(count[i] == 0);
}
printf("Done.\n");

for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
esp_intr_free(inth[i]);
TEST_ESP_OK(gptimer_stop(gptimers[i]));
TEST_ESP_OK(gptimer_del_timer(gptimers[i]));
}
}

Expand Down
Loading

0 comments on commit 705788a

Please sign in to comment.