diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2021-11-30 01:06:49 -0700 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2021-11-30 01:06:49 -0700 |
commit | 6df4a4ed74621ce5df26791b84b9157902aeaa83 (patch) | |
tree | f48c79a6b6c11ee60f6bbf7ba3441beddfc8a512 /main/drv/ws2812b.c | |
parent | 80d6050ab3fe42f8850bf166c33eb3c9150a252b (diff) | |
download | esp32-ws2812b-6df4a4ed74621ce5df26791b84b9157902aeaa83.tar.gz esp32-ws2812b-6df4a4ed74621ce5df26791b84b9157902aeaa83.tar.bz2 esp32-ws2812b-6df4a4ed74621ce5df26791b84b9157902aeaa83.zip |
Break out code into tasks.
Increases the nmuber of LEDs to the full 300 roll.
Can connect to the device using netcat. Set the color by entering
white
red
green
blue
yellow
teal
magenta
black
Diffstat (limited to 'main/drv/ws2812b.c')
-rw-r--r-- | main/drv/ws2812b.c | 51 |
1 files changed, 41 insertions, 10 deletions
diff --git a/main/drv/ws2812b.c b/main/drv/ws2812b.c index 3ab6b41..d0699ee 100644 --- a/main/drv/ws2812b.c +++ b/main/drv/ws2812b.c @@ -1,12 +1,19 @@ #include <drv/ws2812b.h> +#include <memory.h> + +#define WS2812B_FLAG_DIRTY 1 struct WS2812B { spi_device_handle_t spi_handle; + spi_transaction_t spi_transaction; + + uint8_t flags; }; ws2812b_t* ws2812b_init(spi_device_handle_t spi) { ws2812b_t* ret = heap_caps_malloc(sizeof(ws2812b_t), MALLOC_CAP_DEFAULT); + memset(ret, 0, sizeof(*ret)); ret->spi_handle = spi; return ret; @@ -27,6 +34,12 @@ static inline void byte_compile(uint8_t byte, uint8_t compl [3]) static inline void compile(ws2812b_buffer_t* buffer) { + if (buffer->buf_ == buffer->buf_1) { + buffer->buf_ = buffer->buf_2; + } else { + buffer->buf_ = buffer->buf_1; + } + for (size_t i = 0; i < buffer->n_rgb; ++i) { byte_compile(buffer->rgb[i].g, buffer->buf_ + i * 9 + 0); byte_compile(buffer->rgb[i].r, buffer->buf_ + i * 9 + 3); @@ -38,31 +51,49 @@ ws2812b_buffer_t* ws2812b_new_buffer(uint32_t n) { ws2812b_buffer_t* ret = heap_caps_malloc( sizeof(ws2812b_buffer_t) + sizeof(ws2812b_rgb_t) * n, MALLOC_CAP_DEFAULT); - ret->buf_ = heap_caps_malloc(n * 9, MALLOC_CAP_DMA); + ret->buf_1 = heap_caps_malloc(n * 9, MALLOC_CAP_DMA); + ret->buf_2 = heap_caps_malloc(n * 9, MALLOC_CAP_DMA); + ret->buf_ = ret->buf_1; ret->n_rgb = n; return ret; } -esp_err_t ws2812b_write_sync(ws2812b_t* drv, ws2812b_buffer_t* buffer) +esp_err_t ws2812b_wait(ws2812b_t* drv) { esp_err_t err; - compile(buffer); - spi_transaction_t t = {0}; spi_transaction_t* rt; - - t.tx_buffer = buffer->buf_; - t.length = buffer->n_rgb * 9 * 8; - - err = spi_device_queue_trans(drv->spi_handle, &t, portMAX_DELAY); + err = spi_device_get_trans_result( + drv->spi_handle, &rt, 10 / portTICK_PERIOD_MS); + drv->flags &= ~WS2812B_FLAG_DIRTY; if (err != ESP_OK) { return err; } - err = spi_device_get_trans_result(drv->spi_handle, &rt, portMAX_DELAY); + return ESP_OK; +} + +esp_err_t ws2812b_write(ws2812b_t* drv, ws2812b_buffer_t* buffer) +{ + compile(buffer); + + if (drv->flags & WS2812B_FLAG_DIRTY) { + ws2812b_wait(drv); + } + + esp_err_t err; + + memset(&drv->spi_transaction, 0, sizeof(drv->spi_transaction)); + + drv->spi_transaction.tx_buffer = buffer->buf_; + drv->spi_transaction.length = buffer->n_rgb * 9 * 8; + + err = spi_device_queue_trans( + drv->spi_handle, &drv->spi_transaction, portMAX_DELAY); if (err != ESP_OK) { return err; } + drv->flags |= WS2812B_FLAG_DIRTY; return ESP_OK; } |