Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix encoder breakage with 4 or more encoders #23595

Merged
merged 1 commit into from
Apr 26, 2024

Conversation

sigprof
Copy link
Contributor

@sigprof sigprof commented Apr 23, 2024

Description

The encoder support was broken in various ways when having 4 or more encoders on any keyboard side (or, more precisely, when MAX_QUEUED_ENCODER_EVENTS was not a power of 2, which happened when NUM_ENCODERS_MAX_PER_SIDE increased above 3, unless MAX_QUEUED_ENCODER_EVENTS was set directly). In particular, with 4 encoders the encoder rotation did not have any effect.

The problem was caused by encoder_queue_full_advanced() always returning true even when the queue was not actually full, which caused all encoder events to be dropped. The underlying reason was that (events->tail - 1) % MAX_QUEUED_ENCODER_EVENTS did not calculate what the rest of code expected when events->tail was 0, except when MAX_QUEUED_ENCODER_EVENTS happened to be a power of 2, so the code seemed to work when the number of encoders was less than 4 (in that case MAX_QUEUED_ENCODER_EVENTS was set to 4), but broke when the number of encoders was 4 or more. With 4 encoders the code ended up calculating 0xffff % 5U (or 0xffffffff % 5U on 32-bit platforms), which ended up being 0, so the initial state with an empty queue was mistakenly detected as full. But with MAX_QUEUED_ENCODER_EVENTS = 4 the result of 0xffff % 4U in the bad case happened to be what was expected, therefore the bug could not be noticed.

Fix the queue full check to avoid negative numbers in calculations, so that the modulo operations would work as expected.

Types of Changes

  • Core
  • Bugfix
  • New feature
  • Enhancement/optimization
  • Keyboard (addition or update)
  • Keymap/layout/userspace (addition or update)
  • Documentation

Issues Fixed or Closed by This PR

Checklist

  • My code follows the code style of this project: C, Python
  • I have read the PR Checklist document and have made the appropriate changes.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • I have tested the changes and verified that they work and don't break anything (as well as I can manage).

`(events->tail - 1) % MAX_QUEUED_ENCODER_EVENTS` did not calculate what
the rest of code expected when `events->tail` was 0, except when
`MAX_QUEUED_ENCODER_EVENTS` happened to be a power of 2, so the code
seemed to work when the number of encoders was less than 4 (in that case
`MAX_QUEUED_ENCODER_EVENTS` was set to 4), but broke when the number of
encoders was 4 or more.  Fix the queue full check to avoid negative
numbers in calculations.
@tzarc tzarc merged commit 2224a76 into qmk:master Apr 26, 2024
3 of 4 checks passed
mzyt pushed a commit to mzyt/qmk_firmware that referenced this pull request May 6, 2024
IvanJackson pushed a commit to IvanJackson/qmk_firmware that referenced this pull request May 6, 2024
whoisjordangarcia pushed a commit to whoisjordangarcia/qmk_firmware that referenced this pull request Jun 8, 2024
nuess0r pushed a commit to nuess0r/qmk_firmware that referenced this pull request Sep 8, 2024
Ardakilic pushed a commit to Ardakilic/qmk_firmware that referenced this pull request Sep 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug] If 4 rotary encoders are specified, all rotary encoders will stop responding.
2 participants