From f56bc2d4434fa455aceac8ca0eab30c3e939f321 Mon Sep 17 00:00:00 2001 From: crosstyan Date: Mon, 10 Nov 2025 10:24:55 +0800 Subject: [PATCH] refactor: improve SPI data transmission for LED strip handling --- src/led_strip_spi_dev.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/led_strip_spi_dev.c b/src/led_strip_spi_dev.c index 81e0259..81be029 100644 --- a/src/led_strip_spi_dev.c +++ b/src/led_strip_spi_dev.c @@ -3,15 +3,18 @@ * * SPDX-License-Identifier: Apache-2.0 */ +#include #include #include #include #include "esp_log.h" #include "esp_check.h" +#include "esp_private/spi_common_internal.h" #include "esp_rom_gpio.h" #include "soc/spi_periph.h" #include "led_strip.h" #include "led_strip_interface.h" +#include "driver/spi_common.h" #define LED_STRIP_SPI_DEFAULT_RESOLUTION (2.5 * 1000 * 1000) // 2.5MHz resolution #define LED_STRIP_SPI_DEFAULT_TRANS_QUEUE_SIZE 4 @@ -93,10 +96,28 @@ static esp_err_t led_strip_spi_refresh(led_strip_t *strip) spi_transaction_t tx_conf; memset(&tx_conf, 0, sizeof(tx_conf)); - tx_conf.length = spi_strip->strip_len * spi_strip->bytes_per_pixel * SPI_BITS_PER_COLOR_BYTE; - tx_conf.tx_buffer = spi_strip->pixel_buf; + spi_bus_attr_t *bus_attr = spi_bus_get_attr(spi_strip->spi_host); + ESP_RETURN_ON_FALSE(bus_attr, ESP_ERR_INVALID_STATE, TAG, "SPI bus not initialized"); + + size_t acc = 0; + const size_t max_transfer_sz = bus_attr->max_transfer_sz; + const size_t chunk_size = max_transfer_sz - 1; + const size_t total_bytes = spi_strip->strip_len * spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE; + tx_conf.rx_buffer = NULL; - ESP_RETURN_ON_ERROR(spi_device_transmit(spi_strip->spi_device, &tx_conf), TAG, "transmit pixels by SPI failed"); + + // Transfer data in chunks + while (acc < total_bytes) { + size_t remaining_bytes = total_bytes - acc; + size_t transfer_bytes = (remaining_bytes > chunk_size) ? chunk_size : remaining_bytes; + + tx_conf.length = transfer_bytes * 8; // Convert bytes to bits + tx_conf.tx_buffer = spi_strip->pixel_buf + acc; + + ESP_RETURN_ON_ERROR(spi_device_polling_transmit(spi_strip->spi_device, &tx_conf), TAG, "transmit pixels by SPI failed"); + + acc += transfer_bytes; + } return ESP_OK; } @@ -175,6 +196,7 @@ esp_err_t led_strip_new_spi_device(const led_strip_config_t *led_config, const l .quadwp_io_num = -1, .quadhd_io_num = -1, .max_transfer_sz = led_config->max_leds * bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE, + .flags = SPICOMMON_BUSFLAG_MOSI, }; 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"); @@ -192,6 +214,7 @@ esp_err_t led_strip_new_spi_device(const led_strip_config_t *led_config, const l //set -1 when CS is not used .spics_io_num = -1, .queue_size = LED_STRIP_SPI_DEFAULT_TRANS_QUEUE_SIZE, + .flags = SPI_DEVICE_HALFDUPLEX, }; 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");