Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RMT RX Filter "signal_range_min_ns" doesn't work (IDFGH-9977) #11262

Closed
3 tasks done
hamdiolgun opened this issue Apr 24, 2023 · 4 comments
Closed
3 tasks done

RMT RX Filter "signal_range_min_ns" doesn't work (IDFGH-9977) #11262

hamdiolgun opened this issue Apr 24, 2023 · 4 comments
Assignees
Labels
Resolution: NA Issue resolution is unavailable Status: Done Issue is done internally Type: Bug bugs in IDF

Comments

@hamdiolgun
Copy link

hamdiolgun commented Apr 24, 2023

Answers checklist.

  • I have read the documentation ESP-IDF Programming Guide and the issue is not addressed there.
  • I have updated my IDF branch (master or release) to the latest version and checked that the issue is present there.
  • I have searched the issue tracker for a similar issue and not found a similar issue.

IDF version.

v5.0-dev-6416-gef4b1b7704

Operating System used.

Windows

How did you build your project?

Eclipse IDE

If you are using Windows, please specify command line type.

None

Development Kit.

ESP32-WROOM32E

Power Supply used.

Battery

What is the expected behavior?

I am using RMT peripheral to communicate with other devices over HOMEBUS. There are a lot of noises on the bus, as natural.
I am trying to eliminate the noises with RMT RX filter module but i can't achieve it.
The communication baudrate 9600, and 1 bit 104us.
For Homebus, bit 0 means "52us 0-52us 1", bit 1 means "104us 1"

I set the rx config struct as;
static const rmt_receive_config_t rmt_receive_config = {
.signal_range_min_ns = (uint32_t)18 * 1000, //18us
.signal_range_max_ns = (uint32_t)104 * 12 * 1000 //~1200us
};
rmt_receive_config_t::signal_range_min_ns specifies the minimal valid pulse duration (either high or low level). A pulse whose width is smaller than this value will be treated as glitch and ignored by the hardware.
I expect that i should not get signals less than 18us by rmt_rx_done_event_data_t.
image

What is the actual behavior?

I got all signals higher than 1us by rmt_rx_done_event_data_t rx data.

Steps to reproduce.

rmt_channel_handle_t rmt_rx_channel;
const rmt_receive_config_t rmt_receive_config = {
.signal_range_min_ns = (uint32_t)18 * 1000,
.signal_range_max_ns = (uint32_t)104 * 12 * 1000
};
QueueHandle_t rmt_receive_queue;

rmt_rx_channel_config_t rx_channel_cfg = {
.gpio_num = CONFIG_IO_VRF_RX_PIN,
.clk_src = RMT_CLK_SRC_DEFAULT, //80MHz
.resolution_hz = 1000000, // 1MHz resolution, 1 tick = 1us
.mem_block_symbols = 5 * SOC_RMT_MEM_WORDS_PER_CHANNEL,
.flags.invert_in = VRF_GPIO_RX_INVERT,
.flags.with_dma = 0,
.flags.io_loop_back = 0,
};
ESP_ERROR_CHECK(rmt_new_rx_channel(&rx_channel_cfg, &rmt_rx_channel));
configASSERT(rmt_rx_channel);
rmt_receive_queue = xQueueCreate(VRF_DATA_BUF_SIZE, sizeof(rmt_rx_done_event_data_t));
configASSERT(rmt_receive_queue);
rmt_rx_event_callbacks_t rcbs = {
.on_recv_done = rmt_rx_done_callback,
};
ESP_ERROR_CHECK(rmt_rx_register_event_callbacks(rmt_rx_channel, &rcbs, rmt_receive_queue));
ESP_LOGI("RMT", "Init done.");

rmt_enable(rmt_rx_channel);
rmt_receive(rmt_rx_channel, rmt_raw_symbols, sizeof(rmt_raw_symbols), &rmt_receive_config);//ready

Debug Logs.

[0]{50, 0, 470, 1}{1, 9}
[1]{50, 0, 3, 1}{1, 0}
[2]{10, 0, 562, 1}{0, 11}
[3]{48, 0, 54, 1}{1, 1}
[4]{50, 0, 3, 1}{1, 0}
[5]{1, 0, 987, 1}{0, 19}
[6]{48, 0, 262, 1}{1, 5}
[7]{50, 0, 3, 1}{1, 0}
[8]{7, 0, 772, 1}{0, 15}
[9]{48, 0, 574, 1}{1, 11}
[10]{50, 0, 3, 1}{1, 0}
[11]{11, 0, 456, 1}{0, 9}
[12]{49, 0, 262, 1}{1, 5}
[13]{50, 0, 2, 1}{1, 0}
[14]{6, 0, 774, 1}{0, 15}

