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

Removed the need for timeout if using SPLIT_USB_DETECT #9742

Closed
wants to merge 4 commits into from
Closed

Removed the need for timeout if using SPLIT_USB_DETECT #9742

wants to merge 4 commits into from

Conversation

elagil
Copy link
Contributor

@elagil elagil commented Jul 17, 2020

Following my issue #8990, I created a fix for the described problem. To reiterate:

With SPLIT_USB_DETECT, QMK currently tries to find a USB connection during a timeout period (default 2 seconds). If not found, the board half is set to slave, otherwise to master. This is unreliable, if the connection is not found within the timeout period for some reason. Now, the detection is much faster and reliable. It is not required to wait for any timeout to finish.

Description

I implemented a communication phase during the USB master side detection, which works like this:

  • Both halves are initialized as slaves w.r.t. the transport that is used
  • Both halves check for USB connection indefinitely, until one of them finds it
  • The USB-connected half tells the other half, that it found the connection and thus becomes the master
  • The slave half then stops looking for USB and becomes the slave

I tested for UART but implemented changes for I2C as well. I would be happy, if someone could test it, since I have no I2C board available.

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

#8990

Checklist

  • My code follows the code style of this project.
  • 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).

Copy link
Member

@zvecr zvecr left a comment

Choose a reason for hiding this comment

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

Due to the change in behaviour, this should target the develop branch.

