CDC Badge OS
Firmware for the CDC Badge v1.0 hardware security key
Loading...
Searching...
No Matches
host_api_pixel_strip.cpp
Go to the documentation of this file.
1
10
14
15#include "led_strip.h"
16#include "led_strip_rmt.h"
17#include "led_strip_types.h"
18
19#include "freertos/FreeRTOS.h"
20#include "freertos/semphr.h"
21
22#include <cstring>
23
24extern "C" void* plg_get_active_plugin(void);
25
26namespace {
27
28constexpr uint16_t MAX_PIXELS = 1024;
29
30led_strip_handle_t s_handle = nullptr;
31uint8_t s_gpio = 0xFF;
32uint16_t s_count = 0;
33uint8_t s_format = 0xFF;
34
35SemaphoreHandle_t mutex()
36{
37 static SemaphoreHandle_t m = xSemaphoreCreateMutex();
38 return m;
39}
40
41bool manifest_allows()
42{
43 auto* p = static_cast<cdc::plugin_manager::Plugin*>(plg_get_active_plugin());
44 if (!p) return false;
46}
47
48led_pixel_format_t map_format(uint8_t fmt, bool& has_white)
49{
50 has_white = false;
51 switch (fmt) {
52 case PIXEL_FORMAT_GRB: return LED_PIXEL_FORMAT_GRB;
53 case PIXEL_FORMAT_RGB: return LED_PIXEL_FORMAT_GRB; // driver handles ordering at refresh
55 case PIXEL_FORMAT_RGBW: has_white = true; return LED_PIXEL_FORMAT_GRBW;
56 default: return LED_PIXEL_FORMAT_INVALID;
57 }
58}
59
60int create_strip(uint8_t gpio, uint16_t count, uint8_t format)
61{
62 bool has_white = false;
63 led_pixel_format_t pf = map_format(format, has_white);
64 if (pf == LED_PIXEL_FORMAT_INVALID) return HOST_ERR_INVALID_ARG;
65
66 led_strip_config_t cfg{};
67 cfg.strip_gpio_num = gpio;
68 cfg.max_leds = count;
69 cfg.led_pixel_format = pf;
70 cfg.led_model = LED_MODEL_WS2812;
71
72 led_strip_rmt_config_t rmt{};
73 rmt.clk_src = RMT_CLK_SRC_DEFAULT;
74 rmt.resolution_hz = 10 * 1000 * 1000;
75 rmt.mem_block_symbols = 64;
76 rmt.flags.with_dma = 0;
77
78 led_strip_handle_t h = nullptr;
79 if (led_strip_new_rmt_device(&cfg, &rmt, &h) != ESP_OK) return HOST_ERR_GENERIC;
80 s_handle = h;
81 s_gpio = gpio;
82 s_count = count;
83 s_format = format;
84 return HOST_OK;
85}
86
87void destroy_strip()
88{
89 if (s_handle) {
90 led_strip_clear(s_handle);
91 led_strip_del(s_handle);
92 s_handle = nullptr;
93 }
94 s_count = 0;
95 s_gpio = 0xFF;
96 s_format = 0xFF;
97}
98
99struct Lock {
100 SemaphoreHandle_t m;
101 bool ok;
102 explicit Lock(SemaphoreHandle_t s) : m(s), ok(xSemaphoreTake(s, pdMS_TO_TICKS(100)) == pdTRUE) {}
103 ~Lock() { if (ok) xSemaphoreGive(m); }
104};
105
106} // namespace
107
108extern "C" {
109
110int host_pixel_strip_init(uint8_t gpio_pin, uint16_t num_pixels, uint8_t format)
111{
112 if (!manifest_allows()) return HOST_ERR_NO_CAPABILITY;
115 if (num_pixels == 0) return HOST_ERR_INVALID_ARG;
116 if (num_pixels > MAX_PIXELS) return HOST_ERR_INVALID_ARG;
117
118 Lock l(mutex());
119 if (!l.ok) return HOST_ERR_BUSY;
120
121 if (s_handle && s_gpio == gpio_pin && s_count == num_pixels && s_format == format) {
122 return HOST_OK; // idempotent re-init with identical params
123 }
124 destroy_strip();
125 return create_strip(gpio_pin, num_pixels, format);
126}
127
129{
130 if (!manifest_allows()) return HOST_ERR_NO_CAPABILITY;
131 Lock l(mutex());
132 if (!l.ok) return HOST_ERR_BUSY;
133 destroy_strip();
134 return HOST_OK;
135}
136
137int host_pixel_strip_set(uint16_t index, uint8_t r, uint8_t g, uint8_t b)
138{
139 if (!manifest_allows()) return HOST_ERR_NO_CAPABILITY;
140 Lock l(mutex());
141 if (!l.ok) return HOST_ERR_BUSY;
142 if (!s_handle) return HOST_ERR_GENERIC;
143 if (index >= s_count) return HOST_ERR_INVALID_ARG;
144 return led_strip_set_pixel(s_handle, index, r, g, b) == ESP_OK ? HOST_OK : HOST_ERR_GENERIC;
145}
146
147int host_pixel_strip_fill(uint8_t r, uint8_t g, uint8_t b)
148{
149 if (!manifest_allows()) return HOST_ERR_NO_CAPABILITY;
150 Lock l(mutex());
151 if (!l.ok) return HOST_ERR_BUSY;
152 if (!s_handle) return HOST_ERR_GENERIC;
153 for (uint16_t i = 0; i < s_count; ++i) {
154 if (led_strip_set_pixel(s_handle, i, r, g, b) != ESP_OK) return HOST_ERR_GENERIC;
155 }
156 return HOST_OK;
157}
158
160{
161 if (!manifest_allows()) return HOST_ERR_NO_CAPABILITY;
162 Lock l(mutex());
163 if (!l.ok) return HOST_ERR_BUSY;
164 if (!s_handle) return HOST_ERR_GENERIC;
165 return led_strip_clear(s_handle) == ESP_OK ? HOST_OK : HOST_ERR_GENERIC;
166}
167
169{
170 if (!manifest_allows()) return HOST_ERR_NO_CAPABILITY;
171 Lock l(mutex());
172 if (!l.ok) return HOST_ERR_BUSY;
173 if (!s_handle) return HOST_ERR_GENERIC;
174 return led_strip_refresh(s_handle) == ESP_OK ? HOST_OK : HOST_ERR_GENERIC;
175}
176
178{
179 Lock l(mutex());
180 if (!l.ok) return 0;
181 return s_count;
182}
183
185{
186 Lock l(mutex());
187 if (!l.ok) return false;
188 return s_handle != nullptr;
189}
190
191} // extern "C"
Single source of truth for plugin-accessible GPIO pins.
Owned WAMR module instance + per-plugin state.
const PluginManifest & manifest() const noexcept
Definition Plugin.h:88
SemaphoreHandle_t mutex
Definition ctaphid.cpp:51
#define PIXEL_FORMAT_GRBW
Definition host_api.h:1555
int host_pixel_strip_refresh(void)
Push the strip buffer out over the RMT bus.
int host_pixel_strip_clear(void)
Clear every pixel to off (0, 0, 0).
uint16_t host_pixel_strip_length(void)
Number of pixels the strip was initialised with.
#define PIXEL_FORMAT_RGBW
Definition host_api.h:1556
int host_pixel_strip_fill(uint8_t r, uint8_t g, uint8_t b)
Fill every pixel with the same RGB colour.
int host_pixel_strip_set(uint16_t index, uint8_t r, uint8_t g, uint8_t b)
Set one pixel's RGB colour in the strip buffer.
#define PIXEL_FORMAT_RGB
Definition host_api.h:1554
int host_pixel_strip_init(uint8_t gpio_pin, uint16_t num_pixels, uint8_t format)
Initialise or reconfigure the global pixel strip.
int host_pixel_strip_deinit(void)
Tear down the global pixel strip.
#define PIXEL_FORMAT_GRB
Definition host_api.h:1553
bool host_pixel_strip_ready(void)
True when the strip has been successfully initialised.
CDC Badge OS plugin host API - canonical C ABI contract.
#define HOST_ERR_NO_CAPABILITY
Definition host_api.h:40
#define HOST_OK
Definition host_api.h:37
#define HOST_ERR_INVALID_ARG
Definition host_api.h:39
#define HOST_ERR_GENERIC
Definition host_api.h:38
#define HOST_ERR_BUSY
Definition host_api.h:44
void * plg_get_active_plugin(void)