Преглед изворни кода

engine: busy-wait after reset (OTP-init panels like F52)

RESET_SETTLE went straight to INIT_CMD with no busy wait, but every vendor
_InitDisplay() does _waitWhileBusy() right after the reset pulse. Controllers
that load settings/waveforms from OTP after a hardware reset (JD79676 /
GDEY0213F52 - its whole init is just 0xE9 + power-on) hold BUSY during that
load; firing commands before it clears gets them silently dropped, so the
panel never refreshed (bench F52: every wait returned in ~8ms, old content
stayed). Add the post-reset busy wait; panels that don't assert BUSY
post-reset fall straight through, so it's safe for all.

Also revert the F52 descriptor's busy_active_level to false (LOW): the HIGH
experiment hung on the idle-HIGH level (WAIT_BUSY -> ABORTED), confirming the
vendor's LOW is correct - the real issue was the missing post-reset wait.
ZiB пре 3 недеља
родитељ
комит
c5a3283654
2 измењених фајлова са 10 додато и 7 уклоњено
  1. 9 1
      components/gxepd2/cycle_engine.h
  2. 1 6
      components/gxepd2/panel_213c_gdey0213f52.h

+ 9 - 1
components/gxepd2/cycle_engine.h

@@ -97,7 +97,15 @@ class CycleEngine {
           return;
         this->cursor_ = 0;
         this->cmd_phase_ = CmdPhase::BEFORE_DELAY;
-        this->set_state_(State::INIT_CMD);
+        // Post-reset busy wait, matching every vendor _InitDisplay()'s
+        // _waitWhileBusy() right after the reset pulse. Some controllers hold
+        // BUSY while they load settings/waveforms from OTP after a hardware
+        // reset (notably JD79676 / GDEY0213F52, whose init is otherwise just
+        // 0xE9 + power-on) - issuing any command before that clears gets it
+        // silently dropped, so the panel never refreshes. Panels that don't
+        // assert BUSY post-reset read "not busy" on the first poll and fall
+        // straight through to INIT_CMD, so this is safe for all of them.
+        this->start_busy_wait_(State::INIT_CMD);
         return;
 
       case State::INIT_CMD:

+ 1 - 6
components/gxepd2/panel_213c_gdey0213f52.h

@@ -44,12 +44,7 @@ inline const EpdCommand PANEL_213C_GDEY0213F52_REFRESH[] = {
 inline const EpdPanelDescriptor PANEL_213C_GDEY0213F52 = {
     .width = 128,
     .height = 250,
-    // Vendor driver passes busy_level=LOW, but on the bench F52 that made every
-    // busy-wait (power-on, refresh) return in ~8ms and the panel never refreshed
-    // (charge pump not up before the plane write + 0x12). Real BUSY is active
-    // HIGH here - a hardware fact the command capture can't see. Set HIGH so the
-    // engine actually waits out the ~16s refresh.
-    .busy_active_level = true,
+    .busy_active_level = false,  // GxEPD2_EPD(..., /*busy_level=*/LOW, ...) - confirmed: HIGH hangs
     .busy_timeout_ms = 30000,    // vendor full_refresh_time ~16000ms; err long
     .init_sequence = PANEL_213C_GDEY0213F52_INIT,
     .init_sequence_len = sizeof(PANEL_213C_GDEY0213F52_INIT) / sizeof(PANEL_213C_GDEY0213F52_INIT[0]),