diff --git a/README.md b/README.md index 41cf88a..678ac1d 100644 --- a/README.md +++ b/README.md @@ -31,15 +31,18 @@ push) is offered. | Part | Choice | Why | |---|---|---| | MCU | **ESP32-S3-N16R8** (16 MB flash, 8 MB octal PSRAM) | USB OTG host (for the keyboard), Wi-Fi, BLE, dual core @ 240 MHz, plenty of PSRAM for git pack data and screen buffer. Best-supported Rust target in the ESP family. | -| Display | **Waveshare 7.5" V2 SPI (800×480)** for MVP | Partial refresh works, well-supported by `epd-waveshare`, low power, no IT8951 controller board needed. Upgrade path: 10.3" + IT8951 once UX is proven. | +| Display | **GDEY0579T93 + DESPI-c579 breakout** (5.79", 792×272, 1-bit) | Good Display panel matched with its own FPC breakout. Strip aspect (~2.9:1) — Freewrite-coded: ~12 lines of edit area, ~95 cols. Tiny framebuffer (~27 KB) leaves PSRAM headroom. The DESPI-c579 is a passive level-shifter / FPC-to-header board, not an active controller — driven over plain SPI like any other epd. | | Keyboard | **Nuphy Air60/Halo65 wired USB-C** | ESP32-S3 acts as USB host via TinyUSB. BLE-HID is a fallback but contends with Wi-Fi for radio time during push. | | Storage | microSD over SPI | Holds both the git working copy (`/sd/repo/`) **and** the local-only scratch space (`/sd/local/`). Internal flash is for firmware + config only. | | Power | **USB-C wall power for MVP**, 18650 + IP5306 in Phase 3 | Measure power profile on real hardware before sizing the battery. E-ink + sleep should give multi-day battery life but battery introduces charging, safety, and BMS complexity we don't need on day one. | | Enclosure | 3D-printed, hinged lid | Phase 4 concern. | -**Why not the 10.3" parallel screen for MVP:** IT8951 driver is fine but adds -~$80 BOM and parallel pins eat the GPIO budget we want for SD + status LEDs. -Start cheap, prove the loop, then upgrade. +**Why the 5.79" strip aspect:** less screen than a 7.5" page-shaped panel, +but the long-narrow shape biases toward "current line + recent context" — +the writing posture we actually want. The smaller framebuffer is cheap on +RAM, and SPI panels keep the GPIO budget open for SD + future peripherals. +A larger panel (10.3" via IT8951) stays on the table for v1.x once UX is +proven. --- @@ -51,7 +54,7 @@ rejected alternatives below. | Layer | Crate / Component | Notes | |---|---|---| | HAL / runtime | `esp-idf-svc`, `esp-idf-hal` | std build, gives us heap, threads, VFS, mbedtls, Wi-Fi stack. | -| Display | `embedded-graphics` + `epd-waveshare` | Pixel framebuffer with partial-refresh regions. We track dirty rects ourselves. | +| Display | `embedded-graphics` + `epd-waveshare` (or custom driver) | Pixel framebuffer with partial-refresh regions. We track dirty rects ourselves. The GDEY0579T93 uses an SSD1683-class controller; if it's not already in `epd-waveshare`, we write a small driver against `embedded-hal` SPI — ~300 LoC, low risk. | | Editor core | Custom, in-tree | Rope buffer (`ropey`), mode state machine, Vim keymap table. | | TUI-style layout | Custom thin layer (~500 LoC) | API inspired by Ratatui (`Layout`, `Block`, `Paragraph`) but renders directly to `embedded-graphics`. See below. | | USB host | `esp-idf` TinyUSB bindings | Boot-protocol HID is enough for the keyboard. | diff --git a/docs/v0.1-mvp-product.md b/docs/v0.1-mvp-product.md index f7ce3e6..42b450e 100644 --- a/docs/v0.1-mvp-product.md +++ b/docs/v0.1-mvp-product.md @@ -96,34 +96,46 @@ create remote repos. ## Screen layout -Waveshare 7.5" V2 — 800×480, 1-bit. +GDEY0579T93 — 5.79", **792×272**, 1-bit, partial refresh capable. Wide +strip aspect (~2.9:1) — biases the UX toward "current line and recent +context," not a full page. ``` -┌──────────────────────────────────────────────────────────────┐ -│ notes.md ● 14:02:33 │ ← header (1 line) -├──────────────────────────────────────────────────────────────┤ -│ │ -│ Lorem ipsum dolor sit amet, consectetur adipiscing elit. │ -│ Sed do eiusmod tempor incididunt ut labore et dolore magna │ -│ aliqua. │ -│ │ ← edit area -│ The quick brown fox jumps over the lazy▎ │ (cursor block) -│ │ -│ ... │ -│ │ -├──────────────────────────────────────────────────────────────┤ -│ INSERT • unsaved • Wi-Fi ✓ │ ← status (1 line) -└──────────────────────────────────────────────────────────────┘ +┌─────────────────────────────────────────────────────────────────────────────────────┐ +│ notes.md ● 14:02:33 │ ← header +├─────────────────────────────────────────────────────────────────────────────────────┤ +│ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor │ +│ incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud │ +│ exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. │ +│ │ +│ Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu │ +│ fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in │ ← edit area +│ culpa qui officia deserunt mollit anim id est laborum. │ (~11 lines) +│ │ +│ The quick brown fox jumps over the lazy▎ │ (cursor block) +│ │ +│ │ +│ │ +├─────────────────────────────────────────────────────────────────────────────────────┤ +│ INSERT • unsaved • Wi-Fi ✓ │ ← status +└─────────────────────────────────────────────────────────────────────────────────────┘ ``` -- Header: filename, dirty indicator (●/○), wall clock if Wi-Fi has set time. +- Header: filename, dirty indicator (●/○), wall clock if SNTP has set time. - Status: mode (always `INSERT` in v0.1), save state, Wi-Fi state. After a `Ctrl-S` / `Ctrl-G`, status briefly shows the action result (saved at / pushed `abc1234` / error message) then returns to default. - Cursor: solid block at the insertion point. **No blink.** -Fonts: one mono font, embedded in firmware. Probably IBM Plex Mono at a size -that gives ~70 columns and ~25 lines of edit area. +Fonts: one mono font, embedded in firmware. Target sizing: a 14 px mono +glyph at roughly 8 px advance gives ~95 columns × ~11 visible lines of edit +area after header (16 px) and status (16 px) bars. Final size tuned during +spike 2 against real legibility on the panel. + +**UX consequence of the strip aspect:** the cursor stays near the bottom of +the visible area during normal typing; the edit area scrolls one line at a +time. There is no "page" — just a continuously advancing strip. Embrace it, +don't fight it. ## Error UX diff --git a/docs/v0.1-mvp-technical.md b/docs/v0.1-mvp-technical.md index 26ea05b..316f878 100644 --- a/docs/v0.1-mvp-technical.md +++ b/docs/v0.1-mvp-technical.md @@ -73,8 +73,11 @@ We do **not** try to build the whole stack and turn it on. Each spike below is a small program that proves one risk before we commit to the next layer. 1. **Spike 1 — Blink.** Confirm toolchain, flash, and basic GPIO. -2. **Spike 2 — EPD.** Drive the 7.5" panel with `epd-waveshare`; full refresh - "hello world." Validates SPI wiring, panel timings. +2. **Spike 2 — EPD.** Drive the GDEY0579T93 (via DESPI-c579 breakout) over + SPI; full refresh "hello world." Validates SPI wiring, panel timings, and + — critically — whether `epd-waveshare` already supports the panel's + controller (SSD1683-class) or whether we write a thin custom driver + against `embedded-hal`. Either way, ~300 LoC; this spike answers which. 3. **Spike 3 — SD.** Mount FAT, read/write a file. Validates SPI sharing with EPD (or separate bus if needed). 4. **Spike 4 — USB host.** Enumerate the Nuphy as a boot-protocol HID @@ -173,7 +176,7 @@ ESP32-S3-N16R8: 512 KB SRAM + 8 MB PSRAM. We budget conservatively. |---|---|---| | Internal SRAM | ~120 KB | task stacks, DMA buffers, hot code paths | | Internal SRAM | ~80 KB | mbedtls runtime (TLS handshake working set) | -| PSRAM | ~256 KB | EPD framebuffer (800×480×1 = 48 KB) + shadow + glyph cache | +| PSRAM | ~128 KB | EPD framebuffer (792×272×1 ≈ 27 KB) + shadow + glyph cache | | PSRAM | ~512 KB | rope buffer + edit history headroom | | PSRAM | ~1.5 MB | gitoxide working set during push (pack delta, etc.) | | PSRAM | rest | heap headroom |