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.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/quantum/split_common/split_util.c b/quantum/split_common/split_util.c
index 8d414f6fe..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)
@@ -142,3 +157,39 @@ void split_post_init(void) {
142 transport_slave_init(); 157 transport_slave_init();
143 } 158 }
144} 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}