Usage of rmt_fill_tx_items and rmt_tx_start

Ing-Dom
Posts: 15
Joined: Sun Feb 04, 2024 3:33 pm

Usage of rmt_fill_tx_items and rmt_tx_start

Postby Ing-Dom » Wed Jul 31, 2024 7:58 pm

H ithere,

I need to drive some Serial adressable RGB-LEDs (WS2813C). I use the RMT unit for that to do it as fast as possible.

Due to the histry of my project it is for both RP2040 and ESP, and I want to keep it as similar as possible.

Currently, I use a timer interrupt for setting my LEDs, so that blocked loops do not affect the LEDs.

I got RMT working, but I learned that

Code: Select all

 rmt_write_items
cannot be called from an ISR.

So, I wanted to try the other variant mentioned in the IDF docu:

Code: Select all

rmt_fill_tx_items

Code: Select all

rmt_tx_start
and

Code: Select all

rmt_tx_stop

While there is no suitable example and no further information in the IDF docu, I tried that:

Code: Select all

        rmt_fill_tx_items((rmt_channel_t)_rmtChannel, _rmtItems, _ledCount * BITS_PER_LED_CMD, 0);
        rmt_tx_start((rmt_channel_t)_rmtChannel, true);
but that ended up in a totally scrambled signal and weired behaviour of the LEDs.

So I tried that

Code: Select all

        rmt_fill_tx_items((rmt_channel_t)_rmtChannel, _rmtItems, _ledCount * BITS_PER_LED_CMD, 0);
        rmt_tx_start((rmt_channel_t)_rmtChannel, true);
        rmt_wait_tx_done((rmt_channel_t)_rmtChannel, portMAX_DELAY);
        rmt_tx_stop((rmt_channel_t)_rmtChannel);
That resulted in the correct sending of 21 out of 96 rmt_items.

Next thing I tried was using

Code: Select all

rmt_register_tx_end_callback

Code: Select all

    void tx_end_callback(rmt_channel_t channel, void* arg)
    {
        rmt_tx_stop(channel);
        digitalWrite(7, 1); // debug
    }
...
        rmt_config(&config); // ToDo Error Handling
        rmt_driver_install(config.channel, 0, 0); // ToDo Error Handling
        rmt_register_tx_end_callback(tx_end_callback, NULL);
..
but that also resulted in scrambled bits, and tx_end_callback is never called !

Could you please point me to the correct usage of that rmt lib ?
I want to trigger (without delay / non blocking) the sending of a series of rmt items (e.g. 96) from a timer isr.
It should stop the transmission an go to idle after that. How do I do that?

Ing-Dom
Posts: 15
Joined: Sun Feb 04, 2024 3:33 pm

Re: Usage of rmt_fill_tx_items and rmt_tx_start

Postby Ing-Dom » Mon Aug 05, 2024 8:28 am

no one ?

whatever I try, its not working with rmt_tx_start.

I could really use some advice :)

boarchuz
Posts: 606
Joined: Tue Aug 21, 2018 5:28 am

Re: Usage of rmt_fill_tx_items and rmt_tx_start

Postby boarchuz » Mon Aug 05, 2024 9:33 am

Could you use a very high priority task? The priority will ensure it won't be waiting on other tasks, and this way you can avoid the limitations of doing this in an ISR.

From memory there's a configuration field in RMT TX initialisation for the idle_level which should keep the output high when inactive by setting 1.

Ing-Dom
Posts: 15
Joined: Sun Feb 04, 2024 3:33 pm

Re: Usage of rmt_fill_tx_items and rmt_tx_start

Postby Ing-Dom » Wed Aug 07, 2024 5:54 am

Yes, I could switch to a task - that is plan B but requires some refactoring.

I think I can live with the limitations of rmt_tx_start (like, the limited number of rmt items).. and I really want to solve that puzzle :D

I mean, that tx end callback - it should work shouldn't it ?

Who is online

Users browsing this forum: No registered users and 318 guests