led_strip_spi - SPI-based driver for SK9822/APA102
Supported LEDs
The driver supports the following LEDs.
SK9822
APA102
Warning
The driver should work with APA102, but not tested.
Supported targets
The driver supports the following targets.
ESP32-family, including ESP32S2
ESP8266
Because the SPI driver in esp-idf differs from the one in ESP8266 RTOS SDK, the members of led_strip_spi_t — a descriptor to configure and manage LED strip — are different.
Note
If you have better ideas to unify the two structures, I would love to hear.
Usage
Call led_strip_spi_install()
.
#include <led_strip_spi.h>
ESP_ERROR_CHECK(led_strip_spi_install());
Create led_strip_spi_t
and initialize it with LED_STRIP_SPI_DEFAULT()
.
led_strip_spi_t strip = LED_STRIP_SPI_DEFAULT();
Configure the LED strip descriptor. First, set length.
strip.length = N_PIXEL;
led_strip_spi_t
is an alias of either led_strip_spi_esp32_t
or
led_strip_spi_esp8266_t
.
For ESP32, provide spi_device_handle_t, and set max_transfer_sz to the
maximum size of the SPI data to transfer. LED_STRIP_SPI_BUFFER_SIZE()
macro is
provided to calculate the size from the number of pixels. Optionally, set SPI
bus clock speed.
#if HELPER_TARGET_IS_ESP32
spi_device_handle_t device_handle;
strip.device_handle = device_handle;
strip.max_transfer_sz = LED_STRIP_SPI_BUFFER_SIZE(N_PIXEL);
strip.clock_speed_hz = 1000000 * 10;
#endif
Then, call led_strip_spi_init()
.
led_strip_spi_init(&strip);
The strip is now ready. Use led_strip_spi_set_pixel()
and other functions to
modify the buffer. The buffer is sent to the bus when calling
led_strip_spi_flush()
. See the example provided.
SPI signals and GPIO pins
The driver uses hardware SPI to drive LED strip. While ESP32-family chips can route SPI signals to GPIOs using GPIO matrix, ESP8266 cannot.
SPI clock speed
On ESP32, dedicated IO_MUX pins can clock faster (80Mhz) than GPIO pins through GPIO matrix (40Mhz), but the maximum clock frequency of SK9822 is 30Mhz, which is below the maximum clock frequency of GPIO matrix. As such, IO_MUX has no practical benefits here.
Known issues
SK9822 has bits to control global brightness, but the driver does not support it yet.
- group led_strip_spi_esp32
Defines
-
LED_STRIP_SPI_DEFAULT_HOST_DEVICE
Default is
SPI2_HOST
(HSPI_HOST
ifesp-idf
version is v3.x).
-
LED_STRIP_SPI_DEFAULT_MOSI_IO_NUM
GPIO pin number of
LED_STRIP_SPI_DEFAULT_HOST_DEVICE
’s MOSI (default is 13 for ESP32, 7 for ESP32C3)
-
LED_STRIP_SPI_DEFAULT_SCLK_IO_NUM
GPIO pin number of
LED_STRIP_SPI_DEFAULT_HOST_DEVICE
’s SCLK (default is 14 for ESP32, 6 for ESP32C3)
-
LED_STRIP_SPI_DEFAULT_DMA_CHAN
Default DMA channel to use.
Default is
SPI_DMA_CH_AUTO
for ESP-IDF v4.3 and newer, 1 for older versions.
-
LED_STRIP_SPI_DEFAULT_ESP32()
Macro to initialize led_strip_spi_esp32_t.
buf
:NULL
,length
: 1,host_device
:LED_STRIP_SPI_DEFAULT_HOST_DEVICE
,mosi_io_num
:LED_STRIP_SPI_DEFAULT_MOSI_IO_NUM
,max_transfer_sz
: 0,clock_speed_hz
: 1000000,queue_size
: 1,device_handle
:NULL
,dma_chan
: 1
-
struct led_strip_spi_esp32_t
- #include <led_strip_spi_esp32.h>
LED strip descriptor for ESP32-family.
Public Members
-
int mosi_io_num
GPIO number of SPI MOSI.
-
int sclk_io_num
GPIO number of SPI SCLK.
-
int max_transfer_sz
Maximum transfer size in bytes. Defaults to 4094 if 0.
-
int clock_speed_hz
Clock speed in Hz.
-
int queue_size
Queue size used by
spi_device_queue_trans()
.
-
spi_device_handle_t device_handle
Device handle assigned by the driver. The caller must provdie this.
-
int dma_chan
DMA channed to use. Either 1 or 2.
-
spi_transaction_t transaction
SPI transaction used internally by the driver.
-
int mosi_io_num
-
LED_STRIP_SPI_DEFAULT_HOST_DEVICE
- group led_strip_spi_esp8266
Defines
-
LED_STRIP_SPI_DEFAULT_ESP8266()
A macro to initialize led_strip_spi_esp8266_t.
length
: 1clk_div
: SPI_2MHz_DIV
-
struct led_strip_spi_esp8266_t
- #include <led_strip_spi_esp8266.h>
LED strip descriptor for ESP8266.
-
LED_STRIP_SPI_DEFAULT_ESP8266()
- group led_strip_spi
Defines
-
LED_STRIP_SPI_MAX_BRIGHTNESS
Maximum brightness value for a pixel.
Functions
-
esp_err_t led_strip_spi_install()
Setup the driver.
This method must be called before any other led_strip_spi methods
- Returns:
ESP_OK
on success
-
esp_err_t led_strip_spi_init(led_strip_spi_t *strip)
Initialize LED strip and allocate buffer memory.
- Parameters:
strip – Descriptor of LED strip
- Returns:
ESP_OK
on success
-
esp_err_t led_strip_spi_free(led_strip_spi_t *strip)
Free LED strip.
- Parameters:
strip – Descriptor of LED strip
- Returns:
ESP_OK
on success
-
esp_err_t led_strip_spi_flush(led_strip_spi_t *strip)
Send strip buffer to LEDs.
- Parameters:
strip – Descriptor of LED strip
- Returns:
ESP_OK
on success
-
esp_err_t led_strip_spi_set_pixel(led_strip_spi_t *strip, const int num, const rgb_t color)
Set color of single LED in strip.
This function does not actually change colors of the LEDs. Call led_strip_spi_flush() to send buffer to the LEDs.
- Parameters:
strip – Descriptor of LED strip
num – LED number, [0:strip.length - 1].
color – RGB color
- Returns:
ESP_OK
on success
-
esp_err_t led_strip_spi_set_pixel_brightness(led_strip_spi_t *strip, const int num, const rgb_t color, const uint8_t brightness)
Set color of single LED in strip.
This function does not actually change colors of the LEDs. Call led_strip_spi_flush() to send buffer to the LEDs.
- Parameters:
strip – Descriptor of LED strip
num – LED number, [0:strip.length - 1].
color – RGB color
brightness – Brightness of the LED, [0:100].
- Returns:
ESP_OK
on success
-
esp_err_t led_strip_spi_set_pixels(led_strip_spi_t *strip, const int start, size_t len, const rgb_t data)
Set colors of multiple LEDs.
This function does not actually change colors of the LEDs. Call led_strip_spi_flush() to send buffer to the LEDs.
- Parameters:
strip – Descriptor of LED strip
start – First LED index, 0-based
len – Number of LEDs
data – Pointer to RGB data
- Returns:
ESP_OK
on success
-
esp_err_t led_strip_spi_set_pixels_brightness(led_strip_spi_t *strip, const int start, size_t len, const rgb_t data, const uint8_t brightness)
Set colors of multiple LEDs.
This function does not actually change colors of the LEDs. Call led_strip_spi_flush() to send buffer to the LEDs.
- Parameters:
strip – Descriptor of LED strip
start – First LED index, 0-based
len – Number of LEDs
data – Pointer to RGB data
brightness – Brightness of the LED, [0:100].
- Returns:
ESP_OK
on success
-
esp_err_t led_strip_spi_fill(led_strip_spi_t *strip, size_t start, size_t len, rgb_t color)
Set multiple LEDs to the one color.
This function does not actually change colors of the LEDs. Call led_strip_spi_flush() to send buffer to the LEDs.
- Parameters:
strip – Descriptor of LED strip
start – First LED index, 0-based
len – Number of LEDs
color – RGB color
- Returns:
ESP_OK
on success
-
esp_err_t led_strip_spi_fill_brightness(led_strip_spi_t *strip, size_t start, size_t len, rgb_t color, const uint8_t brightness)
Set multiple LEDs to the one color.
This function does not actually change colors of the LEDs. Call led_strip_spi_flush() to send buffer to the LEDs.
- Parameters:
strip – Descriptor of LED strip
start – First LED index, 0-based
len – Number of LEDs
color – RGB color
brightness – Brightness of the LEDs, [0:100].
- Returns:
ESP_OK
on success
-
LED_STRIP_SPI_MAX_BRIGHTNESS
- group led_strip_spi_sk9822
Functions and macros for SK9822 LED strips.
SPI data frame consists of:
A start frame of 32 zero bits (<0x00> <0x00> <0x00> <0x00>).
32 bit LED frames for each LED in the string (<0xE0+brightness> <blue> <green> <red>).
A SK9822 reset frame of 32 zero bits (<0x00> <0x00> <0x00> <0x00>).
An end frame consisting of at least (n/2) bits of 1, where n is the number of LEDs in the string.
For the details, see SK9822 – a clone of the APA102? and Understanding the APA102 “Superled”.
Defines
-
LED_STRIP_SPI_FRAME_SK9822_START_SIZE
The size in bytes of start frame.
-
LED_STRIP_SPI_FRAME_SK9822_LED_SIZE
The size in bytes of each LED frame.
-
LED_STRIP_SPI_FRAME_SK9822_LEDS_SIZE(N_PIXEL)
Total size in bytes of all LED frames in a strip.
N_PIXEL
is the number of pixels in the strip.
-
LED_STRIP_SPI_FRAME_SK9822_RESET_SIZE
The size in bytes of reset frame.
-
LED_STRIP_SPI_FRAME_SK9822_END_SIZE(N_PIXEL)
The size in bytes of the last frame.
N_PIXEL
is the number of pixels in the strip.
-
LED_STRIP_SPI_FRAME_SK9822_LED_MSB3
A magic number of [31:29] in LED frames. The bits must be 1 (APA102, SK9822)
-
LED_STRIP_SPI_FRAME_SK9822_LED_BRIGHTNESS_BITS
Number of bits used to describe the brightness of the LED.
-
LED_STRIP_SPI_BUFFER_SIZE(N_PIXEL)
A macro to caliculate required size of buffer.
N_PIXEL
is the number of pixels in the strip.
Functions
-
esp_err_t led_strip_spi_sk9822_buf_init(led_strip_spi_t *strip)
Initialize the buffer of SK9822 strip.
- Parameters:
strip – [in] LED strip descriptor to initialize
- Returns:
ESP_OK
on success
-
esp_err_t led_strip_spi_set_pixel_sk9822(led_strip_spi_t *strip, size_t num, rgb_t color, uint8_t brightness)
Set color of a pixel of SK9822 strip.
- Parameters:
strip – [in] LED strip descriptor.
num – [in] Index of the LED pixel (zero-based).
color – [in] The color to set.
brightness – [in] The brightness to set, [0:100].
- Returns:
ESP_OK
on success.