aboutsummaryrefslogtreecommitdiff
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
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
-rw-r--r--include/drv/ws2812b.h9
-rw-r--r--main/drv/ws2812b.c51
-rw-r--r--main/main.c150
3 files changed, 137 insertions, 73 deletions
diff --git a/include/drv/ws2812b.h b/include/drv/ws2812b.h
index 39f2794..49337ed 100644
--- a/include/drv/ws2812b.h
+++ b/include/drv/ws2812b.h
@@ -13,7 +13,10 @@ typedef struct {
} ws2812b_rgb_t;
typedef struct {
- uint8_t* buf_; /* Buffer to hold the value to spi. */
+ /* Double-buffering strategy for speed-up. */
+ uint8_t* buf_1;
+ uint8_t* buf_2;
+ uint8_t* buf_; /* Points to either buf_1 or buf_2 */
uint32_t n_rgb; /* Number of rgb values which exist. */
ws2812b_rgb_t rgb[]; /* Colors to write. */
@@ -24,9 +27,11 @@ typedef struct WS2812B ws2812b_t;
ws2812b_buffer_t* ws2812b_new_buffer(uint32_t size);
+esp_err_t ws2812b_wait(ws2812b_t* drv);
+
ws2812b_t* ws2812b_init(spi_device_handle_t spi);
-esp_err_t ws2812b_write_sync(ws2812b_t* drv, ws2812b_buffer_t* buffer);
+esp_err_t ws2812b_write(ws2812b_t* drv, ws2812b_buffer_t* buffer);
static inline void ws2812b_buffer_set_rgb(
ws2812b_buffer_t* buf, size_t idx, uint8_t r, uint8_t g, uint8_t b)
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;
}
diff --git a/main/main.c b/main/main.c
index ff78f76..4caa26a 100644
--- a/main/main.c
+++ b/main/main.c
@@ -2,9 +2,9 @@
#include "drv/ws2812b.h"
#include "esp_spi_flash.h"
#include "esp_system.h"
-#include "lwip/sockets.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
+#include "lwip/sockets.h"
#include "sdkconfig.h"
#include "station.h"
@@ -43,11 +43,92 @@
#define PIN_NUM_BCKL 5
#endif
-void ws_init()
+struct {
+ char color[32];
+ ws2812b_t* drv;
+} ws_params;
+
+#define SIZE 300
+void calculate_colors(ws2812b_buffer_t* buffer)
+{
+ /* RACE Conditions for sure. Need to fix that. */
+ ws2812b_rgb_t color = {0};
+ if (!strcmp(ws_params.color, "black\n")) {
+ } else if (!strcmp(ws_params.color, "green\n")) {
+ color.g = 255;
+ } else if (!strcmp(ws_params.color, "red\n")) {
+ color.r = 255;
+ } else if (!strcmp(ws_params.color, "blue\n")) {
+ color.b = 255;
+ } else if (!strcmp(ws_params.color, "yellow\n")) {
+ color.r = 255;
+ color.g = 255;
+ } else if (!strcmp(ws_params.color, "magenta\n")) {
+ color.r = 255;
+ color.b = 255;
+ } else if (!strcmp(ws_params.color, "teal\n")) {
+ color.g = 255;
+ color.b = 255;
+ } else {
+ color.r = 128;
+ color.g = 128;
+ color.b = 128;
+ }
+
+ int i;
+ for (i = 0; i < SIZE; ++i) {
+ ws2812b_buffer_set_color(buffer, i, &color);
+ }
+}
+
+portTASK_FUNCTION(ws2812b_write_task, params)
{
+ strcpy(ws_params.color, "red\n");
+
+ ws2812b_buffer_t* buffer = ws2812b_new_buffer(SIZE);
+ for (;;) {
+ calculate_colors(buffer);
+ ws2812b_write(ws_params.drv, buffer);
+ vTaskDelay(10 / portTICK_PERIOD_MS);
+ }
}
-uint8_t buffer[256];
+portTASK_FUNCTION(tcp_server, params)
+{
+ wifi_init_station("Wort", "JoshIsBau5");
+
+ int s = socket(AF_INET, SOCK_STREAM, 0);
+ struct sockaddr_in addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_port = htons(1234);
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = INADDR_ANY;
+ int err = bind(s, (struct sockaddr*)&addr, sizeof(addr));
+ if (err) {
+ printf("Error binding to sockaddr: %d\n", err);
+ return;
+ }
+
+ printf("Listening ...\n");
+ listen(s, 1);
+
+ while (true) {
+ printf("Waiting for connection... \n");
+
+ struct sockaddr_in client_addr;
+ socklen_t size;
+ int sock = accept(s, (struct sockaddr*)&client_addr, &size);
+
+ printf("Accepted connection\n");
+ ssize_t len;
+
+ while ((len = read(sock, ws_params.color, sizeof(ws_params.color) - 1)) >
+ 0) {
+ ws_params.color[len] = 0;
+ printf("Read %s\n", ws_params.color);
+ }
+ }
+}
void app_main(void)
{
@@ -63,7 +144,7 @@ void app_main(void)
};
spi_device_interface_config_t devcfg = {
- .clock_speed_hz = 25 * 100 * 1000, /* 2.5 MHz */
+ .clock_speed_hz = 24 * 100 * 1000, /* 2.5 MHz */
.mode = 0,
.spics_io_num = PIN_NUM_CS,
.queue_size = 7,
@@ -83,63 +164,10 @@ void app_main(void)
printf("Add Device\n");
ESP_ERROR_CHECK(error);
- printf("Configuration complete!!\n");
-
- wifi_init_station("Wort", "JoshIsBau5");
-
- int s = socket(AF_INET, SOCK_STREAM, 0);
- struct sockaddr_in addr;
- memset(&addr, 0, sizeof(addr));
- addr.sin_port = htons(1234);
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = INADDR_ANY;
- int err = bind(s, (struct sockaddr*) &addr, sizeof(addr));
-
- if (err) {
- printf("Error binding to sockaddr: %d\n", err);
- return;
- }
-
- printf("Listening ...\n");
- listen(s, 1);
-
- ws2812b_t* drv = ws2812b_init(spi);
- ws2812b_buffer_t* buffer = ws2812b_new_buffer(5);
-
- while (true) {
- printf("Waiting for connection... \n");
- char buf[128];
-
- struct sockaddr_in client_addr;
- socklen_t size;
- int sock = accept(s, (struct sockaddr*)&client_addr, &size);
+ ws_params.drv = ws2812b_init(spi);
- printf("Accepted connection\n");
- ssize_t len;
+ printf("Configuration complete!!\n");
- while ((len = read(sock, buf, sizeof(buf) - 1)) > 0) {
- buf[len] = 0;
- printf("Got %s\n", buf);
-
- ws2812b_rgb_t color = {0};
- if (!strcmp(buf, "green\n")) {
- color.g = 255;
- } else if (!strcmp(buf, "red\n")) {
- color.r = 255;
- } else if (!strcmp(buf, "blue\n")) {
- color.b = 255;
- } else {
- color.r = 255;
- color.g = 255;
- color.b = 255;
- }
-
- for (int i = 0; i < 5; ++ i) {
- ws2812b_buffer_set_color(buffer, i, &color);
- }
-
- ws2812b_write_sync(drv, buffer);
- vTaskDelay(10 / portTICK_PERIOD_MS);
- }
- }
+ xTaskCreate(ws2812b_write_task, "ws2812b_writer", 4096, NULL, 1, NULL);
+ xTaskCreate(tcp_server, "tcp_server", 4096, NULL, 2, NULL);
}