aboutsummaryrefslogtreecommitdiff
path: root/include/ws2812b.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/ws2812b.h')
-rw-r--r--include/ws2812b.h63
1 files changed, 63 insertions, 0 deletions
diff --git a/include/ws2812b.h b/include/ws2812b.h
new file mode 100644
index 0000000..2845bc5
--- /dev/null
+++ b/include/ws2812b.h
@@ -0,0 +1,63 @@
+#pragma once
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#define WIRE_BYTES_PER_COLOR 9
+#define PADDING_BYTES 2
+#define TOTAL_BYTES_PER_LED (PADDING_BYTES + WIRE_BYTES_PER_COLOR)
+
+enum ws2812b_byte_order {
+ BYTE_ORDER_BGR = 0,
+ BYTE_ORDER_GBR = 1,
+};
+
+struct ws2812b_buf {
+ uint8_t* buf; /* Size of the buffer. */
+ size_t total_alloc; /* total number of bytes allocated to the buffer. */
+ size_t cur; /* Current output cursor in the buffer */
+
+ /* The byte order this driver should use. WS2811's use BGR, WS2812b's use GBR.
+ */
+ enum ws2812b_byte_order byte_order;
+
+ /* pointer to the dma_now register. needed to synchronize with the DMA. */
+ volatile uint16_t* dma_now_reg;
+
+ /* pointer to the dma_end register. */
+ volatile uint16_t* dma_end_reg;
+};
+
+struct rgb_compiled {
+ union {
+ struct __attribute__((packed)) {
+ uint32_t first_bits;
+ uint32_t second_bits;
+ uint8_t last_bits;
+ };
+ uint8_t buf[9];
+ };
+};
+
+typedef struct {
+ union {
+ struct __attribute__((packed)) {
+ uint8_t r;
+ uint8_t g;
+ uint8_t b;
+ };
+ uint32_t color;
+ };
+} rgb_t;
+
+int write_rgb(struct ws2812b_buf* out, rgb_t color);
+
+void start_dma(struct ws2812b_buf* buf);
+
+void make_wsb2812b(struct ws2812b_buf* out, void* buf, size_t n_alloc);
+
+void compile_color(
+ rgb_t color, struct rgb_compiled* out, enum ws2812b_byte_order byte_order);
+
+// ch must have at least 73 characters free.
+void compiled_color_dbg_str(struct rgb_compiled* c, char* out);