summaryrefslogtreecommitdiffstats
path: root/quantum/split_common
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/split_common')
-rw-r--r--quantum/split_common/split_util.c51
-rw-r--r--quantum/split_common/split_util.h5
-rw-r--r--quantum/split_common/transactions.c102
-rw-r--r--quantum/split_common/transport.c2
4 files changed, 108 insertions, 52 deletions
diff --git a/quantum/split_common/split_util.c b/quantum/split_common/split_util.c
index 8d414f6fe6..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)
@@ -142,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;
+}
diff --git a/quantum/split_common/split_util.h b/quantum/split_common/split_util.h
index a4c12519e0..ef72043bb7 100644
--- a/quantum/split_common/split_util.h
+++ b/quantum/split_common/split_util.h
@@ -5,8 +5,13 @@
#include <stdio.h>
#include <stdlib.h>
+#include "matrix.h"
+
extern volatile bool isLeftHand;
void matrix_master_OLED_init(void);
void split_pre_init(void);
void split_post_init(void);
+
+bool transport_master_if_connected(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]);
+bool is_transport_connected(void);
diff --git a/quantum/split_common/transactions.c b/quantum/split_common/transactions.c
index 7eb3eca3e7..28ea4ef6d8 100644
--- a/quantum/split_common/transactions.c
+++ b/quantum/split_common/transactions.c
@@ -23,6 +23,7 @@
#include "quantum.h"
#include "transactions.h"
#include "transport.h"
+#include "split_util.h"
#include "transaction_id_define.h"
#define SYNC_TIMER_OFFSET 2
@@ -53,34 +54,30 @@ void slave_rpc_exec_callback(uint8_t initiator2target_buffer_size, const void *i
////////////////////////////////////////////////////
// Helpers
-bool transaction_handler_master(bool okay, matrix_row_t master_matrix[], matrix_row_t slave_matrix[], const char *prefix, bool (*handler)(matrix_row_t master_matrix[], matrix_row_t slave_matrix[])) {
- if (okay) {
- bool this_okay = true;
- for (int iter = 1; iter <= 10; ++iter) {
- if (!this_okay) {
- for (int i = 0; i < iter * iter; ++i) {
- wait_us(10);
- }
+static bool transaction_handler_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[], const char *prefix, bool (*handler)(matrix_row_t master_matrix[], matrix_row_t slave_matrix[])) {
+ int num_retries = is_transport_connected() ? 10 : 1;
+ for (int iter = 1; iter <= num_retries; ++iter) {
+ if (iter > 1) {
+ for (int i = 0; i < iter * iter; ++i) {
+ wait_us(10);
}
- ATOMIC_BLOCK_FORCEON { this_okay = handler(master_matrix, slave_matrix); };
- if (this_okay) break;
- }
- okay &= this_okay;
- if (!okay) {
- dprintf("Failed to execute %s\n", prefix);
}
+ bool this_okay = true;
+ ATOMIC_BLOCK_FORCEON { this_okay = handler(master_matrix, slave_matrix); };
+ if (this_okay) return true;
}
- return okay;
+ dprintf("Failed to execute %s\n", prefix);
+ return false;
}
-#define TRANSACTION_HANDLER_MASTER(prefix) \
- do { \
- okay &= transaction_handler_master(okay, master_matrix, slave_matrix, #prefix, &prefix##_master); \
+#define TRANSACTION_HANDLER_MASTER(prefix) \
+ do { \
+ if (!transaction_handler_master(master_matrix, slave_matrix, #prefix, &prefix##_handlers_master)) return false; \
} while (0)
-#define TRANSACTION_HANDLER_SLAVE(prefix) \
- do { \
- ATOMIC_BLOCK_FORCEON { prefix##_slave(master_matrix, slave_matrix); }; \
+#define TRANSACTION_HANDLER_SLAVE(prefix) \
+ do { \
+ ATOMIC_BLOCK_FORCEON { prefix##_handlers_slave(master_matrix, slave_matrix); }; \
} while (0)
inline static bool read_if_checksum_mismatch(int8_t trans_id_checksum, int8_t trans_id_retrieve, uint32_t *last_update, void *destination, const void *equiv_shmem, size_t length) {
@@ -138,8 +135,8 @@ static void slave_matrix_handlers_slave(matrix_row_t master_matrix[], matrix_row
}
// clang-format off
-#define TRANSACTIONS_SLAVE_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(slave_matrix_handlers)
-#define TRANSACTIONS_SLAVE_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(slave_matrix_handlers)
+#define TRANSACTIONS_SLAVE_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(slave_matrix)
+#define TRANSACTIONS_SLAVE_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(slave_matrix)
#define TRANSACTIONS_SLAVE_MATRIX_REGISTRATIONS \
[GET_SLAVE_MATRIX_CHECKSUM] = trans_target2initiator_initializer(smatrix.checksum), \
[GET_SLAVE_MATRIX_DATA] = trans_target2initiator_initializer(smatrix.matrix),
@@ -160,8 +157,8 @@ static void master_matrix_handlers_slave(matrix_row_t master_matrix[], matrix_ro
memcpy(master_matrix, split_shmem->mmatrix.matrix, sizeof(split_shmem->mmatrix.matrix));
}
-# define TRANSACTIONS_MASTER_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(master_matrix_handlers)
-# define TRANSACTIONS_MASTER_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(master_matrix_handlers)
+# define TRANSACTIONS_MASTER_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(master_matrix)
+# define TRANSACTIONS_MASTER_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(master_matrix)
# define TRANSACTIONS_MASTER_MATRIX_REGISTRATIONS [PUT_MASTER_MATRIX] = trans_initiator2target_initializer(mmatrix.matrix),
#else // SPLIT_TRANSPORT_MIRROR
@@ -196,8 +193,8 @@ static void encoder_handlers_slave(matrix_row_t master_matrix[], matrix_row_t sl
}
// clang-format off
-# define TRANSACTIONS_ENCODERS_MASTER() TRANSACTION_HANDLER_MASTER(encoder_handlers)
-# define TRANSACTIONS_ENCODERS_SLAVE() TRANSACTION_HANDLER_SLAVE(encoder_handlers)
+# define TRANSACTIONS_ENCODERS_MASTER() TRANSACTION_HANDLER_MASTER(encoder)
+# define TRANSACTIONS_ENCODERS_SLAVE() TRANSACTION_HANDLER_SLAVE(encoder)
# define TRANSACTIONS_ENCODERS_REGISTRATIONS \
[GET_ENCODERS_CHECKSUM] = trans_target2initiator_initializer(encoders.checksum), \
[GET_ENCODERS_DATA] = trans_target2initiator_initializer(encoders.state),
@@ -238,8 +235,8 @@ static void sync_timer_handlers_slave(matrix_row_t master_matrix[], matrix_row_t
}
}
-# define TRANSACTIONS_SYNC_TIMER_MASTER() TRANSACTION_HANDLER_MASTER(sync_timer_handlers)
-# define TRANSACTIONS_SYNC_TIMER_SLAVE() TRANSACTION_HANDLER_SLAVE(sync_timer_handlers)
+# define TRANSACTIONS_SYNC_TIMER_MASTER() TRANSACTION_HANDLER_MASTER(sync_timer)
+# define TRANSACTIONS_SYNC_TIMER_SLAVE() TRANSACTION_HANDLER_SLAVE(sync_timer)
# define TRANSACTIONS_SYNC_TIMER_REGISTRATIONS [PUT_SYNC_TIMER] = trans_initiator2target_initializer(sync_timer),
#else // DISABLE_SYNC_TIMER
@@ -272,8 +269,8 @@ static void layer_state_handlers_slave(matrix_row_t master_matrix[], matrix_row_
}
// clang-format off
-# define TRANSACTIONS_LAYER_STATE_MASTER() TRANSACTION_HANDLER_MASTER(layer_state_handlers)
-# define TRANSACTIONS_LAYER_STATE_SLAVE() TRANSACTION_HANDLER_SLAVE(layer_state_handlers)
+# define TRANSACTIONS_LAYER_STATE_MASTER() TRANSACTION_HANDLER_MASTER(layer_state)
+# define TRANSACTIONS_LAYER_STATE_SLAVE() TRANSACTION_HANDLER_SLAVE(layer_state)
# define TRANSACTIONS_LAYER_STATE_REGISTRATIONS \
[PUT_LAYER_STATE] = trans_initiator2target_initializer(layers.layer_state), \
[PUT_DEFAULT_LAYER_STATE] = trans_initiator2target_initializer(layers.default_layer_state),
@@ -303,8 +300,8 @@ static void led_state_handlers_slave(matrix_row_t master_matrix[], matrix_row_t
set_split_host_keyboard_leds(split_shmem->led_state);
}
-# define TRANSACTIONS_LED_STATE_MASTER() TRANSACTION_HANDLER_MASTER(led_state_handlers)
-# define TRANSACTIONS_LED_STATE_SLAVE() TRANSACTION_HANDLER_SLAVE(led_state_handlers)
+# define TRANSACTIONS_LED_STATE_MASTER() TRANSACTION_HANDLER_MASTER(led_state)
+# define TRANSACTIONS_LED_STATE_SLAVE() TRANSACTION_HANDLER_SLAVE(led_state)
# define TRANSACTIONS_LED_STATE_REGISTRATIONS [PUT_LED_STATE] = trans_initiator2target_initializer(led_state),
#else // SPLIT_LED_STATE_ENABLE
@@ -360,8 +357,8 @@ static void mods_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave
# endif
}
-# define TRANSACTIONS_MODS_MASTER() TRANSACTION_HANDLER_MASTER(mods_handlers)
-# define TRANSACTIONS_MODS_SLAVE() TRANSACTION_HANDLER_SLAVE(mods_handlers)
+# define TRANSACTIONS_MODS_MASTER() TRANSACTION_HANDLER_MASTER(mods)
+# define TRANSACTIONS_MODS_SLAVE() TRANSACTION_HANDLER_SLAVE(mods)
# define TRANSACTIONS_MODS_REGISTRATIONS [PUT_MODS] = trans_initiator2target_initializer(mods),
#else // SPLIT_MODS_ENABLE
@@ -385,8 +382,8 @@ static bool backlight_handlers_master(matrix_row_t master_matrix[], matrix_row_t
static void backlight_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { backlight_set(split_shmem->backlight_level); }
-# define TRANSACTIONS_BACKLIGHT_MASTER() TRANSACTION_HANDLER_MASTER(backlight_handlers)
-# define TRANSACTIONS_BACKLIGHT_SLAVE() TRANSACTION_HANDLER_SLAVE(backlight_handlers)
+# define TRANSACTIONS_BACKLIGHT_MASTER() TRANSACTION_HANDLER_MASTER(backlight)
+# define TRANSACTIONS_BACKLIGHT_SLAVE() TRANSACTION_HANDLER_SLAVE(backlight)
# define TRANSACTIONS_BACKLIGHT_REGISTRATIONS [PUT_BACKLIGHT] = trans_initiator2target_initializer(backlight_level),
#else // BACKLIGHT_ENABLE
@@ -422,8 +419,8 @@ static void rgblight_handlers_slave(matrix_row_t master_matrix[], matrix_row_t s
}
}
-# define TRANSACTIONS_RGBLIGHT_MASTER() TRANSACTION_HANDLER_MASTER(rgblight_handlers)
-# define TRANSACTIONS_RGBLIGHT_SLAVE() TRANSACTION_HANDLER_SLAVE(rgblight_handlers)
+# define TRANSACTIONS_RGBLIGHT_MASTER() TRANSACTION_HANDLER_MASTER(rgblight)
+# define TRANSACTIONS_RGBLIGHT_SLAVE() TRANSACTION_HANDLER_SLAVE(rgblight)
# define TRANSACTIONS_RGBLIGHT_REGISTRATIONS [PUT_RGBLIGHT] = trans_initiator2target_initializer(rgblight_sync),
#else // defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
@@ -452,8 +449,8 @@ static void led_matrix_handlers_slave(matrix_row_t master_matrix[], matrix_row_t
led_matrix_set_suspend_state(split_shmem->led_matrix_sync.led_suspend_state);
}
-# define TRANSACTIONS_LED_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(led_matrix_handlers)
-# define TRANSACTIONS_LED_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(led_matrix_handlers)
+# define TRANSACTIONS_LED_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(led_matrix)
+# define TRANSACTIONS_LED_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(led_matrix)
# define TRANSACTIONS_LED_MATRIX_REGISTRATIONS [PUT_LED_MATRIX] = trans_initiator2target_initializer(led_matrix_sync),
#else // defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
@@ -482,8 +479,8 @@ static void rgb_matrix_handlers_slave(matrix_row_t master_matrix[], matrix_row_t
rgb_matrix_set_suspend_state(split_shmem->rgb_matrix_sync.rgb_suspend_state);
}
-# define TRANSACTIONS_RGB_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(rgb_matrix_handlers)
-# define TRANSACTIONS_RGB_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(rgb_matrix_handlers)
+# define TRANSACTIONS_RGB_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(rgb_matrix)
+# define TRANSACTIONS_RGB_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(rgb_matrix)
# define TRANSACTIONS_RGB_MATRIX_REGISTRATIONS [PUT_RGB_MATRIX] = trans_initiator2target_initializer(rgb_matrix_sync),
#else // defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
@@ -507,8 +504,8 @@ static bool wpm_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave
static void wpm_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { set_current_wpm(split_shmem->current_wpm); }
-# define TRANSACTIONS_WPM_MASTER() TRANSACTION_HANDLER_MASTER(wpm_handlers)
-# define TRANSACTIONS_WPM_SLAVE() TRANSACTION_HANDLER_SLAVE(wpm_handlers)
+# define TRANSACTIONS_WPM_MASTER() TRANSACTION_HANDLER_MASTER(wpm)
+# define TRANSACTIONS_WPM_SLAVE() TRANSACTION_HANDLER_SLAVE(wpm)
# define TRANSACTIONS_WPM_REGISTRATIONS [PUT_WPM] = trans_initiator2target_initializer(current_wpm),
#else // defined(WPM_ENABLE) && defined(SPLIT_WPM_ENABLE)
@@ -538,8 +535,8 @@ static void oled_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave
}
}
-# define TRANSACTIONS_OLED_MASTER() TRANSACTION_HANDLER_MASTER(oled_handlers)
-# define TRANSACTIONS_OLED_SLAVE() TRANSACTION_HANDLER_SLAVE(oled_handlers)
+# define TRANSACTIONS_OLED_MASTER() TRANSACTION_HANDLER_MASTER(oled)
+# define TRANSACTIONS_OLED_SLAVE() TRANSACTION_HANDLER_SLAVE(oled)
# define TRANSACTIONS_OLED_REGISTRATIONS [PUT_OLED] = trans_initiator2target_initializer(current_oled_state),
#else // defined(OLED_DRIVER_ENABLE) && defined(SPLIT_OLED_ENABLE)
@@ -569,8 +566,8 @@ static void st7565_handlers_slave(matrix_row_t master_matrix[], matrix_row_t sla
}
}
-# define TRANSACTIONS_ST7565_MASTER() TRANSACTION_HANDLER_MASTER(st7565_handlers)
-# define TRANSACTIONS_ST7565_SLAVE() TRANSACTION_HANDLER_SLAVE(st7565_handlers)
+# define TRANSACTIONS_ST7565_MASTER() TRANSACTION_HANDLER_MASTER(st7565)
+# define TRANSACTIONS_ST7565_SLAVE() TRANSACTION_HANDLER_SLAVE(st7565)
# define TRANSACTIONS_ST7565_REGISTRATIONS [PUT_ST7565] = trans_initiator2target_initializer(current_st7565_state),
#else // defined(ST7565_ENABLE) && defined(SPLIT_ST7565_ENABLE)
@@ -618,7 +615,6 @@ split_transaction_desc_t split_transaction_table[NUM_TOTAL_TRANSACTIONS] = {
};
bool transactions_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
- bool okay = true;
TRANSACTIONS_SLAVE_MATRIX_MASTER();
TRANSACTIONS_MASTER_MATRIX_MASTER();
TRANSACTIONS_ENCODERS_MASTER();
@@ -633,7 +629,7 @@ bool transactions_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix
TRANSACTIONS_WPM_MASTER();
TRANSACTIONS_OLED_MASTER();
TRANSACTIONS_ST7565_MASTER();
- return okay;
+ return true;
}
void transactions_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
@@ -666,6 +662,10 @@ void transaction_register_rpc(int8_t transaction_id, slave_callback_t callback)
}
bool transaction_rpc_exec(int8_t transaction_id, uint8_t initiator2target_buffer_size, const void *initiator2target_buffer, uint8_t target2initiator_buffer_size, void *target2initiator_buffer) {
+ // Prevent transaction attempts while transport is disconnected
+ if (!is_transport_connected()) {
+ return false;
+ }
// Prevent invoking RPC on QMK core sync data
if (transaction_id <= GET_RPC_RESP_DATA) return false;
// Prevent sizing issues
diff --git a/quantum/split_common/transport.c b/quantum/split_common/transport.c
index a711ef85f0..bcc0261417 100644
--- a/quantum/split_common/transport.c
+++ b/quantum/split_common/transport.c
@@ -115,4 +115,4 @@ bool transport_execute_transaction(int8_t id, const void *initiator2target_buf,
bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { return transactions_master(master_matrix, slave_matrix); }
-void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { transactions_slave(master_matrix, slave_matrix); } \ No newline at end of file
+void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { transactions_slave(master_matrix, slave_matrix); }