Page 1 of 1

high-level interrupt GPIO

Posted: Wed Aug 21, 2019 12:52 pm
by darthcloud
Hi Guys, first post here :)

I'm trying to get an example of GPIO interrupt with high-level interrupt to work but can't get it working properly.

Look like my interrupt never get clear which make the interrupt trigger again in loop making the CPU1 wdt trigger.
Disabling the wdt on CPU1 I can see my task not running anymore.

I looked at couple other thread on the subject:
https://esp32.com/viewtopic.php?t=8826
https://esp32.com/viewtopic.php?t=9474

Also looked at this unit test:
https://github.com/espressif/esp-idf/co ... f38425ab75

I'm running ESP-IDF top of master branch (02c7c388)

I'm a bit out of idea maybe a second pair of eyes would help :)

log:

Code: Select all

deneb[master]~/esp/esp32_highint5_gpio$ make
Toolchain path: /home/jacques/.espressif/tools/xtensa-esp32-elf/esp32-2019r1-8.2.0/xtensa-esp32-elf/bin/xtensa-esp32-elf-gcc
Toolchain version: esp32-2019r1
Compiler version: 8.2.0
Python requirements from /home/jacques/esp/esp-idf/requirements.txt are satisfied.

App "esp32_highint5_gpio" version: ba71263
CC build/app_update/esp_app_desc.o
AR build/app_update/libapp_update.a
Generating esp32.project.ld
LD build/esp32_highint5_gpio.elf
esptool.py v2.8-dev
To flash all build output, run 'make flash' or:
python /home/jacques/esp/esp-idf/components/esptool_py/esptool/esptool.py --chip esp32 --port /dev/ttyUSB1 --baud 115200 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size detect 0x1000 /home/jacques/esp/esp32_highint5_gpio/build/bootloader/bootloader.bin 0x10000 /home/jacques/esp/esp32_highint5_gpio/build/esp32_highint5_gpio.bin 0x8000 /home/jacques/esp/esp32_highint5_gpio/build/partitions_singleapp.bin
deneb[master]~/esp/esp32_highint5_gpio$ make monitor
Toolchain path: /home/jacques/.espressif/tools/xtensa-esp32-elf/esp32-2019r1-8.2.0/xtensa-esp32-elf/bin/xtensa-esp32-elf-gcc
Toolchain version: esp32-2019r1
Compiler version: 8.2.0
Python requirements from /home/jacques/esp/esp-idf/requirements.txt are satisfied.
MONITOR
--- idf_monitor on /dev/ttyUSB1 115200 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
ets Jun  8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x3e (SPI_FAST_FLASH_BOOT)
flash read err, 1000
ets_main.c 371
ets Jun  8 2016 00:22:57

