Full hardware swap from Panlee SC01 Plus (480×320 IPS) to Waveshare 2.16" square AMOLED (480×480, CO5300 + CST9220 + AXP2101 + QMI8658). Library stack moves to Arduino_GFX, SensorLib, XPowersLib on the pioarduino platform 55.03.38-1 (Arduino Core 3.x). UI: - 4 screens (splash, usage, controller, bluetooth) with 3-button physical navigation: GPIO 0 = prev, AXP PKEY = cycle, GPIO 18 = next. - IMU-driven 90° auto-rotation. CO5300 can't rotate via MADCTL, so flush callback does CPU strip-rotation in PARTIAL render mode. Rotation transitions use AMOLED brightness flash (instant black → redraw → ramp). - Battery indicator (Lucide icons) in upper-right, RGB565A8 alpha so it blends over the splash animations. - USB plugged/unplugged auto-switches between Usage and Controller screens (suppressed while on splash). - Fonts and icons re-scaled ~1.9× for the higher-DPI panel; 20px margins to clear rounded corners. Splash: - 13 × 20×20 pixel-art creature animations sourced from claudepix.vercel.app via tools/scrape_claudepix.js (scraper handles both PRESET creature-engine and standalone FRAMES+PAL formats). tools/convert_to_c.js emits firmware/src/splash_animations.h. Attribution preserved in README and the generated header. Tooling: - tools/png_to_lvgl.js converts alpha PNGs to LVGL RGB565A8 (planar layout, with --tint to colorize Lucide black-on-transparent sources). - tools/scrape_claudepix.js, tools/convert_to_c.js for the splash pipeline. Docs: - New worktree CLAUDE.md with hardware pin map, file inventory, build commands, and the 8 critical gotchas (CO5300 rotation, OPI PSRAM, pioarduino requirement, LVGL 9 font patching, centralized touch read, even-aligned flush regions, touch swap/mirror values, RGB565A8 layout). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
93 lines
1.9 KiB
JSON
93 lines
1.9 KiB
JSON
[
|
|
{
|
|
"filename": "idle_breathe.html",
|
|
"name": "idle breathe",
|
|
"category": "Idle",
|
|
"frame_count": 16,
|
|
"palette_size": 3
|
|
},
|
|
{
|
|
"filename": "idle_blink.html",
|
|
"name": "idle blink",
|
|
"category": "Idle",
|
|
"frame_count": 16,
|
|
"palette_size": 3
|
|
},
|
|
{
|
|
"filename": "idle_look_around.html",
|
|
"name": "idle look around",
|
|
"category": "Idle",
|
|
"frame_count": 17,
|
|
"palette_size": 3
|
|
},
|
|
{
|
|
"filename": "expression_wink.html",
|
|
"name": "expression wink",
|
|
"category": "Expressions",
|
|
"frame_count": 12,
|
|
"palette_size": 3
|
|
},
|
|
{
|
|
"filename": "expression_surprise.html",
|
|
"name": "expression surprise",
|
|
"category": "Expressions",
|
|
"frame_count": 12,
|
|
"palette_size": 3
|
|
},
|
|
{
|
|
"filename": "expression_sleep.html",
|
|
"name": "expression sleep",
|
|
"category": "Expressions",
|
|
"frame_count": 24,
|
|
"palette_size": 3
|
|
},
|
|
{
|
|
"filename": "dance_bounce.html",
|
|
"name": "dance bounce",
|
|
"category": "Dance",
|
|
"frame_count": 16,
|
|
"palette_size": 3
|
|
},
|
|
{
|
|
"filename": "dance_sway.html",
|
|
"name": "dance sway",
|
|
"category": "Dance",
|
|
"frame_count": 12,
|
|
"palette_size": 3
|
|
},
|
|
{
|
|
"filename": "work_coding.html",
|
|
"name": "work coding",
|
|
"category": "Work",
|
|
"frame_count": 23,
|
|
"palette_size": 10
|
|
},
|
|
{
|
|
"filename": "work_think.html",
|
|
"name": "work think",
|
|
"category": "Work",
|
|
"frame_count": 24,
|
|
"palette_size": 3
|
|
},
|
|
{
|
|
"filename": "dance_bounce_dj.html",
|
|
"name": "dance bounce dj",
|
|
"category": "Dance",
|
|
"frame_count": 16,
|
|
"palette_size": 10
|
|
},
|
|
{
|
|
"filename": "dance_sway_dj.html",
|
|
"name": "dance sway dj",
|
|
"category": "Dance",
|
|
"frame_count": 12,
|
|
"palette_size": 10
|
|
},
|
|
{
|
|
"filename": "dance_djmix.html",
|
|
"name": "dance djmix",
|
|
"category": "Dance",
|
|
"frame_count": 16,
|
|
"palette_size": 10
|
|
}
|
|
] |