Skip to content

Fix power button behavior with USB-C charging.#117

Open
marcoag wants to merge 2 commits intofossasia:masterfrom
marcoag:fix_power_button
Open

Fix power button behavior with USB-C charging.#117
marcoag wants to merge 2 commits intofossasia:masterfrom
marcoag:fix_power_button

Conversation

@marcoag
Copy link
Member

@marcoag marcoag commented Dec 29, 2025

Summary

Fixes power button issues on USB-C version when charging cable is connected.

This PR also makes USBC on by default as this is more widely used at this point than micro-usb.

Changes

  • src/power.c: Removed GPIO A0 (CHARGE_STT_PIN) from wake-up configuration in poweroff(). This pin interferes with KEY1 wake-up when USB is connected.
  • src/main.c: Modified change_mode() to exit charging mode (BOOT) directly to NORMAL mode instead of cycling through all modes, preventing accidental power-off while charging.

Testing

  • Press power button → should power off at some point
  • While in charging mode, press power button → does not power off
  • All pixels working correctly on USB-C version

Related Issues

Fixes power button wake-up and prevents accidental shutdown during charging on USB-C hardware revision.

Summary by Sourcery

Adjust power management and build defaults to improve USB-C device behavior while charging.

Bug Fixes:

  • Prevent power button wake-up issues on USB-C hardware by disabling the charging status pin as a wake source.
  • Avoid accidental power-off when exiting charging mode by transitioning directly from boot/charging to normal mode.

Build:

  • Set USB-C hardware configuration as the default build target instead of micro USB.

Signed-off-by: Marco A. Gutierrez <marcogg@marcogg.com>
@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Dec 29, 2025

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Adjusts power button behavior and default hardware target for the USB-C board by limiting wake sources to KEY1, changing mode transitions out of charging (BOOT) mode, and enabling the USB-C build configuration by default.

Sequence diagram for power button press while charging (BOOT to NORMAL)

sequenceDiagram
  actor User
  participant PowerButton
  participant Firmware
  participant ModeController

  User->>PowerButton: press
  PowerButton->>Firmware: GPIO_interrupt
  Firmware->>ModeController: change_mode()
  alt mode_is_BOOT
    ModeController->>ModeController: mode = NORMAL
    ModeController-->>Firmware: return
  else mode_is_not_BOOT
    ModeController->>ModeController: NEXT_STATE(mode, 0, MODES_COUNT)
    ModeController-->>Firmware: continue_to_mode_setup
  end
Loading

Flow diagram for updated mode change logic

flowchart TD
  Start[change_mode_called] --> CheckBoot{mode == BOOT}
  CheckBoot -->|Yes| SetNormal[Set mode to NORMAL]
  SetNormal --> Return[Return without cycling modes]
  CheckBoot -->|No| NextState["Advance mode using NEXT_STATE(mode, 0, MODES_COUNT)"]
  NextState --> ModeSetup[Invoke corresponding mode_setup function]
  ModeSetup --> End[Mode transition complete]
Loading

Flow diagram for poweroff wake configuration limited to KEY1

flowchart TD
  A[Enter poweroff] --> B[Configure GPIOA pins as floating input]
  B --> C[Configure GPIOB pins as floating input]
  C --> D[Configure KEY1_PIN as input pull-down]
  D --> E[Enable rising edge interrupt on KEY1_PIN]
  E --> F[Enable GPIO_A_IRQn in PFIC]
  F --> G[Enable peripheral wake on GPIO]
  G --> H[Device can wake only via KEY1_PIN]
Loading

File-Level Changes

Change Details Files
Restrict wake-up source in poweroff to the power button (KEY1) only to avoid unreliable charging-pin wake and interference on USB-C hardware.
  • Reset all GPIOA/GPIOB pins to floating input before sleep as before
  • Configure KEY1 pin as pull-down input and enable rising-edge interrupt for wake-up
  • Remove CHARGE_STT_PIN configuration and its falling-edge interrupt from the wake-up setup
  • Document in comments that GPIO A0 charging wake is disabled due to unreliable behavior on USB-C and interference with KEY1
