ULP ISR Question

ns_esp
Posts: 2
Joined: Sun Jun 13, 2021 2:36 am

ULP ISR Question

Postby ns_esp » Sun Jun 13, 2021 2:58 am

Hello,
I want to use both the main core and the ULP core in the following manner:
-The ULP core will read an event input and count the number of events.
-The main core will perform other tasks, and be interrupted by the ULP core when a threshold number of events have occurred.
-When that interrupt occurs the main core will pole the some internal variables and the ULP continues to operate after triggering the interrupt..

After looking at other posts, I have adapted the ulp pulse count example as follows. The main core initializes the ULP and enters a loop where it waits one second and outputs the value of "wakes", which counts the number of times the ISR function has been called. The ULP code increments the stage counter to 20, and then triggers the wake command.

Code: Select all

#include <stdio.h>
#include "esp_sleep.h"
#include "nvs.h"
#include "nvs_flash.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/sens_reg.h"
#include "soc/rtc_periph.h"
#include "driver/gpio.h"
#include "driver/rtc_io.h"
#include "esp32/ulp.h"
#include "ulp_main.h"

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/rtc_cntl.h"


extern const uint8_t ulp_main_bin_start[] asm("_binary_ulp_main_bin_start");
extern const uint8_t ulp_main_bin_end[]   asm("_binary_ulp_main_bin_end");

static void init_ulp_program();

static void ulp_isr_handler();
static void ulp_isr_install();

int wakes;

void app_main()
{
    wakes = 0;
    ulp_isr_install();
    init_ulp_program();
    
    while(1)
    {
        //update_pulse_count();
        vTaskDelay(1000 / portTICK_PERIOD_MS);
        printf("1s: %i\n", wakes);
    }

    printf("Entering deep sleep\n\n");
    //ESP_ERROR_CHECK( esp_sleep_enable_ulp_wakeup() );
    esp_deep_sleep_start();
}

static void init_ulp_program()
{
    esp_err_t err = ulp_load_binary(0, ulp_main_bin_start,
            (ulp_main_bin_end - ulp_main_bin_start) / sizeof(uint32_t));
    ESP_ERROR_CHECK(err);

    esp_deep_sleep_disable_rom_logging(); // suppress boot messages

    /* Set ULP wake up period to T = 20ms.
     * Minimum pulse width has to be T * (ulp_debounce_counter + 1) = 80ms.
     */
    ulp_set_wakeup_period(0, 20000);

    /* Start the program */
    err = ulp_run(&ulp_entry - RTC_SLOW_MEM);
    ESP_ERROR_CHECK(err);
}

static void IRAM_ATTR ulp_isr_handler(void *args)
{
    printf("ULP interrupt: Active ---> Deepsleep\n");

    wakes++;
}

static void ulp_isr_install()
{
    ESP_ERROR_CHECK( rtc_isr_register(&ulp_isr_handler, NULL, RTC_CNTL_SAR_INT_ST_M) );
    REG_SET_BIT(RTC_CNTL_INT_ENA_REG, RTC_CNTL_ULP_CP_INT_ENA_M);
}

Code: Select all

#include "soc/rtc_cntl_reg.h"
#include "soc/rtc_io_reg.h"
#include "soc/soc_ulp.h"

	/* Define variables, which go into .bss section (zero-initialized data) */
	.bss


	/* Code goes into .text section */
	.text
	.global entry
entry:
    STAGE_RST
    jump counttime
counttime:
    wait 100
    STAGE_INC 1
    jumps wakesys, 20, EQ    
    jump counttime
wakesys:    
    wake
    wait 100
    WRITE_RTC_FIELD(RTC_CNTL_STATE0_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN, 0)
    STAGE_RST
    jump counttime
 
The ULP code is a stand-in, as I am trying to get a handle of the interrupt behavior.
So far I have encountered the following problems: since the main core does not go to sleep, the ULP command "wake" causes the code to crash ("abort() was called at PC 0x40082642 on core 0"). Removing the wake command results in the code functioning but no ISR gets triggered. What must I do for this to trigger the interrupt service routine? Why is the ULP "wake" command causing the code to crash, and how do I remedy this.

Other reference posts:
https://www.esp32.com/viewtopic.php?t=17366
https://gist.github.com/igrr/4b002047fc ... main-c-L31
viewtopic.php?f=2&t=4094

Thank you.

felmue
Posts: 37
Joined: Mon Nov 16, 2020 2:55 pm

Re: ULP ISR Question

Postby felmue » Sun Jun 13, 2021 11:05 am

Hello @ns_esp

try removing the 'printf()' from the interrupt service routine 'ulp_isr_handler()'. This should help with the crash.

Thanks
Felix

ns_esp
Posts: 2
Joined: Sun Jun 13, 2021 2:36 am

Re: ULP ISR Question

Postby ns_esp » Sun Jun 13, 2021 5:34 pm

Thank you Felix! That worked! I'd like to know the reason behind it? Are ISR's prevented from accessing UART or is this a timing issue, where the ISR is getting triggered again before the function completes its printf?

Thanks again!

felmue
Posts: 37
Joined: Mon Nov 16, 2020 2:55 pm

Re: ULP ISR Question

Postby felmue » Mon Jun 14, 2021 2:43 pm

Hello @ns_esp

you are welcome.

I found the following answer from ESP_Angus to your question here: viewtopic.php?t=3748#p17131

Thanks
Felix

Return to “ESP-IDF”

Who is online

Users browsing this forum: No registered users and 27 guests