esp32 s2 riscv ulp stuck

mbalci
Posts: 16
Joined: Fri May 13, 2016 11:54 am

esp32 s2 riscv ulp stuck

Postby mbalci » Wed Nov 16, 2022 5:56 am

Hi,
I was testing the existing ulp riscv interrupt sample for the esp32s2, i just added to it a led blink code to see a blink from ulp riscv before going to halt mode. it works 1 or 3 times ,then freezes.;
here is the code (Board is esp32 s2 Mini ) ESP IDF rel 5.0
https://www.wemos.cc/en/latest/_static/ ... v1.0.0.pdf
ulp

Code: Select all

#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include "ulp_riscv.h"
#include "ulp_riscv_utils.h"
#include "ulp_riscv_gpio.h"


int main (void)
{
   ulp_riscv_gpio_init(15);
   ulp_riscv_gpio_set_output_mode(15,RTCIO_MODE_OUTPUT);
   ulp_riscv_gpio_output_enable(15);
   ulp_riscv_gpio_output_level(15,1);
   /* Wakeup interrupt is a level interrupt, wait 1 sec to
      allow user to release button to avoid waking up the ULP multiple times */
   ulp_riscv_delay_cycles(1000*1000 * ULP_RISCV_CYCLES_PER_US);
   ulp_riscv_gpio_output_level(15,0);
   ulp_riscv_gpio_wakeup_clear();
   ulp_riscv_delay_cycles(100 * ULP_RISCV_CYCLES_PER_US);
   ulp_riscv_wakeup_main_processor();
   /* ulp_riscv_halt() is called automatically when main exits */
   return 0;
}

ESP32S2 Code

Code: Select all

#include <stdio.h>
#include "esp_sleep.h"
#include "soc/sens_reg.h"
#include "driver/gpio.h"
#include "ulp_riscv.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#define WAKEUP_PIN 0

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(void);

static void wakeup_gpio_init(void)
{
    /* Configure the button GPIO as input, enable wakeup */
    gpio_config_t config = {
            .pin_bit_mask = BIT64(WAKEUP_PIN),
            .mode = GPIO_MODE_INPUT,
            .pull_up_en = 1
    };
    ESP_ERROR_CHECK(gpio_config(&config));
    gpio_wakeup_enable(WAKEUP_PIN, GPIO_INTR_LOW_LEVEL);
    gpio_hold_en(WAKEUP_PIN);
}

void app_main(void)
{
    esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
    /* not a wakeup from ULP, load the firmware */
    if (cause != ESP_SLEEP_WAKEUP_ULP) {
        printf("Not a ULP-RISC-V wakeup, initializing it! \n");
        wakeup_gpio_init();
        init_ulp_program();
    }

    if (cause == ESP_SLEEP_WAKEUP_ULP) {
        printf("ULP-RISC-V woke up the main CPU! \n");
    }

    /* Go back to sleep, only the ULP Risc-V will run */
    printf("Entering in deep sleep\n\n");

    /* Small delay to ensure the messages are printed */
    vTaskDelay(100);

    /* RTC peripheral power domain needs to be kept on to detect
       the GPIO state change */
    esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);

    ESP_ERROR_CHECK( esp_sleep_enable_ulp_wakeup());
    esp_deep_sleep_start();
}

static void init_ulp_program(void)
{
    esp_err_t err = ulp_riscv_load_binary(ulp_main_bin_start, (ulp_main_bin_end - ulp_main_bin_start));
    ESP_ERROR_CHECK(err);

    /* Start the program */
    ulp_riscv_cfg_t cfg = {
        .wakeup_source = ULP_RISCV_WAKEUP_SOURCE_GPIO,
    };

    err = ulp_riscv_config_and_run(&cfg);
    ESP_ERROR_CHECK(err);
}
if i remove this line from the ulp riscv code ;

Code: Select all

  ulp_riscv_delay_cycles(100 * ULP_RISCV_CYCLES_PER_US);
it works 7 out of 10 times then freezes again....

i really dont see a reason why it freezes.
any help welcome.

while(1);
Posts: 18
Joined: Mon May 02, 2022 9:03 pm

Re: esp32 s2 riscv ulp stuck

Postby while(1); » Fri Nov 17, 2023 3:02 pm

I'm having the same issue - Have you found the solution? I came up with a similar application for this discussion. I would like to run this code in an infinite loop while the main CPU is running and not in sleep mode. I'm using the ESP32-S2-Saola-1 module and PlatformIO. I tried many fixes I found here and have had no luck. I'm probably not implementing the fixes properly. I'm fairly certain I have to POKE some ulp register bits.

ESP32 app_main:

Code: Select all

