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_init call order in keyboard_init #19140

Merged
merged 1 commit into from
Nov 26, 2022

Conversation

chrishoage
Copy link
Contributor

@chrishoage chrishoage commented Nov 22, 2022

Description

From the insight of sigprof it was discovered that encoder_init initializes thisCount which is used in encoder_state_raw memcpy. quantum_init was calling encoder_state_raw though the initialization of bootmatgic calling matrix_scan. This caused undefined behavior resulting in bad values being sent over transport. Adjusting
the call order of encoder_init allows for correct behavior of encoder_state_raw

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).

@github-actions github-actions bot added the core label Nov 22, 2022
Copy link
Contributor Author

@chrishoage chrishoage left a comment

Choose a reason for hiding this comment

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

As mentioned I'm happy to adjust my approach.

In my investigation slave_state was receiving values of 17 and 46 for both from the slave, then alter values of 0 and 46 (as the right side is master for me and thus would not change)

I have no idea where the 17 value is coming from. Doing a full memcopy of encoder_value makes my issue go away entirely.

quantum/encoder.c Outdated Show resolved Hide resolved
quantum/encoder/tests/encoder_tests_split_no_right.cpp Outdated Show resolved Hide resolved
@chrishoage
Copy link
Contributor Author

chrishoage commented Nov 23, 2022

I realized a while after I made this change that it will obviously break the encoder_update_raw logic due to index mismatch.

I spent a little more time playing around and noted that

static uint8_t encoder_state[NUM_ENCODERS_MAX_PER_SIDE]; and uint8_t encoder_state[NUM_ENCODERS_MAX_PER_SIDE] = {0}; in encoder_handlers_slave

both fixed the issue as well

@chrishoage
Copy link
Contributor Author

I opted to go with uint8_t encoder_state[NUM_ENCODERS_MAX_PER_SIDE] = {0}; in encoder_handlers_slave.

All unit tests pass with out modification, and this reliably fixes the issue.

I have tested by flashing my slave half with this change and my master half with out this change.

My moving the usb cable between the halfs I get a burst on the slave and no burst on the right.

I'd really love to understand why this fixes the issue. My current uneducated guess is that split_shmem->encoders.state contains something unexpected (perhaps due to trans_target2initiator_initializer?) which gets copied over to master. encoder_state_raw is later run and this gets the value back to 0 from the previously undefined value.

@sigprof
Copy link
Contributor

sigprof commented Nov 24, 2022

Hmm, there might be some problems in the initialization order:

  • keyboard_init()
    • quantum_init()
      • magic()
        • bootmagic()
          • matrix_scan()
            • transport_master() or transport_slave()
                • encoder_state_raw() — here thisCount is not initialized yet, so memcpy() does nothing, leaving the returned encoder state uninitialized
    • encoder_init() — this initializes thisCount and other similar variables in encoder.c

@chrishoage
Copy link
Contributor Author

@sigprof That is a great insight! I can confrim that moving encoder_init() above quantum_init() in keyboard_init addresses the issue.

Would this be preferable? If so I can update my PR here with the adjustment to the call order in keyboard_init.

diff --git a/quantum/keyboard.c b/quantum/keyboard.c
index 83ade7829a..37675ded0b 100644
--- a/quantum/keyboard.c
+++ b/quantum/keyboard.c
@@ -353,6 +353,9 @@ void keyboard_init(void) {
 #endif
 #ifdef SPLIT_KEYBOARD
     split_pre_init();
+#endif
+#ifdef ENCODER_ENABLE
+    encoder_init();
 #endif
     matrix_init();
     quantum_init();
@@ -374,9 +377,6 @@ void keyboard_init(void) {
 #ifdef RGBLIGHT_ENABLE
     rgblight_init();
 #endif
-#ifdef ENCODER_ENABLE
-    encoder_init();
-#endif
 #ifdef STENO_ENABLE_ALL
     steno_init();
 #endif

@drashna drashna requested review from tzarc and a team November 26, 2022 00:37
@tzarc
Copy link
Member

tzarc commented Nov 26, 2022

Would this be preferable? If so I can update my PR here with the adjustment to the call order in keyboard_init.

Yes, please do so.

@tzarc tzarc added the bug label Nov 26, 2022
@chrishoage chrishoage changed the title Fix encoder_update_raw slave_state issue Fix encoder_init call order in keyboard_init Nov 26, 2022
encoder_init initializes thisCount which is used in encoder_state_raw
memcpy. quantum_init was calling encoder_state_raw though the
initialization of bootmatgic calling matrix_scan. This caused undefined
behavior resulting in bad values being sent over transport. Adjusting
the call order of encoder_init allows for correct behavior of
encoder_state_raw
@chrishoage
Copy link
Contributor Author

@tzarc I have updated the diff to change the call order of encoder_init along with updated the PR title and body and commit message

@tzarc tzarc merged commit 9b51f02 into qmk:develop Nov 26, 2022
@chrishoage chrishoage deleted the hoage/split-enc-transport-copy branch November 27, 2022 00:24
ramonimbao pushed a commit to ramonimbao/qmk_firmware that referenced this pull request Nov 28, 2022
elpekenin pushed a commit to elpekenin/qmk_firmware that referenced this pull request Dec 7, 2022
crembz pushed a commit to crembz/qmk_firmware that referenced this pull request Dec 18, 2022
ohlin added a commit to ohlin/qmk_firmware that referenced this pull request May 25, 2023
… ko-kyria

* 'ko-kyria' of https://github.com/ohlin/qmk_firmware: (603 commits)
  Fix Czech sendstring LUT (qmk#19193)
  fix typo (qmk#19189)
  new keyboard rb1 (qmk#18164)
  Fix RWIN typo within keycode list (qmk#19155)
  [Docs] Update reference_info_json.md (qmk#18817)
  Add piantor (qmk#18920)
  2022 Nov 26 changelog. (qmk#19164)
  Fix API errors in handwired/tractyl_manuform/5x6_right/arduinomicro (qmk#19166)
  Revert lib/usbhost changes (qmk#19165)
  Fix encoder_init call order in keyboard_init (qmk#19140)
  Change `RGB_MATRIX_STARTUP_*` defines to `RGB_MATRIX_DEFAULT_*` (qmk#19079)
  Fixup installation procedure for different Fedora versions. (qmk#19159)
  Joystick feature improvements (qmk#19052)
  Change `LED_MATRIX_STARTUP_*` defines to `LED_MATRIX_DEFAULT_*` (qmk#19080)
  Fix build failures for `bastardkb/tbk` and `jels/boaty` (qmk#19152)
  Fix annepro2/c18:iso_default (qmk#19147)
  jsonify some info.json (qmk#19146)
  Fixup aurora/corne on develop (qmk#19144)
  Additional DD backlight config (qmk#19124)
  [Keymap] komidore64 planck rev6 (qmk#19036)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants