ULP RISC-V Blink application help.

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

ULP RISC-V Blink application help.

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

I put together this simple blink application from many different examples I found for the ULP RISC-V on the ESP32-S2. I don't think I'm missing a step from the ULP RISC-V programming guide. If it is missing here it is because I had it there and it did not seem to do anything.

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. This code builds and loads. The main core runs as I see "Loop" printing out once a second, but no output pin toggling from the copro. If I put the main CPU to sleep, I see one single 10ms pulse.

I appreciate your help.

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;
}

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

Re: ULP RISC-V Blink application help.

Postby while(1); » Fri Nov 17, 2023 9:39 pm

Here is a list of the ULP control registers after the ulp_riscv_run if this helps.

Code: Select all

  RTC_CNTL_ULP_CP_TIMER_REG = 0x80000000
RTC_CNTL_ULP_CP_TIMER_1_REG = 0x0000c800
   RTC_CNTL_ULP_CP_CTRL_REG = 0x00100200
    RTC_CNTL_COCPU_CTRL_REG = 0x010a0811
 SENS_SAR_COCPU_INT_RAW_REG = 0x00000040
 SENS_SAR_COCPU_INT_ENA_REG = 0x00000000
  SENS_SAR_COCPU_INT_ST_REG = 0x00000000
 SENS_SAR_COCPU_INT_CLR_REG = 0x00000000

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

Re: ULP RISC-V Blink application help.

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

I figured it out, though I don't understand it. In Platform IO I needed to clean the project. Once I cleaned it I could see the loop count increment and the IO line toggle. But then I initialized the loop counter and it did not take until I cleaned the project again.

It doesn't seem to need to be cleaned every time. But, that seems to clear it up if I change something with no visible outcome.

Here is my latest minimal blink program:

ESP32 main:

Code: Select all

#include <stdio.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)
{
    printf("Initializing ULP-RISC-V program! \n");
    init_ulp_program();
    printf("Entering main loop.\n\n");

    for (;;)
    {
        vTaskDelay(100);
        printf("Loop %ld\n", ulp_loop_count);
    }
}

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);
}
RISC-V ULP Main:

Code: Select all

#include <stdint.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

volatile uint32_t loop_count;

int main(void)
{
  ulp_riscv_gpio_init(SAMPLE_IO);
  ulp_riscv_gpio_output_level(SAMPLE_IO, 1);
  ulp_riscv_gpio_output_enable(SAMPLE_IO);
  loop_count = 10000;

  for (;;)
  {
    ++loop_count;

    ulp_riscv_delay_cycles(ULP_RISCV_CYCLES_PER_MS);
    ulp_riscv_gpio_output_level(SAMPLE_IO, loop_count & 0x00000001);
  }
  /* ulp_riscv_halt() is called automatically when main exits */
  return 0;
}
CMakeLists.txt for the ESP32 Main

Code: Select all

# Set usual component variables
set(COMPONENT_SRCS "ulp_riscv_example_main.c")
set(COMPONENT_ADD_INCLUDEDIRS "")
set(COMPONENT_REQUIRES soc nvs_flash ulp driver)

register_component()

#
# ULP support additions to component CMakeLists.txt.
#
# 1. The ULP app name must be unique (if multiple components use ULP).
set(ulp_app_name ulp_${COMPONENT_NAME})
#
# 2. Specify all C and Assembly source files.
#    Files should be placed into a separate directory (in this case, ulp/),
#    which should not be added to COMPONENT_SRCS.
set(ulp_riscv_sources "../ulp/main.c")

#
# 3. List all the component source files which include automatically
#    generated ULP export file, ${ulp_app_name}.h:
set(ulp_exp_dep_srcs "ulp_riscv_example_main.c")

#
# 4. Call function to build ULP binary and embed in project using the argument
#    values above.
ulp_embed_binary(${ulp_app_name} "${ulp_riscv_sources}" "${ulp_exp_dep_srcs}")

Who is online

Users browsing this forum: No registered users and 180 guests