Skip to content

Commit 3162e94

Browse files
authored
Fixes RMT filter & idle timing and setup (#8359)
* Fixes Filter and Idle parameter to uint32 * Fixes Filter and Idle setup * Fixes it to 5.1Libs branch * fix RMT CLK source and Filter API * fixes missing ; * fixes missing ; * fixes RMT example
1 parent 065ced1 commit 3162e94

File tree

3 files changed

+41
-17
lines changed

3 files changed

+41
-17
lines changed

Diff for: cores/esp32/esp32-hal-rmt.c

+28-5
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "driver/gpio.h"
2020
#include "driver/rmt_tx.h"
2121
#include "driver/rmt_rx.h"
22+
#include "hal/rmt_ll.h"
2223

2324
#include "esp32-hal-rmt.h"
2425
#include "esp32-hal-periman.h"
@@ -58,6 +59,7 @@ struct rmt_obj_s {
5859
EventGroupHandle_t rmt_events; // read/write done event RMT callback handle
5960
bool rmt_ch_is_looping; // Is this RMT TX Channel in LOOPING MODE?
6061
size_t *num_symbols_read; // Pointer to the number of RMT symbol read by IDF RMT RX Done
62+
uint32_t frequency_Hz; // RMT Frequency
6163

6264
#if !CONFIG_DISABLE_HAL_LOCKS
6365
SemaphoreHandle_t g_rmt_objlocks; // Channel Semaphore Lock
@@ -210,7 +212,7 @@ bool rmtSetCarrier(int pin, bool carrier_en, bool carrier_level, uint32_t freque
210212
return retCode;
211213
}
212214

213-
bool rmtSetFilter(int pin, uint8_t filter_pulse_ns)
215+
bool rmtSetRxMinThreshold(int pin, uint8_t filter_pulse_ticks)
214216
{
215217
rmt_bus_handle_t bus = _rmtGetBus(pin, __FUNCTION__);
216218
if (bus == NULL) {
@@ -221,13 +223,23 @@ bool rmtSetFilter(int pin, uint8_t filter_pulse_ns)
221223
return false;
222224
}
223225

226+
uint32_t filter_pulse_ns = (1000000000 / bus->frequency_Hz) * filter_pulse_ticks;
227+
// RMT_LL_MAX_FILTER_VALUE is 255 for ESP32, S2, S3, C3, C6 and H2;
228+
// filter_pulse_ticks is 8 bits, thus it will not exceed 255
229+
#if 0 // for the future, in case some other SoC has different limit
230+
if (filter_pulse_ticks > RMT_LL_MAX_FILTER_VALUE) {
231+
log_e("filter_pulse_ticks is too big. Max = %d", RMT_LL_MAX_FILTER_VALUE);
232+
return false;
233+
}
234+
#endif
235+
224236
RMT_MUTEX_LOCK(bus);
225237
bus->signal_range_min_ns = filter_pulse_ns; // set zero to disable it
226238
RMT_MUTEX_UNLOCK(bus);
227239
return true;
228240
}
229241

230-
bool rmtSetRxThreshold(int pin, uint16_t value)
242+
bool rmtSetRxMaxThreshold(int pin, uint16_t idle_thres_ticks)
231243
{
232244
rmt_bus_handle_t bus = _rmtGetBus(pin, __FUNCTION__);
233245
if (bus == NULL) {
@@ -238,8 +250,17 @@ bool rmtSetRxThreshold(int pin, uint16_t value)
238250
return false;
239251
}
240252

253+
uint32_t idle_thres_ns = (1000000000 / bus->frequency_Hz) * idle_thres_ticks;
254+
// RMT_LL_MAX_IDLE_VALUE is 65535 for ESP32,S2 and 32767 for S3, C3, C6 and H2
255+
#if RMT_LL_MAX_IDLE_VALUE < 65535 // idle_thres_ticks is 16 bits anyway - save some bytes
256+
if (idle_thres_ticks > RMT_LL_MAX_IDLE_VALUE) {
257+
log_e("idle_thres_ticks is too big. Max = %ld", RMT_LL_MAX_IDLE_VALUE);
258+
return false;
259+
}
260+
#endif
261+
241262
RMT_MUTEX_LOCK(bus);
242-
bus->signal_range_max_ns = value; // set as zero to disable it
263+
bus->signal_range_max_ns = idle_thres_ns;
243264
RMT_MUTEX_UNLOCK(bus);
244265
return true;
245266
}
@@ -462,10 +483,12 @@ bool rmtInit(int pin, rmt_ch_dir_t channel_direction, rmt_reserve_memsize_t mem_
462483
goto Err;
463484
}
464485

486+
// store the RMT Freq to check Filter and Idle valid values in the RMT API
487+
bus->frequency_Hz = frequency_Hz;
465488
// pulses with width smaller than min_ns will be ignored (as a glitch)
466-
bus->signal_range_min_ns = 1000000000 / (frequency_Hz * 2); // 1/2 pulse width
489+
bus->signal_range_min_ns = 0; // disabled
467490
// RMT stops reading if the input stays idle for longer than max_ns
468-
bus->signal_range_max_ns = (1000000000 / frequency_Hz) * 10; // 10 pulses width
491+
bus->signal_range_max_ns = (1000000000 / frequency_Hz) * RMT_LL_MAX_IDLE_VALUE; // maximum possible
469492
// creates the event group to control read_done and write_done
470493
bus->rmt_events = xEventGroupCreate();
471494
if (bus->rmt_events == NULL) {

Diff for: cores/esp32/esp32-hal-rmt.h

+9-8
Original file line numberDiff line numberDiff line change
@@ -177,14 +177,14 @@ bool rmtReadAsync(int pin, rmt_data_t* data, size_t *num_rmt_symbols);
177177
bool rmtReceiveCompleted(int pin);
178178

179179
/**
180-
Function used to set a threshold for the time used to consider that a data reception has ended.
181-
In receive mode, when no edge is detected on the input signal for longer than idle_thres
182-
channel clock cycles, the receiving process is finished and the Data is made available by
180+
Function used to set a threshold (in ticks) used to consider that a data reception has ended.
181+
In receive mode, when no edge is detected on the input signal for longer than idle_thres_ticks
182+
time, the receiving process is finished and the Data is made available by
183183
the rmtRead/Async functions. Note that this time (in RMT channel frequency cycles) will also
184-
define how many low bits are read at the end of the received data.
184+
define how many low/high bits are read at the end of the received data.
185185
The function returns <true> if it is correctly executed, <false> otherwise.
186186
*/
187-
bool rmtSetRxThreshold(int pin, uint16_t value);
187+
bool rmtSetRxMaxThreshold(int pin, uint16_t idle_thres_ticks);
188188

189189
/**
190190
Parameters changed in Arduino Core 3: low and high (ticks) are now expressed in Carrier Freq in Hz and
@@ -201,11 +201,12 @@ bool rmtSetCarrier(int pin, bool carrier_en, bool carrier_level, uint32_t freque
201201

202202
/**
203203
Function used to filter input noise in the RX channel.
204-
In receiving mode, channel will ignore any input pulse which width is smaller than <filter_pulse_ns>
205-
If <filter_level> is Zero, it will to disable the filter.
204+
In receiving mode, channel will ignore any input pulse which width (high or low)
205+
is smaller than <filter_pulse_ticks>
206+
If <filter_pulse_ns> is Zero, it will to disable the filter.
206207
The function returns <true> if it is correctly executed, <false> otherwise.
207208
*/
208-
bool rmtSetFilter(int pin, uint8_t filter_level);
209+
bool rmtSetRxMinThreshold(int pin, uint8_t filter_pulse_ticks);
209210

210211
/**
211212
Deinitializes the driver and releases all allocated memory

Diff for: libraries/ESP32/examples/RMT/RMTLoopback/RMTLoopback.ino

+4-4
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ rmt_data_t data[256];
3737

3838
static EventGroupHandle_t events;
3939

40-
#define RMT_FREQ 10000000
40+
#define RMT_FREQ 10000000 // tick time is 100ns
4141
#define RMT_NUM_EXCHANGED_DATA 30
4242

4343
void setup() {
@@ -51,10 +51,10 @@ void setup() {
5151
Serial.println("init receiver failed\n");
5252
}
5353

54-
// End of transmission shall be detected when line is idle for 2us
55-
rmtSetRxThreshold(RMT_RX_PIN, 2000);
54+
// End of transmission shall be detected when line is idle for 2us = 20*100ns
55+
rmtSetRxMaxThreshold(RMT_RX_PIN, 20);
5656
// Disable Glitch filter
57-
rmtSetFilter(RMT_RX_PIN, 0);
57+
rmtSetRxMinThreshold(RMT_RX_PIN, 0);
5858

5959
Serial.println("real tick set to: 100ns");
6060
Serial.printf("\nPlease connect GPIO %d to GPIO %d, now.\n", RMT_TX_PIN, RMT_RX_PIN);

0 commit comments

Comments
 (0)