Skip to content

ports/esp32/ulp: Initial draft PR for RISCV ULP support S2/S3. #11572

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 13 commits into
base: master
Choose a base branch
from

Conversation

ThinkTransit
Copy link
Contributor

@ThinkTransit ThinkTransit commented May 20, 2023

The S2 and S3 chips contain a RISCV ULP co-processor in addition to the FSM ULP.

This PR is an initial attempt to provide access to the RISCV co-processor from micropython.

Operation

  1. During build cmake checks for the existence of file ports/esp32/ulp_riscv/main.c
  2. main.c is compiled and included in the micropython firmware bin file
  3. Calling ULP.riscv_load_binary() will load binary to ULP co-processor
  4. Calling ULP.riscv_run() will run RISCV ULP.

Compilation

The ULP needs to be enabled in your sdkconfig.board

CONFIG_ESP32S3_ULP_COPROC_ENABLED=y
CONFIG_ESP32S3_ULP_COPROC_RISCV=y
CONFIG_ESP32S3_ULP_COPROC_RESERVE_MEM=4096

Build micropython as normal.

Example - Blinky

Tested with IDF v4.4.4, micropython latest

ports/esp32/ulp_riscv/main.c

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

/* this variable will be exported as a public symbol, visible from main CPU: */
bool gpio_level = false;

int main (void)
{
   ulp_riscv_gpio_init(14);
   ulp_riscv_gpio_set_output_mode(14, RTCIO_MODE_OUTPUT);
   ulp_riscv_gpio_output_enable(14);

   while(1) {
   // Turn on GPIO
       ulp_riscv_gpio_output_level(14, 1);
       gpio_level = true;
   // Delay
       ulp_riscv_delay_cycles(1000 * 1000);
   // Turn off GPIO
       ulp_riscv_gpio_output_level(14, 0);
       gpio_level = false;
   // Delay
       ulp_riscv_delay_cycles(1000 * 1000);
   }

    /* ulp_riscv_halt() is called automatically when main exits */
    return 0;
}
MicroPython 3229791b6-dirty on 2023-05-20; INSIGHT_S3_GENERIC with ESP32-S3
Type "help()" for more information.
>>> import esp32
>>> ulp = esp32.ULP()
>>> ulp.riscv_load_binary()
>>> ulp.riscv_run()
>>>
>>> import machine
>>> machine.deepsleep(0)

After calling run() GPIO_14 will blink rapidly.

After entering deepsleep, GPIO_14 will continue to blink.

Sharing variables between ULP and main processor

Variables declared in the ULP code are made available in the main code using pointers to locations in the RTC memory. For example:

ULP code

bool gpio_level = false;

Micropython

>>> import esp32
>>> ulp = esp32.ULP()
>>> import machine
>>> machine.mem32[ulp.GPIO_LEVEL]
1
>>>  machine.mem32[ulp.GPIO_LEVEL] = 0
>>>

Next steps/improvements

  • Support sharing variables between ULP and main program
  • Documentation/examples
  • Move main.c ULP code to more appropriate location, possibly to board definition sub-folder?
  • Investigate if ULP programs can be compiled independently and uploaded to device, removing the need to re-flash device

Support for compiling and loading RISCV ULP code.

Signed-off-by: Patrick Joy <patrick@joytech.com.au>
…V_ULP

# Conflicts:
#	ports/esp32/esp32_ulp.c
Support for compiling and loading RISCV ULP code.

Signed-off-by: Patrick Joy <patrick@joytech.com.au>
…V_ULP

# Conflicts:
#	ports/esp32/esp32_ulp.c
Signed-off-by: Patrick Joy <patrick@joytech.com.au>
@ThinkTransit ThinkTransit changed the title ports/esp32/ulp: Initial draft PR for RISCV ULP support S2/S3 ports/esp32/ulp: Initial draft PR for RISCV ULP support S2/S3. May 22, 2023
Signed-off-by: Patrick Joy <patrick@joytech.com.au>
Signed-off-by: Patrick Joy <patrick@joytech.com.au>
Signed-off-by: Patrick Joy <patrick@joytech.com.au>
Signed-off-by: Patrick Joy <patrick@joytech.com.au>
@ThinkTransit
Copy link
Contributor Author

This PR is ready for an initial review/feedback.

RISCV ULP code is conditionally built and included in the firmware image if ulp_riscv/main.c is present.

IDF support for the RISCV ULP seems to be still relatively new/WIP. For example only the basic GPIO/ADC functions are available in V4.4.4, i2c support is not supported until v5.1 and there is no v5.1 release yet.

@ThinkTransit ThinkTransit marked this pull request as ready for review May 24, 2023 13:16
@projectgus
Copy link
Contributor

This is an automated heads-up that we've just merged a Pull Request
that removes the STATIC macro from MicroPython's C API.

See #13763

A search suggests this PR might apply the STATIC macro to some C code. If it
does, then next time you rebase the PR (or merge from master) then you should
please replace all the STATIC keywords with static.

Although this is an automated message, feel free to @-reply to me directly if
you have any questions about this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants