aboutsummaryrefslogtreecommitdiff
path: root/main/drv/ws2812b.c
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2021-11-30 01:06:49 -0700
committerJosh Rahm <joshuarahm@gmail.com>2021-11-30 01:06:49 -0700
commit6df4a4ed74621ce5df26791b84b9157902aeaa83 (patch)
treef48c79a6b6c11ee60f6bbf7ba3441beddfc8a512 /main/drv/ws2812b.c
parent80d6050ab3fe42f8850bf166c33eb3c9150a252b (diff)
downloadesp32-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.c51
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;
}