Page 1 of 1

ESP32 Interrupts on lowest level - assembly/C

Posted: Mon Mar 28, 2022 10:57 pm
by kmopsuy
Hello, from few days im trying out to create and register an iterrupt in esp32(2core-xtensa) in lowest possible level.

I was able to reduce interrupt registering to few commands:
gpio_intr_enable(GPIO_NUM_25);
intr_matrix_set(xPortGetCoreID(), source, 13);
xt_set_interrupt_handler(13, asm_isr_handler, 0);
xt_ints_on(1<<13);

And now i would like to break them down even further, i have few questions:
1. Im having big trouble with figuring out what "intr_matrix_set" does. How can i replace it with asm/C write to reg code?
2. How does "xt_set_interrupt_handler" hooks up interrupts?

Code: Select all

#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "driver/gpio.h"
#include "driver/i2s.h"
#include "freertos/queue.h"

//This is the magic file.
#include "soc/gpio_struct.h"

// moje lib
#include "esp_err.h"
#include "esp_log.h"
#include "esp_intr_alloc.h"
#include "esp_attr.h"
#include "hal/cpu_hal.h"
#include "hal/interrupt_controller_hal.h"

#include "soc/gpio_reg.h"
#include "soc/dport_reg.h"

void IRAM_ATTR asm_isr_handler( void * attr );

void app_main(void) {
    gpio_pad_select_gpio(GPIO_NUM_25);
    gpio_set_direction(GPIO_NUM_25, GPIO_MODE_INPUT);
    gpio_set_pull_mode(GPIO_NUM_25, GPIO_PULLUP_ONLY);


    gpio_set_intr_type(GPIO_NUM_25, GPIO_INTR_POSEDGE);
    gpio_intr_enable(GPIO_NUM_25);
    
    intr_matrix_set(xPortGetCoreID(), source, 13);  		// ROM function ??? how to replace it with asm/C write to reg code?
    xt_set_interrupt_handler(13, asm_isr_handler, 0);   	// replaces handler and arg in xtensa_intr_asm.S ?
    xt_ints_on(1<<13);  							// ESP_INTR_ENABLE(13);
    
    while(1) {
	vTaskDelay(50);
    }
    
}
I managed to find that there are some INTENABLE and INTERRUPTS special register.
I tried to view their content but none of them changed after calling "intr_matrix_set"

Code: Select all

#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "driver/gpio.h"
#include "driver/i2s.h"
#include "freertos/queue.h"

//This is the magic file.
#include "soc/gpio_struct.h"

// moje lib
#include "esp_err.h"
#include "esp_log.h"
#include "esp_intr_alloc.h"
#include "esp_attr.h"
#include "hal/cpu_hal.h"
#include "hal/interrupt_controller_hal.h"

#include "soc/gpio_reg.h"
#include "soc/dport_reg.h"

volatile unsigned int zmiennaRob = 0;
    
void app_main(void) {
    asm volatile("rsr.intenable  a15");
    asm volatile("movi a14, zmiennaRob");
    asm volatile("s32i a15, a14, 0");
    asm volatile("rsync");
    printf("zmiennaRob: %d\n", zmiennaRob);

    intr_matrix_set(xPortGetCoreID(), source, 13);  // ROM function intr_matrix_set

    asm volatile("rsync");
    asm volatile("rsr.intenable  a15");
    asm volatile("movi a14, zmiennaRob");
    asm volatile("s32i a15, a14, 0");
    printf("zmiennaRob: %d\n", zmiennaRob);
    
    while(1) {
	vTaskDelay(50);
    }
}

When i tried to disassemble file and find out "intr_matrix_set" instructions i go this:

Code: Select all

  intr_matrix_set(1, 22, 13);
400d0cbf:	dc0c      	movi.n	a12, 13
400d0cc1:	6b1c      	movi.n	a11, 22
400d0cc3:	01a0a2        	movi	a10, 1
400d0cc6:	fcd681        	l32r	a8, 400d0020 <_stext>
400d0cc9:	0008e0        	callx8	a8

Thanks in advance.