#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
*/