ESP-IDF Firmware
Firmware architecture and call graph
Loading...
Searching...
No Matches
led_strip_spi.h File Reference
#include <stdint.h>
#include "esp_err.h"
#include "driver/spi_master.h"
#include "led_strip_types.h"
Include dependency graph for led_strip_spi.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  led_strip_spi_config_t
 LED Strip SPI specific configuration. More...

Functions

esp_err_t led_strip_new_spi_device (const led_strip_config_t *led_config, const led_strip_spi_config_t *spi_config, led_strip_handle_t *ret_strip)
 Create LED strip based on SPI MOSI channel.

Function Documentation

◆ led_strip_new_spi_device()

esp_err_t led_strip_new_spi_device ( const led_strip_config_t * led_config,
const led_strip_spi_config_t * spi_config,
led_strip_handle_t * ret_strip )

Create LED strip based on SPI MOSI channel.

Note
Although only the MOSI line is used for generating the signal, the whole SPI bus can't be used for other purposes.
Parameters
led_configLED strip configuration
spi_configSPI specific configuration
ret_stripReturned LED strip 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
  • ESP_FAIL: create LED strip handle failed because some other error

Definition at line 123 of file led_strip_spi_dev.c.

124{
125 led_strip_spi_obj *spi_strip = NULL;
126 esp_err_t ret = ESP_OK;
127 ESP_GOTO_ON_FALSE(led_config && spi_config && ret_strip, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument");
128 ESP_GOTO_ON_FALSE(led_config->led_pixel_format < LED_PIXEL_FORMAT_INVALID, ESP_ERR_INVALID_ARG, err, TAG, "invalid led_pixel_format");
129 uint8_t bytes_per_pixel = 3;
130 if (led_config->led_pixel_format == LED_PIXEL_FORMAT_GRBW) {
131 bytes_per_pixel = 4;
132 } else if (led_config->led_pixel_format == LED_PIXEL_FORMAT_GRB) {
133 bytes_per_pixel = 3;
134 } else {
135 assert(false);
136 }
137 uint32_t mem_caps = MALLOC_CAP_DEFAULT;
138 if (spi_config->flags.with_dma) {
139 // DMA buffer must be placed in internal SRAM
140 mem_caps |= MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA;
141 }
142 spi_strip = heap_caps_calloc(1, sizeof(led_strip_spi_obj) + led_config->max_leds * bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE, mem_caps);
143
144 ESP_GOTO_ON_FALSE(spi_strip, ESP_ERR_NO_MEM, err, TAG, "no mem for spi strip");
145
146 spi_strip->spi_host = spi_config->spi_bus;
147 // for backward compatibility, if the user does not set the clk_src, use the default value
148 spi_clock_source_t clk_src = SPI_CLK_SRC_DEFAULT;
149 if (spi_config->clk_src) {
150 clk_src = spi_config->clk_src;
151 }
152
153 spi_bus_config_t spi_bus_cfg = {
154 .mosi_io_num = led_config->strip_gpio_num,
155 //Only use MOSI to generate the signal, set -1 when other pins are not used.
156 .miso_io_num = -1,
157 .sclk_io_num = -1,
158 .quadwp_io_num = -1,
159 .quadhd_io_num = -1,
160 .max_transfer_sz = led_config->max_leds * bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE,
161 };
162 ESP_GOTO_ON_ERROR(spi_bus_initialize(spi_strip->spi_host, &spi_bus_cfg, spi_config->flags.with_dma ? SPI_DMA_CH_AUTO : SPI_DMA_DISABLED), err, TAG, "create SPI bus failed");
163
164 if (led_config->flags.invert_out == true) {
165 esp_rom_gpio_connect_out_signal(led_config->strip_gpio_num, spi_periph_signal[spi_strip->spi_host].spid_out, true, false);
166 }
167
168 spi_device_interface_config_t spi_dev_cfg = {
169 .clock_source = clk_src,
170 .command_bits = 0,
171 .address_bits = 0,
172 .dummy_bits = 0,
173 .clock_speed_hz = LED_STRIP_SPI_DEFAULT_RESOLUTION,
174 .mode = 0,
175 //set -1 when CS is not used
176 .spics_io_num = -1,
178 };
179
180 ESP_GOTO_ON_ERROR(spi_bus_add_device(spi_strip->spi_host, &spi_dev_cfg, &spi_strip->spi_device), err, TAG, "Failed to add spi device");
181 //ensure the reset time is enough
182 esp_rom_delay_us(10);
183 int clock_resolution_khz = 0;
184 spi_device_get_actual_freq(spi_strip->spi_device, &clock_resolution_khz);
185 // TODO: ideally we should decide the SPI_BYTES_PER_COLOR_BYTE by the real clock resolution
186 // But now, let's fixed the resolution, the downside is, we don't support a clock source whose frequency is not multiple of LED_STRIP_SPI_DEFAULT_RESOLUTION
187 // clock_resolution between 2.2MHz to 2.8MHz is supported
188 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,
189 TAG, "unsupported clock resolution:%dKHz", clock_resolution_khz);
190
191 spi_strip->bytes_per_pixel = bytes_per_pixel;
192 spi_strip->strip_len = led_config->max_leds;
196 spi_strip->base.clear = led_strip_spi_clear;
197 spi_strip->base.del = led_strip_spi_del;
198
199 *ret_strip = &spi_strip->base;
200 return ESP_OK;
201err:
202 if (spi_strip) {
203 if (spi_strip->spi_device) {
204 spi_bus_remove_device(spi_strip->spi_device);
205 }
206 if (spi_strip->spi_host) {
207 spi_bus_free(spi_strip->spi_host);
208 }
209 free(spi_strip);
210 }
211 return ret;
212}
#define ESP_GOTO_ON_ERROR(x, goto_tag, log_tag, format,...)
int esp_err_t
Definition esp_err.h:21
#define ESP_OK
Definition esp_err.h:23
static esp_err_t led_strip_spi_set_pixel(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue)
static esp_err_t led_strip_spi_refresh(led_strip_t *strip)
static esp_err_t led_strip_spi_set_pixel_rgbw(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue, uint32_t white)
#define SPI_BYTES_PER_COLOR_BYTE
#define LED_STRIP_SPI_DEFAULT_TRANS_QUEUE_SIZE
static esp_err_t led_strip_spi_clear(led_strip_t *strip)
static esp_err_t led_strip_spi_del(led_strip_t *strip)
#define LED_STRIP_SPI_DEFAULT_RESOLUTION
@ LED_PIXEL_FORMAT_GRB
@ LED_PIXEL_FORMAT_INVALID
@ LED_PIXEL_FORMAT_GRBW
static const char * TAG
Definition main/main.c:31
led_pixel_format_t led_pixel_format
struct led_strip_config_t::@145177150267040163336221331365072267202117177200 flags
spi_host_device_t spi_bus
struct led_strip_spi_config_t::@242107237043306072174300312177366152113164360267 flags
spi_clock_source_t clk_src
spi_device_handle_t spi_device
spi_host_device_t spi_host
esp_err_t(* refresh)(led_strip_t *strip)
Refresh memory colors to LEDs.
esp_err_t(* set_pixel)(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue)
Set RGB for a specific pixel.
esp_err_t(* del)(led_strip_t *strip)
Free LED strip resources.
esp_err_t(* set_pixel_rgbw)(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue, uint32_t white)
Set RGBW for a specific pixel. Similar to set_pixel but also set the white component.
esp_err_t(* clear)(led_strip_t *strip)
Clear LED strip (turn off all LEDs).

