Просмотр исходного кода

harness: extend Pattern B to 7-colour ACeP

Generalise B1 to lay one pixel per DISTINCT code across as many bytes as
needed (4 codes -> 1 byte on 4-colour, 7 codes -> 4 bytes on ACeP), so it
exercises every code and also checks the byte-to-byte stride, not just
intra-byte order. Heap-allocate the wrapper (the 7-colour full-page buffer
is ~134KB). Add run_565c_diagB.cpp (GxEPD2_565c, 600x448, 4bpp).

Host-only validation: 565c derives palette black=0 white=1 green=2 blue=3
red=4 yellow=5 orange=6 + MSB-first 2px/byte packing - exactly color7() and
our GXEPD2_PALETTE_7C. 290c (4-colour) regression unchanged.
ZiB 3 недель назад
Родитель
Сommit
9491ec9d41
2 измененных файлов с 67 добавлено и 21 удалено
  1. 19 0
      tools/gxepd2_harness/run_565c_diagB.cpp
  2. 48 21
      tools/gxepd2_harness/run_diagB_harness.h

+ 19 - 0
tools/gxepd2_harness/run_565c_diagB.cpp

@@ -0,0 +1,19 @@
+// Pattern B diagnostic capture for GxEPD2_565c (ACeP 7-colour, 600x448,
+// packed 4bpp, 2 px/byte). Host-only: validates the 7-colour palette +
+// packing derivation against the vendored driver, no hardware - we have no
+// 565c descriptor/panel yet, so this is pure capture groundwork.
+
+#include "epd7c/GxEPD2_565c.h"
+constexpr int16_t WIDTH = GxEPD2_565c::WIDTH;
+constexpr int16_t HEIGHT = GxEPD2_565c::HEIGHT;
+#include "GxEPD2_7C.h"
+
+#include "run_diagB_harness.h"
+
+using Driver = DiagBPeek<GxEPD2_565c>;
+using Wrapper = GxEPD2_7C<Driver, GxEPD2_565c::HEIGHT>;
+
+int main() {
+  run_diagB<Wrapper, Driver>("GxEPD2_565c", WIDTH, HEIGHT, 4);
+  return 0;
+}

+ 48 - 21
tools/gxepd2_harness/run_diagB_harness.h

@@ -58,7 +58,10 @@ template<typename WrapperT, typename DriverT> void run_diagB(const char *name, u
   const uint32_t plane_bytes = (uint32_t) W * H * bpp / 8;  // per region/page
   printf("=== %s: DIAGNOSTIC FILL (Pattern B: packing + codes) bpp=%d ppb=%d ===\n", name, bpp, ppb);
 
-  WrapperT display(DriverT(10, 11, 12, 13));
+  // Heap-allocate: the wrapper embeds a full-page _pixel_buffer, which for a
+  // 7-colour panel (4bpp, e.g. 600x448 -> ~134KB) is too big for the stack.
+  WrapperT *dp = new WrapperT(DriverT(10, 11, 12, 13));
+  WrapperT &display = *dp;
   Trace::set_dc_pin(11);
   Trace::last_busy_release_value = display.epd2.busy_level() == HIGH ? LOW : HIGH;
   display.epd2.selectSPI(SPI, SPISettings());
@@ -109,34 +112,58 @@ template<typename WrapperT, typename DriverT> void run_diagB(const char *name, u
     return -1;
   };
 
-  printf("  [B1] intra-byte order (bg=black; px 0..%d = distinct-code colours):\n", ppb - 1);
-  const uint16_t probe[4] = {GxEPD_RED, GxEPD_YELLOW, GxEPD_WHITE, GxEPD_BLACK};  // codes 3,2,1,0 on 4-colour
+  // [B1] packing order across bytes. Place one pixel per DISTINCT code along
+  // row 0 (so every code the panel has is exercised - 4 on a 4-colour panel,
+  // all 7 on ACeP), spanning ceil(ndist*bpp/8) bytes. Verify each pixel i
+  // lands in byte i/ppb, field i%ppb (MSB-first), which also confirms the
+  // byte-to-byte stride, not just intra-byte order.
+  struct PC {
+    uint16_t color;
+    uint8_t code;
+    const char *label;
+  };
+  PC distinct[16];
+  int nd = 0;
+  for (int k = 0; k < NCOL; k++) {
+    bool seen = false;
+    for (int j = 0; j < nd; j++)
+      if (distinct[j].code == code_of[k])
+        seen = true;
+    if (!seen)
+      distinct[nd++] = {colors[k].color, code_of[k], colors[k].label};
+  }
+  (void) code_for;
+  int nbytes = (nd * bpp + 7) / 8;
+  printf("  [B1] packing order: %d distinct-code pixels across %d byte(s):\n", nd, nbytes);
   Trace::start_record();
   display.firstPage();
   do {
     display.fillScreen(GxEPD_BLACK);
-    for (int i = 0; i < ppb; i++)
-      display.drawPixel(i, 0, probe[i % 4]);
+    for (int i = 0; i < nd; i++)
+      display.drawPixel(i, 0, distinct[i].color);
   } while (display.nextPage());
   Trace::stop_record();
   auto b = diagB_first_burst(plane_bytes);
-  uint8_t byte0 = b.empty() ? 0 : b[0];
-  uint8_t f[8];
-  diagB_fields(byte0, bpp, ppb, f);
-  printf("    byte0=0x%02X  fields MSB..LSB:", byte0);
-  for (int j = 0; j < ppb; j++)
-    printf(" %u", f[j]);
-  printf("\n");
 
   bool msb_first = true, lsb_first = true;
-  for (int i = 0; i < ppb; i++) {
-    int want = code_for(probe[i % 4]);
-    if ((int) f[i] != want)
-      msb_first = false;           // pixel i in field i (MSB-first)
-    if ((int) f[ppb - 1 - i] != want)
-      lsb_first = false;           // pixel i in field (ppb-1-i)
+  for (int i = 0; i < nd; i++) {
+    int bi = i / ppb, fi = i % ppb;
+    uint8_t f[8];
+    diagB_fields(bi < (int) b.size() ? b[bi] : 0, bpp, ppb, f);
+    if ((int) f[fi] != distinct[i].code)
+      msb_first = false;
+    if ((int) f[ppb - 1 - fi] != distinct[i].code)
+      lsb_first = false;
   }
-  printf("    => %s\n", msb_first   ? "MSB-first: pixel i in field i (shift=(ppb-1-i)*bpp)"
-                        : lsb_first ? "LSB-first: pixel i in low fields"
-                                    : "UNKNOWN packing order");
+  printf("    bytes:");
+  for (int t = 0; t < nbytes && t < (int) b.size(); t++)
+    printf(" 0x%02X", b[t]);
+  printf("\n    pixels (label=code):");
+  for (int i = 0; i < nd; i++)
+    printf(" %s=%u", distinct[i].label, distinct[i].code);
+  printf("\n    => %s\n", msb_first   ? "MSB-first: pixel i -> byte i/ppb, field i%ppb (shift=(ppb-1-f)*bpp)"
+                          : lsb_first ? "LSB-first within byte"
+                                      : "UNKNOWN packing order");
+
+  delete dp;
 }