|
|
@@ -73,8 +73,8 @@ by *probing with distinctive inputs and reading the transform back out*:
|
|
|
below.
|
|
|
- **Pixel packing, palette codes, row order.** Diag harnesses
|
|
|
(`run_diag*_harness.h`) replace the uniform fill with positional/value tags
|
|
|
- and read the exact wire bytes: Pattern A recovers 1bpp row ordering
|
|
|
- (`row_interleave`), Pattern B recovers packing + palette codes
|
|
|
+ and read the exact wire bytes: Pattern A recovers row ordering
|
|
|
+ (`line_order`), Pattern B recovers packing + palette codes
|
|
|
(`bits_per_pixel` + `palette`), and a native-path variant handles packed
|
|
|
panels whose re-pack doesn't preserve byte identity.
|
|
|
- **`plane_invert`** (whether each plane's wire byte is the bit-complement of
|
|
|
@@ -136,8 +136,11 @@ subscription.
|
|
|
Multi-plane and multi-region are one mechanism: after writing plane *k*, if
|
|
|
more planes remain the engine writes the next (shared window) or re-enters
|
|
|
`SET_WINDOW` for `window_sequence[k]` (`window_per_plane`, separate regions,
|
|
|
-each sized by `plane_width`). `row_interleave` maps each wire byte through an
|
|
|
-interleaved row order for panels that scan from both edges toward the middle.
|
|
|
+each sized by `plane_width`). `line_order` controls how a plane's wire lines
|
|
|
+map to buffer rows: `SEQUENTIAL` (line i = row i) or `PAIRED_EDGES`, which
|
|
|
+emits `2*height` lines (line 2i = row `H-1-i`, line 2i+1 = row i) to fill the
|
|
|
+2x-height RAM of a controller that scans from both edges toward the middle -
|
|
|
+reproducing GxEPD2's own doubled line emission, orientation included.
|
|
|
|
|
|
Every command and data byte is its own SPI transaction with CS toggled around
|
|
|
it — wasteful versus a burst transfer, but deliberate: matching the vendor
|
|
|
@@ -149,7 +152,7 @@ it — wasteful versus a burst transfer, but deliberate: matching the vendor
|
|
|
`busy_timeout_ms`; `init_sequence` / `window_sequence[2]` / `refresh_sequence`
|
|
|
(arrays of `EpdCommand{cmd, data, len, delay_before, delay_after, wait_busy}`);
|
|
|
`window_per_plane`; `plane_count`, `plane_write_cmd[2]`, `plane_invert[2]`,
|
|
|
-`plane_width`; `row_interleave`; and the pixel format — `bits_per_pixel`
|
|
|
+`plane_width`; `line_order`; and the pixel format — `bits_per_pixel`
|
|
|
(1 = 1bpp plane model; 2/4 = packed code-per-pixel) with `palette` + `blank_code`
|
|
|
for packed panels. "Is it packed" is `bits_per_pixel > 1` and "which codes" is
|
|
|
data, so a 4bpp 7-colour (ACeP) panel is just a palette plus `bits_per_pixel: 4`
|
|
|
@@ -213,7 +216,8 @@ over a plain fill/text for bring-up. It reads the descriptor, so it is
|
|
|
to the colors the panel can show (2 mono, 3 BW+accent, 4/7 packed). A **dithered
|
|
|
grey ramp** gives 1bpp panels a graded sweep rather than two flat blocks, a
|
|
|
**corner-to-corner diagonal** catches coordinate-transform bugs (a dashed
|
|
|
-diagonal is the row-reorder signature that confirmed `row_interleave`), and the
|
|
|
+diagonal is the row-reorder signature that pins down a panel's `line_order`),
|
|
|
+and the
|
|
|
border + corner markers catch clipped/offset origins and rotation/mirror errors.
|
|
|
|
|
|
Pass a font to label the panel with its model (the Good Display part number
|