aboutsummaryrefslogtreecommitdiff
path: root/quantum/split_common/split_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/split_common/split_util.c')
-rw-r--r--quantum/split_common/split_util.c57
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
55static uint8_t connection_errors = 0;
56
42volatile bool isLeftHand = true; 57volatile 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
161bool is_transport_connected(void) { return connection_errors < SPLIT_MAX_CONNECTION_ERRORS; }
162
163bool 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}