CCCPaste

SPI neopixel driving

#include 
#include 
#include 
#include 
#include 
#include 
static const char* TAG = "app";
#define NEOPIXEL_DMA_BUFFER_SIZE (((NEOPIXEL_COUNT * 16 * (24/4)))+1)

static const uint16_t bit_pattern[16] = {
	0x8888,
	0x8C88,
	0xC888,
	0xCC88,
	0x888C,
	0x8C8C,
	0xC88C,
	0xCC8C,
	0x88C8,
	0x8CC8,
	0xC8C8,
	0xCCC8,
	0x88CC,
	0x8CCC,
	0xC8CC,
	0xCCCC
};
static uint16_t* dma_buffer;
static volatile int dma_flushing = 0;
static spi_transaction_t spi_trans;
static spi_device_handle_t spi_handle;
static uint32_t neopixel_colors[NEOPIXEL_COUNT];
void spi_xfer_complete(spi_transaction_t *trans) {
    dma_flushing = 0;
}
bool neopixel_update() {
    while(dma_flushing) {
        portYIELD();
    }
    dma_flushing = 1;
    memset(dma_buffer,0,NEOPIXEL_DMA_BUFFER_SIZE);
    
	uint32_t i;
	esp_err_t err;

	int n = 0;
	for (i = 0; i < NEOPIXEL_COUNT; i++) {
		uint32_t temp = neopixel_colors[i];// Data you want to write to each LEDs
		//R
		dma_buffer[n++] = bit_pattern[0x0f & (temp >>12)];
		dma_buffer[n++] = bit_pattern[0x0f & (temp)>>8];

		//G
		dma_buffer[n++] = bit_pattern[0x0f & (temp >>4)];
		dma_buffer[n++] = bit_pattern[0x0f & (temp)];

		//B
		dma_buffer[n++] = bit_pattern[0x0f & (temp >>20)];
		dma_buffer[n++] = bit_pattern[0x0f & (temp)>>16];
	}

	memset(&spi_trans, 0, sizeof(spi_trans));
	spi_trans.length = NEOPIXEL_DMA_BUFFER_SIZE * 8; //length is in bits
	spi_trans.tx_buffer = dma_buffer;
    err=spi_device_queue_trans(spi_handle,&spi_trans,portMAX_DELAY);
    if(ESP_OK!=err) {
        dma_flushing = 0;
        ESP_LOGE(TAG,"Updating neopixel returned %s",esp_err_to_name(err));
        return false;
    }
    return true;
}
void app_main() {
    spi_bus_config_t bus_cfg;
    memset(&bus_cfg,0,sizeof(bus_cfg));
    bus_cfg.mosi_io_num = NEOPIXEL_PIN;
    bus_cfg.sclk_io_num = -1;
    bus_cfg.miso_io_num = -1;
    bus_cfg.max_transfer_sz = NEOPIXEL_DMA_BUFFER_SIZE;
    if(ESP_OK!=spi_bus_initialize(NEOPIXEL_HOST,&bus_cfg,SPI_DMA_CH_AUTO)) {
        ESP_LOGE(TAG,"Unable to initialize SPI bus");
        return;
    }
    spi_device_interface_config_t dev_cfg;
    memset(&dev_cfg,0,sizeof(dev_cfg));
    dev_cfg.clock_speed_hz = 32*100*1000;
    dev_cfg.dummy_bits = 0;
    dev_cfg.queue_size = 1;
    dev_cfg.post_cb = spi_xfer_complete;
    dev_cfg.spics_io_num = -1;
    if(ESP_OK!=spi_bus_add_device(NEOPIXEL_HOST,&dev_cfg,&spi_handle)) {
        ESP_LOGE(TAG,"Could not initialize SPI device");
        return;
    }
    if(ESP_OK!=spi_device_acquire_bus(spi_handle,portMAX_DELAY)) {
        ESP_LOGE(TAG,"Could not acquire SPI bus");
        return;
    }
    dma_buffer = (uint16_t*)heap_caps_malloc(NEOPIXEL_DMA_BUFFER_SIZE,MALLOC_CAP_DMA);
    if(dma_buffer==NULL) {
        ESP_LOGE(TAG,"Could not allocate DMA memory");
        return;
    }
    memset(neopixel_colors,0,sizeof(neopixel_colors));
    uint32_t ms = pdTICKS_TO_MS(xTaskGetTickCount());
    for(size_t i = 0;i= ms+200) {
            ms = pdTICKS_TO_MS(xTaskGetTickCount());
            vTaskDelay(5);
        }
        
    }
}
/* platformio.ini
[env:esp32-s3-devkitc-1]
platform = espressif32
board = esp32-s3-devkitc-1
framework = espidf
build_flags = -DNEOPIXEL_PIN=48 -DNEOPIXEL_COUNT=1 -DNEOPIXEL_HOST=SPI3_HOST
monitor_filters = esp32_exception_decoder
monitor_speed = 115200
upload_speed = 921600
upload_port = COM13
monitor_port = COM13

[env:esp32-c3-devkitm-1]
platform = espressif32
board = esp32-c3-devkitm-1
framework = espidf
build_flags = -DNEOPIXEL_PIN=8 -DNEOPIXEL_COUNT=1 -DNEOPIXEL_HOST=SPI2_HOST
monitor_filters = esp32_exception_decoder
monitor_speed = 115200
upload_speed = 921600
upload_port = COM12
monitor_port = COM12
*/