nuttx icon indicating copy to clipboard operation
nuttx copied to clipboard

WS2812 LED driver using ESP32's RMT peripheral

Open vbenso opened this issue 3 years ago • 3 comments

Summary

This PR adds support for using the ESP32's RMT peripheral in transmission only mode. With this PR the ws2812 led driver can use ESP32's RMT peripheral to transmit data to the LEDs. Allowing an alternative to the previous method that was using SPI only.

Impact

The implementation besides adding files for the definition of the registers and communication with the peripheral, also adds some code to the esp32-devkitc.h bring_up function, following the pattern used with the already existing peripherals.

Testing

The ws2812 application from the apps repository can be used for testing. So far I've tested with up to 768 leds and there are no glitches.

Further notes

Perhaps another layer of abstraction can be built someday in order to provide a framebuffer interface for driver. https://youtu.be/rmOh9iGzwtk

vbenso avatar Sep 02 '22 16:09 vbenso

@vbenso please fix the issues reported by CI compilation. Suggestion: since it is RMT specific for WS8212 maybe it is better to rename esp32_rmt.c to esp32_rmt_ws8212.c or similar

acassis avatar Sep 02 '22 17:09 acassis

Hi Everyone, Thanks for all the comments, I've learned so much. All the style issues are already checked with checkpatch.sh. The function's prototypes have been moved to the proper places. The PIN and CHANNEL defines have been removed from the Kconfig to esp32-devkitc.h. There is still the issue with using or not modifyreg32 inside the interrupt function, will it impact in the performance somehow? Also, the values of LOGIC_ONE and LOGIC_ZERO will be moved from the RMT layer to the WS2812.

Once I finish this remaining tasks, I'll re-submit the PR. Thanks again for all the help, sorry for taking so much of your time.

vbenso avatar Sep 02 '22 20:09 vbenso

Interrupt handler for the RMT driver should not restrict the usage to a single application.

In the next days I will add a callback to the IRQ, as instructed, so the code that currently is inside the RMT's interruption will be moved to the WS2812 driver. This is allow the application specific logic to be kept outside the driver.

vbenso avatar Sep 08 '22 12:09 vbenso

Hey there @vbenso :-) Did you manage do implement the updates? How can I help? I have ESP32 + WS2812 setup ready for testing / help in development :-)

One question here: would it be possible to generate inverted pulses somehow with RMT so WS2812 gets signals over N-MOSFET transistor? It will invert signals but can interface 3.3V to 5V in case of devices that must have 5V DIO and does not accept direct 3.3V (like WS2812-MINI).

cederom avatar May 18 '23 20:05 cederom

Hey there @vbenso :-) Did you manage do implement the updates? How can I help? I have ESP32 + WS2812 setup ready for testing / help in development :-)

I thas been a while since I work with NuttX. I do remember submitting the PR, fixed many things and left the callback change for last, however couldn't manage to touch it since. I'll move the WS2812 dedicated code into the application. And in the new solution, I think a callback registered from the user's app will translate the pixels to the RMT's time words. Being called by the RMT driver's IRQ every time it needs to refill it's buffer.

One question here: would it be possible to generate inverted pulses somehow with RMT so WS2812 gets signals over N-MOSFET transistor? It will invert signals but can interface 3.3V to 5V in case of devices that must have 5V DIO and does not accept direct 3.3V (like WS2812-MINI).

With this approach the user's callback function will be able to adjust the timing and also de polarity of the output signal. The the RMT will be totally decoupled from the WS2812 and will be more generic, being able to generate other pulse sequences as well.

I'll squeeze out some time this weekend for this changes and also the fix of some other ugly things that remain in this code.

vbenso avatar Jun 13 '23 16:06 vbenso

Thank you @vbenso for the feedback and Your works :-)

  • I am working on a project right now based on ESP32 that will use WS2812 and I have custom hardware ready for testing the code (did not make it with current drivers).
  • I am working on other drivers right now, but after these are done I will get into the WS2812 part.
  • Some time ago I had ESP32+WS2812 working in MicroPython using both bitbang and RMT driver. RMT seems better, but I there was no option to use inverted signals to drive WS2812 over single MOSFET. It would be nice to have in NuttX :-)
  • RMT is amazingly fast peripheral and it would would be really nice to have it in NuttX :-)

cederom avatar Jun 13 '23 17:06 cederom

@vbenso I nice thing that I did with APA102 matrix was making a driver that see it as an ordinary LCD: https://github.com/apache/nuttx/blob/master/drivers/lcd/apa102.c

Doing this way people could create big screens with WS2812 easily

acassis avatar Jun 15 '23 22:06 acassis

Hi everyone and @gustavonihei I've just pushed another version of the RMT driver. Now it does only RMT transmition, all the processing related with the WS2812 was removed from the driver. USAGE:

  • The user opens the an RMT channel that is mapped to a GPIO pin. (/dev/rmtX for channel X);
  • User writes words (uint32_t) to this device;
  • The words are in the format described in the ESP32 Reference Manual
    • ((0x8000|tH)<<16) | (tL)) -- Where tH is time in the high state and tL is time in low state of the channel's output. -- The units are based on the clock divider set for the RMT device, currently no divider, so APB's period.

I'm considering the PR in the apps repository with a sample application @cederom .

BTW: Is there any way to include the checkpatch script in vscode?

vbenso avatar Jun 24 '23 15:06 vbenso

I can see that I've done something wrong with the git flow. Too many files changed. Any contribution about how to fix this will be very welcome.

vbenso avatar Jun 24 '23 15:06 vbenso

Hi @vbenso nice work! You need to rebase your branch with current upstream. Did you follow the documentation explaining how to create the upstream branch to refer to NuttX mainline: https://nuttx.apache.org/docs/latest/contributing/making-changes.html# ?

If so, basically all you need to do is:

$ git checkout upstream $ git pull $ git checkout your_ws2812_brach_name $ git rebase upstream $ git push -f

acassis avatar Jun 24 '23 21:06 acassis

@vbenso please fix the conflicts and update the PR to let us merge this PR

acassis avatar Jul 16 '23 17:07 acassis

Hi @acassis @cederom Is this ok?

vbenso avatar Jul 19 '23 21:07 vbenso

Hi @acassis @cederom Is this ok?

please rebase your change to resolve the conflict.

xiaoxiang781216 avatar Jul 21 '23 17:07 xiaoxiang781216

hello world i will take a look on Monday thank you! :-)

-- CeDeROM, SQ7MHZ, http://www.tomek.cedro.info

cederom avatar Jul 21 '23 17:07 cederom

@vbenso @xiaoxiang781216 after merging it I noticed some details that escaped the review: I think the RMT Debug should be inside arch/xtensa/src/esp32/Kconfig instead of /Kconfig. What do you think?

acassis avatar Jul 23 '23 19:07 acassis

@vbenso @xiaoxiang781216 after merging it I noticed some details that escaped the review: I think the RMT Debug should be inside arch/xtensa/src/esp32/Kconfig instead of /Kconfig. What do you think?

Yes, it's specific to eps32.

xiaoxiang781216 avatar Jul 24 '23 01:07 xiaoxiang781216

Hello world :-) I have created a dedicated Issue https://github.com/apache/nuttx/issues/9885 as there may be more optimization PRs required :-)

cederom avatar Jul 25 '23 01:07 cederom