src/power.c
Modify mode transition logic so exiting charging (BOOT) mode goes directly to NORMAL mode, preventing accidental power-off while charging.
  • Short-circuit change_mode() when current mode is BOOT to set mode to NORMAL and return without cycling through other modes
  • Keep existing NEXT_STATE-based mode cycling for all non-BOOT modes unchanged
src/main.c
Switch the default firmware build target to the USB-C hardware revision.
  • Define USBC_VERSION=1 by default in the Makefile so USB-C is the default build
  • Update Makefile comment to indicate commenting out USBC_VERSION switches to the micro USB build
Makefile

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • The change_mode() special case for mode == BOOT feels a bit ad hoc; consider documenting the state machine behavior more clearly or centralizing the BOOT→NORMAL transition logic so future new modes don’t accidentally bypass this rule.
  • Disabling CHARGE_STT_PIN wake-up unconditionally in poweroff() changes behavior for all hardware; if the issue is specific to the USB-C revision, consider #ifdef USBC_VERSION or a similar hardware-specific guard so micro-USB boards can keep charge-based wake if desired.
  • The Makefile comment and flag name for USBC_VERSION are a bit confusing (comment says 'Comment below to build for micro USB version'); consider renaming the flag or rewording the comment to make the default and override behavior clearer.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `change_mode()` special case for `mode == BOOT` feels a bit ad hoc; consider documenting the state machine behavior more clearly or centralizing the BOOT→NORMAL transition logic so future new modes don’t accidentally bypass this rule.
- Disabling `CHARGE_STT_PIN` wake-up unconditionally in `poweroff()` changes behavior for all hardware; if the issue is specific to the USB-C revision, consider `#ifdef USBC_VERSION` or a similar hardware-specific guard so micro-USB boards can keep charge-based wake if desired.
- The `Makefile` comment and flag name for `USBC_VERSION` are a bit confusing (comment says 'Comment below to build for micro USB version'); consider renaming the flag or rewording the comment to make the default and override behavior clearer.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Signed-off-by: Marco A. Gutierrez <marcogg@marcogg.com>
@marcoag marcoag requested a review from kienvo December 29, 2025 22:07
Comment on lines +83 to 90
// Special case: BOOT mode exits directly to NORMAL (not part of cycle)
if (mode == BOOT) {
mode = NORMAL;
return;
}

// Standard mode cycling
NEXT_STATE(mode, 0, MODES_COUNT);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with the AI here; special-casing BOOT like this is inelegant. Set NORMAL to the minimum state in the NEXT_STATE call instead.

Suggested change
// Special case: BOOT mode exits directly to NORMAL (not part of cycle)
if (mode == BOOT) {
mode = NORMAL;
return;
}
// Standard mode cycling
NEXT_STATE(mode, 0, MODES_COUNT);
NEXT_STATE(mode, NORMAL, MODES_COUNT);

Comment on lines +17 to +24

#ifndef USBC_VERSION
// CHARGE_STT: Enable for micro-USB version
// Note: Disabled on USB-C version because it interferes with KEY1 wake-up
GPIOA_ModeCfg(CHARGE_STT_PIN, GPIO_ModeIN_PU);
GPIOA_ITModeCfg(CHARGE_STT_PIN, GPIO_ITMode_FallEdge);
#endif

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed, since we don't know for sure there is a difference here between micro-USB and USB-C, let's not make this conditional.

Suggested change
#ifndef USBC_VERSION
// CHARGE_STT: Enable for micro-USB version
// Note: Disabled on USB-C version because it interferes with KEY1 wake-up
GPIOA_ModeCfg(CHARGE_STT_PIN, GPIO_ModeIN_PU);
GPIOA_ITModeCfg(CHARGE_STT_PIN, GPIO_ITMode_FallEdge);
#endif

@mhummels mhummels mentioned this pull request Jan 6, 2026
@CodeSpoof
Copy link

Your changes remove the charging screen though. The interrupt is there to power on the board when a cable is plugged in, so it can display the charging animation correctly. Therefor your PR is just a workaround.

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.

3 participants