References led_strip_spi_obj::base, led_strip_spi_obj::bytes_per_pixel, led_strip_t::clear, led_strip_spi_config_t::clk_src, led_strip_t::del, ESP_GOTO_ON_ERROR, ESP_OK, led_strip_config_t::flags, led_strip_spi_config_t::flags, led_strip_config_t::invert_out, led_strip_config_t::led_pixel_format, LED_PIXEL_FORMAT_GRB, LED_PIXEL_FORMAT_GRBW, LED_PIXEL_FORMAT_INVALID, led_strip_spi_clear(), LED_STRIP_SPI_DEFAULT_RESOLUTION, LED_STRIP_SPI_DEFAULT_TRANS_QUEUE_SIZE, led_strip_spi_del(), led_strip_spi_refresh(), led_strip_spi_set_pixel(), led_strip_spi_set_pixel_rgbw(), led_strip_config_t::max_leds, led_strip_t::refresh, led_strip_t::set_pixel, led_strip_t::set_pixel_rgbw, led_strip_spi_config_t::spi_bus, SPI_BYTES_PER_COLOR_BYTE, led_strip_spi_obj::spi_device, led_strip_spi_obj::spi_host, led_strip_config_t::strip_gpio_num, led_strip_spi_obj::strip_len, TAG, and led_strip_spi_config_t::with_dma.

Here is the call graph for this function: