aboutsummaryrefslogtreecommitdiff
path: root/main
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
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')
-rw-r--r--main/drv/ws2812b.c51
-rw-r--r--main/main.c150
2 files changed, 130 insertions, 71 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;
}
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);
}