aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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);
}