// adapted from https://github.com/8-DK/ESP32_SPI_WS2812_idf #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 */