honey_the_codewitch

SPI neopixel driving

Oct 9th, 2025 (edited)
285
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.04 KB | None | 0 0
  1. // adapted from https://github.com/8-DK/ESP32_SPI_WS2812_idf
  2. #include <stdbool.h>
  3. #include <stdint.h>
  4. #include <memory.h>
  5. #include <driver/spi_master.h>
  6. #include <esp_log.h>
  7. #include <stdio.h>
  8. static const char* TAG = "app";
  9. #define NEOPIXEL_DMA_BUFFER_SIZE (((NEOPIXEL_COUNT * 16 * (24/4)))+1)
  10.  
  11. static const uint16_t bit_pattern[16] = {
  12.     0x8888,
  13.     0x8C88,
  14.     0xC888,
  15.     0xCC88,
  16.     0x888C,
  17.     0x8C8C,
  18.     0xC88C,
  19.     0xCC8C,
  20.     0x88C8,
  21.     0x8CC8,
  22.     0xC8C8,
  23.     0xCCC8,
  24.     0x88CC,
  25.     0x8CCC,
  26.     0xC8CC,
  27.     0xCCCC
  28. };
  29. static uint16_t* dma_buffer;
  30. static volatile int dma_flushing = 0;
  31. static spi_transaction_t spi_trans;
  32. static spi_device_handle_t spi_handle;
  33. static uint32_t neopixel_colors[NEOPIXEL_COUNT];
  34. void spi_xfer_complete(spi_transaction_t *trans) {
  35.     dma_flushing = 0;
  36. }
  37. bool neopixel_update() {
  38.     while(dma_flushing) {
  39.         portYIELD();
  40.     }
  41.     dma_flushing = 1;
  42.     memset(dma_buffer,0,NEOPIXEL_DMA_BUFFER_SIZE);
  43.    
  44.     uint32_t i;
  45.     esp_err_t err;
  46.  
  47.     int n = 0;
  48.     for (i = 0; i < NEOPIXEL_COUNT; i++) {
  49.         uint32_t temp = neopixel_colors[i];// Data you want to write to each LEDs
  50.         //R
  51.         dma_buffer[n++] = bit_pattern[0x0f & (temp >>12)];
  52.         dma_buffer[n++] = bit_pattern[0x0f & (temp)>>8];
  53.  
  54.         //G
  55.         dma_buffer[n++] = bit_pattern[0x0f & (temp >>4)];
  56.         dma_buffer[n++] = bit_pattern[0x0f & (temp)];
  57.  
  58.         //B
  59.         dma_buffer[n++] = bit_pattern[0x0f & (temp >>20)];
  60.         dma_buffer[n++] = bit_pattern[0x0f & (temp)>>16];
  61.     }
  62.  
  63.     memset(&spi_trans, 0, sizeof(spi_trans));
  64.     spi_trans.length = NEOPIXEL_DMA_BUFFER_SIZE * 8; //length is in bits
  65.     spi_trans.tx_buffer = dma_buffer;
  66.     err=spi_device_queue_trans(spi_handle,&spi_trans,portMAX_DELAY);
  67.     if(ESP_OK!=err) {
  68.         dma_flushing = 0;
  69.         ESP_LOGE(TAG,"Updating neopixel returned %s",esp_err_to_name(err));
  70.         return false;
  71.     }
  72.     return true;
  73. }
  74. void app_main() {
  75.     spi_bus_config_t bus_cfg;
  76.     memset(&bus_cfg,0,sizeof(bus_cfg));
  77.     bus_cfg.mosi_io_num = NEOPIXEL_PIN;
  78.     bus_cfg.sclk_io_num = -1;
  79.     bus_cfg.miso_io_num = -1;
  80.     bus_cfg.max_transfer_sz = NEOPIXEL_DMA_BUFFER_SIZE;
  81.     if(ESP_OK!=spi_bus_initialize(NEOPIXEL_HOST,&bus_cfg,SPI_DMA_CH_AUTO)) {
  82.         ESP_LOGE(TAG,"Unable to initialize SPI bus");
  83.         return;
  84.     }
  85.     spi_device_interface_config_t dev_cfg;
  86.     memset(&dev_cfg,0,sizeof(dev_cfg));
  87.     dev_cfg.clock_speed_hz = 32*100*1000;
  88.     dev_cfg.dummy_bits = 0;
  89.     dev_cfg.queue_size = 1;
  90.     dev_cfg.post_cb = spi_xfer_complete;
  91.     dev_cfg.spics_io_num = -1;
  92.     if(ESP_OK!=spi_bus_add_device(NEOPIXEL_HOST,&dev_cfg,&spi_handle)) {
  93.         ESP_LOGE(TAG,"Could not initialize SPI device");
  94.         return;
  95.     }
  96.     if(ESP_OK!=spi_device_acquire_bus(spi_handle,portMAX_DELAY)) {
  97.         ESP_LOGE(TAG,"Could not acquire SPI bus");
  98.         return;
  99.     }
  100.     dma_buffer = (uint16_t*)heap_caps_malloc(NEOPIXEL_DMA_BUFFER_SIZE,MALLOC_CAP_DMA);
  101.     if(dma_buffer==NULL) {
  102.         ESP_LOGE(TAG,"Could not allocate DMA memory");
  103.         return;
  104.     }
  105.     memset(neopixel_colors,0,sizeof(neopixel_colors));
  106.     uint32_t ms = pdTICKS_TO_MS(xTaskGetTickCount());
  107.     for(size_t i = 0;i<NEOPIXEL_COUNT;++i) {
  108.         neopixel_colors[i]=0x3FFF;
  109.     }
  110.     if(!neopixel_update()) {
  111.         ESP_LOGE(TAG,"Error updating neopixel");
  112.     }
  113.     while(1) {
  114.         if(pdTICKS_TO_MS(xTaskGetTickCount()) >= ms+200) {
  115.             ms = pdTICKS_TO_MS(xTaskGetTickCount());
  116.             vTaskDelay(5);
  117.         }
  118.        
  119.     }
  120. }
  121. /* platformio.ini
  122. [env:esp32-s3-devkitc-1]
  123. platform = espressif32
  124. board = esp32-s3-devkitc-1
  125. framework = espidf
  126. build_flags = -DNEOPIXEL_PIN=48 -DNEOPIXEL_COUNT=1 -DNEOPIXEL_HOST=SPI3_HOST
  127. monitor_filters = esp32_exception_decoder
  128. monitor_speed = 115200
  129. upload_speed = 921600
  130. upload_port = COM13
  131. monitor_port = COM13
  132.  
  133. [env:esp32-c3-devkitm-1]
  134. platform = espressif32
  135. board = esp32-c3-devkitm-1
  136. framework = espidf
  137. build_flags = -DNEOPIXEL_PIN=8 -DNEOPIXEL_COUNT=1 -DNEOPIXEL_HOST=SPI2_HOST
  138. monitor_filters = esp32_exception_decoder
  139. monitor_speed = 115200
  140. upload_speed = 921600
  141. upload_port = COM12
  142. monitor_port = COM12
  143. */
Advertisement
Add Comment
Please, Sign In to add comment