Is there a way to reset an RMT channel if the buffer has been filled?

jcsbanks
Posts: 305
Joined: Tue Mar 28, 2017 8:03 pm

Is there a way to reset an RMT channel if the buffer has been filled?

Postby jcsbanks » Tue Mar 27, 2018 2:39 pm

rmt_rx_start(rmt_rx.channel, 1); to restart if receiving ended because there was a timeout. In my case with a continuous pulse train this is an error.

rmt_memory_rw_rst(rmt_rx.channel); to reset the buffer position after reading items. In my case I do this in a FreeRTOS task after reading the buffer.

What can be done to reset if the receive buffer has been filled? Neither of the two above work so the ESP32 has to be reset. It is an error condition, but I want to be able to handle it. It should never arise unless a much higher frequency than I need to read is input, I simply need to recover from it.

I am not using the ring buffer as it didn't work with longer idle thresholds than 11ms. I barely need 1 or 2 items, certainly not 64 or more, unless there is an error in which case I do not want the data, so I do not want to use the ring buffer.

jcsbanks
Posts: 305
Joined: Tue Mar 28, 2017 8:03 pm

Re: Is there a way to reset an RMT channel if the buffer has been filled?

Postby jcsbanks » Tue Mar 27, 2018 4:05 pm

rmt_config(&rmt_rx);
rmt_rx_start(rmt_rx.channel, 1);

Also does not restart it. I might have to try silly things like configuring it as a transmitter, or stopping and starting the driver, then trying again.

jcsbanks
Posts: 305
Joined: Tue Mar 28, 2017 8:03 pm

Re: Is there a way to reset an RMT channel if the buffer has been filled?

Postby jcsbanks » Tue Mar 27, 2018 5:18 pm

rmt_rx_stop(rmt_rx.channel);
rmt_config(&rmt_rx);
rmt_driver_install(rmt_rx.channel, 1000, 0);
rmt_driver_uninstall(rmt_rx.channel);
rmt_rx_start(rmt_rx.channel, 1);

This or variations of it do not work.

jcsbanks
Posts: 305
Joined: Tue Mar 28, 2017 8:03 pm

Re: Is there a way to reset an RMT channel if the buffer has been filled?

Postby jcsbanks » Tue Mar 27, 2018 5:39 pm

Unable to transmit on channel 0 after receive has filled the buffer.

jcsbanks
Posts: 305
Joined: Tue Mar 28, 2017 8:03 pm

Re: Is there a way to reset an RMT channel if the buffer has been filled?

Postby jcsbanks » Tue Mar 27, 2018 7:12 pm

esp_restart() doesn't even recover it. Only a reset by button.

rmt_memory_rw_rst either alone or inside rmt_rx_start(rmt_rx.channel, 1); changes the error code.

jcsbanks
Posts: 305
Joined: Tue Mar 28, 2017 8:03 pm

Re: Is there a way to reset an RMT channel if the buffer has been filled?

Postby jcsbanks » Tue Mar 27, 2018 8:11 pm

periph_module_reset(PERIPH_RMT_MODULE);
rmt_config(&rmt_rx);
rmt_rx_start(rmt_rx.channel, 1);

Finally! This allows recovery from buffer full.

Somewhat brutal to restart the whole RMT module though as would affect other channels.

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: Is there a way to reset an RMT channel if the buffer has been filled?

Postby WiFive » Tue Mar 27, 2018 8:36 pm

jcsbanks wrote:esp_restart() doesn't even recover it. Only a reset by button.

rmt_memory_rw_rst either alone or inside rmt_rx_start(rmt_rx.channel, 1); changes the error code.
Changes from what to what?

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: Is there a way to reset an RMT channel if the buffer has been filled?

Postby WiFive » Tue Mar 27, 2018 8:42 pm

jcsbanks wrote: It should never arise unless a much higher frequency than I need to read is input
Can't you set threshold filter to prevent that?

jcsbanks
Posts: 305
Joined: Tue Mar 28, 2017 8:03 pm

Re: Is there a way to reset an RMT channel if the buffer has been filled?

Postby jcsbanks » Wed Mar 28, 2018 8:56 am

Filter threshold is max 255 ticks of 80MHz already. "RMT_RX_FILTER_THRES_CHn In receive mode, channel n ignores input pulse when the pulse width is smaller than this value in APB clock periods."

Error codes are undocumented in the status register but the high byte is 03 and the low byte is the count during normal operation on channel 0 it seems. High byte changes to 0x13 when buffer is full, then 0x14 if it overfull, then 04 if you rmt_memory_rw_rst.

jhnlmn
Posts: 15
Joined: Wed Mar 03, 2021 4:22 am

Re: Is there a way to reset an RMT channel if the buffer has been filled?

Postby jhnlmn » Wed Mar 03, 2021 4:41 am

I found that changing conf0.idle_thres will make RMT on my ESP32-D0WD-V3 leave Wait state and resume RX.

uint32_t status = RMT.status_ch[RMT_CHANNEL_0];
int state = (status >> RMT_STATE_CH0_S) & RMT_STATE_CH0_V;
if(state == 4) { //4 is "Wait" state
ESP_LOGI(TAG, "rmt status %x", RMT.status_ch[RMT_CHANNEL_0]);
rmt_ll_enable_rx(&RMT, RMT_CHANNEL_0, false);
rmt_ll_reset_rx_pointer(&RMT, RMT_CHANNEL_0);
int idle_thres = RMT.conf_ch[RMT_CHANNEL_0].conf0.idle_thres;
RMT.conf_ch[RMT_CHANNEL_0].conf0.idle_thres = 0;
RMT.conf_ch[RMT_CHANNEL_0].conf0.idle_thres = idle_thres;
rmt_ll_enable_rx(&RMT, RMT_CHANNEL_0, true);
ESP_LOGI(TAG, "rmt status %x", RMT.status_ch[RMT_CHANNEL_0]);
}
This prints
I (68103) PWM: rmt status 14000040
I (68113) PWM: rmt status 1

Who is online

Users browsing this forum: MicroController and 104 guests