Skip to content

power_panic: Add settling delay to AC fault startup check - #5254

Open
boinger wants to merge 2 commits into
prusa3d:masterfrom
boinger:ac_fault_startup_debounce
Open

power_panic: Add settling delay to AC fault startup check#5254
boinger wants to merge 2 commits into
prusa3d:masterfrom
boinger:ac_fault_startup_debounce

Conversation

@boinger

@boinger boinger commented Apr 17, 2026

Copy link
Copy Markdown

Fixes #5253

Summary

Adds a 1-second settling-delay retry loop to check_ac_fault_at_startup() to tolerate transient AC fault signals during power-on. See #5253 for the full analysis (Pull::up removal in c9b365bc4, expansion to all printers in 0050cb43a, floating-pin theory, and the alternative hardware fix of restoring Pull::up).

Change

 void check_ac_fault_at_startup() {
+    // Retry with settling delay: the AC power monitoring circuit
+    // may transiently assert fault during power-on. Genuine faults
+    // persist; transients clear within the retry window.
+    for (int i = 0; i < 5 && power_panic::is_ac_fault_active(); ++i) {
+        delay_ms(200);
+    }
     if (power_panic::is_ac_fault_active()) {
         fatal_error(ErrCode::ERR_ELECTRO_ACF_AT_INIT);
     }
     ac_fault_enabled = true;
 }

+6 lines. Uses delay_ms() from timing.h — already included in this file at line 67, consistent with delay_us_precise() already used at line 798. Busy-wait, no FreeRTOS scheduler dependency.

Safety

  • Genuine AC faults persist across the 1s window; the retry only masks transients.
  • IWDG watchdog is not running at this call site (initialized later in Marlin's setup()), so the delay carries no watchdog risk.
  • ac_fault_isr() provides ongoing protection after boot — the startup check only matters for faults already asserted at boot.
  • The brief window between the retry clearing and ac_fault_enabled = true exists in the original code too; not a regression.

Testing

Built cleanly for COREONE target at master HEAD. Hardware verification pending — the exhibiting unit runs 6.5.3+12780 and a local v6.5.3 build failed due to the bootstrap toolchain's Intel-only binary not resolving on Apple Silicon. Will follow up with a result once built on x86 hardware.

Secondary observation: utils/build.py's bootstrap toolchain doesn't support Apple Silicon natively. Happy to file a separate issue if useful.

Alternative noted in issue

A hardware-level fix (restoring Pull::up on the acFault pin) may be more correct than software debounce. That decision depends on the AC monitoring circuit's output stage, which I can't determine from firmware alone. Deferring to your team — happy to close this PR and re-do it as a pindef change if that's preferred.

@boinger

boinger commented Apr 17, 2026

Copy link
Copy Markdown
Author

Noting for clarity on versioning: I'm aware master currently sits at v6.4.0 while v6.5.3 is the latest public tag (with ~1350 commits of divergence between them). I verified check_ac_fault_at_startup() is byte-identical in both — the bug is present in both versions, so this fix applies cleanly to either.

I targeted master since external PRs can't land on tags. Happy to re-target if there's a preferred contribution branch for 6.5.x / 6.6.x work.

@boinger

boinger commented Apr 17, 2026

Copy link
Copy Markdown
Author

Follow-up on hardware verification status:

Rebuilt against the correct --preset coreonel target (printer type 8, matches the Core One L hardware exhibiting the issue). Build succeeds, packs cleanly, produces a valid .bbf — byte-identical to the official COREONE_L_firmware_6.5.3.bbf except for the +12781 build-counter bump (one commit ahead of the v6.5.3 tag, as expected) and the added retry loop.

Confirmed check_ac_fault_at_startup() is byte-identical between the COREONE and COREONEL source paths, so the fix applies equally to both variants.

Local flash on the Core One L was blocked by bootloader signature enforcement (error #35606), as expected for a build signed with zeros. I understand the documented unlock path is to break the appendix seal on the xBuddy PCB, which is a permanent physical modification. Holding off on that step (I JUST got this printer and am trying to help fix this error screen I get every once in a while...but I'm not itching to jump to full "hack the printer" mode) pending any signal from maintainers — happy to do it if you'd like pre-merge confirmation from the exhibiting hardware, otherwise I'll wait for your signed build pipeline to produce a testable artifact.

The AC power monitoring circuit may transiently assert fault during
power-on before stabilizing. The single-read check in
check_ac_fault_at_startup() triggers ERR_ELECTRO_ACF_AT_INIT on
these transients, requiring multiple resets to boot successfully.

Add a retry loop (5x 200ms) that tolerates brief transients while
still catching genuine persistent faults. The IWDG watchdog is not
yet running at this point in boot, so the delay carries no watchdog
risk. The ac_fault_isr() provides ongoing protection after boot.
@boinger
boinger force-pushed the ac_fault_startup_debounce branch from 0e519af to d8c009a Compare July 2, 2026 19:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Spurious ERR_ELECTRO_ACF_AT_INIT (power panic at boot)

1 participant