#include <stdio.h>
#include "esp_sleep.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 "ulp_riscv.h"
#include "ulp_main.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.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(void);

void app_main(void)
{

    vTaskDelay(100);
    printf("Initializing ULP-RISC-V program! \n");
    init_ulp_program();
    vTaskDelay(100);

    printf("Entering main loop.\n\n");

    for (;;)
    {
        vTaskDelay(100);
        printf("Loop\n");
    }
}

static void init_ulp_program(void)
{
    esp_err_t err = ulp_riscv_load_binary(ulp_main_bin_start, (ulp_main_bin_end - ulp_main_bin_start));
    ESP_ERROR_CHECK(err);

    /* Start the program */
    err = ulp_riscv_run();
    ESP_ERROR_CHECK(err);
    printf("Done initializing ULP-RISC-V program! \n");
}
ULP RISC-V main:

Code: Select all

#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include "ulp_riscv.h"
#include "../../ulp_core/include/ulp_riscv_utils.h"
#include "../../ulp_core/include/ulp_riscv_gpio.h"

#define SAMPLE_IO GPIO_NUM_4

int main(void)
{
    ulp_riscv_gpio_init(SAMPLE_IO);
    ulp_riscv_gpio_output_enable(SAMPLE_IO);
    ulp_riscv_gpio_set_output_mode(SAMPLE_IO, RTCIO_MODE_OUTPUT);
    ulp_riscv_gpio_pullup(SAMPLE_IO);
    ulp_riscv_gpio_pulldown_disable(SAMPLE_IO);
    ulp_riscv_gpio_output_level(SAMPLE_IO, 1);

    for (;;)
    {
        ulp_riscv_delay_cycles(10 * ULP_RISCV_CYCLES_PER_MS);
        ulp_riscv_gpio_output_level(SAMPLE_IO, 0);
        ulp_riscv_delay_cycles(10 * ULP_RISCV_CYCLES_PER_MS);
        ulp_riscv_gpio_output_level(SAMPLE_IO, 1);
    }
    /* ulp_riscv_halt() is called automatically when main exits */
    return 0;
}

djixon
Posts: 113
Joined: Sun Oct 01, 2023 7:48 pm

Re: esp32 s2 riscv ulp stuck

Postby djixon » Sat Nov 18, 2023 10:31 am

Did you try it without letting the main CPU to go to sleep? Did you try to make pin configuration by main CPU, by calling rtc_blabla_blabla functions for that GPIO setup and then start ULP program without that GPIO initialization at ULP part of code? Do you know, that you can declare a global variable in ULP main.c module lets say uint32_t my_var and write to it let's say some integer after each line of ULP program in that infinite loop, then in your main.c part in another infinite loop (of main CPU), read that variable and if value is different from previous reading write it to console log.That way you can actually follow execution of each line of that infinite loop in ULP. The ULP processor can not write upper 16 bits in such a variable because it is stored in RTC memory and ULP has only 16 bits wide registers (actually, by hardware design, it will store address of instruction which performed writing to such memory location, in upper 16 bits), so, you can refer to that variable as extern (from you main.c part of code you will declare: extern uint32_t my_var), mask lower 16 bits to see number you populated into it after each line of code (for example you write some counter which you can increment after each line and store to that variable), but also extract upper 16 bits to see what was the last instruction (address of instruction) writing to it, and LOG that output too, to see where it actually stucks. I also see that you hard-coded number 15 instead GPIO15. Check docs for ESP32S2 to see if GPIO15 is defined as pin 15 or some other value ... that, at least, can explain why do you not measuring any change on GPIO15 pad output. But that shouldn't impact on stuck behavior. Also, in sdkconfig, make sure all WDT are turned off (and at first, try to make it work without deep sleep) until you manage it works. Once you get that, try make it working in sleep too. Check the configuration of bit settings for a GPIO when it has to "work" in sleep mode. You have to enable those configuration bits in corresponding GPIO register which will NOT turn off GPIO pad to save power in sleep mode.

while(1);
Posts: 18
Joined: Mon May 02, 2022 9:03 pm

Re: esp32 s2 riscv ulp stuck

Postby while(1); » Mon Nov 20, 2023 4:47 pm

Thanks for your suggestions. You helped me figure it out. See this thread:
viewtopic.php?f=12&t=36859&p=123646#p123646

When I added the variable and printed it from app_main It wasn't behaving as expected. So, I cleaned the project and it started working. I was changing the delay value but I was seeing no impact on the count -- until I cleaned and rebuilt.

Thanks for your suggestions. I got it working with the counter and then added in the IO.

Thanks,

Mike.

Who is online

Users browsing this forum: No registered users and 77 guests