What is the diference between RMT_REG_TX_CONTI_MODE and RMT_MEM_TX_WRAP_EN mode?
Should I activate both for continuous mode? Because enabling only RMT_REG_TX_CONTI_MODE in channel config, does not activate continuous sending, while RMT_MEM_TX_WRAP_EN does.
As per my understanding, RMT_CHn_TX_THR_EVENT_INT_ENA activates RMT_CHn_TX_THR_EVENT_INT when RMT_TX_LIM_CHn entries being sent by RMT, but why RMT_MEM_TX_WRAP_EN is enabled in "rmt_set_tx_thr_intr_en" too?
I realize that activating TX_THR_EVENT_INT without wraparound mode does not make sense, but please confirm.
Also a question about RMT_TX_LIM_CHn being configured for the half of RMT channel memory.
I saw that TX_THR_EVENT_INT is triggered twice, when first half of the items were sent and again after second half. So we can say that it is triggered every RMT_TX_LIM_CHn items? Is this a normal behavior?
And according to my observations, there is only one option to stop continuous transmission: disable wraparound mode and wait for transmission end. Or disable wraparound and set zero delay after the last meaningful item. Because rmt_tx_stop function does not really stop the transmission.
RMT settings clarification
-
- Posts: 3
- Joined: Tue Dec 12, 2017 9:20 am
Re: RMT settings clarification
Hi,
I was going to ask the same question as I am also a bit confused about the functionality of the loop around mode.
As far as I can tell from reading the data sheet and playing around; the RMT_MEM_TX_WRAP_EN applies to all channels and loop around occurs at the end of transmission, i.e when any of the RMT channel buffers hits a 0 length transmission value the channel will loop back to the beginning. For some reason the interrupt that fires at the end of the transmission (RMT_CHn_TX_END_INT_ST) doens't seem to work for me with RMT_MEM_TX_WRAP_EN enabled, however the TX_THR_EVENT_INT does fire.
One thing I have been experimenting with is using the RMT_REG_TX_CONTI_MODE, which is an independent loop aorund mode for each channel. This mode only seems to work if there is at least two 0 length blocks of data at the end of the channel, e.g you only fill 62 blocks instead of 64. But the plus side is that you can independently control them for each channel. Meaning when you have filled the final blocks of data for each channel you can turn the RMT_REG_TX_CONTI_MODE off and the RMT will automatically stop sending when it hits the end 0. This mode also allows for both the RMT_CHn_TX_END_INT_ST interrupts to work as well as the TX_THR_EVENT_INT interrupt.
What I'm wondering is if there's a counter somewhere that can be reset when the end interrupt fires to try and keep everything in sync, as I've been wasting a few days trying to figure this out?
Any assistance would be appreciated.
Cheers.
I was going to ask the same question as I am also a bit confused about the functionality of the loop around mode.
As far as I can tell from reading the data sheet and playing around; the RMT_MEM_TX_WRAP_EN applies to all channels and loop around occurs at the end of transmission, i.e when any of the RMT channel buffers hits a 0 length transmission value the channel will loop back to the beginning. For some reason the interrupt that fires at the end of the transmission (RMT_CHn_TX_END_INT_ST) doens't seem to work for me with RMT_MEM_TX_WRAP_EN enabled, however the TX_THR_EVENT_INT does fire.
This is true as far as I can tell also. In my application I require multiple channels to be sending out data streams which will end at different times. With RMT_MEM_TX_WRAP_EN enabled I cannot do this, as if I disable it to end transmission for one channel whilst another is still running, it will stop all of them from looping around.And according to my observations, there is only one option to stop continuous transmission: disable wraparound mode and wait for transmission end. Or disable wraparound and set zero delay after the last meaningful item. Because rmt_tx_stop function does not really stop the transmission.
One thing I have been experimenting with is using the RMT_REG_TX_CONTI_MODE, which is an independent loop aorund mode for each channel. This mode only seems to work if there is at least two 0 length blocks of data at the end of the channel, e.g you only fill 62 blocks instead of 64. But the plus side is that you can independently control them for each channel. Meaning when you have filled the final blocks of data for each channel you can turn the RMT_REG_TX_CONTI_MODE off and the RMT will automatically stop sending when it hits the end 0. This mode also allows for both the RMT_CHn_TX_END_INT_ST interrupts to work as well as the TX_THR_EVENT_INT interrupt.
This is what happens for me, however what is annoying is that if the RMT_TX_LIM_CHn is set to half RMT memory it seems to go out of sync with the RMT_CHn_TX_END_INT_ST interrupt after a while, which means my transmitted data gets mixed up and it fails to send.Also a question about RMT_TX_LIM_CHn being configured for the half of RMT channel memory.
I saw that TX_THR_EVENT_INT is triggered twice, when first half of the items were sent and again after second half. So we can say that it is triggered every RMT_TX_LIM_CHn items? Is this a normal behavior?
What I'm wondering is if there's a counter somewhere that can be reset when the end interrupt fires to try and keep everything in sync, as I've been wasting a few days trying to figure this out?
Any assistance would be appreciated.
Cheers.
Re: RMT settings clarification
Thanks for sharing what you found out!
TX_END_INT interrupt is fired when I set to 0 value of any RMT channel memory item yet to be sent. And after that transmission is terminated.
While TX_THR_EVENTs are just activated every configured number of sent items.
At the end of interrupt handler I do RMT.int_clr.val = BIT(i) like in the "rmt_driver_isr_default" example.
I'm worried about this note. Does it mean that there will be some extra pulse/pause between transmission repetitions.
I have a slightly different behavior in RMT_MEM_TX_WRAP_EN mode.the RMT_MEM_TX_WRAP_EN applies to all channels and loop around occurs at the end of transmission, i.e when any of the RMT channel buffers hits a 0 length transmission value the channel will loop back to the beginning. For some reason the interrupt that fires at the end of the transmission (RMT_CHn_TX_END_INT_ST) doens't seem to work for me with RMT_MEM_TX_WRAP_EN enabled, however the TX_THR_EVENT_INT does fire.
TX_END_INT interrupt is fired when I set to 0 value of any RMT channel memory item yet to be sent. And after that transmission is terminated.
While TX_THR_EVENTs are just activated every configured number of sent items.
At the end of interrupt handler I do RMT.int_clr.val = BIT(i) like in the "rmt_driver_isr_default" example.
But these two items are not included to the final pulse stream?This mode only seems to work if there is at least two 0 length blocks of data at the end of the channel, e.g you only fill 62 blocks instead of 64.
Code: Select all
Note: When enabling the continuous transmission mode by setting RMT_REG_TX_CONTI_MODE, the
transmitter will transmit the data on the channel continuously, that is, from the first byte to the last one, then from
the first to the last again, and so on. In this mode, there will be an idle level lasting one clk_div cycle between N
and N+1 transmissions.
-
- Posts: 3
- Joined: Tue Dec 12, 2017 9:20 am
Re: RMT settings clarification
That sounds like how It should be, I also clear the interrupts at the end, but have tried at the beginning also and this made no difference.I have a slightly different behavior in RMT_MEM_TX_WRAP_EN mode.
TX_END_INT interrupt is fired when I set to 0 value of any RMT channel memory item yet to be sent. And after that transmission is terminated.
While TX_THR_EVENTs are just activated every configured number of sent items.
At the end of interrupt handler I do RMT.int_clr.val = BIT(i) like in the "rmt_driver_isr_default" example.
Maybe I'm mis-remembering regarding the end interrupt firing. I will have to investigate but I don't think I could get it working in my application.
No when the RMT reaches the zeros at the end of the buffer in conti mode it loops back to the beginning.But these two items are not included to the final pulse stream?
As far as I can tell this means that there will be a single RMT clock pulse of your set idle level at the end of each transmission repetition. For me as I have my RMT clock set to 80MHz (12.5ns/cycle) and my RMT divider set to 2 this gives me a 50ns pause. Which for my application should be acceptable...Note: When enabling the continuous transmission mode by setting RMT_REG_TX_CONTI_MODE, the
transmitter will transmit the data on the channel continuously, that is, from the first byte to the last one, then from
the first to the last again, and so on. In this mode, there will be an idle level lasting one clk_div cycle between N
and N+1 transmissions.
I'm worried about this note. Does it mean that there will be some extra pulse/pause between transmission repetitions.
...However one thing I am aware of is the fact the halfway interrupt seems to fire slightly after when I set it to. Maybe 3 - 4 blocks of data or so. I'm sending data quite quickly and this means that I go out of sync and miss fill blocks relatively soon. What I'm after is a way to synchronise the interrupts so I can avoid this headache.
I've set a pin to toggle on both the end and half way interrupts and logged using a logic analyser. You can see fairly clearly that the interrupts start off okay, but quickly go out of sync.
The halfway interrupt is set to 32 however this also happens when set to 31, as I am sending only 62 blocks at a time.
Shown in the gallery below:
https://imgur.com/a/4Nh7W
Could this be because of this 50ns? I don't think so... but right now I have no idea if it's fixable.
Who is online
Users browsing this forum: esp32New956832 and 95 guests