diff options
Diffstat (limited to 'quantum/split_common/split_util.c')
| -rw-r--r-- | quantum/split_common/split_util.c | 57 |
1 files changed, 56 insertions, 1 deletions
diff --git a/quantum/split_common/split_util.c b/quantum/split_common/split_util.c index 9e75e19ce..35f0a9d18 100644 --- a/quantum/split_common/split_util.c +++ b/quantum/split_common/split_util.c | |||
| @@ -39,6 +39,21 @@ | |||
| 39 | # define SPLIT_USB_TIMEOUT_POLL 10 | 39 | # define SPLIT_USB_TIMEOUT_POLL 10 |
| 40 | #endif | 40 | #endif |
| 41 | 41 | ||
| 42 | // Max number of consecutive failed communications (one per scan cycle) before the communication is seen as disconnected. | ||
| 43 | // Set to 0 to disable the disconnection check altogether. | ||
| 44 | #ifndef SPLIT_MAX_CONNECTION_ERRORS | ||
| 45 | # define SPLIT_MAX_CONNECTION_ERRORS 10 | ||
| 46 | #endif // SPLIT_MAX_CONNECTION_ERRORS | ||
| 47 | |||
| 48 | // How long (in milliseconds) to block all connection attempts after the communication has been flagged as disconnected. | ||
| 49 | // One communication attempt will be allowed everytime this amount of time has passed since the last attempt. If that attempt succeeds, the communication is seen as working again. | ||
| 50 | // Set to 0 to disable communication throttling while disconnected | ||
| 51 | #ifndef SPLIT_CONNECTION_CHECK_TIMEOUT | ||
| 52 | # define SPLIT_CONNECTION_CHECK_TIMEOUT 500 | ||
| 53 | #endif // SPLIT_CONNECTION_CHECK_TIMEOUT | ||
| 54 | |||
| 55 | static uint8_t connection_errors = 0; | ||
| 56 | |||
| 42 | volatile bool isLeftHand = true; | 57 | volatile bool isLeftHand = true; |
| 43 | 58 | ||
| 44 | #if defined(SPLIT_USB_DETECT) | 59 | #if defined(SPLIT_USB_DETECT) |
| @@ -77,7 +92,11 @@ __attribute__((weak)) bool is_keyboard_left(void) { | |||
| 77 | #if defined(SPLIT_HAND_PIN) | 92 | #if defined(SPLIT_HAND_PIN) |
| 78 | // Test pin SPLIT_HAND_PIN for High/Low, if low it's right hand | 93 | // Test pin SPLIT_HAND_PIN for High/Low, if low it's right hand |
| 79 | setPinInput(SPLIT_HAND_PIN); | 94 | setPinInput(SPLIT_HAND_PIN); |
| 95 | # ifdef SPLIT_HAND_PIN_LOW_IS_LEFT | ||
| 96 | return !readPin(SPLIT_HAND_PIN); | ||
| 97 | # else | ||
| 80 | return readPin(SPLIT_HAND_PIN); | 98 | return readPin(SPLIT_HAND_PIN); |
| 99 | # endif | ||
| 81 | #elif defined(SPLIT_HAND_MATRIX_GRID) | 100 | #elif defined(SPLIT_HAND_MATRIX_GRID) |
| 82 | # ifdef SPLIT_HAND_MATRIX_GRID_LOW_IS_RIGHT | 101 | # ifdef SPLIT_HAND_MATRIX_GRID_LOW_IS_RIGHT |
| 83 | return peek_matrix_intersection(SPLIT_HAND_MATRIX_GRID); | 102 | return peek_matrix_intersection(SPLIT_HAND_MATRIX_GRID); |
| @@ -102,7 +121,7 @@ __attribute__((weak)) bool is_keyboard_master(void) { | |||
| 102 | 121 | ||
| 103 | // Avoid NO_USB_STARTUP_CHECK - Disable USB as the previous checks seem to enable it somehow | 122 | // Avoid NO_USB_STARTUP_CHECK - Disable USB as the previous checks seem to enable it somehow |
| 104 | if (usbstate == SLAVE) { | 123 | if (usbstate == SLAVE) { |
| 105 | usb_disable(); | 124 | usb_disconnect(); |
| 106 | } | 125 | } |
| 107 | } | 126 | } |
| 108 | 127 | ||
| @@ -138,3 +157,39 @@ void split_post_init(void) { | |||
| 138 | transport_slave_init(); | 157 | transport_slave_init(); |
| 139 | } | 158 | } |
| 140 | } | 159 | } |
| 160 | |||
| 161 | bool is_transport_connected(void) { return connection_errors < SPLIT_MAX_CONNECTION_ERRORS; } | ||
| 162 | |||
| 163 | bool transport_master_if_connected(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { | ||
| 164 | #if SPLIT_MAX_CONNECTION_ERRORS > 0 && SPLIT_CONNECTION_CHECK_TIMEOUT > 0 | ||
| 165 | // Throttle transaction attempts if target doesn't seem to be connected | ||
| 166 | // Without this, a solo half becomes unusable due to constant read timeouts | ||
| 167 | static uint16_t connection_check_timer = 0; | ||
| 168 | const bool is_disconnected = !is_transport_connected(); | ||
| 169 | if (is_disconnected && timer_elapsed(connection_check_timer) < SPLIT_CONNECTION_CHECK_TIMEOUT) { | ||
| 170 | return false; | ||
| 171 | } | ||
| 172 | #endif // SPLIT_MAX_CONNECTION_ERRORS > 0 && SPLIT_CONNECTION_CHECK_TIMEOUT > 0 | ||
| 173 | |||
| 174 | __attribute__((unused)) bool okay = transport_master(master_matrix, slave_matrix); | ||
| 175 | #if SPLIT_MAX_CONNECTION_ERRORS > 0 | ||
| 176 | if (!okay) { | ||
| 177 | if (connection_errors < UINT8_MAX) { | ||
| 178 | connection_errors++; | ||
| 179 | } | ||
| 180 | # if SPLIT_CONNECTION_CHECK_TIMEOUT > 0 | ||
| 181 | bool connected = is_transport_connected(); | ||
| 182 | if (!connected) { | ||
| 183 | connection_check_timer = timer_read(); | ||
| 184 | dprintln("Target disconnected, throttling connection attempts"); | ||
| 185 | } | ||
| 186 | return connected; | ||
| 187 | } else if (is_disconnected) { | ||
| 188 | dprintln("Target connected"); | ||
| 189 | # endif // SPLIT_CONNECTION_CHECK_TIMEOUT > 0 | ||
| 190 | } | ||
| 191 | |||
| 192 | connection_errors = 0; | ||
| 193 | #endif // SPLIT_MAX_CONNECTION_ERRORS > 0 | ||
| 194 | return true; | ||
| 195 | } | ||
