canshift-firmware
C++17 on Arduino-ESP32, LVGL 8.4, LovyanGFX. Parses CAN over TWAI, decodes signals, drives the panel. Source of truth for the dashboard’s runtime behaviour.
From a sealed box to a dashboard reading your ECU — flashing, wiring, pages, cruise, settings.
Edit pages, bind CAN signals, pick an ECU profile, tune OBD-II polling. Burn the config and the dash reloads — no re-flash.
Heap reservation order, LVGL ownership rules, the PUT_CONFIG burn flow, the cruise polygon trick — the load-bearing rationale.
canshift-firmware
C++17 on Arduino-ESP32, LVGL 8.4, LovyanGFX. Parses CAN over TWAI, decodes signals, drives the panel. Source of truth for the dashboard’s runtime behaviour.
canshift-core
Shared TypeScript domain — Zod schemas, signal map, design tokens. Pulled by tuner and mobile; mirrored by the firmware’s canshift-core/dist types.
canshift-tuner
Vite + React SPA on Vercel. Talks to the dash over Web Serial. Lets a tuner edit the dashboard, run a CAN scan, and flash firmware — the standalone flasher is gone; /firmware is the route.
canshift-mobile
Expo React Native. Pairs over BLE for in-car telemetry and secondary config. Useful when the tuner laptop isn’t in the car.
USB_PROTOCOL_VERSION = 2Different ESP32 board? Different panel? The signal map and most of the runtime are board-agnostic. See Pinout for the GPIO contract and Build flags for the compile-time switches.
The firmware used to carry a thick comment layer explaining the non-obvious bits — LVGL ownership rules, the heap reservation order on a no-PSRAM WROOM, the PUT_CONFIG burn flow, the cruise control polygon workaround. Comments rot the moment they leave their reviewer’s screen. The architecture section is where that rationale lives now, beside the code rather than inside it.
If you are about to edit a non-trivial subsystem, read the matching architecture page first. The surprises in this codebase are written down — and almost all of them are surprises only the second time.