More Information.

No response

@hamdiolgun hamdiolgun added the Type: Bug bugs in IDF label Apr 24, 2023
@github-actions github-actions bot changed the title RMT RX Filter "signal_range_min_ns" doesn't work RMT RX Filter "signal_range_min_ns" doesn't work (IDFGH-9977) Apr 24, 2023
@espressif-bot espressif-bot added the Status: Opened Issue is new label Apr 24, 2023
@espressif-bot espressif-bot added Status: In Progress Work is in progress and removed Status: Opened Issue is new labels Apr 26, 2023
@suda-morris
Copy link
Collaborator

@hamdiolgun

Thanks for reporting! In fact, .signal_range_min_ns = (uint32_t)18 * 1000, //18us will result in a very large register value 1440 (which was calculated in the https://github.com/espressif/esp-idf/blob/master/components/driver/rmt/rmt_rx.c#L368). However, the underlying register is only 8bit-width, so actually what being set in the register is only 1440/256 which is only 5.

We will add a check in the driver in case the user sets a value that will lead to out-of-register-range.

Meanwhile, you can reduce the RMT clock resolution by choosing another clock source, e..g .clk_src = RMT_CLK_SRC_REF_TICK, //1MHz, then we can get a valid register value after calculation.

@hamdiolgun
Copy link
Author

@suda-morris
Thanks for your reply.
I had been realized the calculation of filter threshold.
rmt_ll_rx_set_filter_thres(hal->regs, channel_id, ((uint64_t)group->resolution_hz * config->signal_range_min_ns) / 1000000000UL);
And i've set the signal_range_min_ns according that,

rmt_rx_channel_config_t rx_channel_cfg = {
    .gpio_num = CONFIG_IO_VRF_RX_PIN,
    .clk_src = RMT_CLK_SRC_DEFAULT, //80MHz
    .resolution_hz = 1000000, // 1MHz resolution, 1 tick = 1us
    .mem_block_symbols = 5 * SOC_RMT_MEM_WORDS_PER_CHANNEL,
    .flags.invert_in = VRF_GPIO_RX_INVERT,
    .flags.with_dma = 0,
    .flags.io_loop_back = 0,
};

So,
group->resolution_hz = 1000000
config->signal_range_min_ns = 18 * 1000
filter thres = (1000000 * 18 * 1000) / 1000000000UL = 18
How did you calculated 1440 ?

Best regards

@suda-morris
Copy link
Collaborator

suda-morris commented Apr 26, 2023

So, group->resolution_hz = 1000000

This is a trap of RMT. When setting the filter threshold, we're using the RMT's "group resolution" (one group has several channels). Which by default, equals the source clock's frequency (80MHz e.g.).

https://github.com/espressif/esp-idf/blob/master/components/driver/rmt/rmt_common.c#L166

.resolution_hz = 1000000 this configuration is set the "channel resolution".

@hamdiolgun
Copy link
Author

hamdiolgun commented Apr 26, 2023

Ow sorry, i'd missed it.

So,
if i select RMT_CLK_SRC_REF_TICK (group->resolution_hz will be 1MHz) as rmt tx/rx clk_src and i set tx/rx resolution_hz as 1MHz, i will reach 1us resolution again.
Then, i can set signal_range_min_ns as 18 * 1000.
real_div will be set 1 according the configuration and all that is legal. right?

static inline void rmt_ll_rx_set_channel_clock_div(rmt_dev_t *dev, uint32_t channel, uint32_t div)

If i'm correct,
this gonna solve my filtering problem. (rmt rx gonna filter signals less than 18us)

Regards

@espressif-bot espressif-bot added Status: Reviewing Issue is being reviewed and removed Status: In Progress Work is in progress labels Apr 28, 2023
@espressif-bot espressif-bot added Status: Done Issue is done internally Resolution: NA Issue resolution is unavailable and removed Status: Reviewing Issue is being reviewed labels May 5, 2023
espressif-bot pushed a commit that referenced this issue May 7, 2023
espressif-bot pushed a commit that referenced this issue May 20, 2023
jmpmscorp added a commit to jmpmscorp/esp-sdi-12 that referenced this issue Jun 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: NA Issue resolution is unavailable Status: Done Issue is done internally Type: Bug bugs in IDF
Projects
None yet
Development

No branches or pull requests

3 participants