@@ -285,7 +285,7 @@ bool rmtDeinit(int pin) {
285
285
return false;
286
286
}
287
287
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 ) {
289
289
rmt_bus_handle_t bus = _rmtGetBus (pin , __FUNCTION__ );
290
290
if (bus == NULL ) {
291
291
return false;
@@ -303,11 +303,21 @@ static bool _rmtWrite(int pin, rmt_data_t *data, size_t num_rmt_symbols, bool bl
303
303
}
304
304
}
305
305
306
+ #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE
306
307
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
311
321
312
322
if ((xEventGroupGetBits (bus -> rmt_events ) & RMT_FLAG_TX_DONE ) == 0 ) {
313
323
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
336
346
bus -> rmt_ch_is_looping = false;
337
347
} else { // new writing | looping request
338
348
// 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 ;
341
351
// keeps RMT_FLAG_TX_DONE set - it never changes
342
352
} else {
343
353
// 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
348
358
retCode = false;
349
359
log_w ("GPIO %d - RMT Transmission failed." , pin );
350
360
} 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;
353
365
} else {
354
366
if (blocking ) {
355
367
// 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
402
414
}
403
415
404
416
bool 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 );
406
418
}
407
419
408
420
bool 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*/ );
410
422
}
411
423
412
424
bool 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
+ }
414
447
}
415
448
416
449
bool rmtTransmitCompleted (int pin ) {
0 commit comments