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 9e75e19ce0..35f0a9d181 100644 --- a/quantum/split_common/split_util.c +++ b/quantum/split_common/split_util.c @@ -39,6 +39,21 @@  #    define SPLIT_USB_TIMEOUT_POLL 10  #endif +// Max number of consecutive failed communications (one per scan cycle) before the communication is seen as disconnected. +// Set to 0 to disable the disconnection check altogether. +#ifndef SPLIT_MAX_CONNECTION_ERRORS +#    define SPLIT_MAX_CONNECTION_ERRORS 10 +#endif  // SPLIT_MAX_CONNECTION_ERRORS + +// How long (in milliseconds) to block all connection attempts after the communication has been flagged as disconnected. +// 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. +// Set to 0 to disable communication throttling while disconnected +#ifndef SPLIT_CONNECTION_CHECK_TIMEOUT +#    define SPLIT_CONNECTION_CHECK_TIMEOUT 500 +#endif  // SPLIT_CONNECTION_CHECK_TIMEOUT + +static uint8_t connection_errors = 0; +  volatile bool isLeftHand = true;  #if defined(SPLIT_USB_DETECT) @@ -77,7 +92,11 @@ __attribute__((weak)) bool is_keyboard_left(void) {  #if defined(SPLIT_HAND_PIN)      // Test pin SPLIT_HAND_PIN for High/Low, if low it's right hand      setPinInput(SPLIT_HAND_PIN); +#    ifdef SPLIT_HAND_PIN_LOW_IS_LEFT +    return !readPin(SPLIT_HAND_PIN); +#    else      return readPin(SPLIT_HAND_PIN); +#    endif  #elif defined(SPLIT_HAND_MATRIX_GRID)  #    ifdef SPLIT_HAND_MATRIX_GRID_LOW_IS_RIGHT      return peek_matrix_intersection(SPLIT_HAND_MATRIX_GRID); @@ -102,7 +121,7 @@ __attribute__((weak)) bool is_keyboard_master(void) {          // Avoid NO_USB_STARTUP_CHECK - Disable USB as the previous checks seem to enable it somehow          if (usbstate == SLAVE) { -            usb_disable(); +            usb_disconnect();          }      } @@ -138,3 +157,39 @@ void split_post_init(void) {          transport_slave_init();      }  } + +bool is_transport_connected(void) { return connection_errors < SPLIT_MAX_CONNECTION_ERRORS; } + +bool transport_master_if_connected(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { +#if SPLIT_MAX_CONNECTION_ERRORS > 0 && SPLIT_CONNECTION_CHECK_TIMEOUT > 0 +    // Throttle transaction attempts if target doesn't seem to be connected +    // Without this, a solo half becomes unusable due to constant read timeouts +    static uint16_t connection_check_timer = 0; +    const bool      is_disconnected        = !is_transport_connected(); +    if (is_disconnected && timer_elapsed(connection_check_timer) < SPLIT_CONNECTION_CHECK_TIMEOUT) { +        return false; +    } +#endif  // SPLIT_MAX_CONNECTION_ERRORS > 0 && SPLIT_CONNECTION_CHECK_TIMEOUT > 0 + +    __attribute__((unused)) bool okay = transport_master(master_matrix, slave_matrix); +#if SPLIT_MAX_CONNECTION_ERRORS > 0 +    if (!okay) { +        if (connection_errors < UINT8_MAX) { +            connection_errors++; +        } +#    if SPLIT_CONNECTION_CHECK_TIMEOUT > 0 +        bool connected = is_transport_connected(); +        if (!connected) { +            connection_check_timer = timer_read(); +            dprintln("Target disconnected, throttling connection attempts"); +        } +        return connected; +    } else if (is_disconnected) { +        dprintln("Target connected"); +#    endif  // SPLIT_CONNECTION_CHECK_TIMEOUT > 0 +    } + +    connection_errors = 0; +#endif  // SPLIT_MAX_CONNECTION_ERRORS > 0 +    return true; +} | 
