diff options
Diffstat (limited to 'quantum/split_common/split_util.c')
-rw-r--r-- | quantum/split_common/split_util.c | 51 |
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 | |||
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) |
@@ -142,3 +157,39 @@ void split_post_init(void) { | |||
142 | transport_slave_init(); | 157 | transport_slave_init(); |
143 | } | 158 | } |
144 | } | 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 | } | ||