Skip to content

Commit

Permalink
Fixes RMT filter & idle timing and setup (#8359)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
SuGlider committed Jul 20, 2023
1 parent 065ced1 commit 3162e94
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 17 deletions.
33 changes: 28 additions & 5 deletions cores/esp32/esp32-hal-rmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "driver/gpio.h"
#include "driver/rmt_tx.h"
#include "driver/rmt_rx.h"
#include "hal/rmt_ll.h"

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

#if !CONFIG_DISABLE_HAL_LOCKS
SemaphoreHandle_t g_rmt_objlocks; // Channel Semaphore Lock
Expand Down Expand Up @@ -210,7 +212,7 @@ bool rmtSetCarrier(int pin, bool carrier_en, bool carrier_level, uint32_t freque
return retCode;
}

bool rmtSetFilter(int pin, uint8_t filter_pulse_ns)
bool rmtSetRxMinThreshold(int pin, uint8_t filter_pulse_ticks)
{
rmt_bus_handle_t bus = _rmtGetBus(pin, __FUNCTION__);
if (bus == NULL) {
Expand All @@ -221,13 +223,23 @@ bool rmtSetFilter(int pin, uint8_t filter_pulse_ns)
return false;
}

uint32_t filter_pulse_ns = (1000000000 / bus->frequency_Hz) * filter_pulse_ticks;
// RMT_LL_MAX_FILTER_VALUE is 255 for ESP32, S2, S3, C3, C6 and H2;
// filter_pulse_ticks is 8 bits, thus it will not exceed 255
#if 0 // for the future, in case some other SoC has different limit
if (filter_pulse_ticks > RMT_LL_MAX_FILTER_VALUE) {
log_e("filter_pulse_ticks is too big. Max = %d", RMT_LL_MAX_FILTER_VALUE);
return false;
}
#endif

RMT_MUTEX_LOCK(bus);
bus->signal_range_min_ns = filter_pulse_ns; // set zero to disable it
RMT_MUTEX_UNLOCK(bus);
return true;
}

bool rmtSetRxThreshold(int pin, uint16_t value)
bool rmtSetRxMaxThreshold(int pin, uint16_t idle_thres_ticks)
{
rmt_bus_handle_t bus = _rmtGetBus(pin, __FUNCTION__);
if (bus == NULL) {
Expand All @@ -238,8 +250,17 @@ bool rmtSetRxThreshold(int pin, uint16_t value)
return false;
}

uint32_t idle_thres_ns = (1000000000 / bus->frequency_Hz) * idle_thres_ticks;
// RMT_LL_MAX_IDLE_VALUE is 65535 for ESP32,S2 and 32767 for S3, C3, C6 and H2
#if RMT_LL_MAX_IDLE_VALUE < 65535 // idle_thres_ticks is 16 bits anyway - save some bytes
if (idle_thres_ticks > RMT_LL_MAX_IDLE_VALUE) {
log_e("idle_thres_ticks is too big. Max = %ld", RMT_LL_MAX_IDLE_VALUE);
return false;
}
#endif

RMT_MUTEX_LOCK(bus);
bus->signal_range_max_ns = value; // set as zero to disable it
bus->signal_range_max_ns = idle_thres_ns;
RMT_MUTEX_UNLOCK(bus);
return true;
}
Expand Down Expand Up @@ -462,10 +483,12 @@ bool rmtInit(int pin, rmt_ch_dir_t channel_direction, rmt_reserve_memsize_t mem_
goto Err;
}

// store the RMT Freq to check Filter and Idle valid values in the RMT API
bus->frequency_Hz = frequency_Hz;
// pulses with width smaller than min_ns will be ignored (as a glitch)
bus->signal_range_min_ns = 1000000000 / (frequency_Hz * 2); // 1/2 pulse width
bus->signal_range_min_ns = 0; // disabled
// RMT stops reading if the input stays idle for longer than max_ns
bus->signal_range_max_ns = (1000000000 / frequency_Hz) * 10; // 10 pulses width
bus->signal_range_max_ns = (1000000000 / frequency_Hz) * RMT_LL_MAX_IDLE_VALUE; // maximum possible
// creates the event group to control read_done and write_done
bus->rmt_events = xEventGroupCreate();
if (bus->rmt_events == NULL) {
Expand Down
17 changes: 9 additions & 8 deletions cores/esp32/esp32-hal-rmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,14 +177,14 @@ bool rmtReadAsync(int pin, rmt_data_t* data, size_t *num_rmt_symbols);
bool rmtReceiveCompleted(int pin);

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

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

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

/**
Deinitializes the driver and releases all allocated memory
Expand Down
8 changes: 4 additions & 4 deletions libraries/ESP32/examples/RMT/RMTLoopback/RMTLoopback.ino
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ rmt_data_t data[256];

static EventGroupHandle_t events;

#define RMT_FREQ 10000000
#define RMT_FREQ 10000000 // tick time is 100ns
#define RMT_NUM_EXCHANGED_DATA 30

void setup() {
Expand All @@ -51,10 +51,10 @@ void setup() {
Serial.println("init receiver failed\n");
}

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

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

0 comments on commit 3162e94

Please sign in to comment.