|
@@ -21,15 +21,14 @@ inline const uint8_t PANEL_213_Z98C_DRIVER_OUTPUT_CONTROL[] = {0xF9, 0x00, 0x00}
|
|
|
inline const uint8_t PANEL_213_Z98C_DATA_ENTRY_MODE[] = {0x03};
|
|
inline const uint8_t PANEL_213_Z98C_DATA_ENTRY_MODE[] = {0x03};
|
|
|
inline const uint8_t PANEL_213_Z98C_BORDER_WAVEFORM[] = {0x05};
|
|
inline const uint8_t PANEL_213_Z98C_BORDER_WAVEFORM[] = {0x05};
|
|
|
inline const uint8_t PANEL_213_Z98C_TEMP_SENSOR[] = {0x80};
|
|
inline const uint8_t PANEL_213_Z98C_TEMP_SENSOR[] = {0x80};
|
|
|
-// GxEPD2's vendor source sends {0x00, 0x80} here, but the whole panel came
|
|
|
|
|
-// out solid black regardless of RAM content with that value on real
|
|
|
|
|
-// hardware. The known-working epaper_spi driver on this exact same panel/
|
|
|
|
|
-// wiring (waveshare-2.13in-bv4, see device/epaper-nametag.yaml) sends
|
|
|
|
|
-// {0x80, 0x80} instead - this register controls per-plane RAM bypass
|
|
|
|
|
-// options, so a wrong bypass bit here would force a plane to a constant
|
|
|
|
|
-// value irrespective of what's actually written to it, matching the
|
|
|
|
|
-// symptom exactly.
|
|
|
|
|
-inline const uint8_t PANEL_213_Z98C_DISPLAY_UPDATE_CONTROL[] = {0x80, 0x80};
|
|
|
|
|
|
|
+// Stock GxEPD2 vendor value. Was swapped to {0x80, 0x80} (matching the
|
|
|
|
|
+// epaper_spi reference) while chasing the solid-black/solid-red hardware
|
|
|
|
|
+// symptom - that turned out to be an unrelated bug (display.py never
|
|
|
|
|
+// wired the configured lambda to set_writer() at all, so nothing but
|
|
|
|
|
+// auto_clear's default fill ever rendered). Rolled back now that the real
|
|
|
|
|
+// cause is fixed, to test whether the stock GxEPD2 protocol works as-is
|
|
|
|
|
+// on this panel or genuinely needs epaper_spi's deviations.
|
|
|
|
|
+inline const uint8_t PANEL_213_Z98C_DISPLAY_UPDATE_CONTROL[] = {0x00, 0x80};
|
|
|
|
|
|
|
|
inline const EpdCommand PANEL_213_Z98C_INIT[] = {
|
|
inline const EpdCommand PANEL_213_Z98C_INIT[] = {
|
|
|
{0x12, nullptr, 0, /*delay_before_ms=*/10, /*delay_after_ms=*/10, /*wait_busy_after=*/false}, // SWRESET
|
|
{0x12, nullptr, 0, /*delay_before_ms=*/10, /*delay_after_ms=*/10, /*wait_busy_after=*/false}, // SWRESET
|
|
@@ -40,35 +39,18 @@ inline const EpdCommand PANEL_213_Z98C_INIT[] = {
|
|
|
{0x21, PANEL_213_Z98C_DISPLAY_UPDATE_CONTROL, 2},
|
|
{0x21, PANEL_213_Z98C_DISPLAY_UPDATE_CONTROL, 2},
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-// GxEPD2_213_Z98c::_Update_Full()/_Update_Part() fire a single combined
|
|
|
|
|
-// trigger (0x22/0xF7 + 0x20) and assume it handles power internally. That
|
|
|
|
|
-// matched neither hardware symptom we saw (solid black, then solid red) -
|
|
|
|
|
-// busy genuinely engaged and cleared each time, consistent with a waveform
|
|
|
|
|
-// that ran without properly stabilized power, not a hang. The known-working
|
|
|
|
|
-// epaper_spi driver for this exact panel instead brackets the refresh with
|
|
|
|
|
-// explicit power-on/off triggers, each with its own busy-wait, and resets
|
|
|
|
|
-// the RAM counters again immediately before the refresh trigger itself:
|
|
|
|
|
-// POWER_ON (0x22/0xF8 + 0x20, wait busy)
|
|
|
|
|
-// reset RAM counters (0x4E/0x4F back to 0,0)
|
|
|
|
|
-// REFRESH (0x22/0xF7 + 0x20, wait busy)
|
|
|
|
|
-// POWER_OFF (0x22/0x83 + 0x20, wait busy)
|
|
|
|
|
-// Mirroring that sequence here since GxEPD2's shortcut is what's unproven
|
|
|
|
|
-// on this specific panel/FPC revision.
|
|
|
|
|
-inline const uint8_t PANEL_213_Z98C_POWER_ON_MODE[] = {0xF8};
|
|
|
|
|
|
|
+// GxEPD2_213_Z98c::_Update_Full()/_Update_Part() - stock vendor sequence,
|
|
|
|
|
+// a single combined trigger that assumes it handles power internally.
|
|
|
|
|
+// Bracketed this with explicit power-on/off (matching epaper_spi) while
|
|
|
|
|
+// chasing the solid-black/solid-red symptom, which turned out to be
|
|
|
|
|
+// unrelated (see PANEL_213_Z98C_DISPLAY_UPDATE_CONTROL's comment). Rolled
|
|
|
|
|
+// back to the stock single-trigger sequence to test it now that the real
|
|
|
|
|
+// bug is fixed.
|
|
|
inline const uint8_t PANEL_213_Z98C_UPDATE_MODE[] = {0xF7};
|
|
inline const uint8_t PANEL_213_Z98C_UPDATE_MODE[] = {0xF7};
|
|
|
-inline const uint8_t PANEL_213_Z98C_POWER_OFF_MODE[] = {0x83};
|
|
|
|
|
-inline const uint8_t PANEL_213_Z98C_RESET_X_COUNTER[] = {0x00};
|
|
|
|
|
-inline const uint8_t PANEL_213_Z98C_RESET_Y_COUNTER[] = {0x00, 0x00};
|
|
|
|
|
|
|
|
|
|
inline const EpdCommand PANEL_213_Z98C_REFRESH[] = {
|
|
inline const EpdCommand PANEL_213_Z98C_REFRESH[] = {
|
|
|
- {0x22, PANEL_213_Z98C_POWER_ON_MODE, 1},
|
|
|
|
|
- {0x20, nullptr, 0, /*delay_before_ms=*/0, /*delay_after_ms=*/0, /*wait_busy_after=*/true},
|
|
|
|
|
- {0x4E, PANEL_213_Z98C_RESET_X_COUNTER, 1},
|
|
|
|
|
- {0x4F, PANEL_213_Z98C_RESET_Y_COUNTER, 2},
|
|
|
|
|
{0x22, PANEL_213_Z98C_UPDATE_MODE, 1},
|
|
{0x22, PANEL_213_Z98C_UPDATE_MODE, 1},
|
|
|
{0x20, nullptr, 0, /*delay_before_ms=*/0, /*delay_after_ms=*/0, /*wait_busy_after=*/true},
|
|
{0x20, nullptr, 0, /*delay_before_ms=*/0, /*delay_after_ms=*/0, /*wait_busy_after=*/true},
|
|
|
- {0x22, PANEL_213_Z98C_POWER_OFF_MODE, 1},
|
|
|
|
|
- {0x20, nullptr, 0, /*delay_before_ms=*/0, /*delay_after_ms=*/0, /*wait_busy_after=*/true},
|
|
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
// full_refresh_time/partial_refresh_time from the vendor header are both
|
|
// full_refresh_time/partial_refresh_time from the vendor header are both
|