You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+16Lines changed: 16 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,6 +2,22 @@
2
2
3
3
## [Unreleased]
4
4
5
+
## [crumble-v4.7.2] - 2026-08-05
6
+
7
+
Single firmware: `crumble-v4.7.2-tiny-bitter.bin` (Bitter built-in, fits the stock 6.25 MB slot for SD-card flashing).
8
+
9
+
### Added
10
+
-**Newer X4 units that only stayed awake on USB power now run on battery.** One X4 hardware revision does not self-latch its battery MOSFET, so it appeared dead or unresponsive the moment it was unplugged. CrumBLE now asserts that latch (GPIO13) at boot, matching the fix CrossInk shipped in 1.5.0-rc-2. This is a no-op on every X4 sold before that revision — those self-latch through a pull and never needed firmware to hold the rail — so nothing changes for existing devices.
11
+
12
+
### Changed
13
+
-**Vendored `freeink-sdk` updated to upstream `e6a8048`** (154 commits, from the 2026-07-01 snapshot shipped since 4.6.0). For existing panels this brings: the refresh-completion wait now sleeps on the BUSY interrupt edge instead of polling on a 1 ms tick (X4 joins X3, which already did this), power-up sequencing before a grayscale refresh, and an X4 RED-plane baseline fix. The X4 grayscale waveform table and the X3 LUT bank are byte-for-byte unchanged. The X3 grayscale `wb_gc` fix CrumBLE has carried since v4.6.0 is now upstream's own value, so it survives the update unmodified. The update also compiles in upstream's UC8179 and UC8279 drivers for the newer UltraChip panel controllers — see the known limitation below.
14
+
15
+
### Fixed
16
+
-**Opening a book no longer floods the log with deferred-save errors.** Two heap thresholds disagreed: the settings-save retry admitted a write whenever `maxAlloc` cleared 20 KB, but the re-check immediately before serializing rejected anything under 28 KB. In that 20–28 KB band — easily reached while a book is open — every main-loop tick ran the directory/filesystem work, failed the floor, logged an error, and tried again, hundreds of times a second. Both now use the same floor, so the save defers quietly and retries once there is genuinely room. The save behaviour itself is unchanged; only the futile retry loop is gone.
17
+
18
+
### Known limitations
19
+
-**Newer X3/X4 units with UltraChip UC8279/UC8179 panel controllers are still unsupported.** The drivers are compiled in, but nothing selects them: CrumBLE does not fingerprint the panel controller at boot. The bus probe that would do it hung both an X4 and an X3 during development, and upstream marks the UC8279 path itself as "Pending hardware validation — no UC8279 X3 unit has been on the bench yet". Shipping detection that cannot be validated, and that demonstrably broke working devices, was not a trade worth making. If your display never comes up on CrumBLE, use CrossInk 1.4.0.1 or newer.
20
+
5
21
### Fixed
6
22
- **UI font fallback no longer taxes the reader, and reader UI keeps CJK coverage for free when the primary is CJK-capable.** All three reader activities (EPUB, TXT, XTC) release the standalone UI glyph fallback family on entry and re-arm it on exit, matching the pattern that File Transfer, OPDS, and KOReader auth already use. The fallback exists to fill glyph misses in carousel/shelf/settings labels; book text renders through the primary SD font, which already carries whatever glyphs the book itself needs. Previously the fallback stayed resident through the reading session (~10 KB scattered across the heap) and starved contiguous allocations the reader depends on (page DOM 25-40 KB, CSS rule-table grow, BT font subset). Users can now leave the "UI Font Fallback" setting on and still have full contiguous heap while reading. On top of the release-and-suppress path, if the reader's primary SD font is loaded on entry (the normal case when the user has picked an SD font family like Bitter-LXGWWenKai), the reader points the UI fallback at the primary's already-loaded `EpdFontFamily` -- zero extra heap, and CJK glyph misses in reader UI (title bar, chapter label, progress bar, drawer, in-reader menu) render through the primary. Rendered at the primary's point size, so CJK reads visibly larger than surrounding 10-12pt UI text, but far better than tofu. The alias survives font-change / reindex within the reader (ensureLoaded breaks the fallback pointer before unloading the primary and re-establishes it after the new primary loads).
7
23
-**Progressive JPEG EPUB covers now render smoothly in generated BMP cover assets.** The cover/thumbnail BMP path already detected progressive JPEGs and forced the required 1/8 JPEGDEC decode, but it still upscaled that reduced grid with blocky sampling. `JpegToBmpConverter` now uses a progressive-only bilinear smoothing pass before dithering when those covers are enlarged for home thumbnails and sleep covers, matching the higher-quality behavior already used in the framebuffer renderer while keeping memory bounded to a small line buffer.
Copy file name to clipboardExpand all lines: UC8179-PORT-PLAN.md
+159Lines changed: 159 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -94,6 +94,165 @@ split) unless the facade is also updated, which is most of strategy A anyway.
94
94
release checklist. Third frozen-dependency incident this cycle (prebake wasm,
95
95
sim shim, SDK) and the only one with hardware consequences.
96
96
97
+
## Execution record (steps 1-4 done)
98
+
99
+
### Step 1 — local-patch direction: resolved
100
+
101
+
The vendored SDK was an unmodified snapshot of upstream **`6ee2d06`** (2026-07-01),
102
+
found by matching blob hashes across all 293 upstream commits: 37 of the 42 files
103
+
in the six compiled libs matched that tree exactly. The other 5 carried content
104
+
never seen in any upstream commit — that is the complete local-patch surface:
105
+
106
+
| File | Local patch | Direction |
107
+
|---|---|---|
108
+
|`lut/Uc8253X3Luts.h`| X3 `lut_x3_wb_gc` lead byte `0x54` -> `0x00` (the v321 fix) |**take upstream** — HEAD is byte-identical; only our comment differed |
109
+
|`include/FreeInkDisplay.h`, `src/FreeInkDisplay.cpp`| heap framebuffers, `releaseBuffers`/`reallocBuffers`, `syncWriteBufferFromActive`, secondary-buffer release, `cleanupGrayscale*` restore memcpy, `swapBuffers` null guard |**take upstream** — HEAD has all of them, several comment-for-comment identical (they were backports that landed upstream) |
110
+
|`driver/Ssd1677Driver.cpp`| initial paint FULL -> HALF |**take upstream** — converged; on X4 (`halfSeqOverride=0xD7`) upstream also resolves to HALF |
111
+
|`driver/Ssd1677Driver.h`|`skipInitialResync()` override defusing `_needsInitialFull`|**KEEP — re-applied.** Upstream made `skipInitialResync` a `PanelDriver` virtual and overrides it on X3/UC8179/UC8279 but *not* SSD1677; the base is a no-op, so without this the X4 seamless silent-restart flash returns |
112
+
113
+
The `Uc8253X3Driver.{h,cpp}` hunks the plan flagged are **entirely upstream
114
+
evolution** — the async `displayStart`/`displayFinish` split, the `factoryP1/P2`
115
+
reference banks, and a `forcedFullSync` -> `_forceFullSyncNext` fix. Nothing of
116
+
ours to lose there.
117
+
118
+
### Step 2 — strategy A taken
119
+
120
+
`freeink-sdk/` mirrored to upstream `e6a8048`, excluding `libs/book/` (4 MB
121
+
EPUB engine — expat/miniz/libunibreak plus a test TTF — that CrumBLE never
122
+
compiles) and the nested VCS/`__pycache__` dirs. Re-applied the one kept hunk.
123
+
**Zero firmware call-site changes were needed**; `pio run -e tiny-bitter` built
124
+
clean on the first attempt.
125
+
126
+
Only six SDK libs are actually compiled (`lib_deps`): FreeInkDisplay,
0 commit comments