nodemcu-firmware/components/platform/ws2812.c

333 lines
8.7 KiB
C
Raw Normal View History

2017-04-06 22:59:19 +02:00
/* ****************************************************************************
*
* ESP32 platform interface for WS2812 LEDs.
*
* Copyright (c) 2017, Arnim Laeuger
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* ****************************************************************************/
#include "platform.h"
#include "platform_rmt.h"
2017-04-06 22:59:19 +02:00
#include "driver/rmt.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "soc/periph_defs.h"
#include "rom/gpio.h" // for gpio_matrix_out()
#include "soc/gpio_periph.h"
Update rmt translator (#3629) * Choose the number of RMT buffers in the ws2812 module. The number of buffers required for optimal operation should be selected by the ws2812 module, not the caller. * Add parameters for RGB LED bit times. This patch adds compatibility for different RGB LEDS besides the WS2812. ESP evaluation boards like the ESP32-C3-DevKitM-1 use an SK68XXMINI-HS RGB LED which does not respond to the timings of this module. The patch adds optional parameters for the bit timings to the write function. If the new parameters are not supplied, the old values are used. An example for the SK68XXMINI-HS is provided in the documentation. * Remove restrictions from RTM translator. The old RMT translator was not able to split the bits of the source data into the size requested by the RMT transmitter. Either all 8 bits of an input byte were translated or none. The new routine removes the restriction by delivering exactly the requested amount of data to the transmitter, which results in a more balanced buffering of translated data under load. * Add a parameter for the RGB LED reset time. This patch introduces a new optional parameter for the reset time in the RGB LED communication. The default is 51.2 microseconds. A value of 0 sends no reset signal, which allows a small optimisation for consecutive write commands. Please note that the reset time of the old code should be 50 microseconds, as the define WS2812_DURATION_RESET suggested. Due to the restrictions of the old RMT translator routine, it was slightly increased to 51.2 microseconds. This patch keeps the value of 51.2 microseconds to be as compatible as possible. * Minimize the time drift between RMT channels. Place all RMT channels in a group to minimize the time drift between the signals. Please note that this feature is not available on all platforms. * Fix the description of the SK6812 LED in the example code. The SK6812 expects the data for the green LED first, then red and finally blue. It should be described as a GRB LED.
2024-02-07 23:56:17 +01:00
#include "soc/rmt_reg.h"
2017-04-06 22:59:19 +02:00
#undef WS2812_DEBUG
// divider to generate 100ns base period from 80MHz APB clock
#define WS2812_CLKDIV (100 * 80 /1000)
// descriptor for a ws2812 chain
typedef struct {
bool valid;
bool needs_reset;
2017-04-06 22:59:19 +02:00
uint8_t gpio;
Update rmt translator (#3629) * Choose the number of RMT buffers in the ws2812 module. The number of buffers required for optimal operation should be selected by the ws2812 module, not the caller. * Add parameters for RGB LED bit times. This patch adds compatibility for different RGB LEDS besides the WS2812. ESP evaluation boards like the ESP32-C3-DevKitM-1 use an SK68XXMINI-HS RGB LED which does not respond to the timings of this module. The patch adds optional parameters for the bit timings to the write function. If the new parameters are not supplied, the old values are used. An example for the SK68XXMINI-HS is provided in the documentation. * Remove restrictions from RTM translator. The old RMT translator was not able to split the bits of the source data into the size requested by the RMT transmitter. Either all 8 bits of an input byte were translated or none. The new routine removes the restriction by delivering exactly the requested amount of data to the transmitter, which results in a more balanced buffering of translated data under load. * Add a parameter for the RGB LED reset time. This patch introduces a new optional parameter for the reset time in the RGB LED communication. The default is 51.2 microseconds. A value of 0 sends no reset signal, which allows a small optimisation for consecutive write commands. Please note that the reset time of the old code should be 50 microseconds, as the define WS2812_DURATION_RESET suggested. Due to the restrictions of the old RMT translator routine, it was slightly increased to 51.2 microseconds. This patch keeps the value of 51.2 microseconds to be as compatible as possible. * Minimize the time drift between RMT channels. Place all RMT channels in a group to minimize the time drift between the signals. Please note that this feature is not available on all platforms. * Fix the description of the SK6812 LED in the example code. The SK6812 expects the data for the green LED first, then red and finally blue. It should be described as a GRB LED.
2024-02-07 23:56:17 +01:00
rmt_item32_t reset;
rmt_item32_t bits[2];
2017-04-06 22:59:19 +02:00
const uint8_t *data;
size_t len;
Update rmt translator (#3629) * Choose the number of RMT buffers in the ws2812 module. The number of buffers required for optimal operation should be selected by the ws2812 module, not the caller. * Add parameters for RGB LED bit times. This patch adds compatibility for different RGB LEDS besides the WS2812. ESP evaluation boards like the ESP32-C3-DevKitM-1 use an SK68XXMINI-HS RGB LED which does not respond to the timings of this module. The patch adds optional parameters for the bit timings to the write function. If the new parameters are not supplied, the old values are used. An example for the SK68XXMINI-HS is provided in the documentation. * Remove restrictions from RTM translator. The old RMT translator was not able to split the bits of the source data into the size requested by the RMT transmitter. Either all 8 bits of an input byte were translated or none. The new routine removes the restriction by delivering exactly the requested amount of data to the transmitter, which results in a more balanced buffering of translated data under load. * Add a parameter for the RGB LED reset time. This patch introduces a new optional parameter for the reset time in the RGB LED communication. The default is 51.2 microseconds. A value of 0 sends no reset signal, which allows a small optimisation for consecutive write commands. Please note that the reset time of the old code should be 50 microseconds, as the define WS2812_DURATION_RESET suggested. Due to the restrictions of the old RMT translator routine, it was slightly increased to 51.2 microseconds. This patch keeps the value of 51.2 microseconds to be as compatible as possible. * Minimize the time drift between RMT channels. Place all RMT channels in a group to minimize the time drift between the signals. Please note that this feature is not available on all platforms. * Fix the description of the SK6812 LED in the example code. The SK6812 expects the data for the green LED first, then red and finally blue. It should be described as a GRB LED.
2024-02-07 23:56:17 +01:00
uint8_t bitpos;
2017-04-06 22:59:19 +02:00
} ws2812_chain_t;
// chain descriptor array
static ws2812_chain_t ws2812_chains[RMT_CHANNEL_MAX];
static void ws2812_sample_to_rmt(const void *src, rmt_item32_t *dest, size_t src_size, size_t wanted_num, size_t *translated_size, size_t *item_num)
2017-04-06 22:59:19 +02:00
{
Update rmt translator (#3629) * Choose the number of RMT buffers in the ws2812 module. The number of buffers required for optimal operation should be selected by the ws2812 module, not the caller. * Add parameters for RGB LED bit times. This patch adds compatibility for different RGB LEDS besides the WS2812. ESP evaluation boards like the ESP32-C3-DevKitM-1 use an SK68XXMINI-HS RGB LED which does not respond to the timings of this module. The patch adds optional parameters for the bit timings to the write function. If the new parameters are not supplied, the old values are used. An example for the SK68XXMINI-HS is provided in the documentation. * Remove restrictions from RTM translator. The old RMT translator was not able to split the bits of the source data into the size requested by the RMT transmitter. Either all 8 bits of an input byte were translated or none. The new routine removes the restriction by delivering exactly the requested amount of data to the transmitter, which results in a more balanced buffering of translated data under load. * Add a parameter for the RGB LED reset time. This patch introduces a new optional parameter for the reset time in the RGB LED communication. The default is 51.2 microseconds. A value of 0 sends no reset signal, which allows a small optimisation for consecutive write commands. Please note that the reset time of the old code should be 50 microseconds, as the define WS2812_DURATION_RESET suggested. Due to the restrictions of the old RMT translator routine, it was slightly increased to 51.2 microseconds. This patch keeps the value of 51.2 microseconds to be as compatible as possible. * Minimize the time drift between RMT channels. Place all RMT channels in a group to minimize the time drift between the signals. Please note that this feature is not available on all platforms. * Fix the description of the SK6812 LED in the example code. The SK6812 expects the data for the green LED first, then red and finally blue. It should be described as a GRB LED.
2024-02-07 23:56:17 +01:00
size_t cnt_in;
size_t cnt_out;
const uint8_t *pucData;
uint8_t ucData;
uint8_t ucBitPos;
esp_err_t tStatus;
void *pvContext;
ws2812_chain_t *ptContext;
uint8_t ucBit;
cnt_in = 0;
cnt_out = 0;
if( dest!=NULL && wanted_num>0 )
{
tStatus = rmt_translator_get_context(item_num, &pvContext);
if( tStatus==ESP_OK )
{
ptContext = (ws2812_chain_t *)pvContext;
if( ptContext->needs_reset==true )
{
dest[cnt_out++] = ptContext->reset;
ptContext->needs_reset = false;
}
if( src!=NULL && src_size>0 )
{
ucBitPos = ptContext->bitpos;
/* Each bit of the input data is converted into one RMT item. */
pucData = (const uint8_t*)src;
/* Get the current byte. */
ucData = pucData[cnt_in] << ucBitPos;
while( cnt_in<src_size && cnt_out<wanted_num )
{
/* Get the current bit. */
ucBit = (ucData & 0x80U) >> 7U;
/* Translate the bit to a WS2812 input code. */
dest[cnt_out++] = ptContext->bits[ucBit];
/* Move to the next bit. */
++ucBitPos;
if( ucBitPos<8U )
{
ucData <<= 1;
}
else
{
ucBitPos = 0U;
++cnt_in;
ucData = pucData[cnt_in];
}
}
ptContext->bitpos = ucBitPos;
}
2017-04-06 22:59:19 +02:00
}
}
Update rmt translator (#3629) * Choose the number of RMT buffers in the ws2812 module. The number of buffers required for optimal operation should be selected by the ws2812 module, not the caller. * Add parameters for RGB LED bit times. This patch adds compatibility for different RGB LEDS besides the WS2812. ESP evaluation boards like the ESP32-C3-DevKitM-1 use an SK68XXMINI-HS RGB LED which does not respond to the timings of this module. The patch adds optional parameters for the bit timings to the write function. If the new parameters are not supplied, the old values are used. An example for the SK68XXMINI-HS is provided in the documentation. * Remove restrictions from RTM translator. The old RMT translator was not able to split the bits of the source data into the size requested by the RMT transmitter. Either all 8 bits of an input byte were translated or none. The new routine removes the restriction by delivering exactly the requested amount of data to the transmitter, which results in a more balanced buffering of translated data under load. * Add a parameter for the RGB LED reset time. This patch introduces a new optional parameter for the reset time in the RGB LED communication. The default is 51.2 microseconds. A value of 0 sends no reset signal, which allows a small optimisation for consecutive write commands. Please note that the reset time of the old code should be 50 microseconds, as the define WS2812_DURATION_RESET suggested. Due to the restrictions of the old RMT translator routine, it was slightly increased to 51.2 microseconds. This patch keeps the value of 51.2 microseconds to be as compatible as possible. * Minimize the time drift between RMT channels. Place all RMT channels in a group to minimize the time drift between the signals. Please note that this feature is not available on all platforms. * Fix the description of the SK6812 LED in the example code. The SK6812 expects the data for the green LED first, then red and finally blue. It should be described as a GRB LED.
2024-02-07 23:56:17 +01:00
*translated_size = cnt_in;
*item_num = cnt_out;
2017-04-06 22:59:19 +02:00
}
Update rmt translator (#3629) * Choose the number of RMT buffers in the ws2812 module. The number of buffers required for optimal operation should be selected by the ws2812 module, not the caller. * Add parameters for RGB LED bit times. This patch adds compatibility for different RGB LEDS besides the WS2812. ESP evaluation boards like the ESP32-C3-DevKitM-1 use an SK68XXMINI-HS RGB LED which does not respond to the timings of this module. The patch adds optional parameters for the bit timings to the write function. If the new parameters are not supplied, the old values are used. An example for the SK68XXMINI-HS is provided in the documentation. * Remove restrictions from RTM translator. The old RMT translator was not able to split the bits of the source data into the size requested by the RMT transmitter. Either all 8 bits of an input byte were translated or none. The new routine removes the restriction by delivering exactly the requested amount of data to the transmitter, which results in a more balanced buffering of translated data under load. * Add a parameter for the RGB LED reset time. This patch introduces a new optional parameter for the reset time in the RGB LED communication. The default is 51.2 microseconds. A value of 0 sends no reset signal, which allows a small optimisation for consecutive write commands. Please note that the reset time of the old code should be 50 microseconds, as the define WS2812_DURATION_RESET suggested. Due to the restrictions of the old RMT translator routine, it was slightly increased to 51.2 microseconds. This patch keeps the value of 51.2 microseconds to be as compatible as possible. * Minimize the time drift between RMT channels. Place all RMT channels in a group to minimize the time drift between the signals. Please note that this feature is not available on all platforms. * Fix the description of the SK6812 LED in the example code. The SK6812 expects the data for the green LED first, then red and finally blue. It should be described as a GRB LED.
2024-02-07 23:56:17 +01:00
int platform_ws2812_setup( uint8_t gpio_num, uint32_t reset, uint32_t t0h, uint32_t t0l, uint32_t t1h, uint32_t t1l, const uint8_t *data, size_t len )
2017-04-06 22:59:19 +02:00
{
int channel;
Update rmt translator (#3629) * Choose the number of RMT buffers in the ws2812 module. The number of buffers required for optimal operation should be selected by the ws2812 module, not the caller. * Add parameters for RGB LED bit times. This patch adds compatibility for different RGB LEDS besides the WS2812. ESP evaluation boards like the ESP32-C3-DevKitM-1 use an SK68XXMINI-HS RGB LED which does not respond to the timings of this module. The patch adds optional parameters for the bit timings to the write function. If the new parameters are not supplied, the old values are used. An example for the SK68XXMINI-HS is provided in the documentation. * Remove restrictions from RTM translator. The old RMT translator was not able to split the bits of the source data into the size requested by the RMT transmitter. Either all 8 bits of an input byte were translated or none. The new routine removes the restriction by delivering exactly the requested amount of data to the transmitter, which results in a more balanced buffering of translated data under load. * Add a parameter for the RGB LED reset time. This patch introduces a new optional parameter for the reset time in the RGB LED communication. The default is 51.2 microseconds. A value of 0 sends no reset signal, which allows a small optimisation for consecutive write commands. Please note that the reset time of the old code should be 50 microseconds, as the define WS2812_DURATION_RESET suggested. Due to the restrictions of the old RMT translator routine, it was slightly increased to 51.2 microseconds. This patch keeps the value of 51.2 microseconds to be as compatible as possible. * Minimize the time drift between RMT channels. Place all RMT channels in a group to minimize the time drift between the signals. Please note that this feature is not available on all platforms. * Fix the description of the SK6812 LED in the example code. The SK6812 expects the data for the green LED first, then red and finally blue. It should be described as a GRB LED.
2024-02-07 23:56:17 +01:00
if ((channel = platform_rmt_allocate( 1, RMT_MODE_TX )) >= 0) {
2017-04-06 22:59:19 +02:00
ws2812_chain_t *chain = &(ws2812_chains[channel]);
Update rmt translator (#3629) * Choose the number of RMT buffers in the ws2812 module. The number of buffers required for optimal operation should be selected by the ws2812 module, not the caller. * Add parameters for RGB LED bit times. This patch adds compatibility for different RGB LEDS besides the WS2812. ESP evaluation boards like the ESP32-C3-DevKitM-1 use an SK68XXMINI-HS RGB LED which does not respond to the timings of this module. The patch adds optional parameters for the bit timings to the write function. If the new parameters are not supplied, the old values are used. An example for the SK68XXMINI-HS is provided in the documentation. * Remove restrictions from RTM translator. The old RMT translator was not able to split the bits of the source data into the size requested by the RMT transmitter. Either all 8 bits of an input byte were translated or none. The new routine removes the restriction by delivering exactly the requested amount of data to the transmitter, which results in a more balanced buffering of translated data under load. * Add a parameter for the RGB LED reset time. This patch introduces a new optional parameter for the reset time in the RGB LED communication. The default is 51.2 microseconds. A value of 0 sends no reset signal, which allows a small optimisation for consecutive write commands. Please note that the reset time of the old code should be 50 microseconds, as the define WS2812_DURATION_RESET suggested. Due to the restrictions of the old RMT translator routine, it was slightly increased to 51.2 microseconds. This patch keeps the value of 51.2 microseconds to be as compatible as possible. * Minimize the time drift between RMT channels. Place all RMT channels in a group to minimize the time drift between the signals. Please note that this feature is not available on all platforms. * Fix the description of the SK6812 LED in the example code. The SK6812 expects the data for the green LED first, then red and finally blue. It should be described as a GRB LED.
2024-02-07 23:56:17 +01:00
rmt_item32_t tRmtItem;
uint32_t half;
2017-04-06 22:59:19 +02:00
chain->valid = true;
chain->gpio = gpio_num;
chain->len = len;
chain->data = data;
Update rmt translator (#3629) * Choose the number of RMT buffers in the ws2812 module. The number of buffers required for optimal operation should be selected by the ws2812 module, not the caller. * Add parameters for RGB LED bit times. This patch adds compatibility for different RGB LEDS besides the WS2812. ESP evaluation boards like the ESP32-C3-DevKitM-1 use an SK68XXMINI-HS RGB LED which does not respond to the timings of this module. The patch adds optional parameters for the bit timings to the write function. If the new parameters are not supplied, the old values are used. An example for the SK68XXMINI-HS is provided in the documentation. * Remove restrictions from RTM translator. The old RMT translator was not able to split the bits of the source data into the size requested by the RMT transmitter. Either all 8 bits of an input byte were translated or none. The new routine removes the restriction by delivering exactly the requested amount of data to the transmitter, which results in a more balanced buffering of translated data under load. * Add a parameter for the RGB LED reset time. This patch introduces a new optional parameter for the reset time in the RGB LED communication. The default is 51.2 microseconds. A value of 0 sends no reset signal, which allows a small optimisation for consecutive write commands. Please note that the reset time of the old code should be 50 microseconds, as the define WS2812_DURATION_RESET suggested. Due to the restrictions of the old RMT translator routine, it was slightly increased to 51.2 microseconds. This patch keeps the value of 51.2 microseconds to be as compatible as possible. * Minimize the time drift between RMT channels. Place all RMT channels in a group to minimize the time drift between the signals. Please note that this feature is not available on all platforms. * Fix the description of the SK6812 LED in the example code. The SK6812 expects the data for the green LED first, then red and finally blue. It should be described as a GRB LED.
2024-02-07 23:56:17 +01:00
chain->bitpos = 0;
// Send a reset if "reset" is not 0.
chain->needs_reset = (reset != 0);
// Construct the RMT item for a reset.
tRmtItem.level0 = 0;
tRmtItem.level1 = 0;
// The reset duration must fit into one RMT item. This leaves 2*15 bit,
// which results in a maximum of 0xfffe .
if (reset>0xfffe)
{
reset = 0xfffe;
}
if (reset>0x7fff)
{
tRmtItem.duration0 = 0x7fff;
tRmtItem.duration1 = reset - 0x7fff;
}
else
{
half = reset >> 1U;
tRmtItem.duration0 = half;
tRmtItem.duration1 = reset - half;
}
chain->reset = tRmtItem;
// Limit the bit times to the available 15 bits.
// The values must not be 0.
if( t0h==0 )
{
t0h = 1;
}
else if( t0h>0x7fffU )
{
t0h = 0x7fffU;
}
if( t0l==0 )
{
t0l = 1;
}
else if( t0l>0x7fffU )
{
t0l = 0x7fffU;
}
if( t1h==0 )
{
t1h = 1;
}
else if( t1h>0x7fffU )
{
t1h = 0x7fffU;
}
if( t1l==0 )
{
t1l = 1;
}
else if( t1l>0x7fffU )
{
t1l = 0x7fffU;
}
// Construct the RMT item for a 0 bit.
tRmtItem.level0 = 1;
tRmtItem.duration0 = t0h;
tRmtItem.level1 = 0;
tRmtItem.duration1 = t0l;
chain->bits[0] = tRmtItem;
// Construct the RMT item for a 1 bit.
tRmtItem.level0 = 1;
tRmtItem.duration0 = t1h;
tRmtItem.level1 = 0;
tRmtItem.duration1 = t1l;
chain->bits[1] = tRmtItem;
2017-04-06 22:59:19 +02:00
#ifdef WS2812_DEBUG
ESP_LOGI("ws2812", "Setup done for gpio %d on RMT channel %d", gpio_num, channel);
#endif
return PLATFORM_OK;
}
return PLATFORM_ERR;
}
int platform_ws2812_release( void )
{
for (rmt_channel_t channel = 0; channel < RMT_CHANNEL_MAX; channel++) {
ws2812_chain_t *chain = &(ws2812_chains[channel]);
if (chain->valid) {
rmt_driver_uninstall( channel );
platform_rmt_release( channel );
chain->valid = false;
2017-04-06 22:59:19 +02:00
// attach GPIO to pin, driving 0
gpio_set_level( chain->gpio, 0 );
gpio_set_direction( chain->gpio, GPIO_MODE_DEF_OUTPUT );
gpio_matrix_out( chain->gpio, SIG_GPIO_OUT_IDX, 0, 0 );
}
}
return PLATFORM_OK;
}
int platform_ws2812_send( void )
{
rmt_config_t rmt_tx;
int res = PLATFORM_OK;
// common settings
rmt_tx.mem_block_num = 1;
rmt_tx.clk_div = WS2812_CLKDIV;
rmt_tx.flags = 0;
2017-04-06 22:59:19 +02:00
rmt_tx.tx_config.loop_en = false;
rmt_tx.tx_config.carrier_en = false;
rmt_tx.tx_config.idle_level = 0;
rmt_tx.tx_config.idle_output_en = true;
rmt_tx.rmt_mode = RMT_MODE_TX;
// configure selected RMT channels
for (rmt_channel_t channel = 0; channel < RMT_CHANNEL_MAX && res == PLATFORM_OK; channel++) {
if (ws2812_chains[channel].valid) {
rmt_tx.channel = channel;
rmt_tx.gpio_num = ws2812_chains[channel].gpio;
if (rmt_config( &rmt_tx ) != ESP_OK) {
res = PLATFORM_ERR;
break;
}
if (rmt_driver_install( channel, 0, PLATFORM_RMT_INTR_FLAGS ) != ESP_OK) {
2017-04-06 22:59:19 +02:00
res = PLATFORM_ERR;
break;
}
if (rmt_translator_init(channel, ws2812_sample_to_rmt) != ESP_OK) {
res = PLATFORM_ERR;
break;
}
if (rmt_translator_set_context(channel, &ws2812_chains[channel]) != ESP_OK) {
res = PLATFORM_ERR;
break;
}
2017-04-06 22:59:19 +02:00
}
}
Update rmt translator (#3629) * Choose the number of RMT buffers in the ws2812 module. The number of buffers required for optimal operation should be selected by the ws2812 module, not the caller. * Add parameters for RGB LED bit times. This patch adds compatibility for different RGB LEDS besides the WS2812. ESP evaluation boards like the ESP32-C3-DevKitM-1 use an SK68XXMINI-HS RGB LED which does not respond to the timings of this module. The patch adds optional parameters for the bit timings to the write function. If the new parameters are not supplied, the old values are used. An example for the SK68XXMINI-HS is provided in the documentation. * Remove restrictions from RTM translator. The old RMT translator was not able to split the bits of the source data into the size requested by the RMT transmitter. Either all 8 bits of an input byte were translated or none. The new routine removes the restriction by delivering exactly the requested amount of data to the transmitter, which results in a more balanced buffering of translated data under load. * Add a parameter for the RGB LED reset time. This patch introduces a new optional parameter for the reset time in the RGB LED communication. The default is 51.2 microseconds. A value of 0 sends no reset signal, which allows a small optimisation for consecutive write commands. Please note that the reset time of the old code should be 50 microseconds, as the define WS2812_DURATION_RESET suggested. Due to the restrictions of the old RMT translator routine, it was slightly increased to 51.2 microseconds. This patch keeps the value of 51.2 microseconds to be as compatible as possible. * Minimize the time drift between RMT channels. Place all RMT channels in a group to minimize the time drift between the signals. Please note that this feature is not available on all platforms. * Fix the description of the SK6812 LED in the example code. The SK6812 expects the data for the green LED first, then red and finally blue. It should be described as a GRB LED.
2024-02-07 23:56:17 +01:00
// Try to add all channels to a group. This moves the start of all RMT sequences closer
// together.
#if SOC_RMT_SUPPORT_TX_SYNCHRO
for (rmt_channel_t channel = 0; channel < RMT_CHANNEL_MAX && res == PLATFORM_OK; channel++) {
if (ws2812_chains[channel].valid) {
if (rmt_add_channel_to_group( channel ) != ESP_OK) {
res = PLATFORM_ERR;
break;
}
}
}
#endif
2017-04-06 22:59:19 +02:00
// start selected channels one by one
for (rmt_channel_t channel = 0; channel < RMT_CHANNEL_MAX && res == PLATFORM_OK; channel++) {
if (ws2812_chains[channel].valid) {
// ws2812_sample_to_rmt takes care of translating the data to rmt_item32_t
// format, as well as prepending the reset sequence.
if (rmt_write_sample(channel, ws2812_chains[channel].data, ws2812_chains[channel].len, false) != ESP_OK) {
2017-04-06 22:59:19 +02:00
res = PLATFORM_ERR;
break;
}
}
}
// wait for all channels to finish
for (rmt_channel_t channel = 0; channel < RMT_CHANNEL_MAX; channel++) {
if (ws2812_chains[channel].valid) {
2017-09-12 22:21:33 +02:00
rmt_wait_tx_done( channel, portMAX_DELAY );
2017-04-06 22:59:19 +02:00
}
}
Update rmt translator (#3629) * Choose the number of RMT buffers in the ws2812 module. The number of buffers required for optimal operation should be selected by the ws2812 module, not the caller. * Add parameters for RGB LED bit times. This patch adds compatibility for different RGB LEDS besides the WS2812. ESP evaluation boards like the ESP32-C3-DevKitM-1 use an SK68XXMINI-HS RGB LED which does not respond to the timings of this module. The patch adds optional parameters for the bit timings to the write function. If the new parameters are not supplied, the old values are used. An example for the SK68XXMINI-HS is provided in the documentation. * Remove restrictions from RTM translator. The old RMT translator was not able to split the bits of the source data into the size requested by the RMT transmitter. Either all 8 bits of an input byte were translated or none. The new routine removes the restriction by delivering exactly the requested amount of data to the transmitter, which results in a more balanced buffering of translated data under load. * Add a parameter for the RGB LED reset time. This patch introduces a new optional parameter for the reset time in the RGB LED communication. The default is 51.2 microseconds. A value of 0 sends no reset signal, which allows a small optimisation for consecutive write commands. Please note that the reset time of the old code should be 50 microseconds, as the define WS2812_DURATION_RESET suggested. Due to the restrictions of the old RMT translator routine, it was slightly increased to 51.2 microseconds. This patch keeps the value of 51.2 microseconds to be as compatible as possible. * Minimize the time drift between RMT channels. Place all RMT channels in a group to minimize the time drift between the signals. Please note that this feature is not available on all platforms. * Fix the description of the SK6812 LED in the example code. The SK6812 expects the data for the green LED first, then red and finally blue. It should be described as a GRB LED.
2024-02-07 23:56:17 +01:00
#if SOC_RMT_SUPPORT_TX_SYNCHRO
for (rmt_channel_t channel = 0; channel < RMT_CHANNEL_MAX; channel++) {
if (ws2812_chains[channel].valid) {
if (rmt_remove_channel_from_group( channel ) != ESP_OK) {
res = PLATFORM_ERR;
break;
}
}
}
#endif
2017-04-06 22:59:19 +02:00
return res;
}
void platform_ws2812_init( void )
{
for (rmt_channel_t channel = 0; channel < RMT_CHANNEL_MAX; channel++) {
ws2812_chains[channel].valid = false;
}
}