diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..974e708 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,26 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# top-most EditorConfig file +root = true + +# Unix-style newlines with a newline ending every file +[*] +end_of_line = lf +insert_final_newline = true +# Set default charset +charset = utf-8 + +# 4 space indentation +[*.{c, h, cpp}] +indent_style = space +indent_size = 4 + +# Tab indentation (no size specified) +[Makefile] +indent_style = tab + +# Matches the exact files either package.json or .travis.yml +[{package.json,.travis.yml}] +indent_style = space +indent_size = 2 + diff --git a/esp_ws28xx.c b/esp_ws28xx.c index 3e27113..d64fa17 100644 --- a/esp_ws28xx.c +++ b/esp_ws28xx.c @@ -1,115 +1,107 @@ #include "esp_ws28xx.h" -uint16_t *dma_buffer; -CRGB *ws28xx_pixels; +uint16_t* dma_buffer; +CRGB* ws28xx_pixels; static int n_of_leds, reset_delay, dma_buf_size; led_strip_model_t led_model; -static spi_settings_t spi_settings = { - .host = SPI2_HOST, - .dma_chan = SPI_DMA_CH_AUTO, - .buscfg = - { - .miso_io_num = -1, - .sclk_io_num = -1, - .quadwp_io_num = -1, - .quadhd_io_num = -1, - }, - .devcfg = { - .clock_speed_hz = 3.2 * 1000 * 1000, // Clock out at 3.2 MHz - .mode = 0, // SPI mode 0 - .spics_io_num = -1, // CS pin - .queue_size = 1, - .command_bits = 0, - .address_bits = 0, - .flags = SPI_DEVICE_TXBIT_LSBFIRST, - }}; +static spi_settings_t spi_settings = {.host = SPI2_HOST, + .dma_chan = SPI_DMA_CH_AUTO, + .buscfg = + { + .miso_io_num = -1, + .sclk_io_num = -1, + .quadwp_io_num = -1, + .quadhd_io_num = -1, + }, + .devcfg = { + .clock_speed_hz = 3.2 * 1000 * 1000, // Clock out at 3.2 MHz + .mode = 0, // SPI mode 0 + .spics_io_num = -1, // CS pin + .queue_size = 1, + .command_bits = 0, + .address_bits = 0, + .flags = SPI_DEVICE_TXBIT_LSBFIRST, + }}; -esp_err_t ws28xx_init(int pin, led_strip_model_t model, int num_of_leds, - CRGB **led_buffer_ptr) { - esp_err_t err = ESP_OK; - n_of_leds = num_of_leds; - led_model = model; - dma_buf_size = - n_of_leds * 12 + - (reset_delay + 1) * - 2; // 12 bytes for each led + bytes for initial zero and reset state - ws28xx_pixels = malloc(sizeof(CRGB) * n_of_leds); - if (ws28xx_pixels == NULL) { - return ESP_ERR_NO_MEM; - } - *led_buffer_ptr = ws28xx_pixels; - spi_settings.buscfg.mosi_io_num = pin; - spi_settings.buscfg.max_transfer_sz = dma_buf_size; - err = spi_bus_initialize(spi_settings.host, &spi_settings.buscfg, - spi_settings.dma_chan); - if (err != ESP_OK) { - free(ws28xx_pixels); - return err; - } - err = spi_bus_add_device(spi_settings.host, &spi_settings.devcfg, - &spi_settings.spi); - if (err != ESP_OK) { - free(ws28xx_pixels); - return err; - } - reset_delay = (model == WS2812B) - ? 3 - : 30; // insrease if something breaks. values are less that - // recommended in datasheets but seem stable - dma_buffer = heap_caps_malloc(dma_buf_size, - MALLOC_CAP_DMA); // Critical to be DMA memory. - if (dma_buffer == NULL) { - free(ws28xx_pixels); - return ESP_ERR_NO_MEM; - } - return ESP_OK; +esp_err_t ws28xx_init(int pin, led_strip_model_t model, int num_of_leds, CRGB** led_buffer_ptr) { + esp_err_t err = ESP_OK; + n_of_leds = num_of_leds; + led_model = model; + dma_buf_size = + n_of_leds * 12 + (reset_delay + 1) * 2; // 12 bytes for each led + bytes for initial zero and reset state + ws28xx_pixels = malloc(sizeof(CRGB) * n_of_leds); + if (ws28xx_pixels == NULL) { + return ESP_ERR_NO_MEM; + } + *led_buffer_ptr = ws28xx_pixels; + spi_settings.buscfg.mosi_io_num = pin; + spi_settings.buscfg.max_transfer_sz = dma_buf_size; + err = spi_bus_initialize(spi_settings.host, &spi_settings.buscfg, spi_settings.dma_chan); + if (err != ESP_OK) { + free(ws28xx_pixels); + return err; + } + err = spi_bus_add_device(spi_settings.host, &spi_settings.devcfg, &spi_settings.spi); + if (err != ESP_OK) { + free(ws28xx_pixels); + return err; + } + reset_delay = (model == WS2812B) ? 3 : 30; // insrease if something breaks. values are less that + // recommended in datasheets but seem stable + dma_buffer = heap_caps_malloc(dma_buf_size, + MALLOC_CAP_DMA); // Critical to be DMA memory. + if (dma_buffer == NULL) { + free(ws28xx_pixels); + return ESP_ERR_NO_MEM; + } + return ESP_OK; } void ws28xx_fill_all(CRGB color) { - for (int i = 0; i < n_of_leds; i++) { - ws28xx_pixels[i] = color; - } + for (int i = 0; i < n_of_leds; i++) { + ws28xx_pixels[i] = color; + } } esp_err_t ws28xx_update() { - uint16_t timing_bits[16] = {0x1111, 0x7111, 0x1711, 0x7711, 0x1171, 0x7171, - 0x1771, 0x7771, 0x1117, 0x7117, 0x1717, 0x7717, - 0x1177, 0x7177, 0x1777, 0x7777}; - esp_err_t err; - int n = 0; - memset(dma_buffer, 0, dma_buf_size); + uint16_t timing_bits[16] = {0x1111, 0x7111, 0x1711, 0x7711, 0x1171, 0x7171, 0x1771, 0x7771, + 0x1117, 0x7117, 0x1717, 0x7717, 0x1177, 0x7177, 0x1777, 0x7777}; + esp_err_t err; + int n = 0; + memset(dma_buffer, 0, dma_buf_size); - dma_buffer[n++] = 0; - for (int i = 0; i < n_of_leds; i++) { - uint32_t temp = ws28xx_pixels[i].num; // Data you want to write to each LEDs - if (led_model == WS2815) { - // Red - dma_buffer[n++] = timing_bits[0x0f & (temp >> 4)]; - dma_buffer[n++] = timing_bits[0x0f & (temp)]; - - // Green - dma_buffer[n++] = timing_bits[0x0f & (temp >> 12)]; - dma_buffer[n++] = timing_bits[0x0f & (temp) >> 8]; - } else { - // Green - dma_buffer[n++] = timing_bits[0x0f & (temp >> 12)]; - dma_buffer[n++] = timing_bits[0x0f & (temp) >> 8]; - - // Red - dma_buffer[n++] = timing_bits[0x0f & (temp >> 4)]; - dma_buffer[n++] = timing_bits[0x0f & (temp)]; - } - // Blue - dma_buffer[n++] = timing_bits[0x0f & (temp >> 20)]; - dma_buffer[n++] = timing_bits[0x0f & (temp) >> 16]; - } - for (int i = 0; i < reset_delay; i++) dma_buffer[n++] = 0; + for (int i = 0; i < n_of_leds; i++) { + uint32_t temp = ws28xx_pixels[i].num; // Data you want to write to each LEDs + if (led_model == WS2815) { + // Red + dma_buffer[n++] = timing_bits[0x0f & (temp >> 4)]; + dma_buffer[n++] = timing_bits[0x0f & (temp)]; - err = spi_device_transmit(spi_settings.spi, &(spi_transaction_t){ - .length = dma_buf_size * 8, - .tx_buffer = dma_buffer, - }); - return err; + // Green + dma_buffer[n++] = timing_bits[0x0f & (temp >> 12)]; + dma_buffer[n++] = timing_bits[0x0f & (temp) >> 8]; + } else { + // Green + dma_buffer[n++] = timing_bits[0x0f & (temp >> 12)]; + dma_buffer[n++] = timing_bits[0x0f & (temp) >> 8]; + + // Red + dma_buffer[n++] = timing_bits[0x0f & (temp >> 4)]; + dma_buffer[n++] = timing_bits[0x0f & (temp)]; + } + // Blue + dma_buffer[n++] = timing_bits[0x0f & (temp >> 20)]; + dma_buffer[n++] = timing_bits[0x0f & (temp) >> 16]; + } + for (int i = 0; i < reset_delay; i++) { + dma_buffer[n++] = 0; + } + + err = spi_device_transmit(spi_settings.spi, &(spi_transaction_t){ + .length = dma_buf_size * 8, + .tx_buffer = dma_buffer, + }); + return err; } diff --git a/esp_ws28xx.h b/esp_ws28xx.h index f4abd04..308d8f1 100644 --- a/esp_ws28xx.h +++ b/esp_ws28xx.h @@ -1,46 +1,48 @@ #ifndef MAIN_ESP_WS28XX_H_ #define MAIN_ESP_WS28XX_H_ -#include "driver/gpio.h" -#include "driver/spi_master.h" #include #include +#include "driver/gpio.h" +#include "driver/spi_master.h" typedef struct { - union { - struct { - union { - uint8_t r; - uint8_t red; - }; - union { - uint8_t g; - uint8_t green; - }; - union { - uint8_t b; - uint8_t blue; - }; + union { + struct { + union { + uint8_t r; + uint8_t red; + }; + + union { + uint8_t g; + uint8_t green; + }; + + union { + uint8_t b; + uint8_t blue; + }; + }; + + uint8_t raw[3]; + uint32_t num; }; - uint8_t raw[3]; - uint32_t num; - }; } CRGB; typedef struct { - spi_host_device_t host; - spi_device_handle_t spi; - int dma_chan; - spi_device_interface_config_t devcfg; - spi_bus_config_t buscfg; + spi_host_device_t host; + spi_device_handle_t spi; + int dma_chan; + spi_device_interface_config_t devcfg; + spi_bus_config_t buscfg; } spi_settings_t; typedef enum { - WS2812B = 0, - WS2815, + WS2812B = 0, + WS2815, } led_strip_model_t; -esp_err_t ws28xx_init(int pin, led_strip_model_t model, int num_of_leds, - CRGB **led_buffer_ptr); +esp_err_t ws28xx_init(int pin, led_strip_model_t model, int num_of_leds, CRGB** led_buffer_ptr); void ws28xx_fill_all(CRGB color); esp_err_t ws28xx_update();