-
-
Notifications
You must be signed in to change notification settings - Fork 8.2k
esp32: Add the ability to disable ULP module using mpconfigport.h and ULP images built into custom builds #16469
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
Conversation
Add the ability to disable the built in ULP module using mpconfigport.h Add the ability to compile custom ULP image into the build by defining the cmake variables: ulp_app_name ulp_sources ulp_exp_dep_srcs Signed-off-by: Damian Nowacki (purewack) <bobimaster15@gmail.com>
I'm SUPER interested in learning more about RISCV ULP. Do you have an example you'd be able to share (ulp/main.c, etc...) on how you were able to do it? I'm looking into low power ADC sampling of audio for my project (https://github.com/stephanelsmith/micro-aprs) and doubly interested in getting started on RISCV. Appreciate you putting it on my radar, and hope this one gets merged! |
Sure! I will try and create an example in my fork later tonight or by tomorrow. I am using the RISCV ULP because it's simpler to understand the c code 🤣. There are similarities between the two types of ULP's but the ESP-IDF examples aren't very clear in my opinion. I had to cross reference multiple headers to find out how to use gpios in ULP c code for example. Just to be clear, I have disabled the built in FSM module in micropython in favour of my own minimal module implementation, which acts sort of like a bridge between the micropython runtime and the user-defined variables exposed through the RTC ram. Essentially I had written a system monitor for battery voltage observation as well as a custom key input mechanism but that's beyond the scope of this PR Edit: I think I will investigate this more or perhaps see If I can adapt the adc module so that it works well with RISCV adc configuration, since the esp-idf adc-example and ulp-adc-example work well already. As promised though, I have created an example in my own fork, where I modified the ESP32_GENERIC_S3 board to include an extra c module called |
I'm but a simple man, I get excited when something compiles! This is GREAT! Very much appreciated it, been thinking all day how cool it'd be to have a ulp enabled squelch. And thank you for the additional IDF examples as well. I'll definitely be digging in! In case someone hasn't already told it to you today, YOU ROCK! 👊 |
Possible override if you prefer to still use FSM ULP by specifying: `set(PREFER_FSM_ULP ON)` and appending: `boards/sdkconfig.ulp_fsm` to your `mpconfigboard.cmake` of your target board No RTC pin configuration yet, RISCV can configure its own RTC pins. FSM - I have not found a way of doing so yet without explicitly setting each pin required using ``` rtc_gpio_init(pin); rtc_gpio_set_direction(pin, RTC_GPIO_MODE_OUTPUT_ONLY); rtc_gpio_pulldown_dis(pin); rtc_gpio_pullup_dis(pin); ```
Unified interface for the ULP. `ULP.run(buffer)` will load & run the binary. (`ULP.run(entry, buffer)` on esp32) `ULP.pause()` and `ULP.resume()` functions added to start and stop the *wakeup* timer. If your ULP code is in an infinite loop, it will not be stopped on FSM as there is no ulp_halt() function. `ULP.read(address)` and `ULP.write(address,value)` will allow interacting with variables if an embedded application is used, variable addresses will abtomatically be saved and added to the ULP class, meaning you can do `ulp.read(ulp.VAR_TEST)` and `ulp.write(ulp.VAR_TEST, 12345)` addresses are relative from RTC_SLOW_MEM, but you can use the full address too.
Allow initialization of ADC and RTC pins using `ULP.rtc_init(pin)` `ULP.rtc_deinit(pin)` `ULP.adc_init(unit,channel)` During testing, it turns out that this needs to be done, so that the FSM can utilize IO. RISCV is already able to do this from its own code, however, you can still use this if you do not configure RISCV pins explicitly in the ulp code.
esp32/adc: Updated the module to use new driver (esp_adc/adc_oneshot.h). Tested and confired working state on several pins using: - esp32 - esp32 C3 - esp32 S2 - esp32 S3 I am unable to test any more hardware as I do not own it yet. esp32/ulp: Enable RISCV ULP by default on targets that support it (esp32 S2 & S3) with an option of reverting back to FSM in a custom build. To use FSM instead, add the line `set(PREFER_FSM_ULP ON)` in your board's mpconfigboard.cmake and add `boards/sdkconfig.ulp_fsm` to the end of SDKCONFIG_DEFAULTS like so: ``` set(SDKCONFIG_DEFAULTS boards/sdkconfig.base boards/sdkconfig.usb boards/sdkconfig.ble boards/sdkconfig.spiram_sx boards/ESP32_GENERIC_S3/sdkconfig.board boards/sdkconfig.ulp_fsm ) ``` To embed ULP code, define the sources and dependant files using the generated `ulp_embedded.h` file The app will always be called `ulp_embedded` internally An example board definition that uses custom ulp code located at `boards/${board}/ulp/main.c` has the following mpconfigboard.cmake ``` set(MICROPY_SOURCE_BOARD ${MICROPY_SOURCE_BOARD} ${MICROPY_BOARD_DIR}/cmodules/modtest.c ) set(ulp_embedded_sources ${MICROPY_BOARD_DIR}/ulp/main_pin.c) set(ulp_dependants ${MICROPY_BOARD_DIR}/cmodules/modtest.c) ``` The `ulp_dependants` is only needed if you have custom c modules that want to reference ULP variables directly. You can also read and write the embedded ULP variables using `ULP.read(address)` and `ULP.write(address, value)` By default, when you embed a ULP app, all c variables with the prefix `var_` will be added as constant address offsets to the ULP class, so you can call `ulp.read(ulp.VAR_TEST)` to get a value that way. I have confirmed that it *is* possible to load the binary ULP code after flashing a built in version.
The new PR #16521 might be what you were after ;) |
🤯 🤯 🤯 🤯 Indeed! |
esp32: Add the ability to compile custom ULP image into the build by defining ulp_app_name, ulp_sources, and ulp_exp_dep_srcs
Summary
I think it should be configurable to disable the ULP module, so that experimentation with the RISCV ULP can be done without causing conflicts in the esp-idf build steps, since only one type of ULP can be enabled at a time (for those chips that do have 2 types)
Testing
I have tested this by writing my own test module which uses the RISCV ULP by firstly disabling the built in ULP module. I have done the test by creating a custom board definition for testing and defining ULP specific build steps in mpconfigboard.cmake as follows: