Skip to content
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

feat(led_strip): support led strip group based on parlio_tx #463

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions led_strip/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 3.1.0

- Support for led strip group based on the Parallel IO backend
- new interface type led_strip_group_handle
- new API led_strip_group_get_strip_handle
- new API led_strip_group_del

## 3.0.0

- Discontinued support for ESP-IDF v4.x
Expand Down
6 changes: 5 additions & 1 deletion led_strip/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ if(CONFIG_SOC_RMT_SUPPORTED)
list(APPEND srcs "src/led_strip_rmt_dev.c" "src/led_strip_rmt_encoder.c")
endif()

if(CONFIG_SOC_PARLIO_SUPPORTED)
list(APPEND srcs "src/led_strip_parlio_dev.c")
endif()

# the SPI backend driver relies on some feature that was available in IDF 5.1
if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER_EQUAL "5.1")
if(CONFIG_SOC_GPSPI_SUPPORTED)
Expand All @@ -16,7 +20,7 @@ endif()

# Starting from esp-idf v5.3, the RMT and SPI drivers are moved to separate components
if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER_EQUAL "5.3")
list(APPEND public_requires "esp_driver_rmt" "esp_driver_spi")
list(APPEND public_requires "esp_driver_rmt" "esp_driver_spi" "esp_driver_parlio" "esp_driver_gpio")
else()
list(APPEND public_requires "driver")
endif()
Expand Down
52 changes: 52 additions & 0 deletions led_strip/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,58 @@ ESP_ERROR_CHECK(led_strip_new_spi_device(&strip_config, &spi_config, &led_strip)

The number of LED strip objects can be created depends on how many free SPI buses are free to use in your project.

### The [Parallel IO](https://docs.espressif.com/projects/esp-idf/en/latest/esp32h2/api-reference/peripherals/parlio.html) Peripheral

Parallel IO peripheral can also be used to generate the timing required by the LED strip. Since the Parallel IO peripheral is a parallel interface, we manage it through groups. The number of LED strips supported in a strip group depends on the maximum data width of the Parallel IO tx_unit.
The strip_handle obtained through **get_strip_handle** API is consistent with the handles used in RMT backend and SPI backend. However, it cannot be deleted individually. Call **group_del** API to delete the entire group.

Please note, the Parallel IO backend has a dependency of **ESP-IDF >= 5.1**

#### Allocate LED Strip Object with Parallel IO Backend

```c
#define LED_STRIP_COUNT 4
#define LED_STRIP0_GPIO_PIN 0
#define LED_STRIP1_GPIO_PIN 1
#define LED_STRIP2_GPIO_PIN 2
#define LED_STRIP3_GPIO_PIN 3

/// LED strip common configuration
led_strip_config_t strip_config = {
.max_leds = 1, // The number of LEDs in the strip,
.led_model = LED_MODEL_WS2812, // LED strip model, it determines the bit timing
.color_component_format = LED_STRIP_COLOR_COMPONENT_FMT_GRB, // The color component format is G-R-B
.flags = {
.invert_out = false, // don't invert the output signal
}
};

/// Parallel IO backend specific configuration
led_strip_parlio_config_t parlio_config = {
.clk_src = PARLIO_CLK_SRC_DEFAULT, // different clock source can lead to different power consumption
.strip_count = LED_STRIP_COUNT,
.strip_gpio_num = {
LED_STRIP0_GPIO_PIN,
LED_STRIP1_GPIO_PIN,
LED_STRIP2_GPIO_PIN,
LED_STRIP3_GPIO_PIN,
...,
},
};

/// Create the LED strip group object
led_strip_group_handle_t parlio_group;
ESP_ERROR_CHECK(led_strip_new_parlio_group(&strip_config, &parlio_config, &parlio_group));

/// get the LED strip object
led_strip_handle_t *led_strip = calloc(LED_STRIP_COUNT, sizeof(led_strip_handle_t));
for(int i = 0; i < LED_STRIP_COUNT; i++) {
ESP_ERROR_CHECK(led_strip_group_get_strip_handle(parlio_group, i, &led_strip[i]));
}
```

The number of LED strip group objects can be created depends on how many free Parallel IO TX unit are free to use in your project.

## FAQ

* Which led_strip backend should I choose?
Expand Down
152 changes: 151 additions & 1 deletion led_strip/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## Header files

- [include/led_strip.h](#file-includeled_striph)
- [include/led_strip_parlio.h](#file-includeled_strip_parlioh)
- [include/led_strip_rmt.h](#file-includeled_strip_rmth)
- [include/led_strip_spi.h](#file-includeled_strip_spih)
- [include/led_strip_types.h](#file-includeled_strip_typesh)
Expand All @@ -16,6 +17,8 @@
| ---: | :--- |
| esp\_err\_t | [**led\_strip\_clear**](#function-led_strip_clear) ([**led\_strip\_handle\_t**](#typedef-led_strip_handle_t) strip) <br>_Clear LED strip (turn off all LEDs)_ |
| esp\_err\_t | [**led\_strip\_del**](#function-led_strip_del) ([**led\_strip\_handle\_t**](#typedef-led_strip_handle_t) strip) <br>_Free LED strip resources._ |
| esp\_err\_t | [**led\_strip\_group\_del**](#function-led_strip_group_del) ([**led\_strip\_group\_handle\_t**](#typedef-led_strip_group_handle_t) group) <br>_Delete the LED strip group._ |
| esp\_err\_t | [**led\_strip\_group\_get\_strip\_handle**](#function-led_strip_group_get_strip_handle) ([**led\_strip\_group\_handle\_t**](#typedef-led_strip_group_handle_t) group, uint8\_t index, [**led\_strip\_handle\_t**](#typedef-led_strip_handle_t) \*ret\_strip) <br>_Get the handle of the LED strip._ |
| esp\_err\_t | [**led\_strip\_refresh**](#function-led_strip_refresh) ([**led\_strip\_handle\_t**](#typedef-led_strip_handle_t) strip) <br>_Refresh memory colors to LEDs._ |
| esp\_err\_t | [**led\_strip\_set\_pixel**](#function-led_strip_set_pixel) ([**led\_strip\_handle\_t**](#typedef-led_strip_handle_t) strip, uint32\_t index, uint32\_t red, uint32\_t green, uint32\_t blue) <br>_Set RGB for a specific pixel._ |
| 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) <br>_Set HSV for a specific pixel._ |
Expand Down Expand Up @@ -61,6 +64,48 @@ esp_err_t led_strip_del (
- ESP\_OK: Free resources successfully
- ESP\_FAIL: Free resources failed because error occurred

### function `led_strip_group_del`

_Delete the LED strip group._

```c
esp_err_t led_strip_group_del (
led_strip_group_handle_t group
)
```

**Parameters:**

- `group` Handle of the LED strip group

**Returns:**

- ESP\_OK: Delete the LED strip group successfully
- ESP\_ERR\_INVALID\_ARG: Invalid argument

### function `led_strip_group_get_strip_handle`

_Get the handle of the LED strip._

```c
esp_err_t led_strip_group_get_strip_handle (
led_strip_group_handle_t group,
uint8_t index,
led_strip_handle_t *ret_strip
)
```

**Parameters:**

- `group` LED strip group handle
- `index` Index of the LED strip in the group
- `ret_strip` Pointer to store the handle of the LED strip

**Returns:**

- ESP\_OK: Get the handle of the LED strip successfully
- ESP\_ERR\_INVALID\_ARG: Invalid argument

### function `led_strip_refresh`

_Refresh memory colors to LEDs._
Expand Down Expand Up @@ -178,6 +223,65 @@ 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

## File include/led_strip_parlio.h

## Structures and Types

| Type | Name |
| ---: | :--- |
| struct | [**led\_strip\_parlio\_config\_t**](#struct-led_strip_parlio_config_t) <br>_LED Strip PARLIO specific configuration._ |

## Functions

| Type | Name |
| ---: | :--- |
| esp\_err\_t | [**led\_strip\_new\_parlio\_group**](#function-led_strip_new_parlio_group) (const [**led\_strip\_config\_t**](#struct-led_strip_config_t) \*led\_config, const [**led\_strip\_parlio\_config\_t**](#struct-led_strip_parlio_config_t) \*parlio\_config, [**led\_strip\_group\_handle\_t**](#typedef-led_strip_group_handle_t) \*ret\_group) <br>_Create LED strip group based on PARLIO\_TX unit._ |

## Structures and Types Documentation

### struct `led_strip_parlio_config_t`

_LED Strip PARLIO specific configuration._

Variables:

- parlio\_clock\_source\_t clk_src <br>PARLIO clock source

- uint8\_t strip_count <br>Number of LED strips. Should be a power of 2 and not larger than SOC\_PARLIO\_TX\_UNIT\_MAX\_DATA\_WIDTH

- gpio\_num\_t strip_gpio_num <br>GPIO number that used by LED strip

## Functions Documentation

### function `led_strip_new_parlio_group`

_Create LED strip group based on PARLIO\_TX unit._

```c
esp_err_t led_strip_new_parlio_group (
const led_strip_config_t *led_config,
const led_strip_parlio_config_t *parlio_config,
led_strip_group_handle_t *ret_group
)
```

**Note:**

The strip\_gpio\_num in led\_config no longer takes effect, and other configurations will be shared by all LED strips in the group.

**Parameters:**

- `led_config` LED strip configuration
- `parlio_config` PARLIO specific configuration
- `ret_group` Returned LED strip group handle

**Returns:**

- ESP\_OK: create LED strip handle successfully
- ESP\_ERR\_INVALID\_ARG: create LED strip handle failed because of invalid argument
- ESP\_ERR\_NOT\_SUPPORTED: create LED strip handle failed because of unsupported configuration
- ESP\_ERR\_NO\_MEM: create LED strip handle failed because of out of memory

## File include/led_strip_rmt.h

## Structures and Types
Expand Down Expand Up @@ -315,6 +419,7 @@ Although only the MOSI line is used for generating the signal, the whole SPI bus
| enum | [**led\_model\_t**](#enum-led_model_t) <br>_LED strip model._ |
| struct | [**led\_strip\_config\_t**](#struct-led_strip_config_t) <br>_LED Strip common configurations The common configurations are not specific to any backend peripheral._ |
| struct | [**led\_strip\_extra\_flags**](#struct-led_strip_config_tled_strip_extra_flags) <br> |
| typedef struct [**led\_strip\_group\_t**](#struct-led_strip_group_t) \* | [**led\_strip\_group\_handle\_t**](#typedef-led_strip_group_handle_t) <br>_Type of LED strip group handle._ |
| typedef struct [**led\_strip\_t**](#struct-led_strip_t) \* | [**led\_strip\_handle\_t**](#typedef-led_strip_handle_t) <br>_Type of LED strip handle._ |

## Macros
Expand Down Expand Up @@ -366,6 +471,7 @@ _LED strip model._
enum led_model_t {
LED_MODEL_WS2812,
LED_MODEL_SK6812,
LED_MODEL_WS2811,
LED_MODEL_INVALID
};
```
Expand Down Expand Up @@ -396,6 +502,14 @@ Variables:

- uint32\_t invert_out <br>Invert output signal

### typedef `led_strip_group_handle_t`

_Type of LED strip group handle._

```c
typedef struct led_strip_group_t* led_strip_group_handle_t;
```

### typedef `led_strip_handle_t`

_Type of LED strip handle._
Expand Down Expand Up @@ -438,11 +552,47 @@ _Helper macros to set the color component format._

| Type | Name |
| ---: | :--- |
| struct | [**led\_strip\_group\_t**](#struct-led_strip_group_t) <br>_LED strip group interface definition._ |
| typedef struct [**led\_strip\_group\_t**](#struct-led_strip_group_t) | [**led\_strip\_group\_t**](#typedef-led_strip_group_t) <br> |
| struct | [**led\_strip\_t**](#struct-led_strip_t) <br>_LED strip interface definition._ |
| typedef struct led\_strip\_t | [**led\_strip\_t**](#typedef-led_strip_t) <br> |
| typedef struct [**led\_strip\_t**](#struct-led_strip_t) | [**led\_strip\_t**](#typedef-led_strip_t) <br> |

## Structures and Types Documentation

### struct `led_strip_group_t`

_LED strip group interface definition._

Variables:

- esp\_err\_t(\* del <br>_Free LED strip group resources._<br>**Parameters:**

- `group` LED strip group

**Returns:**

- ESP\_OK: Free resources successfully
- ESP\_FAIL: Free resources failed because error occurred

- esp\_err\_t(\* get_strip_handle <br>_Get LED strip handle by index._<br>**Parameters:**

- `group` LED strip group
- `index` LED strip index
- `ret_strip` Retured LED strip handle

**Returns:**

- ESP\_OK: Success
- ESP\_ERR\_INVALID\_ARG: Invalid argument

### typedef `led_strip_group_t`

```c
typedef struct led_strip_group_t led_strip_group_t;
```

Type of LED group strip

### struct `led_strip_t`

_LED strip interface definition._
Expand Down
6 changes: 6 additions & 0 deletions led_strip/examples/led_strip_parlio_ws2812/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
cmake_minimum_required(VERSION 3.16)

set(COMPONENTS main)

include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(led_strip_parlio_ws2812)
31 changes: 31 additions & 0 deletions led_strip/examples/led_strip_parlio_ws2812/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# LED Strip Example (Parallel IO backend + WS2812)

This example demonstrates how to blink the WS2812 LED using the [led_strip](https://components.espressif.com/component/espressif/led_strip) component.

## How to Use Example

### Hardware Required

* A development board with Espressif SoC
* A USB cable for Power supply and programming
* WS2812 LED strip

### Configure the Example

Before project configuration and build, be sure to set the correct chip target using `idf.py set-target <chip_name>`. Then assign the proper GPIO in the [source file](main/led_strip_parlio_ws2812_main.c). If your led strip has multiple LEDs, don't forget update the number.

### Build and Flash

Run `idf.py -p PORT build flash monitor` to build, flash and monitor the project.

(To exit the serial monitor, type ``Ctrl-]``.)

See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects.

## Example Output

```text
I (299) gpio: GPIO[14]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
I (309) example: Created LED strip object with PARLIO backend
I (309) example: Start blinking LED strip
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
idf_component_register(SRCS "led_strip_parlio_ws2812_main.c"
INCLUDE_DIRS ".")
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
## IDF Component Manager Manifest File
dependencies:
espressif/led_strip:
version: '^3'
override_path: '../../../'
idf: ">=5.1"
Loading
Loading