Stop the main-loop digit demo so host-driven display persists; expose clear/progress/digit modes with RGB and intensity via protobuf and goTool. Co-authored-by: Cursor <cursoragent@cursor.com>
126 lines
3.3 KiB
C
126 lines
3.3 KiB
C
#include "cmd_led_ring.h"
|
|
#include "esp_log.h"
|
|
#include "led_ring.h"
|
|
#include "uart_cmd.h"
|
|
|
|
static const char *TAG = "[LED_RING_CMD]";
|
|
|
|
#define LED_RING_MODE_CLEAR 0
|
|
#define LED_RING_MODE_PROGRESS 1
|
|
#define LED_RING_MODE_DIGIT 2
|
|
|
|
static uint8_t clamp_u8(uint32_t v) {
|
|
if (v > 255) {
|
|
return 255;
|
|
}
|
|
return (uint8_t)v;
|
|
}
|
|
|
|
static uint8_t clamp_progress(uint32_t v) {
|
|
if (v > 100) {
|
|
return 100;
|
|
}
|
|
return (uint8_t)v;
|
|
}
|
|
|
|
static void apply_intensity(uint8_t *r, uint8_t *g, uint8_t *b, uint8_t intensity) {
|
|
if (intensity == 0) {
|
|
return;
|
|
}
|
|
*r = (uint16_t)(*r) * intensity / 255;
|
|
*g = (uint16_t)(*g) * intensity / 255;
|
|
*b = (uint16_t)(*b) * intensity / 255;
|
|
}
|
|
|
|
static void reply(bool success, uint32_t mode, uint32_t progress, uint32_t digit) {
|
|
alox_UartMessage response;
|
|
uart_cmd_init_response(&response, alox_MessageType_LED_RING,
|
|
alox_UartMessage_led_ring_progress_response_tag);
|
|
response.payload.led_ring_progress_response.success = success;
|
|
response.payload.led_ring_progress_response.mode = mode;
|
|
response.payload.led_ring_progress_response.progress = progress;
|
|
response.payload.led_ring_progress_response.digit = digit;
|
|
uart_cmd_send(&response, TAG);
|
|
}
|
|
|
|
static void handle_led_ring(const uint8_t *data, size_t len) {
|
|
alox_UartMessage uart_msg;
|
|
alox_LedRingProgressRequest req = alox_LedRingProgressRequest_init_zero;
|
|
|
|
if (uart_cmd_decode(data, len, &uart_msg) != ESP_OK) {
|
|
ESP_LOGW(TAG, "decode failed");
|
|
reply(false, 0, 0, 0);
|
|
return;
|
|
}
|
|
|
|
const alox_LedRingProgressRequest *req_ptr = UART_CMD_REQ(
|
|
&uart_msg, alox_UartMessage_led_ring_progress_request_tag,
|
|
led_ring_progress_request);
|
|
if (req_ptr != NULL) {
|
|
req = *req_ptr;
|
|
}
|
|
|
|
uint32_t mode = req.mode;
|
|
uint8_t r = clamp_u8(req.r);
|
|
uint8_t g = clamp_u8(req.g);
|
|
uint8_t b = clamp_u8(req.b);
|
|
uint8_t intensity = clamp_u8(req.intensity);
|
|
if (intensity == 0) {
|
|
intensity = 255;
|
|
}
|
|
apply_intensity(&r, &g, &b, intensity);
|
|
|
|
led_command_t cmd = {0};
|
|
|
|
switch (mode) {
|
|
case LED_RING_MODE_CLEAR:
|
|
cmd.mode = LED_CMD_CLEAR;
|
|
led_ring_send_command(&cmd);
|
|
ESP_LOGI(TAG, "clear");
|
|
reply(true, mode, 0, 0);
|
|
return;
|
|
|
|
case LED_RING_MODE_PROGRESS: {
|
|
uint8_t progress = clamp_progress(req.progress);
|
|
cmd.mode = LED_CMD_PROGRESS;
|
|
cmd.progress = progress;
|
|
cmd.r = r;
|
|
cmd.g = g;
|
|
cmd.b = b;
|
|
cmd.intensity = intensity;
|
|
led_ring_send_command(&cmd);
|
|
ESP_LOGI(TAG, "progress %u%% rgb=%u,%u,%u", (unsigned)progress,
|
|
(unsigned)r, (unsigned)g, (unsigned)b);
|
|
reply(true, mode, progress, 0);
|
|
return;
|
|
}
|
|
|
|
case LED_RING_MODE_DIGIT: {
|
|
if (req.digit > 10) {
|
|
ESP_LOGW(TAG, "digit %lu out of range", (unsigned long)req.digit);
|
|
reply(false, mode, 0, req.digit);
|
|
return;
|
|
}
|
|
cmd.mode = LED_CMD_SET_DIGIT;
|
|
cmd.value = (uint8_t)req.digit;
|
|
cmd.r = r;
|
|
cmd.g = g;
|
|
cmd.b = b;
|
|
led_ring_send_command(&cmd);
|
|
ESP_LOGI(TAG, "digit %u rgb=%u,%u,%u", (unsigned)cmd.value, (unsigned)r,
|
|
(unsigned)g, (unsigned)b);
|
|
reply(true, mode, 0, req.digit);
|
|
return;
|
|
}
|
|
|
|
default:
|
|
ESP_LOGW(TAG, "unknown mode %lu", (unsigned long)mode);
|
|
reply(false, mode, 0, 0);
|
|
return;
|
|
}
|
|
}
|
|
|
|
void cmd_led_ring_register(void) {
|
|
uart_cmd_register(alox_MessageType_LED_RING, handle_led_ring);
|
|
}
|