From bb9639bd2b6a3f0959df35573d7896e3105ca907 Mon Sep 17 00:00:00 2001 From: Eren Terzioglu Date: Fri, 22 Aug 2025 10:29:13 +0200 Subject: [PATCH] Docs/xtensa/esp32[-s2|-s3]: Add ULP RISC-V Coprocessor docs for esp32[-s2|-s3] Add ULP RISC-V Coprocessor docs for esp32[-s2|-s3] Signed-off-by: Eren Terzioglu --- .../esp32s2/boards/esp32s2-saola-1/index.rst | 41 +++++ .../platforms/xtensa/esp32s2/index.rst | 161 +++++++++++++++++ .../esp32s3/boards/esp32s3-devkit/index.rst | 41 +++++ .../boards/esp32s3-devkit/ulp_riscv_blink.bin | Bin 0 -> 140 bytes .../platforms/xtensa/esp32s3/index.rst | 164 ++++++++++++++++++ 5 files changed, 407 insertions(+) create mode 100755 Documentation/platforms/xtensa/esp32s3/boards/esp32s3-devkit/ulp_riscv_blink.bin diff --git a/Documentation/platforms/xtensa/esp32s2/boards/esp32s2-saola-1/index.rst b/Documentation/platforms/xtensa/esp32s2/boards/esp32s2-saola-1/index.rst index 15110fe53d0..0173dbe2e96 100644 --- a/Documentation/platforms/xtensa/esp32s2/boards/esp32s2-saola-1/index.rst +++ b/Documentation/platforms/xtensa/esp32s2/boards/esp32s2-saola-1/index.rst @@ -621,6 +621,47 @@ the ``Device Drivers -> CAN Driver Support -> CAN loopback mode`` option and run SJW: 3 ID: 1 DLC: 1 +ulp +--- + +This configuration enables the support for the ULP RISC-V core coprocessor. +To get more information about LP Core please check :ref:`ULP LP Core Coprocessor docs. ` + +Configuration uses a pre-built binary in ``Documentation/platforms/xtensa/esp32s3/boards/esp32s3-devkit/ulp_riscv_blink.bin`` +which is a blink example for GPIO0. After flashing operation, GPIO0 pin will blink. + +Prebuild binary runs this code: + +.. code-block:: C + + #include + #include + #include + #include "ulp_riscv.h" + #include "ulp_riscv_utils.h" + #include "ulp_riscv_gpio.h" + + #define GPIO_PIN 0 + + #define nop() __asm__ __volatile__ ("nop") + + bool gpio_level_previous = true; + + int main (void) + { + while (1) + { + ulp_riscv_gpio_output_level(GPIO_PIN, gpio_level_previous); + gpio_level_previous = !gpio_level_previous; + for (int i = 0; i < 10000; i++) + { + nop(); + } + } + + return 0; + } + watchdog -------- diff --git a/Documentation/platforms/xtensa/esp32s2/index.rst b/Documentation/platforms/xtensa/esp32s2/index.rst index f0394902fa2..2b6e11af7a4 100644 --- a/Documentation/platforms/xtensa/esp32s2/index.rst +++ b/Documentation/platforms/xtensa/esp32s2/index.rst @@ -821,6 +821,167 @@ to ``Application image secondary slot``. and change usage mode to ``Release`` in `System Type --> Application Image Configuration --> Enable usage mode`. **After disabling UART Download Mode you will not be able to flash other images through UART.** +.. _esp32s2_ulp: + +ULP RISC-V Coprocessor +====================== + +The ULP RISC-V core is a 32-bit coprocessor integrated into the ESP32-S2 SoC. +It is designed to run independently of the main high-performance (HP) core and is capable of executing lightweight tasks +such as GPIO polling, simple peripheral control and I/O interactions. + +This coprocessor benefits to offload simple tasks from HP core (e.g., GPIO polling , I2C operations, basic control logic) and +frees the main CPU for higher-level processing + +For more information about ULP RISC-V Coprocessor `check here `__. + +Features of the ULP RISC-V Coprocessor +-------------------------------------- + +* Processor Architecture + - RV32IMC RISC-V core — Integer (I), Multiplication/Division (M), and Compressed (C) instructions + - Runs at 17.5 MHz +* Memory + - Access to 8 KB of RTC slow memory (RTC_SLOW_MEM) memory region, and registers in RTC_CNTL, RTC_IO, and SARADC peripherals +* Debugging + - Logging via bit-banged UART + - Shared memory for state inspection + - Panic or exception handlers can trigger wake-up or signal to main CPU if main CPU is in sleep +* Peripheral support + - RTC domain peripherals (RTC GPIO, RTC I2C, ADC) + +Loading Binary into ULP RISC-V Coprocessor +------------------------------------------ + +There are two ways to load a binary into LP-Core: + - Using a prebuilt binary + - Using NuttX internal build system to build your own (bare-metal) application + +When using a prebuilt binary, the already compiled output for the ULP system whether built from NuttX +or the ESP-IDF environment can be leveraged. However, whenever the ULP code needs to be modified, it must be rebuilt separately, +and the resulting .bin file has to be integrated into NuttX. This workflow, while compatible, can become tedious. + +With NuttX internal build system, the ULP binary code can be built and flashed from a single location. It is more convenient but +using build system has some dependencies on example side. + +Both methods requires `CONFIG_ESP32S2_ULP_COPROC_RESERVE_MEM` variable to set ULP RISC-V core and +`CONFIG_ESPRESSIF_ULP_RISCV_PROJECT_PATH` variable to set the path to the ULP project or prebuilt binary file +relative to NuttX root folder. +These variables can be set using `make menuconfig` or `kconfig-tweak` commands. + +Here is an example for enabling ULP and using a prebuilt binary for ULP RISC-V core:: + + make distclean + ./tools/configure.sh esp32s2-saola-1:nsh + kconfig-tweak --set-val CONFIG_ESP32S2_ULP_COPROC_RESERVE_MEM 8176 + kconfig-tweak --set-str CONFIG_ESPRESSIF_ULP_RISCV_PROJECT_PATH "Documentation/platforms/xtensa/esp32s3/boards/esp32s3-devkit/ulp_riscv_blink.bin" + make olddefconfig + make -j + +Creating an ULP RISC-V Coprocessor Application +---------------------------------------------- + +To use NuttX's internal build system to compile the bare-metal ULP RISC-V Coprocessor binary, check the following instructions. + +First, create a folder for the ULP source and header files. This folder is just for ULP project and it is +an independent project. Therefore, the NuttX example guide should not be followed, and no Makefile or similar +build files should be added. Also folder location could be anywhere. To include ULP folder into build +system don't forget to set `CONFIG_ESPRESSIF_ULP_RISCV_PROJECT_PATH` variable with path of the ULP project folder relative to +NuttX root folder. Instructions for setting up can be found above. + +NuttX's internal functions or POSIX calls are not supported. + +Here is an example: + +- ULP UART Snippet: + +.. code-block:: C + + #include "ulp_riscv.h" + #include "ulp_riscv_utils.h" + #include "ulp_riscv_print.h" + #include "ulp_riscv_uart_ulp_core.h" + #include "sdkconfig.h" + + static ulp_riscv_uart_t s_print_uart; + + int main (void) + { + ulp_riscv_uart_cfg_t cfg = { + .tx_pin = 0, + }; + ulp_riscv_uart_init(&s_print_uart, &cfg); + ulp_riscv_print_install((putc_fn_t)ulp_riscv_uart_putc, &s_print_uart); + + while(1) + { + ulp_riscv_print_str("Hello from the LP core!!\r\n"); + ulp_riscv_delay_cycles(1000 * ULP_RISCV_CYCLES_PER_MS); + } + + return 0; + } + +For more information about ULP RISC-V Coprocessor examples `check here `__. +After these settings follow the same steps as for any other configuration to build NuttX. Build system checks ULP project path, +adds every source and header file into project and builds it. + +To sum up, here is an complete example. `ulp_example/ulp (../ulp_example/ulp)` folder selected as example +to create a subfolder for ULP but folder that includes ULP source code can be anywhere: + +- Tree view: + +.. code-block:: text + + nuttxspace/ + ├── nuttx/ + └── apps/ + └── ulp_example/ + └── ulp/ + └── ulp_main.c + +- Contents in ulp_main.c: + +.. code-block:: C + + #include + #include + #include + #include "ulp_riscv.h" + #include "ulp_riscv_utils.h" + #include "ulp_riscv_gpio.h" + + #define GPIO_PIN 0 + + #define nop() __asm__ __volatile__ ("nop") + + bool gpio_level_previous = true; + + int main (void) + { + while (1) + { + ulp_riscv_gpio_output_level(GPIO_PIN, gpio_level_previous); + gpio_level_previous = !gpio_level_previous; + for (int i = 0; i < 10000; i++) + { + nop(); + } + } + + return 0; + } + +- Command to build:: + + make distclean + ./tools/configure.sh esp32s2-saola-1:nsh + kconfig-tweak --set-val CONFIG_ESP32S2_ULP_COPROC_RESERVE_MEM 8176 + kconfig-tweak -e CONFIG_DEV_GPIO + kconfig-tweak --set-str CONFIG_ESPRESSIF_ULP_RISCV_PROJECT_PATH "../ulp_example/ulp" + make olddefconfig + make -j + _`Managing esptool on virtual environment` ========================================== diff --git a/Documentation/platforms/xtensa/esp32s3/boards/esp32s3-devkit/index.rst b/Documentation/platforms/xtensa/esp32s3/boards/esp32s3-devkit/index.rst index fa70170112f..4a6dd901b6f 100644 --- a/Documentation/platforms/xtensa/esp32s3/boards/esp32s3-devkit/index.rst +++ b/Documentation/platforms/xtensa/esp32s3/boards/esp32s3-devkit/index.rst @@ -1151,6 +1151,47 @@ the ``Device Drivers -> CAN Driver Support -> CAN loopback mode`` option and run SJW: 3 ID: 1 DLC: 1 +ulp +--- + +This configuration enables the support for the ULP RISC-V core coprocessor. +To get more information about LP Core please check :ref:`ULP LP Core Coprocessor docs. ` + +Configuration uses a pre-built binary in ``Documentation/platforms/xtensa/esp32s3/boards/esp32s3-devkit/ulp_riscv_blink.bin`` +which is a blink example for GPIO0. After flashing operation, GPIO0 pin will blink. + +Prebuild binary runs this code: + +.. code-block:: C + + #include + #include + #include + #include "ulp_riscv.h" + #include "ulp_riscv_utils.h" + #include "ulp_riscv_gpio.h" + + #define GPIO_PIN 0 + + #define nop() __asm__ __volatile__ ("nop") + + bool gpio_level_previous = true; + + int main (void) + { + while (1) + { + ulp_riscv_gpio_output_level(GPIO_PIN, gpio_level_previous); + gpio_level_previous = !gpio_level_previous; + for (int i = 0; i < 10000; i++) + { + nop(); + } + } + + return 0; + } + usbnsh ------ diff --git a/Documentation/platforms/xtensa/esp32s3/boards/esp32s3-devkit/ulp_riscv_blink.bin b/Documentation/platforms/xtensa/esp32s3/boards/esp32s3-devkit/ulp_riscv_blink.bin new file mode 100755 index 0000000000000000000000000000000000000000..32e8f12654d871b16b4cb227e7a3350286089442 GIT binary patch literal 140 zcmWevWMB|xWc;G2V5_01!MI>y`s8+Zff>%**$({uD^}V+<8V_0T+Hpje~{SrWBd%E zKpBuK2PP1Uae-#~$~0m2c8AGrZVt?D2RL{S&2gIi{k#3-=j;x14hg%7F(|Vg;F!$b bV8_VtSN!Y$kNahuVe&GEk8aQZF#kIMQpY?U literal 0 HcmV?d00001 diff --git a/Documentation/platforms/xtensa/esp32s3/index.rst b/Documentation/platforms/xtensa/esp32s3/index.rst index 76b6be36e25..8309bdd9711 100644 --- a/Documentation/platforms/xtensa/esp32s3/index.rst +++ b/Documentation/platforms/xtensa/esp32s3/index.rst @@ -646,6 +646,170 @@ Set the attribute ``__attribute__ ((section (".ext_ram.bss")))`` to the variable This is particularly useful when the internal RAM is not enough to hold all the data. +.. _esp32s3_ulp: + +ULP RISC-V Coprocessor +====================== + +The ULP RISC-V core is a 32-bit coprocessor integrated into the ESP32-S3 SoC. +It is designed to run independently of the main high-performance (HP) core and is capable of executing lightweight tasks +such as GPIO polling, simple peripheral control and I/O interactions. + +This coprocessor benefits to offload simple tasks from HP core (e.g., GPIO polling , I2C operations, basic control logic) and +frees the main CPU for higher-level processing + +For more information about ULP RISC-V Coprocessor `check here `__. + +Features of the ULP RISC-V Coprocessor +-------------------------------------- + +* Processor Architecture + - RV32IMC RISC-V core — Integer (I), Multiplication/Division (M), and Compressed (C) instructions + - Runs at 17.5 MHz +* Memory + - Access to 8 KB of RTC slow memory (RTC_SLOW_MEM) memory region, and registers in RTC_CNTL, RTC_IO, and SARADC peripherals +* Debugging + - Logging via bit-banged UART + - Shared memory for state inspection + - Panic or exception handlers can trigger wake-up or signal to main CPU if main CPU is in sleep +* Peripheral support + - RTC domain peripherals (RTC GPIO, RTC I2C, ADC) + +Loading Binary into ULP RISC-V Coprocessor +------------------------------------------ + +There are two ways to load a binary into LP-Core: + - Using a prebuilt binary + - Using NuttX internal build system to build your own (bare-metal) application + +When using a prebuilt binary, the already compiled output for the ULP system whether built from NuttX +or the ESP-IDF environment can be leveraged. However, whenever the ULP code needs to be modified, it must be rebuilt separately, +and the resulting .bin file has to be integrated into NuttX. This workflow, while compatible, can become tedious. + +With NuttX internal build system, the ULP binary code can be built and flashed from a single location. It is more convenient but +using build system has some dependencies on example side. + +Both methods requires `CONFIG_ESP32S3_ULP_COPROC_ENABLED` and `CONFIG_ESP32S3_ULP_COPROC_RESERVE_MEM` variables to set ULP RISC-V core and +`CONFIG_ESPRESSIF_ULP_RISCV_PROJECT_PATH` variable to set the path to the ULP project or prebuilt binary file +relative to NuttX root folder. +These variables can be set using `make menuconfig` or `kconfig-tweak` commands. + +Here is an example for enabling ULP and using a prebuilt binary for ULP RISC-V core:: + + make distclean + ./tools/configure.sh esp32s3-devkit:nsh + kconfig-tweak -e CONFIG_ESP32S3_ULP_COPROC_ENABLED + kconfig-tweak --set-val CONFIG_ESP32S3_ULP_COPROC_RESERVE_MEM 8176 + kconfig-tweak --set-str CONFIG_ESPRESSIF_ULP_RISCV_PROJECT_PATH "Documentation/platforms/xtensa/esp32s3/boards/esp32s3-devkit/ulp_riscv_blink.bin" + make olddefconfig + make -j + +Creating an ULP RISC-V Coprocessor Application +---------------------------------------------- + +To use NuttX's internal build system to compile the bare-metal ULP RISC-V Coprocessor binary, check the following instructions. + +First, create a folder for the ULP source and header files. This folder is just for ULP project and it is +an independent project. Therefore, the NuttX example guide should not be followed, and no Makefile or similar +build files should be added. Also folder location could be anywhere. To include ULP folder into build +system don't forget to set `CONFIG_ESPRESSIF_ULP_RISCV_PROJECT_PATH` variable with path of the ULP project folder relative to +NuttX root folder. Instructions for setting up can be found above. + +NuttX's internal functions or POSIX calls are not supported. + +Here is an example: + +- ULP UART Snippet: + +.. code-block:: C + + #include "ulp_riscv.h" + #include "ulp_riscv_utils.h" + #include "ulp_riscv_print.h" + #include "ulp_riscv_uart_ulp_core.h" + #include "sdkconfig.h" + + static ulp_riscv_uart_t s_print_uart; + + int main (void) + { + ulp_riscv_uart_cfg_t cfg = { + .tx_pin = 0, + }; + ulp_riscv_uart_init(&s_print_uart, &cfg); + ulp_riscv_print_install((putc_fn_t)ulp_riscv_uart_putc, &s_print_uart); + + while(1) + { + ulp_riscv_print_str("Hello from the LP core!!\r\n"); + ulp_riscv_delay_cycles(1000 * ULP_RISCV_CYCLES_PER_MS); + } + + return 0; + } + +For more information about ULP RISC-V Coprocessor examples `check here `__. +After these settings follow the same steps as for any other configuration to build NuttX. Build system checks ULP project path, +adds every source and header file into project and builds it. + +To sum up, here is an complete example. `ulp_example/ulp (../ulp_example/ulp)` folder selected as example +to create a subfolder for ULP but folder that includes ULP source code can be anywhere: + +- Tree view: + +.. code-block:: text + + nuttxspace/ + ├── nuttx/ + └── apps/ + └── ulp_example/ + └── ulp/ + └── ulp_main.c + +- Contents in ulp_main.c: + +.. code-block:: C + + #include + #include + #include + #include "ulp_riscv.h" + #include "ulp_riscv_utils.h" + #include "ulp_riscv_gpio.h" + + #define GPIO_PIN 0 + + #define nop() __asm__ __volatile__ ("nop") + + bool gpio_level_previous = true; + + int main (void) + { + while (1) + { + ulp_riscv_gpio_output_level(GPIO_PIN, gpio_level_previous); + gpio_level_previous = !gpio_level_previous; + for (int i = 0; i < 10000; i++) + { + nop(); + } + } + + return 0; + } + +- Command to build:: + + make distclean + ./tools/configure.sh esp32s3-devkitc:nsh + kconfig-tweak -e CONFIG_ESP32S3_ULP_COPROC_ENABLED + kconfig-tweak --set-val CONFIG_ESP32S3_ULP_COPROC_RESERVE_MEM 8176 + kconfig-tweak -e CONFIG_DEV_GPIO + kconfig-tweak --set-str CONFIG_ESPRESSIF_ULP_RISCV_PROJECT_PATH "../ulp_example/ulp" + make olddefconfig + make -j + + _`Managing esptool on virtual environment` ==========================================