@@ -285,7 +285,7 @@ bool rmtDeinit(int pin) {
285285 return false;
286286}
287287
288- static bool _rmtWrite (int pin , rmt_data_t * data , size_t num_rmt_symbols , bool blocking , bool loop , uint32_t timeout_ms ) {
288+ static bool _rmtWrite (int pin , rmt_data_t * data , size_t num_rmt_symbols , bool blocking , uint32_t loop , uint32_t timeout_ms ) {
289289 rmt_bus_handle_t bus = _rmtGetBus (pin , __FUNCTION__ );
290290 if (bus == NULL ) {
291291 return false;
@@ -303,11 +303,21 @@ static bool _rmtWrite(int pin, rmt_data_t *data, size_t num_rmt_symbols, bool bl
303303 }
304304 }
305305
306+ #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE
306307 log_v ("GPIO: %d - Request: %d RMT Symbols - %s - Timeout: %d" , pin , num_rmt_symbols , blocking ? "Blocking" : "Non-Blocking" , timeout_ms );
307- log_v (
308- "GPIO: %d - Currently in Loop Mode: [%s] | Asked to Loop: %s, LoopCancel: %s" , pin , bus -> rmt_ch_is_looping ? "YES" : "NO" , loop ? "YES" : "NO" ,
309- loopCancel ? "YES" : "NO"
310- );
308+ // loop parameter semantics:
309+ // loop == 0: no looping (single transmission)
310+ // loop == 1: infinite looping
311+ // loop > 1: transmit the data 'loop' times
312+ {
313+ char buf [17 ]; // placeholder for up to maximum uint32_t value (4294967295) = 10 digits + " times" (6 chars) + null terminator (17 bytes)
314+ snprintf (buf , sizeof (buf ), "%lu times" , loop );
315+ log_v (
316+ "GPIO: %d - Currently in Loop Mode: [%s] | Loop Request: [%s], LoopCancel: [%s]" , pin , bus -> rmt_ch_is_looping ? "YES" : "NO" ,
317+ loop == 0 ? "NO" : (loop == 1 ? "FOREVER" : buf ), loopCancel ? "YES" : "NO"
318+ );
319+ }
320+ #endif
311321
312322 if ((xEventGroupGetBits (bus -> rmt_events ) & RMT_FLAG_TX_DONE ) == 0 ) {
313323 log_v ("GPIO %d - RMT Write still pending to be completed." , pin );
@@ -336,8 +346,8 @@ static bool _rmtWrite(int pin, rmt_data_t *data, size_t num_rmt_symbols, bool bl
336346 bus -> rmt_ch_is_looping = false;
337347 } else { // new writing | looping request
338348 // looping | Writing over a previous looping state is valid
339- if (loop ) {
340- transmit_cfg .loop_count = -1 ; // enable infinite loop mode
349+ if (loop > 0 ) {
350+ transmit_cfg .loop_count = ( loop == 1 ) ? -1 : loop ;
341351 // keeps RMT_FLAG_TX_DONE set - it never changes
342352 } else {
343353 // looping mode never sets this flag (IDF 5.1) in the callback
@@ -348,8 +358,10 @@ static bool _rmtWrite(int pin, rmt_data_t *data, size_t num_rmt_symbols, bool bl
348358 retCode = false;
349359 log_w ("GPIO %d - RMT Transmission failed." , pin );
350360 } else { // transmit OK
351- if (loop ) {
352- bus -> rmt_ch_is_looping = true; // for ever... until a channel canceling or new writing
361+ if (loop > 0 ) {
362+ // rmt_ch_is_looping is used as a flag to indicate that RMT is in looping execution in order to
363+ // be canceled whenever a new _rmtWrite() is executed while it is looping
364+ bus -> rmt_ch_is_looping = true;
353365 } else {
354366 if (blocking ) {
355367 // wait for transmission confirmation | timeout
@@ -402,15 +414,36 @@ static bool _rmtRead(int pin, rmt_data_t *data, size_t *num_rmt_symbols, bool wa
402414}
403415
404416bool rmtWrite (int pin , rmt_data_t * data , size_t num_rmt_symbols , uint32_t timeout_ms ) {
405- return _rmtWrite (pin , data , num_rmt_symbols , true /*blocks*/ , false /*looping*/ , timeout_ms );
417+ return _rmtWrite (pin , data , num_rmt_symbols , true /*blocks*/ , 0 /*looping*/ , timeout_ms );
406418}
407419
408420bool rmtWriteAsync (int pin , rmt_data_t * data , size_t num_rmt_symbols ) {
409- return _rmtWrite (pin , data , num_rmt_symbols , false /*blocks*/ , false /*looping*/ , 0 /*N/A*/ );
421+ return _rmtWrite (pin , data , num_rmt_symbols , false /*blocks*/ , 0 /*looping*/ , 0 /*N/A*/ );
410422}
411423
412424bool rmtWriteLooping (int pin , rmt_data_t * data , size_t num_rmt_symbols ) {
413- return _rmtWrite (pin , data , num_rmt_symbols , false /*blocks*/ , true /*looping*/ , 0 /*N/A*/ );
425+ return _rmtWrite (pin , data , num_rmt_symbols , false /*blocks*/ , 1 /*looping*/ , 0 /*N/A*/ );
426+ }
427+
428+ // Same as rmtWriteLooping(...) but it transmits the data a fixed number of times ("loop_count").
429+ // loop_count == 0 is invalid (no transmission); loop_count == 1 transmits once (no looping); loop_count > 1 transmits the data repeatedly (looping).
430+ bool rmtWriteRepeated (int pin , rmt_data_t * data , size_t num_rmt_symbols , uint32_t loop_count ) {
431+ if (loop_count == 0 ) {
432+ log_e ("RMT TX GPIO %d : Invalid loop_count (%u). Must be at least 1." , pin , loop_count );
433+ return false;
434+ }
435+ if (loop_count == 1 ) {
436+ // send the RMT symbols once using non-blocking write (single non-looping transmission)
437+ return _rmtWrite (pin , data , num_rmt_symbols , false /*blocks*/ , 0 /*looping*/ , 0 /*N/A*/ );
438+ } else {
439+ // write the RMT symbols for loop_count times
440+ #if SOC_RMT_SUPPORT_TX_LOOP_COUNT
441+ return _rmtWrite (pin , data , num_rmt_symbols , false /*blocks*/ , loop_count /*looping*/ , 0 /*N/A*/ );
442+ #else
443+ log_e ("RMT TX GPIO %d : Loop Count is not supported. Writing failed." , pin );
444+ return false;
445+ #endif
446+ }
414447}
415448
416449bool rmtTransmitCompleted (int pin ) {
0 commit comments