diff --git a/components/esp_system/intr_alloc.c b/components/esp_system/intr_alloc.c index 9327b0ff8c..7e7de6dbe9 100644 --- a/components/esp_system/intr_alloc.c +++ b/components/esp_system/intr_alloc.c @@ -469,9 +469,7 @@ esp_err_t esp_intr_alloc_intrstatus(int source, int flags, uint32_t intrstatusre //ToDo: if we are to allow placing interrupt handlers into the 0x400c0000—0x400c2000 region, //we need to make sure the interrupt is connected to the CPU0. //CPU1 does not have access to the RTC fast memory through this region. - if ((flags&ESP_INTR_FLAG_IRAM) && - (ptrdiff_t) handler >= SOC_RTC_IRAM_HIGH && - (ptrdiff_t) handler < SOC_RTC_DATA_LOW ) { + if ((flags & ESP_INTR_FLAG_IRAM) && handler && !esp_ptr_in_iram(handler) && !esp_ptr_in_rtc_iram_fast(handler)) { return ESP_ERR_INVALID_ARG; } diff --git a/components/esp_system/test/test_intr_alloc.c b/components/esp_system/test/test_intr_alloc.c index 578e85a5de..8ddeffc827 100644 --- a/components/esp_system/test/test_intr_alloc.c +++ b/components/esp_system/test/test_intr_alloc.c @@ -2,190 +2,156 @@ Tests for the interrupt allocator. */ -#include #include +#include "esp_types.h" #include "esp_rom_sys.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/semphr.h" #include "freertos/queue.h" #include "unity.h" -#include "soc/uart_periph.h" -#include "soc/gpio_periph.h" #include "esp_intr_alloc.h" #include "driver/periph_ctrl.h" #include "driver/timer.h" +#include "soc/soc_caps.h" +#include "soc/spi_periph.h" +#include "hal/spi_ll.h" #include "sdkconfig.h" -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3,ESP32C3) -// TODO ESP32-C3 IDF-2585 +#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 */ -#define TIMER_DIVIDER 16 /*!< Hardware timer clock divider */ -#define TIMER_SCALE (TIMER_BASE_CLK / TIMER_DIVIDER) /*!< used to calculate counter value */ -#define TIMER_INTERVAL0_SEC (3.4179) /*!< test interval for timer 0 */ -#define TIMER_INTERVAL1_SEC (5.78) /*!< test interval for timer 1 */ - - -static void my_timer_init(int timer_group, int timer_idx, int ival) +static void my_timer_init(int timer_group, int timer_idx, uint64_t alarm_value) { - timer_config_t config; - config.alarm_en = 1; - config.auto_reload = 1; - config.counter_dir = TIMER_COUNT_UP; - config.divider = TIMER_DIVIDER; - config.intr_type = TIMER_INTR_LEVEL; - config.counter_en = TIMER_PAUSE; + 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, 0x00000000ULL); + timer_set_counter_value(timer_group, timer_idx, 0); /*Set alarm value*/ - timer_set_alarm_value(timer_group, timer_idx, ival); + timer_set_alarm_value(timer_group, timer_idx, alarm_value); /*Enable timer interrupt*/ timer_enable_intr(timer_group, timer_idx); } -static volatile int count[4]={0,0,0,0}; - +static volatile int count[SOC_TIMER_GROUP_TOTAL_TIMERS] = {0}; static void timer_isr(void *arg) { 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]++; - if (timer_idx==0) { - timer_group_clr_intr_status_in_isr(TIMER_GROUP_0, TIMER_0); - timer_group_enable_alarm_in_isr(TIMER_GROUP_0, TIMER_0); - } - if (timer_idx==1) { - timer_group_clr_intr_status_in_isr(TIMER_GROUP_0, TIMER_1); - timer_group_enable_alarm_in_isr(TIMER_GROUP_0, TIMER_1); - } - if (timer_idx==2) { - timer_group_clr_intr_status_in_isr(TIMER_GROUP_1, TIMER_0); - timer_group_enable_alarm_in_isr(TIMER_GROUP_1, TIMER_0); - } - if (timer_idx==3) { - timer_group_clr_intr_status_in_isr(TIMER_GROUP_1, TIMER_1); - timer_group_enable_alarm_in_isr(TIMER_GROUP_1, TIMER_1); - } + + timer_group_clr_intr_status_in_isr(group_id, timer_id); + timer_group_enable_alarm_in_isr(group_id, timer_id); } - -static void timer_test(int flags) { - int x; - timer_isr_handle_t inth[4]; - my_timer_init(TIMER_GROUP_0, TIMER_0, 110000); - my_timer_init(TIMER_GROUP_0, TIMER_1, 120000); - my_timer_init(TIMER_GROUP_1, TIMER_0, 130000); - my_timer_init(TIMER_GROUP_1, TIMER_1, 140000); - timer_isr_register(TIMER_GROUP_0, TIMER_0, timer_isr, (void*)0, flags|ESP_INTR_FLAG_INTRDISABLED, &inth[0]); - timer_isr_register(TIMER_GROUP_0, TIMER_1, timer_isr, (void*)1, flags, &inth[1]); - timer_isr_register(TIMER_GROUP_1, TIMER_0, timer_isr, (void*)2, flags, &inth[2]); - timer_isr_register(TIMER_GROUP_1, TIMER_1, timer_isr, (void*)3, flags, &inth[3]); - timer_start(TIMER_GROUP_0, TIMER_0); - timer_start(TIMER_GROUP_0, TIMER_1); - timer_start(TIMER_GROUP_1, TIMER_0); - timer_start(TIMER_GROUP_1, TIMER_1); - - for (x=0; x<4; x++) count[x]=0; - printf("Interrupts allocated: %d (dis) %d %d %d\n", - esp_intr_get_intno(inth[0]), esp_intr_get_intno(inth[1]), - esp_intr_get_intno(inth[2]), esp_intr_get_intno(inth[3])); - printf("Timer values on start: %d %d %d %d\n", count[0], count[1], count[2], count[3]); - vTaskDelay(1000 / portTICK_PERIOD_MS); - printf("Timer values after 1 sec: %d %d %d %d\n", count[0], count[1], count[2], count[3]); - TEST_ASSERT(count[0]==0); - TEST_ASSERT(count[1]!=0); - TEST_ASSERT(count[2]!=0); - TEST_ASSERT(count[3]!=0); - - printf("Disabling timers 1 and 2...\n"); - esp_intr_enable(inth[0]); - esp_intr_disable(inth[1]); - esp_intr_disable(inth[2]); - for (x=0; x<4; x++) count[x]=0; - vTaskDelay(1000 / portTICK_PERIOD_MS); - printf("Timer values after 1 sec: %d %d %d %d\n", count[0], count[1], count[2], count[3]); - TEST_ASSERT(count[0]!=0); - TEST_ASSERT(count[1]==0); - TEST_ASSERT(count[2]==0); - TEST_ASSERT(count[3]!=0); - printf("Disabling other half...\n"); - esp_intr_enable(inth[1]); - esp_intr_enable(inth[2]); - esp_intr_disable(inth[0]); - esp_intr_disable(inth[3]); - for (x=0; x<4; x++) count[x]=0; - vTaskDelay(1000 / portTICK_PERIOD_MS); - printf("Timer values after 1 sec: %d %d %d %d\n", count[0], count[1], count[2], count[3]); - TEST_ASSERT(count[0]==0); - TEST_ASSERT(count[1]!=0); - TEST_ASSERT(count[2]!=0); - TEST_ASSERT(count[3]==0); - printf("Done.\n"); - esp_intr_free(inth[0]); - esp_intr_free(inth[1]); - esp_intr_free(inth[2]); - esp_intr_free(inth[3]); -} - -static volatile int int_timer_ctr; - - -void int_timer_handler(void *arg) { - xthal_set_ccompare(1, xthal_get_ccount()+8000000); - int_timer_ctr++; -} - -void local_timer_test(void) +static void timer_test(int flags) { - intr_handle_t ih; - esp_err_t r; - r=esp_intr_alloc(ETS_INTERNAL_TIMER1_INTR_SOURCE, 0, int_timer_handler, NULL, &ih); - TEST_ASSERT(r==ESP_OK); - printf("Int timer 1 intno %d\n", esp_intr_get_intno(ih)); - xthal_set_ccompare(1, xthal_get_ccount()+8000000); - int_timer_ctr=0; - vTaskDelay(1000 / portTICK_PERIOD_MS); - printf("Timer val after 1 sec: %d\n", int_timer_ctr); - TEST_ASSERT(int_timer_ctr!=0); - printf("Disabling int\n"); - esp_intr_disable(ih); - int_timer_ctr=0; - vTaskDelay(1000 / portTICK_PERIOD_MS); - printf("Timer val after 1 sec: %d\n", int_timer_ctr); - TEST_ASSERT(int_timer_ctr==0); - printf("Re-enabling\n"); - esp_intr_enable(ih); - vTaskDelay(1000 / portTICK_PERIOD_MS); - printf("Timer val after 1 sec: %d\n", int_timer_ctr); - TEST_ASSERT(int_timer_ctr!=0); + 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); + } + } + + printf("Timer values on start:"); + for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) { + count[i] = 0; + printf(" %d", count[i]); + } + printf("\r\n"); - printf("Free int, re-alloc disabled\n"); - r=esp_intr_free(ih); - TEST_ASSERT(r==ESP_OK); - r=esp_intr_alloc(ETS_INTERNAL_TIMER1_INTR_SOURCE, ESP_INTR_FLAG_INTRDISABLED, int_timer_handler, NULL, &ih); - TEST_ASSERT(r==ESP_OK); - int_timer_ctr=0; vTaskDelay(1000 / portTICK_PERIOD_MS); - printf("Timer val after 1 sec: %d\n", int_timer_ctr); - TEST_ASSERT(int_timer_ctr==0); - printf("Re-enabling\n"); - esp_intr_enable(ih); + printf("Timer values after 1 sec:"); + for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) { + printf(" %d", count[i]); + } + printf("\r\n"); + + TEST_ASSERT(count[0] == 0); + for (int i = 1; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) { + TEST_ASSERT(count[i] != 0); + } + + 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]); + } + for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) { + count[i] = 0; + } + vTaskDelay(1000 / portTICK_PERIOD_MS); - printf("Timer val after 1 sec: %d\n", int_timer_ctr); - TEST_ASSERT(int_timer_ctr!=0); - r=esp_intr_free(ih); - TEST_ASSERT(r==ESP_OK); + printf("Timer values after 1 sec:"); + for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) { + 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]); + } + 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"); -} - - -TEST_CASE("Intr_alloc test, CPU-local int source", "[intr_alloc]") -{ - local_timer_test(); + for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) { + esp_intr_free(inth[i]); + } } TEST_CASE("Intr_alloc test, private ints", "[intr_alloc]") @@ -198,35 +164,6 @@ TEST_CASE("Intr_alloc test, shared ints", "[intr_alloc]") timer_test(ESP_INTR_FLAG_SHARED); } -TEST_CASE("Can allocate IRAM int only with an IRAM handler", "[intr_alloc]") -{ - void dummy(void* arg) - { - } - IRAM_ATTR void dummy_iram(void* arg) - { - } - RTC_IRAM_ATTR void dummy_rtc(void* arg) - { - } - intr_handle_t ih; - esp_err_t err = esp_intr_alloc(ETS_INTERNAL_SW0_INTR_SOURCE, - ESP_INTR_FLAG_IRAM, &dummy, NULL, &ih); - TEST_ASSERT_EQUAL_INT(ESP_ERR_INVALID_ARG, err); - err = esp_intr_alloc(ETS_INTERNAL_SW0_INTR_SOURCE, - ESP_INTR_FLAG_IRAM, &dummy_iram, NULL, &ih); - TEST_ESP_OK(err); - err = esp_intr_free(ih); - TEST_ESP_OK(err); - err = esp_intr_alloc(ETS_INTERNAL_SW0_INTR_SOURCE, - ESP_INTR_FLAG_IRAM, &dummy_rtc, NULL, &ih); - TEST_ESP_OK(err); - err = esp_intr_free(ih); - TEST_ESP_OK(err); -} - - -#include "soc/spi_periph.h" typedef struct { bool flag1; bool flag2; @@ -234,9 +171,9 @@ typedef struct { bool flag4; } intr_alloc_test_ctx_t; -void IRAM_ATTR int_handler1(void* arg) +void IRAM_ATTR int_handler1(void *arg) { - intr_alloc_test_ctx_t* ctx=(intr_alloc_test_ctx_t*)arg; + intr_alloc_test_ctx_t *ctx = (intr_alloc_test_ctx_t *)arg; esp_rom_printf("handler 1 called.\n"); if ( ctx->flag1 ) { ctx->flag3 = true; @@ -244,16 +181,16 @@ void IRAM_ATTR int_handler1(void* arg) ctx->flag1 = true; } - #ifdef CONFIG_IDF_TARGET_ESP32 - SPI2.slave.trans_done = 0; - #else - GPSPI2.slave.trans_done = 0; - #endif +#ifdef CONFIG_IDF_TARGET_ESP32 + spi_ll_clear_int_stat(&SPI2); +#else + spi_ll_clear_int_stat(&GPSPI2); +#endif } -void IRAM_ATTR int_handler2(void* arg) +void IRAM_ATTR int_handler2(void *arg) { - intr_alloc_test_ctx_t* ctx = (intr_alloc_test_ctx_t*)arg; + intr_alloc_test_ctx_t *ctx = (intr_alloc_test_ctx_t *)arg; esp_rom_printf("handler 2 called.\n"); if ( ctx->flag2 ) { ctx->flag4 = true; @@ -262,71 +199,94 @@ void IRAM_ATTR int_handler2(void* arg) } } -TEST_CASE("allocate 2 handlers for a same source and remove the later one","[intr_alloc]") +TEST_CASE("allocate 2 handlers for a same source and remove the later one", "[intr_alloc]") { intr_alloc_test_ctx_t ctx = {false, false, false, false }; intr_handle_t handle1, handle2; - #ifdef CONFIG_IDF_TARGET_ESP32 - //enable HSPI(spi2) - periph_module_enable(PERIPH_HSPI_MODULE); - #else - periph_module_enable(PERIPH_FSPI_MODULE); - #endif + // enable SPI2 + periph_module_enable(spi_periph_signal[1].module); esp_err_t r; - r=esp_intr_alloc(ETS_SPI2_INTR_SOURCE, ESP_INTR_FLAG_SHARED, int_handler1, &ctx, &handle1); + r = esp_intr_alloc(spi_periph_signal[1].irq, ESP_INTR_FLAG_SHARED, int_handler1, &ctx, &handle1); TEST_ESP_OK(r); //try an invalid assign first - r=esp_intr_alloc(ETS_SPI2_INTR_SOURCE, 0, int_handler2, NULL, &handle2); - TEST_ASSERT_EQUAL_INT(r, ESP_ERR_NOT_FOUND ); + r = esp_intr_alloc(spi_periph_signal[1].irq, 0, int_handler2, NULL, &handle2); + TEST_ASSERT_EQUAL_INT(ESP_ERR_NOT_FOUND, r); //assign shared then - r=esp_intr_alloc(ETS_SPI2_INTR_SOURCE, ESP_INTR_FLAG_SHARED, int_handler2, &ctx, &handle2); + r = esp_intr_alloc(spi_periph_signal[1].irq, ESP_INTR_FLAG_SHARED, int_handler2, &ctx, &handle2); TEST_ESP_OK(r); - #ifdef CONFIG_IDF_TARGET_ESP32 - SPI2.slave.trans_inten = 1; - #else - GPSPI2.slave.int_trans_done_en = 1; - #endif +#ifdef CONFIG_IDF_TARGET_ESP32 + spi_ll_enable_int(&SPI2); +#else + spi_ll_enable_int(&GPSPI2); +#endif printf("trigger first time.\n"); - #ifdef CONFIG_IDF_TARGET_ESP32 - SPI2.slave.trans_done = 1; - #else - GPSPI2.slave.trans_done = 1; - #endif +#ifdef CONFIG_IDF_TARGET_ESP32 + spi_ll_set_int_stat(&SPI2); +#else + spi_ll_set_int_stat(&GPSPI2); +#endif vTaskDelay(100); TEST_ASSERT( ctx.flag1 && ctx.flag2 ); printf("remove intr 1.\n"); - r=esp_intr_free(handle2); + r = esp_intr_free(handle2); printf("trigger second time.\n"); - #ifdef CONFIG_IDF_TARGET_ESP32 - SPI2.slave.trans_done = 1; - #else - GPSPI2.slave.trans_done = 1; - #endif +#ifdef CONFIG_IDF_TARGET_ESP32 + spi_ll_set_int_stat(&SPI2); +#else + spi_ll_set_int_stat(&GPSPI2); +#endif vTaskDelay(500); TEST_ASSERT( ctx.flag3 && !ctx.flag4 ); printf("test passed.\n"); + esp_intr_free(handle1); } +static void dummy(void *arg) +{ +} +static IRAM_ATTR void dummy_iram(void *arg) +{ +} +static RTC_IRAM_ATTR void dummy_rtc(void *arg) +{ +} + +TEST_CASE("Can allocate IRAM int only with an IRAM handler", "[intr_alloc]") +{ + intr_handle_t ih; + esp_err_t err = esp_intr_alloc(spi_periph_signal[1].irq, + ESP_INTR_FLAG_IRAM, &dummy, NULL, &ih); + TEST_ASSERT_EQUAL_INT(ESP_ERR_INVALID_ARG, err); + err = esp_intr_alloc(spi_periph_signal[1].irq, + ESP_INTR_FLAG_IRAM, &dummy_iram, NULL, &ih); + TEST_ESP_OK(err); + err = esp_intr_free(ih); + TEST_ESP_OK(err); + err = esp_intr_alloc(spi_periph_signal[1].irq, + ESP_INTR_FLAG_IRAM, &dummy_rtc, NULL, &ih); + TEST_ESP_OK(err); + err = esp_intr_free(ih); + TEST_ESP_OK(err); +} #ifndef CONFIG_FREERTOS_UNICORE - void isr_free_task(void *param) { esp_err_t ret = ESP_FAIL; intr_handle_t *test_handle = (intr_handle_t *)param; - if(*test_handle != NULL) { + if (*test_handle != NULL) { ret = esp_intr_free(*test_handle); - if(ret == ESP_OK) { + if (ret == ESP_OK) { *test_handle = NULL; } } @@ -336,15 +296,15 @@ void isr_free_task(void *param) void isr_alloc_free_test(void) { intr_handle_t test_handle = NULL; - esp_err_t ret = esp_intr_alloc(ETS_SPI2_INTR_SOURCE, 0, int_handler1, NULL, &test_handle); - if(ret != ESP_OK) { + esp_err_t ret = esp_intr_alloc(spi_periph_signal[1].irq, 0, int_handler1, NULL, &test_handle); + if (ret != ESP_OK) { printf("alloc isr handle fail\n"); } else { - printf("alloc isr handle on core %d\n",esp_intr_get_cpu(test_handle)); + printf("alloc isr handle on core %d\n", esp_intr_get_cpu(test_handle)); } TEST_ASSERT(ret == ESP_OK); - xTaskCreatePinnedToCore(isr_free_task, "isr_free_task", 1024*2, (void *)&test_handle, 10, NULL, !xPortGetCoreID()); - vTaskDelay(1000/portTICK_RATE_MS); + xTaskCreatePinnedToCore(isr_free_task, "isr_free_task", 1024 * 2, (void *)&test_handle, 10, NULL, !xPortGetCoreID()); + vTaskDelay(1000 / portTICK_RATE_MS); TEST_ASSERT(test_handle == NULL); printf("test passed\n"); } @@ -353,6 +313,64 @@ TEST_CASE("alloc and free isr handle on different core", "[intr_alloc]") { isr_alloc_free_test(); } - #endif -#endif // #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3, ESP32C3) + +#if __XTENSA__ +static volatile int int_timer_ctr; + +void int_timer_handler(void *arg) +{ + xthal_set_ccompare(1, xthal_get_ccount() + 8000000); + int_timer_ctr++; +} + +static void local_timer_test(void) +{ + intr_handle_t ih; + esp_err_t r; + r = esp_intr_alloc(ETS_INTERNAL_TIMER1_INTR_SOURCE, 0, int_timer_handler, NULL, &ih); + TEST_ASSERT(r == ESP_OK); + printf("Int timer 1 intno %d\n", esp_intr_get_intno(ih)); + xthal_set_ccompare(1, xthal_get_ccount() + 8000000); + int_timer_ctr = 0; + vTaskDelay(1000 / portTICK_PERIOD_MS); + printf("Timer val after 1 sec: %d\n", int_timer_ctr); + TEST_ASSERT(int_timer_ctr != 0); + printf("Disabling int\n"); + esp_intr_disable(ih); + int_timer_ctr = 0; + vTaskDelay(1000 / portTICK_PERIOD_MS); + printf("Timer val after 1 sec: %d\n", int_timer_ctr); + TEST_ASSERT(int_timer_ctr == 0); + printf("Re-enabling\n"); + esp_intr_enable(ih); + vTaskDelay(1000 / portTICK_PERIOD_MS); + printf("Timer val after 1 sec: %d\n", int_timer_ctr); + TEST_ASSERT(int_timer_ctr != 0); + + printf("Free int, re-alloc disabled\n"); + r = esp_intr_free(ih); + TEST_ASSERT(r == ESP_OK); + r = esp_intr_alloc(ETS_INTERNAL_TIMER1_INTR_SOURCE, ESP_INTR_FLAG_INTRDISABLED, int_timer_handler, NULL, &ih); + TEST_ASSERT(r == ESP_OK); + int_timer_ctr = 0; + vTaskDelay(1000 / portTICK_PERIOD_MS); + printf("Timer val after 1 sec: %d\n", int_timer_ctr); + TEST_ASSERT(int_timer_ctr == 0); + printf("Re-enabling\n"); + esp_intr_enable(ih); + vTaskDelay(1000 / portTICK_PERIOD_MS); + printf("Timer val after 1 sec: %d\n", int_timer_ctr); + TEST_ASSERT(int_timer_ctr != 0); + r = esp_intr_free(ih); + TEST_ASSERT(r == ESP_OK); + printf("Done.\n"); +} + + +TEST_CASE("Intr_alloc test, CPU-local int source", "[intr_alloc]") +{ + local_timer_test(); +} + +#endif // #if __XTENSA__ diff --git a/components/hal/interrupt_controller_hal.c b/components/hal/interrupt_controller_hal.c index 9e00841fdb..f7e815beff 100644 --- a/components/hal/interrupt_controller_hal.c +++ b/components/hal/interrupt_controller_hal.c @@ -20,8 +20,10 @@ static bool is_interrupt_number_reserved(int interrupt_number) { - //TODO. Workaround to reserve interrupt number 1 for Wi-Fi and 5&8 for Bluetooth. - if (interrupt_number == 1 || interrupt_number == 5 || interrupt_number == 8) { + // Workaround to reserve interrupt number 1 for Wi-Fi, 5,8 for Bluetooth, 6 for "permanently disabled interrupt" + // [TODO: IDF-2465] + const uint32_t reserved = BIT(1) | BIT(5) | BIT(6) | BIT(8); + if (reserved & BIT(interrupt_number)) { return true; } diff --git a/tools/ci/config/target-test.yml b/tools/ci/config/target-test.yml index cb7508b750..81a456d69a 100644 --- a/tools/ci/config/target-test.yml +++ b/tools/ci/config/target-test.yml @@ -573,7 +573,7 @@ UT_046: UT_C3: extends: .unit_test_c3_template - parallel: 27 + parallel: 28 tags: - ESP32C3_IDF - UT_T1_1