@@ -135,6 +132,9 @@ __attribute__((weak)) bool is_keyboard_master(void) {
void split_pre_init(void) {
isLeftHand = is_keyboard_left();

// Start in slave configuration and wait for a master to emerge
transport_slave_init();
Copy link
Member

Choose a reason for hiding this comment

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

Adding this here now calls init twice, and breaks #8235 again.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You mean, it's called twice for the master half?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I guess, for changing the target branch without strange side effects, I need to reopen this.

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do you think that if I just remove the repeated initialization in split_post_init, it will bring back the race-condition bug? The slave will finish USB initialization when the master is determined and will not overwrite any settings that are sent over the transport.

@zvecr zvecr requested a review from a team July 17, 2020 09:06
@elagil elagil changed the base branch from master to develop July 17, 2020 09:13
@elagil elagil changed the base branch from develop to master July 17, 2020 09:13
@@ -135,6 +132,9 @@ __attribute__((weak)) bool is_keyboard_master(void) {
void split_pre_init(void) {
isLeftHand = is_keyboard_left();
Copy link
Member

Choose a reason for hiding this comment

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

This will infinite loop on MASTER_LEFT/MASTER_RIGHT as the slave transport is not established.

Copy link
Contributor Author

@elagil elagil Jul 17, 2020

Choose a reason for hiding this comment

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

Can you explain? Do you mean that it will not return as long as there is no slave that answers the master's messages?

Edit: Also, is that a problem? I just tested with my UART split board and the master does not stay in that loop after connecting USB. It works without a slave as well.

Copy link
Member

Choose a reason for hiding this comment

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

I just tested with my UART split board and the master does not stay in that loop after connecting USB. It works without a slave as well.

This is a board that uses EE_HANDS/SPLIT_HAND_PIN for handedness?

Copy link
Contributor Author

@elagil elagil Jul 17, 2020

Choose a reason for hiding this comment

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

Yes, it is (EE_HANDS). Let's say it was a board that entered is_keyboard_master(), this would return after finding USB or receiving a message from the master. Am I missing something?

Copy link
Member

Choose a reason for hiding this comment

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

in that case is_keyboard_left calls is_keyboard_master before transport_slave_init happens. Thus it will never get its "slave" assignment as there will never be anything listening.

Copy link
Contributor Author

@elagil elagil Jul 17, 2020

Choose a reason for hiding this comment

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

@zvecr zvecr requested a review from a team July 17, 2020 09:24
@zvecr zvecr changed the base branch from master to develop July 17, 2020 09:24
@zvecr zvecr added the breaking_change Changes that need to wait for a version increment label Jul 17, 2020
@elagil
Copy link
Contributor Author

elagil commented Jul 17, 2020

I did some cleanup for rebasing this onto the develop branch. Excuse the repeated force-pushes.

Edit: Force-push to the develop branch required fixing again.

@elagil elagil requested review from zvecr and removed request for a team July 17, 2020 14:43
@elagil
Copy link
Contributor Author

elagil commented Jul 17, 2020

I managed to remove the review request for qmk/collaborators, sorry for that.

@zvecr zvecr requested a review from a team July 17, 2020 16:35
@elagil
Copy link
Contributor Author

elagil commented Jul 24, 2020

@zvecr For pushing this forward, do you see any further issues with the current state of the code? Sadly, I cannot test the operation for I2C.

@zvecr
Copy link
Member

zvecr commented Jul 26, 2020

Yes, #8235 would still be re-broken by this change.

@elagil
Copy link
Contributor Author

elagil commented Jul 27, 2020

Yes, #8235 would still be re-broken by this change.

I am failing to see why that would be the case. Let me summarize the new order of events upon initialization:

  1. USB Master switches on, is initialized as a slave w.r.t. transport
  2. Slave switches on, is initialized as a slave, too. Probably reads EEPROM for RGB settings at this point. No further initialization is done on the slave beyond this point.
  3. Master finds USB, is finally initialized as master w.r.t transport
  4. Master shares RGB information with the slave, and tells it that USB was found. Slave takes these settings.
  5. Initialization finished

I don't see where the slave overwrites the RGB settings that it got from the master via transport with those old settings from EEPROM. The slave is initialized at the beginning in 2), prior to receiving new RGB settings. If it is initialized after the master has already found USB, then the serial transfer of new settings failswell and will be repeated. Therefore, no race condition can happen, as far as I can understand.

To reiterate: there is only one initialization on the slave side, before any communication with the master can occur. Therefore, initialization (and reading old settings from EEPROM) cannot happen after a link to the master is successfully established.

@noroadsleft
Copy link
Member

This needs to be rebased, and the merge conflicts resolved.

@elagil
Copy link
Contributor Author

elagil commented Aug 15, 2020

This needs to be rebased, and the merge conflicts resolved.

I will do it next week.

@elagil
Copy link
Contributor Author

elagil commented Aug 16, 2020

@noroadsleft Rebased to latest develop force-push.

Copy link
Member

@zvecr zvecr left a comment

Choose a reason for hiding this comment

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

#8235 describes the issue. The main part is that slave is listening during startup, so will respond to any rgb sync actions before its ready to do so. Also, the listening on the master side being left on would also mean that serial commands would still trigger the ISR processing on both halves.

@noroadsleft noroadsleft force-pushed the develop branch 2 times, most recently from 1d4c0cd to 65c27a3 Compare August 29, 2020 21:41
@elagil
Copy link
Contributor Author

elagil commented Aug 30, 2020

@zvecr I don't quite get how communication works. Could you clarify a bit?

I see that in 'matrix_post_scan()', the 'transport_master()' and 'transport_slave()' functions are called. These handle any data that was shared over the transport (UART or I2C). I am on AVR at the moment, so this is not ChibiOS-based, right? Can you point me to the interrupt handler that you are talking about? I only find one for ChibiOS.

With regard to leaving the slave interrupt handlers enabled on the master-side, I will look into disabling them after the master was found.

@elagil
Copy link
Contributor Author

elagil commented Nov 29, 2020

@tzarc Should further development continue on this issue?

@tzarc
Copy link
Member

tzarc commented Nov 30, 2020

I was in the process of reopening accidentally closed PRs -- we went through a develop -> master merge and the source branch was accidentally deleted, closing all open PRs at the time of deletion. Was just reopening yours so that it can proceed. This was one of about 80 that were reopened.

@elagil
Copy link
Contributor Author

elagil commented Nov 30, 2020

I understand!

@gsadams gsadams mentioned this pull request Feb 27, 2021
@tzarc tzarc closed this Feb 27, 2021
@tzarc tzarc deleted the branch qmk:develop February 27, 2021 20:27
@noroadsleft noroadsleft reopened this Feb 27, 2021
@drashna
Copy link
Member

drashna commented Mar 14, 2021

This has a bunch of merge conflicts, now.

@elagil
Copy link
Contributor Author

elagil commented Mar 27, 2021

This has a bunch of merge conflicts, now.

I will address them soon. @drashna Maybe it makes sense to work on a unified PR according to #12033?

@tzarc tzarc added stale Issues or pull requests that have become inactive without resolution. and removed breaking_change Changes that need to wait for a version increment labels Nov 1, 2021
@stale
Copy link

stale bot commented Jan 3, 2022

Thank you for your contribution!
This pull request has been automatically marked as stale because it has not had activity in the last 45 days. It will be closed in 30 days if no further activity occurs. Please feel free to give a status update now, or re-open when it's ready.
For maintainers: Please label with awaiting review, breaking_change, in progress, or on hold to prevent the issue from being re-flagged.

@elagil
Copy link
Contributor Author

elagil commented Apr 9, 2022

Closing, out of date.

@stale stale bot removed the stale Issues or pull requests that have become inactive without resolution. label Apr 9, 2022
@elagil elagil closed this Apr 9, 2022
@elagil elagil deleted the split_enhancement branch April 9, 2022 07:51
@GilDev
Copy link

GilDev commented Oct 11, 2023

@elagil Hey, is it out of date because it has been fixed elsewhere somehow? Thanks!

@elagil
Copy link
Contributor Author

elagil commented Oct 12, 2023

@GilDev I don't know if it was fixed, but my contribution is no longer compatible with the current codebase (and was never merged).

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.

8 participants