From f02dc6dd8f77ce655460b697537305c31a848873 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20de=20Giessen?= Date: Mon, 16 Feb 2026 15:27:34 +0100 Subject: [PATCH] esp32/esp32_rmt: Release GIL while waiting for TX done. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the timeout parameter of `esp32.RMT.wait_done()` is set to a non-zero value, the underlying `rmt_tx_wait_all_done` blocks (it passes the timeout to `xQueueReceive`). Thus we should release the GIL so that other MicroPython threads are not blocked from running. Signed-off-by: Daniƫl van de Giessen --- ports/esp32/esp32_rmt.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/ports/esp32/esp32_rmt.c b/ports/esp32/esp32_rmt.c index 8b77e2ac6f..3f4f6357dc 100644 --- a/ports/esp32/esp32_rmt.c +++ b/ports/esp32/esp32_rmt.c @@ -275,16 +275,24 @@ static mp_obj_t esp32_rmt_wait_done(size_t n_args, const mp_obj_t *pos_args, mp_ mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); esp32_rmt_obj_t *self = MP_OBJ_TO_PTR(args[0].u_obj); + mp_int_t timeout = args[1].u_int; if (self->pin == -1) { mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("already deinitialized")); } else if (!self->enabled) { return mp_const_true; - } else if (args[1].u_int == 0 && self->tx_ongoing > 0) { + } else if (timeout == 0 && self->tx_ongoing > 0) { // shortcut to avoid console spamming with timeout msgs by rmt_tx_wait_all_done() return mp_const_false; } - esp_err_t err = rmt_tx_wait_all_done(self->channel, args[1].u_int); + if (timeout != 0) { + MP_THREAD_GIL_EXIT(); + } + esp_err_t err = rmt_tx_wait_all_done(self->channel, timeout); + if (timeout != 0) { + MP_THREAD_GIL_ENTER(); + } + return err == ESP_OK ? mp_const_true : mp_const_false; } static MP_DEFINE_CONST_FUN_OBJ_KW(esp32_rmt_wait_done_obj, 1, esp32_rmt_wait_done);