From 3078091b94b17ef06c57b4ba7341f7f406cc38e9 Mon Sep 17 00:00:00 2001 From: Sugar Glider Date: Wed, 20 Aug 2025 11:23:54 -0300 Subject: [PATCH 1/4] feat(rmt): adds new function to send specific number of loops Adds a new function `rmtWriteLoopingCount()` to send a specific number of times, repeating the same RMT Symbols. --- cores/esp32/esp32-hal-rmt.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cores/esp32/esp32-hal-rmt.h b/cores/esp32/esp32-hal-rmt.h index c15eadfbcd1..358bad0102a 100644 --- a/cores/esp32/esp32-hal-rmt.h +++ b/cores/esp32/esp32-hal-rmt.h @@ -124,7 +124,9 @@ bool rmtWrite(int pin, rmt_data_t *data, size_t num_rmt_symbols, uint32_t timeou bool rmtWriteAsync(int pin, rmt_data_t *data, size_t num_rmt_symbols); /** - Writing data up to the reserved memsize, looping continuously + Writing data up to the reserved memsize, looping continuously (rmtWriteLooping) or fixed + number of times (rmtWriteLoopingCount()) + is a 32 bits structure as defined by rmt_data_t type. It is possible to use the macro RMT_SYMBOLS_OF(data), if data is an array of rmt_data_t @@ -136,6 +138,7 @@ bool rmtWriteAsync(int pin, rmt_data_t *data, size_t num_rmt_symbols); will return always while it is looping. */ bool rmtWriteLooping(int pin, rmt_data_t *data, size_t num_rmt_symbols); +bool rmtWriteLoopingCount(int pin, rmt_data_t *data, size_t num_rmt_symbols, uint32_t loop_count); /** Checks if transmission is completed and the rmtChannel ready for transmitting new data. From ddf778a08954331a37b1967624858df0a65bb089 Mon Sep 17 00:00:00 2001 From: Sugar Glider Date: Wed, 20 Aug 2025 11:36:10 -0300 Subject: [PATCH 2/4] feat(rmt): adds new function to send specific number of loops Adds: bool rmtWriteLoopingCount(int pin, rmt_data_t *data, size_t num_rmt_symbols, uint32_t loop_count) It will send a pattern defined by `*data` RMT Symbols for `loop_count` times (repeated). This is different from `rmtWriteLooping()`, which will repeat it for ever (endless looping). --- cores/esp32/esp32-hal-rmt.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/cores/esp32/esp32-hal-rmt.c b/cores/esp32/esp32-hal-rmt.c index 7bca1a1b529..12b9dcc459f 100644 --- a/cores/esp32/esp32-hal-rmt.c +++ b/cores/esp32/esp32-hal-rmt.c @@ -285,8 +285,7 @@ bool rmtDeinit(int pin) { return false; } -static bool _rmtWrite(int pin, rmt_data_t *data, size_t num_rmt_symbols, bool blocking, bool loop, uint32_t timeout_ms) { - rmt_bus_handle_t bus = _rmtGetBus(pin, __FUNCTION__); +static bool _rmtWrite(int pin, rmt_data_t *data, size_t num_rmt_symbols, bool blocking, uint32_t loop, uint32_t timeout_ms) { rmt_bus_handle_t bus = _rmtGetBus(pin, __FUNCTION__); if (bus == NULL) { return false; } @@ -308,6 +307,10 @@ static bool _rmtWrite(int pin, rmt_data_t *data, size_t num_rmt_symbols, bool bl "GPIO: %d - Currently in Loop Mode: [%s] | Asked to Loop: %s, LoopCancel: %s", pin, bus->rmt_ch_is_looping ? "YES" : "NO", loop ? "YES" : "NO", loopCancel ? "YES" : "NO" ); + // loop == 1 means infinite loop. + if (loop > 1) { + log_v("GPIO: %d - Loop count: %lu times", pin, loop); + } if ((xEventGroupGetBits(bus->rmt_events) & RMT_FLAG_TX_DONE) == 0) { log_v("GPIO %d - RMT Write still pending to be completed.", pin); @@ -336,8 +339,8 @@ static bool _rmtWrite(int pin, rmt_data_t *data, size_t num_rmt_symbols, bool bl bus->rmt_ch_is_looping = false; } else { // new writing | looping request // looping | Writing over a previous looping state is valid - if (loop) { - transmit_cfg.loop_count = -1; // enable infinite loop mode + if (loop) { + transmit_cfg.loop_count = (loop == 1) ? -1 : loop; // keeps RMT_FLAG_TX_DONE set - it never changes } else { // looping mode never sets this flag (IDF 5.1) in the callback @@ -349,7 +352,8 @@ static bool _rmtWrite(int pin, rmt_data_t *data, size_t num_rmt_symbols, bool bl log_w("GPIO %d - RMT Transmission failed.", pin); } else { // transmit OK if (loop) { - bus->rmt_ch_is_looping = true; // for ever... until a channel canceling or new writing + bus->rmt_ch_is_looping = true; // for ever... until a channel canceling or new writing. + // NOTE: even if loop count is finite number } else { if (blocking) { // wait for transmission confirmation | timeout @@ -402,15 +406,20 @@ static bool _rmtRead(int pin, rmt_data_t *data, size_t *num_rmt_symbols, bool wa } bool rmtWrite(int pin, rmt_data_t *data, size_t num_rmt_symbols, uint32_t timeout_ms) { - return _rmtWrite(pin, data, num_rmt_symbols, true /*blocks*/, false /*looping*/, timeout_ms); + return _rmtWrite(pin, data, num_rmt_symbols, true /*blocks*/, 0 /*looping*/, timeout_ms); } bool rmtWriteAsync(int pin, rmt_data_t *data, size_t num_rmt_symbols) { - return _rmtWrite(pin, data, num_rmt_symbols, false /*blocks*/, false /*looping*/, 0 /*N/A*/); + return _rmtWrite(pin, data, num_rmt_symbols, false /*blocks*/, 0 /*looping*/, 0 /*N/A*/); } bool rmtWriteLooping(int pin, rmt_data_t *data, size_t num_rmt_symbols) { - return _rmtWrite(pin, data, num_rmt_symbols, false /*blocks*/, true /*looping*/, 0 /*N/A*/); + return _rmtWrite(pin, data, num_rmt_symbols, false /*blocks*/, 1 /*looping*/, 0 /*N/A*/); +} + +// Same as rmtWriteLooping(...) but limits number of loops to "loop_count" +bool rmtWriteLoopingCount(int pin, rmt_data_t *data, size_t num_rmt_symbols, uint32_t loop_count) { + return _rmtWrite(pin, data, num_rmt_symbols, false /*blocks*/, loop_count /*looping*/, 0 /*N/A*/); } bool rmtTransmitCompleted(int pin) { From a9fe74d7c09024f24ea7c8054684e70e7d8b40b0 Mon Sep 17 00:00:00 2001 From: Sugar Glider Date: Wed, 20 Aug 2025 11:38:48 -0300 Subject: [PATCH 3/4] fix(rmt): bad code formatting --- cores/esp32/esp32-hal-rmt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cores/esp32/esp32-hal-rmt.c b/cores/esp32/esp32-hal-rmt.c index 12b9dcc459f..6db65659c8a 100644 --- a/cores/esp32/esp32-hal-rmt.c +++ b/cores/esp32/esp32-hal-rmt.c @@ -285,7 +285,8 @@ bool rmtDeinit(int pin) { return false; } -static bool _rmtWrite(int pin, rmt_data_t *data, size_t num_rmt_symbols, bool blocking, uint32_t loop, uint32_t timeout_ms) { rmt_bus_handle_t bus = _rmtGetBus(pin, __FUNCTION__); +static bool _rmtWrite(int pin, rmt_data_t *data, size_t num_rmt_symbols, bool blocking, uint32_t loop, uint32_t timeout_ms) { + rmt_bus_handle_t bus = _rmtGetBus(pin, __FUNCTION__); if (bus == NULL) { return false; } From 5413697d9c74a2993e83217b2420d0c9b2148210 Mon Sep 17 00:00:00 2001 From: Sugar Glider Date: Wed, 20 Aug 2025 11:39:35 -0300 Subject: [PATCH 4/4] fix(rmt): bad code formatting --- cores/esp32/esp32-hal-rmt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cores/esp32/esp32-hal-rmt.c b/cores/esp32/esp32-hal-rmt.c index 6db65659c8a..b42eb0589b0 100644 --- a/cores/esp32/esp32-hal-rmt.c +++ b/cores/esp32/esp32-hal-rmt.c @@ -340,7 +340,7 @@ static bool _rmtWrite(int pin, rmt_data_t *data, size_t num_rmt_symbols, bool bl bus->rmt_ch_is_looping = false; } else { // new writing | looping request // looping | Writing over a previous looping state is valid - if (loop) { + if (loop) { transmit_cfg.loop_count = (loop == 1) ? -1 : loop; // keeps RMT_FLAG_TX_DONE set - it never changes } else {