diff --git a/led_strip/CHANGELOG.md b/led_strip/CHANGELOG.md
index 66906b6c71..4770754441 100644
--- a/led_strip/CHANGELOG.md
+++ b/led_strip/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 2.5.6
+
+- Add pixel order configuration array to support user-defined pixel order.
+
## 2.5.5
- Simplified the led_strip component dependency, the time of full build with ESP-IDF v5.3 can now be shorter.
diff --git a/led_strip/CMakeLists.txt b/led_strip/CMakeLists.txt
index a4e576be7a..13c35ec3d3 100644
--- a/led_strip/CMakeLists.txt
+++ b/led_strip/CMakeLists.txt
@@ -1,6 +1,6 @@
include($ENV{IDF_PATH}/tools/cmake/version.cmake)
-set(srcs "src/led_strip_api.c")
+set(srcs "src/led_strip_api.c" "src/led_strip_common.c")
set(public_requires)
# Starting from esp-idf v5.x, the RMT driver is rewritten
diff --git a/led_strip/api.md b/led_strip/api.md
index 8fc04af4f4..ee9f375ac1 100644
--- a/led_strip/api.md
+++ b/led_strip/api.md
@@ -21,6 +21,13 @@
| esp\_err\_t | [**led\_strip\_set\_pixel\_hsv**](#function-led_strip_set_pixel_hsv) ([**led\_strip\_handle\_t**](#typedef-led_strip_handle_t) strip, uint32\_t index, uint16\_t hue, uint8\_t saturation, uint8\_t value)
_Set HSV for a specific pixel._ |
| esp\_err\_t | [**led\_strip\_set\_pixel\_rgbw**](#function-led_strip_set_pixel_rgbw) ([**led\_strip\_handle\_t**](#typedef-led_strip_handle_t) strip, uint32\_t index, uint32\_t red, uint32\_t green, uint32\_t blue, uint32\_t white)
_Set RGBW for a specific pixel._ |
+## Macros
+
+| Type | Name |
+| ---: | :--- |
+| define | [**LED\_STRIP\_ADJUST\_RGBW\_ORDER**](#define-led_strip_adjust_rgbw_order) (R, G, B, W)
_Help macro to adjust pixel RGBW color order The default order of the four-color LED strips is GRBW. If you have a different order, you can use the macro to set_ `config_pixel_order`_in_[_**led\_strip\_config\_t**_](#struct-led_strip_config_t)_._ |
+| define | [**LED\_STRIP\_ADJUST\_RGB\_ORDER**](#define-led_strip_adjust_rgb_order) (R, G, B)
_Help macro to adjust pixel RGB color order The default order of the three-color LED strips is GRB. If you have a different order, you can use the macro to set_ `config_pixel_order`_in_[_**led\_strip\_config\_t**_](#struct-led_strip_config_t)_._ |
+
## Functions Documentation
### function `led_strip_clear`
@@ -178,6 +185,32 @@ Also see `led_strip_set_pixel` if you only want to specify the RGB part of the c
- ESP\_ERR\_INVALID\_ARG: Set RGBW color for a specific pixel failed because of an invalid argument
- ESP\_FAIL: Set RGBW color for a specific pixel failed because other error occurred
+## Macros Documentation
+
+### define `LED_STRIP_ADJUST_RGBW_ORDER`
+
+_Help macro to adjust pixel RGBW color order The default order of the four-color LED strips is GRBW. If you have a different order, you can use the macro to set_ `config_pixel_order`_in_[_**led\_strip\_config\_t**_](#struct-led_strip_config_t)_._
+
+```c
+#define LED_STRIP_ADJUST_RGBW_ORDER (R, G, B, W) (R << 0 | G << 2 | B << 4 | W << 6)
+```
+
+**Note:**
+
+The order starts from 0. And the user needs to make sure that all the numbers appear exactly once and are all less than the number of colors per pixel.
+
+### define `LED_STRIP_ADJUST_RGB_ORDER`
+
+_Help macro to adjust pixel RGB color order The default order of the three-color LED strips is GRB. If you have a different order, you can use the macro to set_ `config_pixel_order`_in_[_**led\_strip\_config\_t**_](#struct-led_strip_config_t)_._
+
+```c
+#define LED_STRIP_ADJUST_RGB_ORDER (R, G, B) (R << 0 | G << 2 | B << 4)
+```
+
+**Note:**
+
+The order starts from 0. And the user needs to make sure that all the numbers appear exactly once and are all less than the number of colors per pixel.
+
## File include/led_strip_rmt.h
## Structures and Types
@@ -346,7 +379,9 @@ _LED Strip Configuration._
Variables:
-- struct led\_strip\_config\_t::@2 flags
Extra driver flags
+- uint8\_t config_pixel_order
+
+- struct led\_strip\_config\_t::@2 flags
The order of the pixel color. Use help macro LED\_STRIP\_ADJUST\_RGB\_ORDER or LED\_STRIP\_ADJUST\_RGBW\_ORDER to set. Not set or set to 0 if the default order is used. Extra driver flags
- uint32\_t invert_out
Invert output signal
diff --git a/led_strip/examples/led_strip_rmt_ws2812/main/led_strip_rmt_ws2812_main.c b/led_strip/examples/led_strip_rmt_ws2812/main/led_strip_rmt_ws2812_main.c
index 5cae3f079c..15ae977af4 100644
--- a/led_strip/examples/led_strip_rmt_ws2812/main/led_strip_rmt_ws2812_main.c
+++ b/led_strip/examples/led_strip_rmt_ws2812/main/led_strip_rmt_ws2812_main.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@@ -11,9 +11,9 @@
#include "esp_err.h"
// GPIO assignment
-#define LED_STRIP_BLINK_GPIO 2
+#define LED_STRIP_GPIO_PIN 2
// Numbers of the LED in the strip
-#define LED_STRIP_LED_NUMBERS 24
+#define LED_STRIP_LED_COUNT 24
// 10MHz resolution, 1 tick = 0.1us (led strip needs a high resolution)
#define LED_STRIP_RMT_RES_HZ (10 * 1000 * 1000)
@@ -23,11 +23,12 @@ led_strip_handle_t configure_led(void)
{
// LED strip general initialization, according to your led board design
led_strip_config_t strip_config = {
- .strip_gpio_num = LED_STRIP_BLINK_GPIO, // The GPIO that connected to the LED strip's data line
- .max_leds = LED_STRIP_LED_NUMBERS, // The number of LEDs in the strip,
+ .strip_gpio_num = LED_STRIP_GPIO_PIN, // The GPIO that connected to the LED strip's data line
+ .max_leds = LED_STRIP_LED_COUNT, // The number of LEDs in the strip,
.led_pixel_format = LED_PIXEL_FORMAT_GRB, // Pixel format of your LED strip
.led_model = LED_MODEL_WS2812, // LED strip model
.flags.invert_out = false, // whether to invert the output signal
+ .config_pixel_order = 0, // The order of the pixel color. Not set or set to 0 if the default order is used
};
// LED strip backend configuration: RMT
@@ -57,7 +58,7 @@ void app_main(void)
while (1) {
if (led_on_off) {
/* Set the LED pixel using RGB from 0 (0%) to 255 (100%) for each color */
- for (int i = 0; i < LED_STRIP_LED_NUMBERS; i++) {
+ for (int i = 0; i < LED_STRIP_LED_COUNT; i++) {
ESP_ERROR_CHECK(led_strip_set_pixel(led_strip, i, 5, 5, 5));
}
/* Refresh the strip to send data */
diff --git a/led_strip/examples/led_strip_spi_ws2812/main/led_strip_spi_ws2812_main.c b/led_strip/examples/led_strip_spi_ws2812/main/led_strip_spi_ws2812_main.c
index 69b780c5aa..ab048a613e 100644
--- a/led_strip/examples/led_strip_spi_ws2812/main/led_strip_spi_ws2812_main.c
+++ b/led_strip/examples/led_strip_spi_ws2812/main/led_strip_spi_ws2812_main.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@@ -11,9 +11,9 @@
#include "esp_err.h"
// GPIO assignment
-#define LED_STRIP_BLINK_GPIO 2
+#define LED_STRIP_GPIO_PIN 2
// Numbers of the LED in the strip
-#define LED_STRIP_LED_NUMBERS 24
+#define LED_STRIP_LED_COUNT 24
static const char *TAG = "example";
@@ -21,11 +21,12 @@ led_strip_handle_t configure_led(void)
{
// LED strip general initialization, according to your led board design
led_strip_config_t strip_config = {
- .strip_gpio_num = LED_STRIP_BLINK_GPIO, // The GPIO that connected to the LED strip's data line
- .max_leds = LED_STRIP_LED_NUMBERS, // The number of LEDs in the strip,
+ .strip_gpio_num = LED_STRIP_GPIO_PIN, // The GPIO that connected to the LED strip's data line
+ .max_leds = LED_STRIP_LED_COUNT, // The number of LEDs in the strip,
.led_pixel_format = LED_PIXEL_FORMAT_GRB, // Pixel format of your LED strip
.led_model = LED_MODEL_WS2812, // LED strip model
.flags.invert_out = false, // whether to invert the output signal
+ .config_pixel_order = 0, // The order of the pixel color. Not set or set to 0 if the default order is used
};
// LED strip backend configuration: SPI
@@ -51,7 +52,7 @@ void app_main(void)
while (1) {
if (led_on_off) {
/* Set the LED pixel using RGB from 0 (0%) to 255 (100%) for each color */
- for (int i = 0; i < LED_STRIP_LED_NUMBERS; i++) {
+ for (int i = 0; i < LED_STRIP_LED_COUNT; i++) {
ESP_ERROR_CHECK(led_strip_set_pixel(led_strip, i, 5, 5, 5));
}
/* Refresh the strip to send data */
diff --git a/led_strip/idf_component.yml b/led_strip/idf_component.yml
index 4928449549..ae2e6031bc 100644
--- a/led_strip/idf_component.yml
+++ b/led_strip/idf_component.yml
@@ -1,4 +1,4 @@
-version: "2.5.5"
+version: "2.5.6"
description: Driver for Addressable LED Strip (WS2812, etc)
url: https://github.com/espressif/idf-extra-components/tree/master/led_strip
dependencies:
diff --git a/led_strip/include/esp_private/led_strip_common.h b/led_strip/include/esp_private/led_strip_common.h
new file mode 100644
index 0000000000..3499cd2e96
--- /dev/null
+++ b/led_strip/include/esp_private/led_strip_common.h
@@ -0,0 +1,41 @@
+/*
+ * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#pragma once
+
+#include
+#include "esp_err.h"
+#include "led_strip_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief LED strip pixel order index
+ */
+typedef enum {
+ LED_PIXEL_INDEX_RED, /*!< Red pixel index */
+ LED_PIXEL_INDEX_GREEN, /*!< Green pixel index */
+ LED_PIXEL_INDEX_BLUE, /*!< Blue pixel index */
+ LED_PIXEL_INDEX_WHITE, /*!< White pixel index */
+ LED_PIXEL_INDEX_MAX /*!< Max pixel index */
+} led_pixel_order_index_t;
+
+/**
+ * @brief Adjust LED color order
+ *
+ * @param led_pixel_offset Each pixel's offset
+ * @param config_pixel_order `config_pixel_order` parameter in LED strip configuration
+ * @param bytes_per_pixel bytes per pixel
+ * @return
+ * - ESP_OK: Adjust LED color order successfully
+ * - ESP_ERR_INVALID_ARG: Adjust LED color order failed because of invalid argument
+ */
+esp_err_t led_strip_adjust_color_order(uint8_t *led_pixel_offset, const uint8_t config_pixel_order, const uint8_t bytes_per_pixel);
+
+#ifdef __cplusplus
+}
+#endif
\ No newline at end of file
diff --git a/led_strip/include/led_strip.h b/led_strip/include/led_strip.h
index a4e994675e..afc085a042 100644
--- a/led_strip/include/led_strip.h
+++ b/led_strip/include/led_strip.h
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -18,6 +18,20 @@
extern "C" {
#endif
+/**
+ * @brief Help macro to adjust pixel RGB color order
+ * The default order of the three-color LED strips is GRB. If you have a different order, you can use the macro to set `config_pixel_order` in led_strip_config_t.
+ * @note The order starts from 0. And the user needs to make sure that all the numbers appear exactly once and are all less than the number of colors per pixel.
+ */
+#define LED_STRIP_ADJUST_RGB_ORDER(R, G, B) (R << 0 | G << 2 | B << 4)
+
+/**
+ * @brief Help macro to adjust pixel RGBW color order
+ * The default order of the four-color LED strips is GRBW. If you have a different order, you can use the macro to set `config_pixel_order` in led_strip_config_t.
+ * @note The order starts from 0. And the user needs to make sure that all the numbers appear exactly once and are all less than the number of colors per pixel.
+ */
+#define LED_STRIP_ADJUST_RGBW_ORDER(R, G, B, W) (R << 0 | G << 2 | B << 4 | W << 6)
+
/**
* @brief Set RGB for a specific pixel
*
diff --git a/led_strip/include/led_strip_types.h b/led_strip/include/led_strip_types.h
index 691f0bc394..42b0c220a6 100644
--- a/led_strip/include/led_strip_types.h
+++ b/led_strip/include/led_strip_types.h
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -43,7 +43,9 @@ typedef struct {
uint32_t max_leds; /*!< Maximum LEDs in a single strip */
led_pixel_format_t led_pixel_format; /*!< LED pixel format */
led_model_t led_model; /*!< LED model */
-
+ uint8_t config_pixel_order; /*! The order of the pixel color.
+ Use help macro LED_STRIP_ADJUST_RGB_ORDER or LED_STRIP_ADJUST_RGBW_ORDER to set.
+ Not set or set to 0 if the default order is used. */
struct {
uint32_t invert_out: 1; /*!< Invert output signal */
} flags; /*!< Extra driver flags */
diff --git a/led_strip/src/led_strip_common.c b/led_strip/src/led_strip_common.c
new file mode 100644
index 0000000000..67999d6cbe
--- /dev/null
+++ b/led_strip/src/led_strip_common.c
@@ -0,0 +1,38 @@
+/*
+ * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#include
+#include "esp_log.h"
+#include "esp_check.h"
+#include "esp_bit_defs.h"
+#include "esp_private/led_strip_common.h"
+
+static const char *TAG = "led_strip_common";
+
+esp_err_t led_strip_adjust_color_order(uint8_t *led_pixel_offset, const uint8_t config_pixel_order, const uint8_t bytes_per_pixel)
+{
+ esp_err_t ret = ESP_OK;
+ ESP_RETURN_ON_FALSE(led_pixel_offset && bytes_per_pixel, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
+ if (config_pixel_order) {
+ uint8_t r_order = (config_pixel_order >> 0) & 0x03;
+ uint8_t g_order = (config_pixel_order >> 2) & 0x03;
+ uint8_t b_order = (config_pixel_order >> 4) & 0x03;
+ uint8_t w_order = (config_pixel_order >> 6) & 0x03;
+ uint8_t mask = bytes_per_pixel == 3 ? BIT(r_order) | BIT(g_order) | BIT(b_order) : BIT(r_order) | BIT(g_order) | BIT(b_order) | BIT(w_order);
+ // Check for invalid values
+ ESP_RETURN_ON_FALSE(__builtin_popcount(mask) == bytes_per_pixel && r_order < bytes_per_pixel && g_order < bytes_per_pixel && b_order < bytes_per_pixel && w_order < bytes_per_pixel,
+ ESP_ERR_INVALID_ARG, TAG, "invalid order argument");
+ led_pixel_offset[LED_PIXEL_INDEX_RED] = r_order;
+ led_pixel_offset[LED_PIXEL_INDEX_GREEN] = g_order;
+ led_pixel_offset[LED_PIXEL_INDEX_BLUE] = b_order;
+ led_pixel_offset[LED_PIXEL_INDEX_WHITE] = w_order;
+ } else {
+ led_pixel_offset[LED_PIXEL_INDEX_RED] = 1;
+ led_pixel_offset[LED_PIXEL_INDEX_GREEN] = 0;
+ led_pixel_offset[LED_PIXEL_INDEX_BLUE] = 2;
+ led_pixel_offset[LED_PIXEL_INDEX_WHITE] = 3;
+ }
+ return ret;
+}
diff --git a/led_strip/src/led_strip_rmt_dev.c b/led_strip/src/led_strip_rmt_dev.c
index 1cbf0e45ae..4556d585c0 100644
--- a/led_strip/src/led_strip_rmt_dev.c
+++ b/led_strip/src/led_strip_rmt_dev.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -12,6 +12,7 @@
#include "led_strip.h"
#include "led_strip_interface.h"
#include "led_strip_rmt_encoder.h"
+#include "esp_private/led_strip_common.h"
#define LED_STRIP_RMT_DEFAULT_RESOLUTION 10000000 // 10MHz resolution
#define LED_STRIP_RMT_DEFAULT_TRANS_QUEUE_SIZE 4
@@ -30,6 +31,7 @@ typedef struct {
rmt_encoder_handle_t strip_encoder;
uint32_t strip_len;
uint8_t bytes_per_pixel;
+ uint8_t led_pixel_offset[LED_PIXEL_INDEX_MAX];
uint8_t pixel_buf[];
} led_strip_rmt_obj;
@@ -38,12 +40,15 @@ static esp_err_t led_strip_rmt_set_pixel(led_strip_t *strip, uint32_t index, uin
led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base);
ESP_RETURN_ON_FALSE(index < rmt_strip->strip_len, ESP_ERR_INVALID_ARG, TAG, "index out of maximum number of LEDs");
uint32_t start = index * rmt_strip->bytes_per_pixel;
- // In thr order of GRB, as LED strip like WS2812 sends out pixels in this order
- rmt_strip->pixel_buf[start + 0] = green & 0xFF;
- rmt_strip->pixel_buf[start + 1] = red & 0xFF;
- rmt_strip->pixel_buf[start + 2] = blue & 0xFF;
+ uint8_t *pixel_buf = rmt_strip->pixel_buf;
+ uint8_t *offset = rmt_strip->led_pixel_offset;
+ // Support all kinds of pixel order
+ pixel_buf[start + offset[LED_PIXEL_INDEX_RED]] = red & 0xFF;
+ pixel_buf[start + offset[LED_PIXEL_INDEX_GREEN]] = green & 0xFF;
+ pixel_buf[start + offset[LED_PIXEL_INDEX_BLUE]] = blue & 0xFF;
+
if (rmt_strip->bytes_per_pixel > 3) {
- rmt_strip->pixel_buf[start + 3] = 0;
+ pixel_buf[start + offset[LED_PIXEL_INDEX_WHITE]] = 0;
}
return ESP_OK;
}
@@ -53,12 +58,14 @@ static esp_err_t led_strip_rmt_set_pixel_rgbw(led_strip_t *strip, uint32_t index
led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base);
ESP_RETURN_ON_FALSE(index < rmt_strip->strip_len, ESP_ERR_INVALID_ARG, TAG, "index out of maximum number of LEDs");
ESP_RETURN_ON_FALSE(rmt_strip->bytes_per_pixel == 4, ESP_ERR_INVALID_ARG, TAG, "wrong LED pixel format, expected 4 bytes per pixel");
- uint8_t *buf_start = rmt_strip->pixel_buf + index * 4;
+ uint32_t start = index * rmt_strip->bytes_per_pixel;
+ uint8_t *pixel_buf = rmt_strip->pixel_buf;
+ uint8_t *offset = rmt_strip->led_pixel_offset;
// SK6812 component order is GRBW
- *buf_start = green & 0xFF;
- *++buf_start = red & 0xFF;
- *++buf_start = blue & 0xFF;
- *++buf_start = white & 0xFF;
+ pixel_buf[start + offset[LED_PIXEL_INDEX_RED]] = red & 0xFF;
+ pixel_buf[start + offset[LED_PIXEL_INDEX_GREEN]] = green & 0xFF;
+ pixel_buf[start + offset[LED_PIXEL_INDEX_BLUE]] = blue & 0xFF;
+ pixel_buf[start + offset[LED_PIXEL_INDEX_WHITE]] = white & 0xFF;
return ESP_OK;
}
@@ -138,7 +145,7 @@ esp_err_t led_strip_new_rmt_device(const led_strip_config_t *led_config, const l
.led_model = led_config->led_model
};
ESP_GOTO_ON_ERROR(rmt_new_led_strip_encoder(&strip_encoder_conf, &rmt_strip->strip_encoder), err, TAG, "create LED strip encoder failed");
-
+ ESP_GOTO_ON_ERROR(led_strip_adjust_color_order(rmt_strip->led_pixel_offset, led_config->config_pixel_order, bytes_per_pixel), err, TAG, "adjust color order failed");
rmt_strip->bytes_per_pixel = bytes_per_pixel;
rmt_strip->strip_len = led_config->max_leds;
diff --git a/led_strip/src/led_strip_rmt_dev_idf4.c b/led_strip/src/led_strip_rmt_dev_idf4.c
index a1067cd7c4..27ad5fe94f 100644
--- a/led_strip/src/led_strip_rmt_dev_idf4.c
+++ b/led_strip/src/led_strip_rmt_dev_idf4.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -11,6 +11,7 @@
#include "driver/rmt.h"
#include "led_strip.h"
#include "led_strip_interface.h"
+#include "esp_private/led_strip_common.h"
static const char *TAG = "led_strip_rmt";
@@ -43,6 +44,7 @@ typedef struct {
rmt_channel_t rmt_channel;
uint32_t strip_len;
uint8_t bytes_per_pixel;
+ uint8_t led_pixel_offset[LED_PIXEL_INDEX_MAX];
uint8_t buffer[0];
} led_strip_rmt_obj;
@@ -83,12 +85,14 @@ static esp_err_t led_strip_rmt_set_pixel(led_strip_t *strip, uint32_t index, uin
led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base);
ESP_RETURN_ON_FALSE(index < rmt_strip->strip_len, ESP_ERR_INVALID_ARG, TAG, "index out of the maximum number of leds");
uint32_t start = index * rmt_strip->bytes_per_pixel;
- // In thr order of GRB
- rmt_strip->buffer[start + 0] = green & 0xFF;
- rmt_strip->buffer[start + 1] = red & 0xFF;
- rmt_strip->buffer[start + 2] = blue & 0xFF;
+ uint8_t *pixel_buf = rmt_strip->buffer;
+ uint8_t *offset = rmt_strip->led_pixel_offset;
+ // Support all kinds of pixel order
+ pixel_buf[start + offset[LED_PIXEL_INDEX_RED]] = red & 0xFF;
+ pixel_buf[start + offset[LED_PIXEL_INDEX_GREEN]] = green & 0xFF;
+ pixel_buf[start + offset[LED_PIXEL_INDEX_BLUE]] = blue & 0xFF;
if (rmt_strip->bytes_per_pixel > 3) {
- rmt_strip->buffer[start + 3] = 0;
+ rmt_strip->buffer[start + offset[LED_PIXEL_INDEX_WHITE]] = 0;
}
return ESP_OK;
}
@@ -174,6 +178,7 @@ esp_err_t led_strip_new_rmt_device(const led_strip_config_t *led_config, const l
// adapter to translates the LES strip date frame into RMT symbols
rmt_translator_init((rmt_channel_t)dev_config->rmt_channel, ws2812_rmt_adapter);
+ ESP_GOTO_ON_ERROR(led_strip_adjust_color_order(rmt_strip->led_pixel_offset, led_config->config_pixel_order, bytes_per_pixel), err, TAG, "adjust color order failed");
rmt_strip->bytes_per_pixel = bytes_per_pixel;
rmt_strip->rmt_channel = (rmt_channel_t)dev_config->rmt_channel;
diff --git a/led_strip/src/led_strip_spi_dev.c b/led_strip/src/led_strip_spi_dev.c
index 6c66d7e375..a4f34afbbd 100644
--- a/led_strip/src/led_strip_spi_dev.c
+++ b/led_strip/src/led_strip_spi_dev.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -10,9 +10,10 @@
#include "esp_check.h"
#include "esp_rom_gpio.h"
#include "soc/spi_periph.h"
+#include "hal/spi_hal.h"
#include "led_strip.h"
#include "led_strip_interface.h"
-#include "hal/spi_hal.h"
+#include "esp_private/led_strip_common.h"
#define LED_STRIP_SPI_DEFAULT_RESOLUTION (2.5 * 1000 * 1000) // 2.5MHz resolution
#define LED_STRIP_SPI_DEFAULT_TRANS_QUEUE_SIZE 4
@@ -28,6 +29,7 @@ typedef struct {
spi_device_handle_t spi_device;
uint32_t strip_len;
uint8_t bytes_per_pixel;
+ uint8_t led_pixel_offset[LED_PIXEL_INDEX_MAX];
uint8_t pixel_buf[];
} led_strip_spi_obj;
@@ -51,14 +53,16 @@ static esp_err_t led_strip_spi_set_pixel(led_strip_t *strip, uint32_t index, uin
{
led_strip_spi_obj *spi_strip = __containerof(strip, led_strip_spi_obj, base);
ESP_RETURN_ON_FALSE(index < spi_strip->strip_len, ESP_ERR_INVALID_ARG, TAG, "index out of maximum number of LEDs");
- // LED_PIXEL_FORMAT_GRB takes 72bits(9bytes)
+ // 3 pixels take 72bits(9bytes)
uint32_t start = index * spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE;
- memset(spi_strip->pixel_buf + start, 0, spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE);
- __led_strip_spi_bit(green, &spi_strip->pixel_buf[start]);
- __led_strip_spi_bit(red, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE]);
- __led_strip_spi_bit(blue, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * 2]);
+ uint8_t *pixel_buf = spi_strip->pixel_buf;
+ uint8_t *offset = spi_strip->led_pixel_offset;
+ memset(pixel_buf + start, 0, spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE);
+ __led_strip_spi_bit(red, &pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * offset[LED_PIXEL_INDEX_RED]]);
+ __led_strip_spi_bit(green, &pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * offset[LED_PIXEL_INDEX_GREEN]]);
+ __led_strip_spi_bit(blue, &pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * offset[LED_PIXEL_INDEX_BLUE]]);
if (spi_strip->bytes_per_pixel > 3) {
- __led_strip_spi_bit(0, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * 3]);
+ __led_strip_spi_bit(0, &pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * LED_PIXEL_INDEX_WHITE]);
}
return ESP_OK;
}
@@ -70,12 +74,14 @@ static esp_err_t led_strip_spi_set_pixel_rgbw(led_strip_t *strip, uint32_t index
ESP_RETURN_ON_FALSE(spi_strip->bytes_per_pixel == 4, ESP_ERR_INVALID_ARG, TAG, "wrong LED pixel format, expected 4 bytes per pixel");
// LED_PIXEL_FORMAT_GRBW takes 96bits(12bytes)
uint32_t start = index * spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE;
+ uint8_t *pixel_buf = spi_strip->pixel_buf;
+ uint8_t *offset = spi_strip->led_pixel_offset;
// SK6812 component order is GRBW
- memset(spi_strip->pixel_buf + start, 0, spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE);
- __led_strip_spi_bit(green, &spi_strip->pixel_buf[start]);
- __led_strip_spi_bit(red, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE]);
- __led_strip_spi_bit(blue, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * 2]);
- __led_strip_spi_bit(white, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * 3]);
+ memset(pixel_buf + start, 0, spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE);
+ __led_strip_spi_bit(red, &pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * offset[LED_PIXEL_INDEX_RED]]);
+ __led_strip_spi_bit(green, &pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * offset[LED_PIXEL_INDEX_GREEN]]);
+ __led_strip_spi_bit(blue, &pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * offset[LED_PIXEL_INDEX_BLUE]]);
+ __led_strip_spi_bit(white, &pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * offset[LED_PIXEL_INDEX_WHITE]]);
return ESP_OK;
}
@@ -186,6 +192,7 @@ esp_err_t led_strip_new_spi_device(const led_strip_config_t *led_config, const l
// clock_resolution between 2.2MHz to 2.8MHz is supported
ESP_GOTO_ON_FALSE((clock_resolution_khz < LED_STRIP_SPI_DEFAULT_RESOLUTION / 1000 + 300) && (clock_resolution_khz > LED_STRIP_SPI_DEFAULT_RESOLUTION / 1000 - 300), ESP_ERR_NOT_SUPPORTED, err,
TAG, "unsupported clock resolution:%dKHz", clock_resolution_khz);
+ ESP_GOTO_ON_ERROR(led_strip_adjust_color_order(spi_strip->led_pixel_offset, led_config->config_pixel_order, bytes_per_pixel), err, TAG, "adjust color order failed");
spi_strip->bytes_per_pixel = bytes_per_pixel;
spi_strip->strip_len = led_config->max_leds;