Fix battery-sleep reboot loop: sample tach idle level before arming SENSE - #114
Merged
Merged
Conversation
…ENSE System OFF entry hardcoded the tach wake pin as SENSE-LOW, assuming the line idles high under the pull-up. The tach pickup's Schmitt-inverter + optocoupler output stage can idle low, in which case DETECT is satisfied the instant System OFF is entered and the device wake-resets within a second whenever it sleeps on battery. USB sleep was unaffected because a present cable parks in the charging loop and never enters System OFF, and runtime RPM counting can't expose the polarity (a spark pulse yields exactly one falling edge either way), so only battery sleep showed it. Shutdown now samples the parked tach line (15 reads over ~30 ms) and arms SENSE for the opposite of the observed idle level. The majority vote lives in the host-tested wake_cause unit (tachIdleIsHigh); a tie or floating input resolves to idle-high, preserving the original SENSE-LOW arm. Buttons stay fixed SENSE-LOW (active-low by wiring). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BNr2KMMP1yjhPgdaUXHmGt
Coverage — host-testable units📂 Overall coverage
📄 File coverage
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Sleeping on battery reboot-looped within a second: System OFF entry hardcoded the tach wake pin as
SENSE-LOW(assuming an idle-high line), but the tach pickup's Schmitt-inverter + optocoupler output stage idles the line low — DETECT was satisfied the instant System OFF was entered and the chip wake-reset immediately. USB sleep never showed it (a present cable parks in the charging loop, System OFF is never entered), and runtime RPM counting can't expose the polarity (one falling edge per spark pulse either way).shutdownSystemOff()now samples the parked tach line (15 reads over ~30 ms) and arms SENSE for the opposite of the observed idle level, so both output-stage polarities sleep and wake correctly. The majority vote lives in the host-testedwake_causeunit (tachIdleIsHigh()); ties and floating/disconnected inputs resolve to idle-high, preserving the original SENSE-LOW arm. Buttons stay fixed SENSE-LOW (active-low by wiring).Type of change
How it was verified
ctest --test-dir tests/build) — including newtachIdleIsHigh()cases (clear majorities, single-blip noise rejection, tie/empty-burst default)clang-tidyclean (CI)Checklist
CHANGELOG.mdupdated under[Unreleased](if user-visible)ARCHITECTURE.md/CLAUDE.mdupdated (if a module or interface changed)tests/Related issues
None filed — reported directly (battery-only instant reboot after sleep entry).
🤖 Generated with Claude Code
https://claude.ai/code/session_01BNr2KMMP1yjhPgdaUXHmGt
Generated by Claude Code