|
|
|
|
@@ -45,7 +45,7 @@ blocked by I/O.
|
|
|
|
|
| Task | Core | Stack | Responsibility |
|
|
|
|
|
| ------------- | ---- | ----- | -------------------------------------------------------- |
|
|
|
|
|
| `usb_task` | 0 | 8 KB | TinyUSB host loop, decode HID reports, post `KeyEvent`s |
|
|
|
|
|
| `wifi_task` | 0 | 8 KB | Station mode only (no provisioning AP); expose status |
|
|
|
|
|
| `wifi_task` | 0 | 8 KB | On-demand station: off by default, brought up by `Ctrl-G` |
|
|
|
|
|
| `ui_task` | 1 | 16 KB | Consume `KeyEvent`s, mutate editor state, enqueue render |
|
|
|
|
|
| `render_task` | 1 | 12 KB | Drain render queue, do partial/full refresh on EPD |
|
|
|
|
|
| `git_task` | 1 | 32 KB | Triggered by `Ctrl-G`; runs gitoxide commit + push |
|
|
|
|
|
@@ -67,7 +67,7 @@ read snapshot (render diff).
|
|
|
|
|
└─ present → continue
|
|
|
|
|
5. Init SPI bus (shared: EPD + SD on different CS)
|
|
|
|
|
6. Init EPD, full refresh: splash + boot log
|
|
|
|
|
7. Start tasks: usb, wifi (station), ui, render
|
|
|
|
|
7. Start tasks: usb, wifi (spawned in `Off` state — no radio bring-up), ui, render
|
|
|
|
|
8. ui_task opens /sd/repo/notes.md, places cursor, enqueues full render
|
|
|
|
|
9. STEADY STATE
|
|
|
|
|
```
|
|
|
|
|
@@ -156,15 +156,32 @@ Storage split rationale:
|
|
|
|
|
- The file is read fully into the rope at boot. v0.1 caps file size at
|
|
|
|
|
256 KB; larger files refuse to open with a clear message.
|
|
|
|
|
|
|
|
|
|
### `wifi` — provisioning + station
|
|
|
|
|
### `wifi` — on-demand station
|
|
|
|
|
|
|
|
|
|
- Provisioning: SoftAP `typewriter-setup`, captive-portal DNS, tiny HTTP
|
|
|
|
|
server (`esp-idf-svc::http`). Form submits config; on success, restart in
|
|
|
|
|
station mode.
|
|
|
|
|
- Station: reconnect with exponential backoff (1, 2, 5, 10, 30, 60 s, hold
|
|
|
|
|
at 60). Status exposed via a `WifiState` atomic enum.
|
|
|
|
|
- Time sync via SNTP — needed for commit timestamps. Failure is logged but
|
|
|
|
|
non-fatal; commits use device uptime if SNTP fails.
|
|
|
|
|
- **Off by default.** The radio is powered down (`esp_wifi_stop`) except
|
|
|
|
|
during a Publish and a short grace window after. This is the load-bearing
|
|
|
|
|
battery decision: always-on station mode burns ~410 mAh/day just for the
|
|
|
|
|
radio; on-demand is closer to ~25 mAh/day at 10 Publishes/day. See
|
|
|
|
|
[qfd.md H13](qfd.md#6-critical-performance-budget).
|
|
|
|
|
- **Bring-up on `Ctrl-G`.** `wifi_task` transitions `Off → Associating →
|
|
|
|
|
Connected`. Association timeout: 10 s. If association fails, the local
|
|
|
|
|
commit is preserved and the status line shows `⌁ ✗`; no background retry.
|
|
|
|
|
- **Grace window** of ~90 s after a Publish completes. A `Ctrl-G` inside
|
|
|
|
|
the window reuses the connection (no second association cost). If no
|
|
|
|
|
Publish fires before the window expires, the radio tears down.
|
|
|
|
|
- **No reconnect-backoff state machine.** There is nothing to reconnect to
|
|
|
|
|
when the user isn't trying to Publish. Single-shot try-on-demand replaces
|
|
|
|
|
the exponential-backoff approach.
|
|
|
|
|
- **SNTP** runs on the first successful bring-up of a power session. The
|
|
|
|
|
result is cached for up to 24 h; subsequent Publishes use the cached time
|
|
|
|
|
for the commit message. Falls back to device uptime if SNTP has never
|
|
|
|
|
succeeded — logged but non-fatal.
|
|
|
|
|
- **Status exposed via a `WifiState` atomic enum** (`Off`, `Associating`,
|
|
|
|
|
`Connected`, `Failed`).
|
|
|
|
|
|
|
|
|
|
On-device provisioning (SSID, PAT rotation, etc.) is deliberately deferred
|
|
|
|
|
to v0.9. v0.1 reads all config from the binary at build time — see
|
|
|
|
|
"Provisioning — build-time only" below.
|
|
|
|
|
|
|
|
|
|
### `git` — commit + push
|
|
|
|
|
|
|
|
|
|
|