|
|
@@ -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;
|
|
|
}
|