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.
Is there a way to reset an RMT channel if the buffer has been filled?
Re: Is there a way to reset an RMT channel if the buffer has been filled?
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.
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.
Re: Is there a way to reset an RMT channel if the buffer has been filled?
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.
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.
Re: Is there a way to reset an RMT channel if the buffer has been filled?
Unable to transmit on channel 0 after receive has filled the buffer.
Re: Is there a way to reset an RMT channel if the buffer has been filled?
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.
rmt_memory_rw_rst either alone or inside rmt_rx_start(rmt_rx.channel, 1); changes the error code.
Re: Is there a way to reset an RMT channel if the buffer has been filled?
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.
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.
Re: Is there a way to reset an RMT channel if the buffer has been filled?
Changes from what to what?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.
Re: Is there a way to reset an RMT channel if the buffer has been filled?
Can't you set threshold filter to prevent that?jcsbanks wrote: It should never arise unless a much higher frequency than I need to read is input
Re: Is there a way to reset an RMT channel if the buffer has been filled?
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.
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.
Re: Is there a way to reset an RMT channel if the buffer has been filled?
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
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