Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions firmware/main/board_147b.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#pragma once
// ESP32-S3-LCD-1.47B — ST7789 SPI
#define LCD_CS 21
#define LCD_SCL 38 // SPI CLK
#define LCD_SDA 39 // SPI MOSI
#define LCD_RST 40
#define LCD_DC 45
#define LCD_BL 46 // 背光,高=亮(8050)
// ESP32-S3-LCD-1.47B — ST7789 SPI (pins from board schematic)
#define LCD_CS 42
#define LCD_SCL 40 // SPI CLK
#define LCD_SDA 45 // SPI MOSI (DIN)
#define LCD_RST 39
#define LCD_DC 41
#define LCD_BL 46 // backlight, high=on
#define LCD_H_RES 172
#define LCD_V_RES 320
#define LCD_X_GAP 34
Expand Down
106 changes: 74 additions & 32 deletions firmware/main/ui_147b.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,66 +3,108 @@

#define AMBER 0xFFB000
#define DIM 0xC8870F
#define EMPTY 0x5A3F08
#define STALE 0x9C6A0C
#define BG 0x0B0A07

static lv_obj_t *lbl_5h_pct, *lbl_reset, *lbl_7d, *bar5, *bar7, *lbl_bottom;
static lv_obj_t *lbl_5h_pct, *lbl_5h_reset, *bar5;
static lv_obj_t *lbl_7d_pct, *bar7;
static lv_obj_t *lbl_session, *lbl_state;

static lv_obj_t *mklbl(lv_obj_t *p, const char *txt, int y, int size, uint32_t color)
static lv_obj_t *mklbl(lv_obj_t *p, const char *txt, int x, int y,
const lv_font_t *font, uint32_t color)
{
(void)size; /* size param reserved for future font switching */
lv_obj_t *l = lv_label_create(p);
lv_label_set_text(l, txt);
lv_obj_set_style_text_color(l, lv_color_hex(color), 0);
lv_obj_set_style_text_font(l, &lv_font_montserrat_14, 0);
lv_obj_set_pos(l, 8, y);
lv_obj_set_style_text_font(l, font, 0);
lv_obj_set_pos(l, x, y);
return l;
}

void ui_build(lv_display_t *disp)
// Thin horizontal rule spanning the column.
static void mksep(lv_obj_t *p, int x, int y, int w, uint32_t color)
{
lv_obj_t *scr = lv_display_get_screen_active(disp);
lv_obj_set_style_bg_color(scr, lv_color_hex(0x0B0A07), 0);
lv_obj_t *o = lv_obj_create(p);
lv_obj_remove_style_all(o);
lv_obj_set_size(o, w, 2);
lv_obj_set_pos(o, x, y);
lv_obj_set_style_bg_color(o, lv_color_hex(color), 0);
lv_obj_set_style_bg_opa(o, LV_OPA_COVER, 0);
}

mklbl(scr, "TOKENPULSE", 6, 14, AMBER);
mklbl(scr, "CLAUDE CODE", 40, 14, AMBER);
mklbl(scr, "5H WINDOW", 64, 14, DIM);
static lv_obj_t *mkbar(lv_obj_t *p, int x, int y, int w, int h)
{
lv_obj_t *b = lv_bar_create(p);
lv_obj_set_size(b, w, h);
lv_obj_set_pos(b, x, y);
lv_obj_set_style_bg_color(b, lv_color_hex(EMPTY), 0);
lv_obj_set_style_bg_color(b, lv_color_hex(AMBER), LV_PART_INDICATOR);
lv_bar_set_range(b, 0, 100);
return b;
}

