Skip to content
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

Cannot write to IOMUX conf register from ULP-FSM on ESP32-S2/S3 (IDFGH-10966) #12158

Closed
3 tasks done
wnienhaus opened this issue Aug 30, 2023 · 3 comments
Closed
3 tasks done
Labels
Resolution: NA Issue resolution is unavailable Status: Done Issue is done internally Type: Bug bugs in IDF

Comments

@wnienhaus
Copy link

Answers checklist.

  • I have read the documentation ESP-IDF Programming Guide and the issue is not addressed there.
  • I have updated my IDF branch (master or release) to the latest version and checked that the issue is present there.
  • I have searched the issue tracker for a similar issue and not found a similar issue.

IDF version.

v5.0.3

Operating System used.

Linux

How did you build your project?

Command line with idf.py

If you are using Windows, please specify command line type.

None

Development Kit.

Waveshare ESP32-S2 dev board and LILYGO T-Display-S3

Power Supply used.

USB

What is the expected behavior?

The following, when run from the ULP-FSM, should set the SENS_IOMUX_CLK_GATE_EN bit in the SENS_SAR_IO_MUX_CONF_REG register.

WRITE_RTC_FIELD(SENS_SAR_IO_MUX_CONF_REG, SENS_IOMUX_CLK_GATE_EN, 1)

The above is for the ESP32-S2. On the ESP32-S3 the register is called SENS_SAR_PERI_CLK_GATE_CONF_REG and the field SENS_IOMUX_CLK_EN so the assembly code for the ULP is:

WRITE_RTC_FIELD(SENS_SAR_PERI_CLK_GATE_CONF_REG, SENS_IOMUX_CLK_EN, 1)

(Btw, the ESP-IDF has the exact code in an example (here), but that line has no effect. The example still works correctly, because the IOMUX clock gate was already enabled by rtc_gpio_init calls made from the main CPU before the ULP program was started)

What is the actual behavior?

In both cases (S2 and S3) the register remains unchanged when written to from ULP code (confirmed by reading the register from the main CPU).

(Note, writing to the register from code running on the main CPU works correctly)

Steps to reproduce.

  1. Create a ULP binary with the code WRITE_RTC_FIELD(SENS_SAR_IO_MUX_CONF_REG, SENS_IOMUX_CLK_GATE_EN, 1) (or equivalent for the S3).
  2. In the main app, print the contents of the SENS_SAR_IO_MUX_CONF_REG register.
  3. Then in the main app, load the ULP binary from step 1 and start (run) the ULP. Do not call any rtc_gpio_init before doing this, to keep the IOMUX clock gate disabled as per default.
  4. In the main app, after some delay (to allow the ULP code to run at least once) print the contents of the SENS_SAR_IO_MUX_CONF_REG register again.
  5. Notice the register content remains unchanged.

For comparison, try writing to the register from the main CPU:

  1. In the main app, print the contents of the SENS_SAR_IO_MUX_CONF_REG register.
  2. Then call WRITE_RTC_FIELD(SENS_SAR_IO_MUX_CONF_REG, SENS_IOMUX_CLK_GATE_EN, 1) from the main app's code. (or alternatively use SENS.sar_io_mux_conf.iomux_clk_gate_en = 1; which does the same thing)
  3. Then from the main app, print the register content again.
  4. Notice the register content has changed (if printed as binary, notice exactly 1 bit has changed to 1... as intended)

Debug Logs.

No response

More Information.

Writing to this register is needed to allow reading GPIO inputs from ULP code.

Normally with the IDF, one would rtc_gpio_init the necessary GPIO pins, which enabled the IOMUX clock gate correctly. However, I am using MicroPython, which does not expose the rtc_gpio_init function.

This has so far not been a problem with the original ESP32, because all of what rtc_gpio_init does can be achieved by ULP code to set the right flags in the right registers (e.g. to put pin into RTC mode, to set pin direction, to set pullups/-downs, etc).

However, on the S2 and S3 the IOMUX clock gate must also be enabled for GPIO input (output works fine without it). All other register writes (like setting pin direction, pull downs, etc) still work fine (confirmed by inspecting the registers and by the effect of the changes), it's only setting the IOMUX conf register that does not work.

Is this by design perhaps? Or is it a bug?

@wnienhaus wnienhaus added the Type: Bug bugs in IDF label Aug 30, 2023
@wnienhaus
Copy link
Author

There is a related issue #8720, but the accepted answer there worked only because the wakeup stub runs on the main CPU. This issue here is about code running on the ULP-FSM.

@espressif-bot espressif-bot added the Status: Opened Issue is new label Aug 30, 2023
@github-actions github-actions bot changed the title Cannot write to IOMUX conf register from ULP-FSM on ESP32-S2/S3 Cannot write to IOMUX conf register from ULP-FSM on ESP32-S2/S3 (IDFGH-10966) Aug 30, 2023
@boarchuz
Copy link
Contributor

boarchuz commented Aug 30, 2023

@wnienhaus
This is possibly related: #11652
binutils doesn't seem to be affected by this bug though so I'm not sure. You might want to take a deeper look than I have to rule it out.

@wnienhaus
Copy link
Author

Wow! Thank you so much for the fast response. That was exactly it!

I actually built my ULP binary using the micropython-esp32-ulp assembler project (to which I am a contributor), using the newly added S2/S3 support (PR pending merge: micropython/micropython-esp32-ulp#91).

We do have integration tests that compare our binary output with what binutils generates - but we didnt have an integration test for that case :).

The fix we needed was exactly what you linked to. Now our (new) integration test passes and I have also tested this on both an S2 and S3 board physically - and it works!

@espressif-bot espressif-bot added Status: Done Issue is done internally Resolution: NA Issue resolution is unavailable and removed Status: Opened Issue is new labels Aug 31, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: NA Issue resolution is unavailable Status: Done Issue is done internally Type: Bug bugs in IDF
Projects
None yet
Development

No branches or pull requests

3 participants