8000 RMT.loop doesn't work for ESP32-S3 · Issue #11213 · micropython/micropython · GitHub
[go: up one dir, main page]

Skip to content

RMT.loop doesn't work for ESP32-S3 #11213

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

Closed
IcedRooibos opened this issue Apr 7, 2023 · 3 comments
Closed

RMT.loop doesn't work for ESP32-S3 #11213

IcedRooibos opened this issue Apr 7, 2023 · 3 comments
Labels

Comments

@IcedRooibos
Copy link
Contributor

Running this code on the ESP32 vs ESP32-S3 gives different results (pin changed for ESP32-S3).

import esp32
from machine import Pin

r = esp32.RMT(0, pin=Pin(2), clock_div=255)
r.loop(1)
r.write_pulses((32767, 32767)) 

On the ESP32 it will continue to loop as expected, on the S3 it will just write the pulses one time.

Hardware ESP32: ESP32 DEVKIT V1
Hardware ESP32S3: LuatOS ESP32-S3 running MicroPython v1.19.1-995-g0a3600a9a on 2023-03-31; ESP32S3 module (spiram octal) with ESP32S3

@IcedRooibos IcedRooibos added the bug label Apr 7, 2023
@IcedRooibos
Copy link
Contributor Author

I've found a fix for the S3. But not sure if it breaks something for other boards? There seems to be some history/old changes on looping issues for RMT.

Link to code

If self.loop_en was true then loop mode was disabled, then the pulses were written, then loop mode was enabled again.

    if (self->loop_en) {
        bool loop_en;
        check_esp_err(rmt_get_tx_loop_mode(self->channel_id, &loop_en));
        if (loop_en) {
            check_esp_err(rmt_set_tx_intr_en(self->channel_id, true));
            check_esp_err(rmt_set_tx_loop_mode(self->channel_id, false));
        }
        check_esp_err(rmt_wait_tx_done(self->channel_id, portMAX_DELAY));
    }

    check_esp_err(rmt_write_items(self->channel_id, self->items, num_items, false));

    if (self->loop_en) {
        check_esp_err(rmt_set_tx_intr_en(self->channel_id, false));
        check_esp_err(rmt_set_tx_loop_mode(self->channel_id, true));
    }

I changed the order of the code so that the pulses were written after loop mode was enabled again. Works fine now.

    if (self->loop_en) {
        bool loop_en;
        check_esp_err(rmt_get_tx_loop_mode(self->channel_id, &loop_en));
        if (loop_en) {
            check_esp_err(rmt_set_tx_intr_en(self->channel_id, true));
            check_esp_err(rmt_set_tx_loop_mode(self->channel_id, false));
        }
        check_esp_err(rmt_wait_tx_done(self->channel_id, portMAX_DELAY));
    }

    if (self->loop_en) {
        check_esp_err(rmt_set_tx_intr_en(self->channel_id, false));
        check_esp_err(rmt_set_tx_loop_mode(self->channel_id, true));
    }

    check_esp_err(rmt_write_items(self->channel_id, self->items, num_items, false));

I'm curious - why was this implemented the way it was?

Firmware binary attached in case anyone needs it (GENERIC_S3_SPIRAM_OCT version) but use at your own risk.
firmware-rmt-esp32s3-loop.zip

@IcedRooibos
Copy link
Contributor Author
IcedRooibos commented Apr 13, 2023

Here's a copy of the firmware compiled for the original ESP32 as well (BOARD=GENERIC)
esp32-rmt-loop-fix.zip

I've tested it using the following code:

import esp32
from machine import Pin

r = esp32.RMT(0, pin=Pin(2), clock_div=255)
r.loop(1)
r.write_pulses((32767, 32767)) 

to toggle the built-in LED on GPIO2 and it turns it on and off in a loop so it works fine on the original ESP32 as well.

video.mp4

@IcedRooibos
Copy link
Contributor Author

Fixed: 7ea06a3

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

No branches or pull requests

1 participant
0