lbl_5h_pct = mklbl(scr, "--%", 82, 28, AMBER);
// Portrait 172x320 — mirrors the 4.3C dashboard: 5H hero, thicker bars,
// drawn separators, session line, single ONLINE/STALE status.
void ui_build(lv_display_t *disp)
{
lv_obj_t *scr = lv_display_get_screen_active(disp);
lv_obj_set_style_bg_color(scr, lv_color_hex(BG), 0);

bar5 = lv_bar_create(scr);
lv_obj_set_size(bar5, 156, 12);
lv_obj_set_pos(bar5, 8, 120);
lv_obj_set_style_bg_color(bar5, lv_color_hex(0x5A3F08), 0);
lv_obj_set_style_bg_color(bar5, lv_color_hex(AMBER), LV_PART_INDICATOR);
// Header
mklbl(scr, "TOKENPULSE", 8, 8, &lv_font_montserrat_14, AMBER);
mklbl(scr, "CLAUDE CODE", 8, 26, &lv_font_montserrat_14, DIM);
mksep(scr, 8, 48, 156, DIM);

lbl_reset = mklbl(scr, "RESET --:--:--", 138, 14, DIM);
lbl_7d = mklbl(scr, "7-DAY --%", 170, 14, DIM);
// 5H WINDOW (hero)
mklbl(scr, "5H WINDOW", 8, 58, &lv_font_montserrat_14, DIM);
lbl_5h_pct = mklbl(scr, "--%", 8, 78, &lv_font_montserrat_28, AMBER);
bar5 = mkbar(scr, 8, 124, 156, 18);
lbl_5h_reset = mklbl(scr, "RESET --:--:--", 8, 150, &lv_font_montserrat_14, DIM);
mksep(scr, 8, 176, 156, DIM);

bar7 = lv_bar_create(scr);
lv_obj_set_size(bar7, 156, 8);
lv_obj_set_pos(bar7, 8, 192);
lv_obj_set_style_bg_color(bar7, lv_color_hex(0x5A3F08), 0);
lv_obj_set_style_bg_color(bar7, lv_color_hex(AMBER), LV_PART_INDICATOR);
// 7-DAY (secondary, inline)
mklbl(scr, "7-DAY", 8, 188, &lv_font_montserrat_14, DIM);
lbl_7d_pct = mklbl(scr, "--%", 110, 188, &lv_font_montserrat_14, AMBER);
bar7 = mkbar(scr, 8, 214, 156, 14);
mksep(scr, 8, 238, 156, DIM);

lbl_bottom = mklbl(scr, "* RUNNING", 296, 14, AMBER);
// Footer
lbl_session = mklbl(scr, "SESSION $--.--", 8, 250, &lv_font_montserrat_14, AMBER);
lbl_state = mklbl(scr, "* ONLINE", 8, 290, &lv_font_montserrat_14, AMBER);
}

void ui_update(const ui_state_t *st)
{
char buf[32];
uint32_t c = st->stale ? 0x9C6A0C : AMBER;
char buf[40];
uint32_t c = st->stale ? STALE : AMBER;

// 5H
snprintf(buf, sizeof buf, "%d%%", st->five_pct);
lv_label_set_text(lbl_5h_pct, st->stale ? "--%" : buf);
lv_obj_set_style_text_color(lbl_5h_pct, lv_color_hex(c), 0);
lv_bar_set_value(bar5, st->stale ? 0 : st->five_pct, LV_ANIM_OFF);

long s = st->five_reset_s;
snprintf(buf, sizeof buf, "RESET %02ld:%02ld:%02ld", s / 3600, (s % 3600) / 60, s % 60);
lv_label_set_text(lbl_reset, st->stale ? "RESET --:--:--" : buf);
snprintf(buf, sizeof buf, "RESET %02ld:%02ld:%02ld",
s / 3600, (s % 3600) / 60, s % 60);
lv_label_set_text(lbl_5h_reset, st->stale ? "RESET --:--:--" : buf);

snprintf(buf, sizeof buf, "7-DAY %d%%", st->week_pct);
lv_label_set_text(lbl_7d, st->stale ? "7-DAY --%" : buf);
// 7D
snprintf(buf, sizeof buf, "%d%%", st->week_pct);
lv_label_set_text(lbl_7d_pct, st->stale ? "--%" : buf);
lv_obj_set_style_text_color(lbl_7d_pct, lv_color_hex(c), 0);
lv_bar_set_value(bar7, st->stale ? 0 : st->week_pct, LV_ANIM_OFF);

(void)lbl_bottom; /* bottom label stays static in ui_update */
// Session cost
if (st->stale) {
lv_label_set_text(lbl_session, "SESSION $--.--");
} else {
snprintf(buf, sizeof buf, "SESSION $%.2f", st->session_usd);
lv_label_set_text(lbl_session, buf);
}

// Status (single indicator; greyed when stale)
lv_obj_set_style_text_color(lbl_state, lv_color_hex(c), 0);
lv_label_set_text(lbl_state, st->stale ? "* STALE" : "* ONLINE");
}
2 changes: 2 additions & 0 deletions firmware/sdkconfig.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ CONFIG_SPIRAM_SPEED_80M=y
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
CONFIG_FREERTOS_HZ=1000
# Bigger font for the hero metric (both boards)
CONFIG_LV_FONT_MONTSERRAT_28=y
# TinyUSB CDC + HID composite
CONFIG_TINYUSB_CDC_ENABLED=y
CONFIG_TINYUSB_CDC_COUNT=1
Expand Down