From 45480da94e5c5f97264882fca3c6a15c5bccb77f Mon Sep 17 00:00:00 2001 From: Rodrigo Garcia Date: Tue, 27 Jun 2023 14:42:11 -0300 Subject: [PATCH 1/7] Fixes Filter and Idle parameter to uint32 --- cores/esp32/esp32-hal-rmt.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/cores/esp32/esp32-hal-rmt.h b/cores/esp32/esp32-hal-rmt.h index a968d471377..7aa3e814e52 100644 --- a/cores/esp32/esp32-hal-rmt.h +++ b/cores/esp32/esp32-hal-rmt.h @@ -174,14 +174,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 for the time (ns) 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_ns + 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. The function returns if it is correctly executed, otherwise. */ -bool rmtSetRxThreshold(int pin, uint16_t value); +bool rmtSetRxThreshold(int pin, uint32_t idle_thres_ns); /** Parameters changed in Arduino Core 3: low and high (ticks) are now expressed in Carrier Freq in Hz and @@ -199,10 +199,10 @@ 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 - If is Zero, it will to disable the filter. + If is Zero, it will to disable the filter. The function returns if it is correctly executed, otherwise. */ -bool rmtSetFilter(int pin, uint8_t filter_level); +bool rmtSetFilter(int pin, uint32_t filter_pulse_ns); /** Deinitializes the driver and releases all allocated memory @@ -214,4 +214,4 @@ bool rmtDeinit(int pin); } #endif -#endif /* MAIN_ESP32_HAL_RMT_H_ */ \ No newline at end of file +#endif /* MAIN_ESP32_HAL_RMT_H_ */ From fa2929111c3c62cee454e4e2460c4132d09c62bc Mon Sep 17 00:00:00 2001 From: Rodrigo Garcia Date: Tue, 27 Jun 2023 14:43:28 -0300 Subject: [PATCH 2/7] Fixes Filter and Idle setup --- cores/esp32/esp32-hal-rmt.c | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/cores/esp32/esp32-hal-rmt.c b/cores/esp32/esp32-hal-rmt.c index ec1cf7b59bb..ea894d86ee7 100644 --- a/cores/esp32/esp32-hal-rmt.c +++ b/cores/esp32/esp32-hal-rmt.c @@ -16,6 +16,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" @@ -55,6 +56,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 xSemaphoreHandle g_rmt_objlocks; // Channel Semaphore Lock @@ -207,7 +209,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 rmtSetFilter(int pin, uint32_t filter_pulse_ns) { rmt_bus_handle_t bus = _rmtGetBus(pin, __FUNCTION__); if (bus == NULL) { @@ -218,13 +220,19 @@ bool rmtSetFilter(int pin, uint8_t filter_pulse_ns) return false; } + uint32_t filter_reg_value = (1000000000 / bus->frequency_Hz) * RMT_LL_MAX_FILTER_VALUE; + if (filter_pulse_ns >= filter_reg_value) { + log_e("filter_pulse_ns is too big. Max = %d", filter_reg_value); + return false; + } + 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 rmtSetRxThreshold(int pin, uint32_t idle_thres_ns) { rmt_bus_handle_t bus = _rmtGetBus(pin, __FUNCTION__); if (bus == NULL) { @@ -235,8 +243,14 @@ bool rmtSetRxThreshold(int pin, uint16_t value) return false; } + uint32_t idle_reg_value = (1000000000 / bus->frequency_Hz) * RMT_LL_MAX_IDLE_VALUE; + if (idle_thres_ns >= idle_reg_value) { + log_e("idle_thres_ns is too big. Max = %ld", idle_reg_value); + return false; + } + 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; } @@ -459,10 +473,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) { @@ -478,7 +494,11 @@ bool rmtInit(int pin, rmt_ch_dir_t channel_direction, rmt_reserve_memsize_t mem_ // TX Channel rmt_tx_channel_config_t tx_cfg; tx_cfg.gpio_num = pin; +#if CONFIG_IDF_TARGET_ESP32C6 + tx_cfg.clk_src = RMT_CLK_SRC_DEFAULT; +#else tx_cfg.clk_src = RMT_CLK_SRC_APB; +#endif tx_cfg.resolution_hz = frequency_Hz; tx_cfg.mem_block_symbols = SOC_RMT_MEM_WORDS_PER_CHANNEL * mem_size; tx_cfg.trans_queue_depth = 10; // maximum allowed @@ -503,7 +523,11 @@ bool rmtInit(int pin, rmt_ch_dir_t channel_direction, rmt_reserve_memsize_t mem_ // RX Channel rmt_rx_channel_config_t rx_cfg; rx_cfg.gpio_num = pin; +#if CONFIG_IDF_TARGET_ESP32C6 + rx_cfg.clk_src = RMT_CLK_SRC_DEFAULT; +#else rx_cfg.clk_src = RMT_CLK_SRC_APB; +#endif rx_cfg.resolution_hz = frequency_Hz; rx_cfg.mem_block_symbols = SOC_RMT_MEM_WORDS_PER_CHANNEL * mem_size; rx_cfg.flags.invert_in = 0; From 9adc276b0f8dad376d6c419d5d4bed69de61f491 Mon Sep 17 00:00:00 2001 From: Rodrigo Garcia Date: Tue, 27 Jun 2023 14:50:03 -0300 Subject: [PATCH 3/7] Fixes it to 5.1Libs branch --- cores/esp32/esp32-hal-rmt.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/cores/esp32/esp32-hal-rmt.c b/cores/esp32/esp32-hal-rmt.c index ea894d86ee7..f6dcff398c5 100644 --- a/cores/esp32/esp32-hal-rmt.c +++ b/cores/esp32/esp32-hal-rmt.c @@ -494,11 +494,7 @@ bool rmtInit(int pin, rmt_ch_dir_t channel_direction, rmt_reserve_memsize_t mem_ // TX Channel rmt_tx_channel_config_t tx_cfg; tx_cfg.gpio_num = pin; -#if CONFIG_IDF_TARGET_ESP32C6 - tx_cfg.clk_src = RMT_CLK_SRC_DEFAULT; -#else tx_cfg.clk_src = RMT_CLK_SRC_APB; -#endif tx_cfg.resolution_hz = frequency_Hz; tx_cfg.mem_block_symbols = SOC_RMT_MEM_WORDS_PER_CHANNEL * mem_size; tx_cfg.trans_queue_depth = 10; // maximum allowed @@ -523,11 +519,7 @@ bool rmtInit(int pin, rmt_ch_dir_t channel_direction, rmt_reserve_memsize_t mem_ // RX Channel rmt_rx_channel_config_t rx_cfg; rx_cfg.gpio_num = pin; -#if CONFIG_IDF_TARGET_ESP32C6 - rx_cfg.clk_src = RMT_CLK_SRC_DEFAULT; -#else rx_cfg.clk_src = RMT_CLK_SRC_APB; -#endif rx_cfg.resolution_hz = frequency_Hz; rx_cfg.mem_block_symbols = SOC_RMT_MEM_WORDS_PER_CHANNEL * mem_size; rx_cfg.flags.invert_in = 0; From e20c0bf69faeb0f57147652df4058a1832a81d03 Mon Sep 17 00:00:00 2001 From: Rodrigo Garcia Date: Tue, 18 Jul 2023 17:26:02 -0300 Subject: [PATCH 4/7] fix RMT CLK source and Filter API --- cores/esp32/esp32-hal-rmt.c | 27 +++++++++++++++++---------- cores/esp32/esp32-hal-rmt.h | 13 +++++++------ 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/cores/esp32/esp32-hal-rmt.c b/cores/esp32/esp32-hal-rmt.c index f6dcff398c5..bec3ff6f37f 100644 --- a/cores/esp32/esp32-hal-rmt.c +++ b/cores/esp32/esp32-hal-rmt.c @@ -209,7 +209,7 @@ bool rmtSetCarrier(int pin, bool carrier_en, bool carrier_level, uint32_t freque return retCode; } -bool rmtSetFilter(int pin, uint32_t filter_pulse_ns) +bool rmtSetRxMinThreshold(int pin, uint8_t filter_pulse_ticks) { rmt_bus_handle_t bus = _rmtGetBus(pin, __FUNCTION__); if (bus == NULL) { @@ -220,11 +220,15 @@ bool rmtSetFilter(int pin, uint32_t filter_pulse_ns) return false; } - uint32_t filter_reg_value = (1000000000 / bus->frequency_Hz) * RMT_LL_MAX_FILTER_VALUE; - if (filter_pulse_ns >= filter_reg_value) { - log_e("filter_pulse_ns is too big. Max = %d", filter_reg_value); + 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 @@ -232,7 +236,7 @@ bool rmtSetFilter(int pin, uint32_t filter_pulse_ns) return true; } -bool rmtSetRxThreshold(int pin, uint32_t idle_thres_ns) +bool rmtSetRxMaxThreshold(int pin, uint16_t idle_thres_ticks) { rmt_bus_handle_t bus = _rmtGetBus(pin, __FUNCTION__); if (bus == NULL) { @@ -243,11 +247,14 @@ bool rmtSetRxThreshold(int pin, uint32_t idle_thres_ns) return false; } - uint32_t idle_reg_value = (1000000000 / bus->frequency_Hz) * RMT_LL_MAX_IDLE_VALUE; - if (idle_thres_ns >= idle_reg_value) { - log_e("idle_thres_ns is too big. Max = %ld", idle_reg_value); + 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 = idle_thres_ns; @@ -494,7 +501,7 @@ bool rmtInit(int pin, rmt_ch_dir_t channel_direction, rmt_reserve_memsize_t mem_ // TX Channel rmt_tx_channel_config_t tx_cfg; tx_cfg.gpio_num = pin; - tx_cfg.clk_src = RMT_CLK_SRC_APB; + tx_cfg.clk_src = RMT_CLK_SRC_DEFAULT; tx_cfg.resolution_hz = frequency_Hz; tx_cfg.mem_block_symbols = SOC_RMT_MEM_WORDS_PER_CHANNEL * mem_size; tx_cfg.trans_queue_depth = 10; // maximum allowed @@ -519,7 +526,7 @@ bool rmtInit(int pin, rmt_ch_dir_t channel_direction, rmt_reserve_memsize_t mem_ // RX Channel rmt_rx_channel_config_t rx_cfg; rx_cfg.gpio_num = pin; - rx_cfg.clk_src = RMT_CLK_SRC_APB; + rx_cfg.clk_src = RMT_CLK_SRC_DEFAULT; rx_cfg.resolution_hz = frequency_Hz; rx_cfg.mem_block_symbols = SOC_RMT_MEM_WORDS_PER_CHANNEL * mem_size; rx_cfg.flags.invert_in = 0; diff --git a/cores/esp32/esp32-hal-rmt.h b/cores/esp32/esp32-hal-rmt.h index 7aa3e814e52..6e88af8a0f8 100644 --- a/cores/esp32/esp32-hal-rmt.h +++ b/cores/esp32/esp32-hal-rmt.h @@ -174,14 +174,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 (ns) 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_ns + 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 if it is correctly executed, otherwise. */ -bool rmtSetRxThreshold(int pin, uint32_t idle_thres_ns); +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 @@ -198,11 +198,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 + In receiving mode, channel will ignore any input pulse which width (high or low) + is smaller than If is Zero, it will to disable the filter. The function returns if it is correctly executed, otherwise. */ -bool rmtSetFilter(int pin, uint32_t filter_pulse_ns); +bool rmtSetRxMinThreshold(int pin, uint8_t filter_pulse_ticks) /** Deinitializes the driver and releases all allocated memory From 56ceb41db98ce557595b719d26de12d1ffe4d30d Mon Sep 17 00:00:00 2001 From: Rodrigo Garcia Date: Tue, 18 Jul 2023 17:37:26 -0300 Subject: [PATCH 5/7] fixes missing ; --- cores/esp32/esp32-hal-rmt.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cores/esp32/esp32-hal-rmt.h b/cores/esp32/esp32-hal-rmt.h index b9a9898aaa9..fedc75dba40 100644 --- a/cores/esp32/esp32-hal-rmt.h +++ b/cores/esp32/esp32-hal-rmt.h @@ -184,7 +184,7 @@ bool rmtReceiveCompleted(int pin); define how many low/high bits are read at the end of the received data. The function returns if it is correctly executed, otherwise. */ -bool rmtSetRxMaxThreshold(int pin, uint16_t idle_thres_ticks) +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 @@ -206,7 +206,7 @@ bool rmtSetCarrier(int pin, bool carrier_en, bool carrier_level, uint32_t freque If is Zero, it will to disable the filter. The function returns if it is correctly executed, otherwise. */ -bool rmtSetRxMinThreshold(int pin, uint8_t filter_pulse_ticks) +bool rmtSetRxMinThreshold(int pin, uint8_t filter_pulse_ticks); /** Deinitializes the driver and releases all allocated memory From 96939089d749f0a1c3066e2b0f985af1800eefdb Mon Sep 17 00:00:00 2001 From: Rodrigo Garcia Date: Tue, 18 Jul 2023 17:44:38 -0300 Subject: [PATCH 6/7] fixes missing ; --- 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 415bec65ed6..9131970a608 100644 --- a/cores/esp32/esp32-hal-rmt.c +++ b/cores/esp32/esp32-hal-rmt.c @@ -223,7 +223,7 @@ bool rmtSetRxMinThreshold(int pin, uint8_t filter_pulse_ticks) return false; } - uint32_t filter_pulse_ns = (1000000000 / bus->frequency_Hz) * filter_pulse_ticks + 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 From 28bb0b8075e83261ff5af6f45267b3ad93cdf0f5 Mon Sep 17 00:00:00 2001 From: Rodrigo Garcia Date: Tue, 18 Jul 2023 18:10:26 -0300 Subject: [PATCH 7/7] fixes RMT example --- libraries/ESP32/examples/RMT/RMTLoopback/RMTLoopback.ino | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/ESP32/examples/RMT/RMTLoopback/RMTLoopback.ino b/libraries/ESP32/examples/RMT/RMTLoopback/RMTLoopback.ino index e77a9dddabc..c2d8a18ded1 100644 --- a/libraries/ESP32/examples/RMT/RMTLoopback/RMTLoopback.ino +++ b/libraries/ESP32/examples/RMT/RMTLoopback/RMTLoopback.ino @@ -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() { @@ -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);