-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
xtensa/espressif/rmt: Implement a common RMT (Remote Control) driver for xtensa-based devices. #11428
xtensa/espressif/rmt: Implement a common RMT (Remote Control) driver for xtensa-based devices. #11428
Conversation
The RMT (Remote Control) character driver allows to use the RMT peripheral (usually, a one-wire peripheral dedicated to driving IR remote control) as a character driver. Please note that this perpiheral depends on the lower-half specific driver implementation.
Although the LED might be RGB-only, the LED data is packed in a 32-bit long variable and, then, this is the default size of a LED pixel to define the 'WS2812_RW_PIXEL_SIZE' macro. Please note that the lower-half driver will deal with the case of the addressable LED being 3 or 4-pixel sized.
The lower-half implementation of the RMT character driver based on Espressif HAL enables using the RMT peripheral of ESP32, ESP32-S2 and ESP32-S3 as a common xtensa-based Espressif driver. The RMT packages on Espressif SoCs are 4-byte long and are known as "items". Please check the Techinal Reference Manual of the chip to obtain more details.
This lower-half WS2812 LED driver uses the RMT peripheral of the Espressif's SoCs to drive the RGB addressable LEDs. Compared to the SPI-based implementation, it is faster!
By integrating the Espressif`s HAL repository into the current ESP32-S3 implementation on NuttX, it is possible to call functions that make it easier to set up the registers of the ESP32-S3 and enables the usage of common Espressif drivers. Please note that Espressif's HAL repository was already being used for the Wi-Fi driver. Then, this commit includes other source files to be used by other drivers other than Wi-Fi and reorganize the build process.
This commit use the new common RMT driver for all Espressif's xtensa-based chips on ESP32-S3.
By integrating the Espressif`s HAL repository into the current ESP32-S2 implementation on NuttX, it is possible to call functions that makes it easier to setup the registers of the ESP32-S2, enabling the usage of common Espressif drivers.
This commit use the new common RMT driver for all Espressif's xtensa-based chips on ESP32-S2.
This update has no impact on devices. The update aims to update all HAL-based devices to the same version.
but, it's good to use the vendor hal file directly |
I'm sorry, I didn't understand what you meant. Could you please elaborate a little further? |
#ifdef WS2812_HAS_WHITE | ||
# define WS2812_RW_PIXEL_SIZE 4 | ||
#else | ||
# define WS2812_RW_PIXEL_SIZE 3 | ||
#endif | ||
|
||
#ifdef CONFIG_WS2812_NON_SPI_DRIVER | ||
|
||
#else /* CONFIG_WS2812_NON_SPI_DRIVER */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @acassis !
Yes, I know (in fact, the "real" ws2812 doesn't contain 4 LEDs at all, only variants that use the same protocol and sometimes are sold as ws2812 RGBW), but the variable that the LED driver uses is 4-byte long (independent of the LED). The lower-half driver should handle that. I explained in the commit message:
Although the LED might be RGB-only, the LED data is packed in a 32-bit long variable and, then, this is the default size of a LED pixel to define the 'WS2812_RW_PIXEL_SIZE' macro. Please note that the lower-half driver will deal with the case of the addressable LED being 3 or 4-pixel sized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, understood. So maybe @vbenso was thinking that the model without white LED was 24-bit instead of 32-bit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@acassis , just to make it clearer: the model is 24-bit, but this is handled by the lower-half driver. The way the upper-half driver works on NuttX, it uses 32-bit (a word) for both RGB and RGBW models.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi guys, merry Christmas.
I didn't want to allocate 32 bits unless it was strictly required. That being said, I understand that using packed structures could degrade the performance. One could say that there is plenty of memory and people shouldn't care too much about it. In my case, I was using 700+ leds, so there were some memory concerns.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi guys, merry Christmas. I didn't want to allocate 32 bits unless it was strictly required. That being said, I understand that using packed structures could degrade the performance. One could say that there is plenty of memory and people shouldn't care too much about it. In my case, I was using 700+ leds, so there were some memory concerns.
Hi, Merry Christmas!
Yes, I understand your concerns about using a 32-bit when only 24-bit is necessary. However, no application that used the WS2812 encodes the LED pixel data in 24-bit space (this would depend on the application itself).
Even considering that the application could encode LED data in 24-bit/pixel, we still had:
#ifdef WS2812_HAS_WHITE
# define WS2812_RW_PIXEL_SIZE 4
#else
# define WS2812_RW_PIXEL_SIZE 3
#endif
with WS2812_HAS_WHITE
not being defined by Kconfig (it should be 'CONFIG_WS2812_HAS_WHITE). Also, the [
ws2812_write](https://github.com/apache/nuttx/blob/d1326e81bca47617aa253705ca778c7d51f82038/drivers/leds/ws2812.c#L316) (for
CONFIG_WS2812_NON_SPI_DRIVER`) is not compliant with raw 24-bit data length (LED pixel data should be encoded in 32-bit space).
All upstream code never calls vendor HAL directly, only download and link the static library. |
Oh, I see... this PR isn't about the "HAL", it's about the implementation of a common driver that is valid for all Espressif's xtensa-based devices. The same "common driver" approach is true for RISC-V-based devices, like ESP32-C3, ESP32-C6, ESP32-H2, for instance. Espressif is making a huge effort to avoid using closed static libraries: we plan to provide as much as possible the sources. Specifically for NuttX, we are just using header files and building specific auxiliary functions. There is no direct usage of "Espressif's HAL" on NuttX. Drivers' code and HAL-adapters are implemented on NuttX. License is compliant, there is no "HAL" code on NuttX (all code is downloaded or cloned) and called functions are according to NuttX standards. Please note that the same is valid for the Wireless driver of xtensa-based SoCs. |
Just to make sure: please note that there is no generic code. The repository being downloaded is dedicated to providing sources being used on NuttX: Similar approach with other manufacturers' implementation:
|
Thanks for explanation, the change looks good to me. |
Following up the 'Espressif HAL fullly integration for ESP32s2/s3' changes in apache#11428 There are few missing interrupt type constants need update. So update them to avoid the build error.
Following up the 'Espressif HAL fullly integration for ESP32s2/s3' changes in #11428 There are few missing interrupt type constants need update. So update them to avoid the build error.
Following up the 'Espressif HAL fullly integration for ESP32s2/s3' changes in apache#11428 There are few missing interrupt type constants need update. So update them to avoid the build error.
Following up the 'Espressif HAL fullly integration for ESP32s2/s3' changes in apache#11428 There are few missing interrupt type constants need update. So update them to avoid the build error.
Following up the 'Espressif HAL fullly integration for ESP32s2/s3' changes in apache#11428 There are few missing interrupt type constants need update. So update them to avoid the build error.
@tmedicci hi, why is this driver not in |
Hi @raiden00pl! The RMT peripheral is very versatile (the name doesn't reflect all of its capabilities). To cover more applications we developed this driver in layers. There is the generic RMT upper-half driver that enables using it directly for any kind of application based on timed signals, but the lower-half can be bound to any kind of existing driver with the correct adapter (for instance, we created an intermediate layer to use it with the upper-half WS2812 driver). So, answering your question: yes, we can use it with |
In that case you should use some kind of lower-half architecture API for For example, like its done for timer peripheral in stm32: you have one low-level interface for timers (https://github.com/apache/nuttx/blob/master/arch/arm/src/stm32/stm32_tim.h), and that interface is used to implement other features like periodic timer, oneshot or tickless. Equivalent functions from |
Hi @raiden00pl , I may have understood your concerns wrongly, but the current implementation is more like the GOOD than the BAD. See, let's check Note that, the RMT peripheral is initialized by Backing to
Also, please note that the |
My reasoning is that if it's in the common driver headers ( RMT upper-half itself seems to be wrong, as it's architecture specific driver. ESP architecture logic should implement Currently we have 2 drivers implementing IR driver that are incompatible with each other, which means there is no way to have a portable architecture between different vendors. Especially when |
Yes, I also have the same feeling, both RMT and PNCT(#15079) don't define the clear contract between the application and driver. The general driver framework should:
both definitions should be general enough to support the different hardware. The user can't write a general application to control the hardware come from different provider if these key elements doesn't catch in the design. |
Hi @raiden00pl and @xiaoxiang781216, let's put into perspective about RMT:
We can move it to
It isn't, it's used by either RISC-V and xtensa devices with the RMT peripheral.
We did this exactly the way you described for WS2812 upper-half. We didn't implement it for RC, but we encourage community to do it (and we can help with testing and validation). Then, I agree that we could even remove the RMT upper-half driver (
I agree that this is partially true for the RMT peripheral, but users can move between different devices/architectures (from ESP32 to ESP32-C3, for instance). About WS2812, this isn't true: the same application (https://github.com/apache/nuttx-apps/tree/master/examples/ws2812, for instance) can be used by any chip/arch/vendor that implements the driver. In general, I agree with your considerations regarding the driver organization, but I'm not convinced that we aren't providing that. Not allowing binding a peripheral to an existing upper-half driver is different from providing an upper-half driver for a peripheral whose capabilities are not covered by the existing upper-half drivers. We implement our drivers thinking that they could be bound to any other existing driver (just like the ws2812 upper-half driver) |
The point is that the entire RMT driver belongs to
I can't agree here. It's vendor specific driver, only used by ESP chips, so it should be in
RMT shouldn't be in
I don't see a problem with WS2812, the problem is in RMT.
There is no feature that RMT implements that cannot be implemented with existing portable drivers. IR with |
Let's avoid using
You've said earlier:
And I just said that it isn't architecture specific. It's vendor-specific (at least for now), not arch-specific.
I suppose you are referring to include/nuttx/rmt/rmt.h, right? If so, as I've said earlier: it isn't related to the upper-half driver and it can be moved to the arch. I'm not that convinced that it's in the wrong place because it's totally decoupled with the upper-half RMT driver (drivers/rmt/rmtchar.c) and its header file (include/nuttx/rmt/rmtchar.h), but we can move it to arch folder (duplicating it for xtensa and RISC-V).
Now I suppose you are referring to drivers/rmt/rmtchar.c, right? If so, I said earlier that this upper-half driver isn't needed for WS2812.
I'm not sure if I got your point here. The "common" API it uses is defined at include/nuttx/rmt/rmt.h. If we simply move it to arch-folder without any modification it'd be called "esp-specific API for RMT"? If so, again, I'm not against it...
I agree, and there are a bunch of other features that could be implemented with the RMT peripheral (PWM, audio, DACs etc). Our main goal is to provide support for the peripherals. Unfortunately, we have limited resources to create bindings to all of those upper-half driver, so we implemented the RMT lower-half driver and bound it with an existing upper-half driver (ws2812). Then, we provided a generic API for users to deal directly with the RMT peripheral (drivers/rmt/rmtchar.c). As soon as people bind the lower-half driver with the existing upper-half drivers, RMT upper-half wouldn't be necessary anymore and can be removed. There is a difference between the good and the needed. |
If you want to stick with RMT character driver then yes, I mean to move it to
We can argue whether it's arch-specific or vendor-specific. This doesn't make sense to me, since both should be placed in
Again, this approach is against |
Summary
The RMT (Remote Control) character driver allows to use the RMT peripheral (usually, a one-wire peripheral dedicated to driving IR remote control) as a character driver.
Although the LED might be RGB-only, the LED data is packed in a 32-bit long variable and, then, this is the default size of a LED pixel to define the 'WS2812_RW_PIXEL_SIZE' macro. Please note that the lower-half driver will deal with the case of the addressable LED being 3 or 4-pixel sized.
The lower-half implementation of the RMT character driver based on Espressif HAL enables using the RMT peripheral of ESP32, ESP32-S2 and ESP32-S3 as a common xtensa-based Espressif driver.
This lower-half WS2812 LED driver uses the RMT peripheral of the Espressif's SoCs to drive the RGB addressable LEDs. Compared to the SPI-based implementation, it is faster!
By integrating the Espressif`s HAL repository into the current ESP32-S3 implementation on NuttX, it is possible to call functions that make it easier to set up the registers of the ESP32-S3 and enable the usage of common Espressif drivers. Please note that Espressif's HAL repository was already being used for the Wi-Fi driver.
This commit use the new common RMT driver for all Espressif's xtensa-based chips on ESP32-S3.
By integrating the Espressif`s HAL repository into the current ESP32-S2 implementation on NuttX, it is possible to call functions that make it easier to setup the registers of the ESP32-S2, enabling the usage of common Espressif drivers.
This commit use the new common RMT driver for all Espressif's xtensa-based chips on ESP32-S2.
Impact
Implement a common RMT driver for xtensa-based devices. ESP32 requires updating the Wi-Fi driver to enable using the HAL (and the common RMT driver)
Testing
Internal CI testing + ESP32-S2-Saola-1 board and ESP32-S3-DevKitC-1 v1.0 board (loopback test + WS2812 LED strip)