Boards & custom hardware
Kog describes each board in one declarative file, board.yaml (schema): the chip, memory, display, touch controller, and pins. Today those descriptions live in the Kog repository (boards/*.yaml). They drive the flash manifest, the Studio picker, and the simulator's board geometry. Each blessed board's runtime image carries a matching hand-written firmware descriptor, which is where its display setup and reserved pins come from. The CLI doesn't read a project's own board.yaml yet. To target a board, flash it with kog flash --board <slug> and set board: '<slug>' in kog.config.ts so the simulator matches its size and shape.
Blessed boards
These are the boards we test and host prebuilt images for. A scaffolded project's board.yaml names one of them with an extends: line (commented out until you pick):
extends: waveshare-esp32-s3-touch-lcd-1.46b
Current blessed boards:
| Board | Chip | Display | Flash target |
|---|---|---|---|
| Waveshare ESP32-S3-Touch-LCD-1.46B | ESP32-S3 (PSRAM) | round touch LCD | waveshare-1.46b |
| Waveshare ESP32-S3-Touch-AMOLED-2.06 | ESP32-S3 (PSRAM) | 2.06″ rounded-rect touch AMOLED | waveshare-amoled-2.06 |
| ESP32-2432S028R "Cheap Yellow Display" | ESP32 | SPI 320×240, resistive touch | cyd |
| ESP32-2432S028R, classic panel | ESP32 | same board, ILI9341-generation glass (BGR + mirrored scan) | cyd-classic |
The CYD ships in two panel generations with the same silkscreen. You can't tell them apart by
looking at the board, or over USB (both are plain ESP32). Flash the standard cyd image
first. If the screen comes up left/right mirrored with orange buttons where the UI should be
blue, your unit is the classic generation. Reflash with kog flash --board cyd-classic (the
browser flasher offers the same choice). Touch works identically on both.
What each board's firmware drives beyond display and touch:
| AMOLED-2.06 | 1.46B | CYD | |
|---|---|---|---|
Battery (expo-battery) | AXP2101 gauge | — | — |
Brightness (expo-brightness) | AMOLED register (DCS) | backlight PWM | backlight PWM |
Accelerometer, gyroscope (expo-sensors) | QMI8658 | QMI8658 (axes not yet checked on hardware) | — |
Haptics, Vibration | motor | — | — |
Board keys (useButton) | BOOT 0, PWR 10 | — | — |
Wall clock (clock) | PCF85063 RTC | PCF85063 RTC | SoC counter |
microSD (file:///sd/) | SD 1-bit | SD 1-bit | — |
A dash means the board doesn't have the part: the API throws or rejects with an error that names
the board and the board.yaml entry, and each module's isAvailableAsync() returns false
(Device services).
You don't pick between the two ESP32-S3 boards: they're the same chip but ship different flash
parts, so kog flash, the browser flasher and Studio read the flash size and choose (32 MB is the
AMOLED-2.06, 16 MB the 1.46B). Only when the flash size can't be read do they ask, with --board
or the board picker.
Waveshare ESP32-S3-Touch-AMOLED-2.06
A watch-form board: ESP32-S3R8 with 8 MB octal PSRAM and a 32 MB flash part (the Kog image uses
the same 16 MB layout as the 1.46B). The 2.06″ 410×502 CO5300 AMOLED runs at ui_scale: 2, so
apps lay out in 205×251 logical px. The glass is a rounded rectangle (corner radius 114
physical px, measured from Waveshare's dimension drawing); useDisplay().safeRect is
{ x: 15, y: 19, width: 175, height: 213 } in logical px, and <SafeAreaView> keeps content
inside it.
What works today:
- Display and touch: the CO5300 panel and the FT3168 capacitive touch controller
(FT5x06-compatible, I2C
0x38). Colors, orientation and tap accuracy have been checked on glass; thetouch-testexample draws a dot under every press if you want to check your own unit. - Brightness:
expo-brightnesswrites the panel's own brightness register. The panel boots at full brightness, and hot reload restores it. - Battery:
expo-batteryreads the AXP2101's fuel gauge and charger state, every 2 seconds. Kog only reads the PMIC: it never switches a power rail or changes the charger settings. - Motion:
expo-sensors'Accelerometer(g) andGyroscope(rad/s) read the QMI8658, in the display's frame (x right, y up, z out of the glass; flat on a table readsz ≈ +1). - Vibration:
expo-hapticsandVibrationdrive the motor on GPIO 18. It is off at boot and stops on hot reload. - Keys:
useButton(0)reads the BOOT key (pressed = low) anduseButton(10, { activeLow: false })the PWR key, which the AXP2101 mirrors on SYS_OUT (pressed = high). Holding PWR for several seconds powers the board off; the PMIC does that in hardware. Neither pin is reserved. BOOT is also the download-mode strap, so don't hold it while resetting. - Wall clock: the PCF85063 battery RTC.
clock.source()returns'external-rtc', and the time survives a reboot. - Flash and the dev loop:
kog flash,kog devhot reload andkog deployare confirmed on the board. - microSD: SD 1-bit over SDMMC, like the 1.46B. Not yet tested on this board (no card on the bench).
- The rest runs the same ESP32-S3 runtime as the 1.46B: bundled and network images, the 4 MB asset pack, networking, and the 256 KB bundle ceiling.
examples/watch-demo shows all of these on one screen.
Declared, API coming: the speaker and microphones. The firmware reserves their pins now.
Other boards (planned)
spec/06 plans two more ways to run Kog on hardware that isn't blessed. Neither is available yet:
- Generic image +
board.yaml, no compiling (Tier B): a generic prebuilt image per chip and PSRAM class, configured at boot by a binary blob generated from yourboard.yaml. Neither the blob nor a generic image exists yet, andkog board validate(schema validation) isn't wired up. - Custom firmware build (Tier C):
npx kog firmware buildwould compile a runtime from yourboard.yamlwith a pinned, managed ESP-IDF installed into~/.kog/toolchains. Today the command exits with "isn't wired up yet".
Until then, supporting a new board means building the firmware from the Kog repository (native/firmware). The runtime's compiled-in drivers today are the ST7789, ILI9341, SPD2010 and CO5300 panels (SPI and QSPI buses) and XPT2046 (SPI), SPD2010 (I2C) and FT3168 (I2C) touch.