rst:0x10 (RTCWDT_RTC_RESET),boot:0x3e (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:5340
load:0x40078000,len:11596
ho 0 tail 12 room 4
load:0x40080400,len:6300
entry 0x4008070c
I (134) cpu_start: Pro cpu up.
I (134) cpu_start: Application information:
I (134) cpu_start: Project name:     esp32_highint5_gpio
I (137) cpu_start: App version:      1
I (142) cpu_start: Compile time:     Aug 21 2019 08:06:03
I (148) cpu_start: ELF file SHA256:  87b64a54ff623843...
I (154) cpu_start: ESP-IDF:          v4.1-dev-58-g02c7c3885-dirty
I (161) cpu_start: Starting app cpu, entry point is 0x40081118
0x40081118: call_start_cpu1 at /home/jacques/esp/esp-idf/components/esp32/cpu_start.c:281

I (0) cpu_start: App cpu up.
I (171) heap_init: Initializing. RAM available for dynamic allocation:
I (178) heap_init: At 3FFAE6E0 len 0000F480 (61 KiB): DRAM
I (184) heap_init: At 3FFC10E0 len 0001EF20 (123 KiB): DRAM
I (190) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (197) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (203) heap_init: At 4008A618 len 000159E8 (86 KiB): IRAM
I (209) cpu_start: Pro cpu start user code
I (227) spi_flash: detected chip: generic
I (228) spi_flash: flash io: dio
I (228) cpu_start: Chip Revision: 1
W (229) cpu_start: Chip revision is higher than the one configured in menuconfig. Suggest to upgrade it.
I (239) esp_core_dump_common: Init core dump to UART
E (245) esp_core_dump_common: No core dump partition found!
I (252) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I (0) gpio: GPIO[26]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:2
cpu1_task alive
cpu1_task alive
cpu1_task alive
cpu1_task alive
ets Jun  8 2016 00:22:57

rst:0x8 (TG1WDT_SYS_RESET),boot:0x3e (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:5340
load:0x40078000,len:11596
ho 0 tail 12 room 4
load:0x40080400,len:6300
entry 0x4008070c
W (183) boot: PRO CPU has been reset by WDT.
W (183) boot: WDT reset info: PRO CPU PC=0x4008536b
0x4008536b: panicHandler at /home/jacques/esp/esp-idf/components/esp32/panic.c:247 (discriminator 1)

W (184) boot: WDT reset info: APP CPU PC=0x4008285f
0x4008285f: xt_highint5 at /home/jacques/esp/esp32_highint5_gpio/main/highint5.S:31
code:

Code: Select all

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_intr_alloc.h"
#include "driver/gpio.h"

static void cpu1_task(void *arg) {
    gpio_config_t io_conf = {
        .intr_type = GPIO_PIN_INTR_NEGEDGE,
        .pin_bit_mask = (1ULL << 26),
        .mode = GPIO_MODE_INPUT,
        .pull_down_en = GPIO_PULLDOWN_DISABLE,
        .pull_up_en = GPIO_PULLUP_DISABLE
    };

    gpio_config(&io_conf);

#if 1
    ESP_INTR_DISABLE(26);
    intr_matrix_set(1, ETS_GPIO_INTR_SOURCE, 26);
    ESP_INTR_ENABLE(26);
#else
    esp_intr_alloc(ETS_UART1_INTR_SOURCE, ESP_INTR_FLAG_LEVEL5 | ESP_INTR_FLAG_IRAM, NULL, NULL, NULL);
#endif

    while (1) {
        printf("%s alive\n", __FUNCTION__);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}

void app_main()
{
    xTaskCreatePinnedToCore(cpu1_task, "cpu1_task", 2048, NULL, 10, NULL, 1);
}

Code: Select all

#include <xtensa/coreasm.h>
#include <xtensa/corebits.h>
#include <xtensa/config/system.h>
#include "freertos/xtensa_context.h"
#include "esp_private/panic_reason.h"
#include "sdkconfig.h"
#include "soc/soc.h"
#include "soc/gpio_reg.h"
#include "soc/dport_reg.h"

#define L5_INTR_STACK_SIZE  12
#define L5_INTR_A2_OFFSET   0
#define L5_INTR_A3_OFFSET   4
#define L5_INTR_A4_OFFSET   8
    .data
_l5_intr_stack:
    .space      L5_INTR_STACK_SIZE

    .section .iram1,"ax"
    .global     xt_highint5
    .type       xt_highint5,@function
    .align      4
xt_highint5:
/* Clear interupt on GPIO26 in GPIO_STATUS_W1TC_REG */
    movi    a14, 0x3FF4404C
    movi    a15, (1<<26)
    l32i    a15, a14, 0

/* Try to force write */
    movi    a14, 0x3FF44044
    l32i    a14, a14, 0
    memw

    rsr     a0, EXCSAVE_5 // restore a0
    rfi     5

/* The linker has no reason to link in this file; all symbols it exports are already defined
   (weakly!) in the default int handler. Define a symbol here so we can use it to have the
   linker inspect this anyway. */

    .global ld_include_xt_highint5
ld_include_xt_highint5:
PS: esp_intr_alloc still doesn't work to alloc an highint5, the asm code is never called.

Code available on github:
https://github.com/darthcloud/esp32_highint5_gpio

Thanks for help,
Jacques

Re: high-level interrupt GPIO

Posted: Wed Aug 21, 2019 12:59 pm
by ESP_igrr
Hi Jacques,

In this part:
movi a14, 0x3FF4404C
movi a15, (1<<26)
l32i a15, a14, 0
did you mean s32i instead of l32i? Looks like you never write to the w1tc register, so the interrupt is not getting cleared.

Re: high-level interrupt GPIO

Posted: Wed Aug 21, 2019 1:14 pm
by darthcloud
ESP_igrr wrote:
Wed Aug 21, 2019 12:59 pm
Hi Jacques,

In this part:
movi a14, 0x3FF4404C
movi a15, (1<<26)
l32i a15, a14, 0
did you mean s32i instead of l32i? Looks like you never write to the w1tc register, so the interrupt is not getting cleared.
Dohhh , shame on me :)
It work now, thanks igrr. I think I need some sleep :)

Re: high-level interrupt GPIO

Posted: Wed Aug 21, 2019 3:05 pm
by darthcloud
ESP_igrr wrote:
Wed Aug 21, 2019 12:59 pm
Hi Jacques,

In this part:
movi a14, 0x3FF4404C
movi a15, (1<<26)
l32i a15, a14, 0
did you mean s32i instead of l32i? Looks like you never write to the w1tc register, so the interrupt is not getting cleared.
Thanks that was it :), I updated my repo for future reference: https://github.com/darthcloud/esp32_highint5_gpio

Re: high-level interrupt GPIO

Posted: Thu Aug 22, 2019 1:18 pm
by darthcloud
I disabled the watchdog on core 1 with:
# CONFIG_ESP_INT_WDT_CHECK_CPU1 is not set
# CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1 is not set

Then made an infinite loop in the highint5 interrupt.

I would expect this to only affect task on Core1, but my task on Core 0 are not running anymore. (and CPU0 watchdog dont trigger)

Is this expected?

Re: high-level interrupt GPIO

Posted: Fri Aug 23, 2019 5:08 am
by ESP_igrr
No, this won't work. You need to allow for an occasional level 4 interrupt to be triggered from CPU0, it is used as part of the DPORT bug workaround, when accessing DPORT registers.