aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoakim Tufvegren <jocke@barbanet.com>2021-08-22 02:51:17 +0200
committerGitHub <noreply@github.com>2021-08-22 10:51:17 +1000
commit0ae20e74578ae4420af3e684f7ad9fcbd7beee94 (patch)
treec6e1ae2876f3f27b80858cecb72a53935b91aaf5
parentc5f41d42d8e4dc88b2aeb414aa0d26ad23ad34f1 (diff)
downloadqmk_firmware-0ae20e74578ae4420af3e684f7ad9fcbd7beee94.tar.gz
qmk_firmware-0ae20e74578ae4420af3e684f7ad9fcbd7beee94.zip
Make solo half of split keyboards (more) usable. (#13523)
* Make solo half of split keyboards (more) usable. Using only one half of a split keyboard (that's using the split_common framework to communicate) is not a great experience, since several read timeouts per scan cycle cause an unusably slow scan rate. This change blocks all split communication attempts for 500 ms (configurable) after an error occurs, causing the scan rate to become at least _more_ usable, but might need some tweaking to work fully on most keyboards. One read timeout still needs to occur after the 500 ms has passed, and if that timeout isn't low enough, some scan cycles may still be too slow. * Fix lint complaint. * Require 25 consecutive comm errors to see comms as disconnected. The number of max errors can be overridden by defining `SPLIT_MAX_CONNECTION_ERRORS`. * Add comments to new defines, and ability to disable disconnection check. Also increase `SPLIT_MAX_CONNECTION_ERRORS` to 40, since it's divisible by most relevant numbers for the description. * Make lint happy ...again * Only update `connection_check_timer` when needed. * Add new defines to split keyboard documentation. * Move connection timeout logic to transport.c, add `is_transport_connected`. * Use split_common disconnection logic in matrix.c. Instead of doing more or less the same thing twice. * Move disconnection logic to `transport_master`. Is a cleaner implementation, and causes the scan rate while disconnected to increase instead of decrease. * Lint fixes. * Lower default `SERIAL_USART_TIMEOUT` to 20 ms. The read timeout must be low enough to not cause exessively long scan cycles when using a solo split half. 10 ms was determined from testing to work fine even with the slowest defined baudrate of 19200 (5 ms was too low for that case), so 20 ms should be fine for most cases. * Remove `SERIAL_USART_TIMEOUT` from ergodox_infinity/config.h Was somewhat mistakenly included in an earlier PR. * Fix building with `USE_I2C`. * Reduce built firmware size. Not really sure why this works, the idea was taken from tzarc's work on split disconnection. * Tweak and improve opt-out for split disconnection logic. There are now two ways to opt out from this feature: * Set `SPLIT_MAX_CONNECTION_ERRORS` to 0. This will completely disable the connection status checks (also affects the slave matrix reset logic in matrix.c, though). * Set `SPLIT_CONNECTION_CHECK_TIMEOUT` to 0. This will only disable the communication throttling while disconnected. Will make the firmware smaller. * Make split disconnection logic work with custom transports. Includes a fallback implementation for keyboards using a custom split_util.c but not a custom matrix.c (currently no such keyboard seems to be merged, though). * Remove unnecessary include of timer.h Co-authored-by: Joel Challis <git@zvecr.com> Co-authored-by: Joel Challis <git@zvecr.com>
-rw-r--r--docs/feature_split_keyboard.md16
-rw-r--r--docs/serial_driver.md6
-rw-r--r--keyboards/ergodox_infinity/config.h1
-rw-r--r--platforms/chibios/drivers/serial_usart.h2
-rw-r--r--quantum/matrix.c36
-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
9 files changed, 143 insertions, 78 deletions
diff --git a/docs/feature_split_keyboard.md b/docs/feature_split_keyboard.md
index a84d38460..27df46a82 100644
--- a/docs/feature_split_keyboard.md
+++ b/docs/feature_split_keyboard.md
@@ -204,6 +204,22 @@ If you're having issues with serial communication, you can change this value, as
204This sets the maximum number of milliseconds before forcing a synchronization of data from master to slave. Under normal circumstances this sync occurs whenever the data _changes_, for safety a data transfer occurs after this number of milliseconds if no change has been detected since the last sync. 204This sets the maximum number of milliseconds before forcing a synchronization of data from master to slave. Under normal circumstances this sync occurs whenever the data _changes_, for safety a data transfer occurs after this number of milliseconds if no change has been detected since the last sync.
205 205
206```c 206```c
207#define SPLIT_MAX_CONNECTION_ERRORS 10
208```
209This sets the maximum number of failed communication attempts (one per scan cycle) from the master part before it assumes that no slave part is connected. This makes it possible to use a master part without the slave part connected.
210
211Set to 0 to disable the disconnection check altogether.
212
213```c
214#define SPLIT_CONNECTION_CHECK_TIMEOUT 500
215```
216How long (in milliseconds) the master part should block all connection attempts to the slave after the communication has been flagged as disconnected (see `SPLIT_MAX_CONNECTION_ERRORS` above).
217
218One 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.
219
220Set to 0 to disable this throttling of communications while disconnected. This can save you a couple of bytes of firmware size.
221
222```c
207#define SPLIT_TRANSPORT_MIRROR 223#define SPLIT_TRANSPORT_MIRROR
208``` 224```
209 225
diff --git a/docs/serial_driver.md b/docs/serial_driver.md
index ed989b0a1..3e89deffa 100644
--- a/docs/serial_driver.md
+++ b/docs/serial_driver.md
@@ -63,7 +63,7 @@ Configure the hardware via your config.h:
63 // 5: about 19200 baud 63 // 5: about 19200 baud
64#define SERIAL_USART_DRIVER SD1 // USART driver of TX pin. default: SD1 64#define SERIAL_USART_DRIVER SD1 // USART driver of TX pin. default: SD1
65#define SERIAL_USART_TX_PAL_MODE 7 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7 65#define SERIAL_USART_TX_PAL_MODE 7 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7
66#define SERIAL_USART_TIMEOUT 100 // USART driver timeout. default 100 66#define SERIAL_USART_TIMEOUT 20 // USART driver timeout. default 20
67``` 67```
68 68
69You must also enable the ChibiOS `SERIAL` feature: 69You must also enable the ChibiOS `SERIAL` feature:
@@ -105,10 +105,10 @@ Next configure the hardware via your config.h:
105 // 3: 57600 baud 105 // 3: 57600 baud
106 // 4: 38400 baud 106 // 4: 38400 baud
107 // 5: 19200 baud 107 // 5: 19200 baud
108#define SERIAL_USART_DRIVER SD1 // USART driver of TX and RX pin. default: SD1 108#define SERIAL_USART_DRIVER SD1 // USART driver of TX and RX pin. default: SD1
109#define SERIAL_USART_TX_PAL_MODE 7 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7 109#define SERIAL_USART_TX_PAL_MODE 7 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7
110#define SERIAL_USART_RX_PAL_MODE 7 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7 110#define SERIAL_USART_RX_PAL_MODE 7 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7
111#define SERIAL_USART_TIMEOUT 100 // USART driver timeout. default 100 111#define SERIAL_USART_TIMEOUT 20 // USART driver timeout. default 20
112``` 112```
113 113
114You must also enable the ChibiOS `SERIAL` feature: 114You must also enable the ChibiOS `SERIAL` feature:
diff --git a/keyboards/ergodox_infinity/config.h b/keyboards/ergodox_infinity/config.h
index e0208ba4d..4bee8c3d9 100644
--- a/keyboards/ergodox_infinity/config.h
+++ b/keyboards/ergodox_infinity/config.h
@@ -67,7 +67,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
67#define SERIAL_USART_DRIVER SD1 // Only true for the master half 67#define SERIAL_USART_DRIVER SD1 // Only true for the master half
68#define SERIAL_USART_CONFIG { (SERIAL_USART_SPEED), } // Only field is speed 68#define SERIAL_USART_CONFIG { (SERIAL_USART_SPEED), } // Only field is speed
69#define SERIAL_USART_FULL_DUPLEX 69#define SERIAL_USART_FULL_DUPLEX
70#define SERIAL_USART_TIMEOUT 50
71 70
72/* number of backlight levels */ 71/* number of backlight levels */
73#define BACKLIGHT_LEVELS 3 72#define BACKLIGHT_LEVELS 3
diff --git a/platforms/chibios/drivers/serial_usart.h b/platforms/chibios/drivers/serial_usart.h
index c64e15566..7b135b31e 100644
--- a/platforms/chibios/drivers/serial_usart.h
+++ b/platforms/chibios/drivers/serial_usart.h
@@ -110,7 +110,7 @@
110#endif 110#endif
111 111
112#if !defined(SERIAL_USART_TIMEOUT) 112#if !defined(SERIAL_USART_TIMEOUT)
113# define SERIAL_USART_TIMEOUT 100 113# define SERIAL_USART_TIMEOUT 20
114#endif 114#endif
115 115
116#define HANDSHAKE_MAGIC 7 116#define HANDSHAKE_MAGIC 7
diff --git a/quantum/matrix.c b/quantum/matrix.c
index d22817bf4..33586c431 100644
--- a/quantum/matrix.c
+++ b/quantum/matrix.c
@@ -25,10 +25,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
25# include "split_common/split_util.h" 25# include "split_common/split_util.h"
26# include "split_common/transactions.h" 26# include "split_common/transactions.h"
27 27
28# ifndef ERROR_DISCONNECT_COUNT
29# define ERROR_DISCONNECT_COUNT 5
30# endif // ERROR_DISCONNECT_COUNT
31
32# define ROWS_PER_HAND (MATRIX_ROWS / 2) 28# define ROWS_PER_HAND (MATRIX_ROWS / 2)
33#else 29#else
34# define ROWS_PER_HAND (MATRIX_ROWS) 30# define ROWS_PER_HAND (MATRIX_ROWS)
@@ -307,33 +303,31 @@ void matrix_init(void) {
307} 303}
308 304
309#ifdef SPLIT_KEYBOARD 305#ifdef SPLIT_KEYBOARD
306// Fallback implementation for keyboards not using the standard split_util.c
307__attribute__((weak)) bool transport_master_if_connected(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
308 transport_master(master_matrix, slave_matrix);
309 return true; // Treat the transport as always connected
310}
311
310bool matrix_post_scan(void) { 312bool matrix_post_scan(void) {
311 bool changed = false; 313 bool changed = false;
312 if (is_keyboard_master()) { 314 if (is_keyboard_master()) {
313 static uint8_t error_count;
314
315 matrix_row_t slave_matrix[ROWS_PER_HAND] = {0}; 315 matrix_row_t slave_matrix[ROWS_PER_HAND] = {0};
316 if (!transport_master(matrix + thisHand, slave_matrix)) { 316 if (transport_master_if_connected(matrix + thisHand, slave_matrix)) {
317 error_count++;
318
319 if (error_count > ERROR_DISCONNECT_COUNT) {
320 // reset other half if disconnected
321 for (int i = 0; i < ROWS_PER_HAND; ++i) {
322 matrix[thatHand + i] = 0;
323 slave_matrix[i] = 0;
324 }
325
326 changed = true;
327 }
328 } else {
329 error_count = 0;
330
331 for (int i = 0; i < ROWS_PER_HAND; ++i) { 317 for (int i = 0; i < ROWS_PER_HAND; ++i) {
332 if (matrix[thatHand + i] != slave_matrix[i]) { 318 if (matrix[thatHand + i] != slave_matrix[i]) {
333 matrix[thatHand + i] = slave_matrix[i]; 319 matrix[thatHand + i] = slave_matrix[i];
334 changed = true; 320 changed = true;
335 } 321 }
336 } 322 }
323 } else {
324 // reset other half if disconnected
325 for (int i = 0; i < ROWS_PER_HAND; ++i) {
326 matrix[thatHand + i] = 0;
327 slave_matrix[i] = 0;
328 }
329
330 changed = true;
337 } 331 }
338 332
339 matrix_scan_quantum(); 333 matrix_scan_quantum();
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}
diff --git a/quantum/split_common/split_util.h b/quantum/split_common/split_util.h
index a4c12519e..ef72043bb 100644
--- a/quantum/split_common/split_util.h
+++ b/quantum/split_common/split_util.h
@@ -5,8 +5,13 @@
5#include <stdio.h> 5#include <stdio.h>
6#include <stdlib.h> 6#include <stdlib.h>
7 7
8#include "matrix.h"
9
8extern volatile bool isLeftHand; 10extern volatile bool isLeftHand;
9 11
10void matrix_master_OLED_init(void); 12void matrix_master_OLED_init(void);
11void split_pre_init(void); 13void split_pre_init(void);
12void split_post_init(void); 14void split_post_init(void);
15
16bool transport_master_if_connected(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]);
17bool is_transport_connected(void);
diff --git a/quantum/split_common/transactions.c b/quantum/split_common/transactions.c
index 7eb3eca3e..28ea4ef6d 100644
--- a/quantum/split_common/transactions.c
+++ b/quantum/split_common/transactions.c
@@ -23,6 +23,7 @@
23#include "quantum.h" 23#include "quantum.h"
24#include "transactions.h" 24#include "transactions.h"
25#include "transport.h" 25#include "transport.h"
26#include "split_util.h"
26#include "transaction_id_define.h" 27#include "transaction_id_define.h"
27 28
28#define SYNC_TIMER_OFFSET 2 29#define SYNC_TIMER_OFFSET 2
@@ -53,34 +54,30 @@ void slave_rpc_exec_callback(uint8_t initiator2target_buffer_size, const void *i
53//////////////////////////////////////////////////// 54////////////////////////////////////////////////////
54// Helpers 55// Helpers
55 56
56bool 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[])) { 57static 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[])) {
57 if (okay) { 58 int num_retries = is_transport_connected() ? 10 : 1;
58 bool this_okay = true; 59 for (int iter = 1; iter <= num_retries; ++iter) {
59 for (int iter = 1; iter <= 10; ++iter) { 60 if (iter > 1) {
60 if (!this_okay) { 61 for (int i = 0; i < iter * iter; ++i) {
61 for (int i = 0; i < iter * iter; ++i) { 62 wait_us(10);
62 wait_us(10);
63 }
64 } 63 }
65 ATOMIC_BLOCK_FORCEON { this_okay = handler(master_matrix, slave_matrix); };
66 if (this_okay) break;
67 }
68 okay &= this_okay;
69 if (!okay) {
70 dprintf("Failed to execute %s\n", prefix);
71 } 64 }
65 bool this_okay = true;
66 ATOMIC_BLOCK_FORCEON { this_okay = handler(master_matrix, slave_matrix); };
67 if (this_okay) return true;
72 } 68 }
73 return okay; 69 dprintf("Failed to execute %s\n", prefix);
70 return false;
74} 71}
75 72
76#define TRANSACTION_HANDLER_MASTER(prefix) \ 73#define TRANSACTION_HANDLER_MASTER(prefix) \
77 do { \ 74 do { \
78 okay &= transaction_handler_master(okay, master_matrix, slave_matrix, #prefix, &prefix##_master); \ 75 if (!transaction_handler_master(master_matrix, slave_matrix, #prefix, &prefix##_handlers_master)) return false; \
79 } while (0) 76 } while (0)
80 77
81#define TRANSACTION_HANDLER_SLAVE(prefix) \ 78#define TRANSACTION_HANDLER_SLAVE(prefix) \
82 do { \ 79 do { \
83 ATOMIC_BLOCK_FORCEON { prefix##_slave(master_matrix, slave_matrix); }; \ 80 ATOMIC_BLOCK_FORCEON { prefix##_handlers_slave(master_matrix, slave_matrix); }; \
84 } while (0) 81 } while (0)
85 82
86inline 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) { 83inline 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
138} 135}
139 136
140// clang-format off 137// clang-format off
141#define TRANSACTIONS_SLAVE_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(slave_matrix_handlers) 138#define TRANSACTIONS_SLAVE_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(slave_matrix)
142#define TRANSACTIONS_SLAVE_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(slave_matrix_handlers) 139#define TRANSACTIONS_SLAVE_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(slave_matrix)
143#define TRANSACTIONS_SLAVE_MATRIX_REGISTRATIONS \ 140#define TRANSACTIONS_SLAVE_MATRIX_REGISTRATIONS \
144 [GET_SLAVE_MATRIX_CHECKSUM] = trans_target2initiator_initializer(smatrix.checksum), \ 141 [GET_SLAVE_MATRIX_CHECKSUM] = trans_target2initiator_initializer(smatrix.checksum), \
145 [GET_SLAVE_MATRIX_DATA] = trans_target2initiator_initializer(smatrix.matrix), 142 [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
160 memcpy(master_matrix, split_shmem->mmatrix.matrix, sizeof(split_shmem->mmatrix.matrix)); 157 memcpy(master_matrix, split_shmem->mmatrix.matrix, sizeof(split_shmem->mmatrix.matrix));
161} 158}
162 159
163# define TRANSACTIONS_MASTER_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(master_matrix_handlers) 160# define TRANSACTIONS_MASTER_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(master_matrix)
164# define TRANSACTIONS_MASTER_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(master_matrix_handlers) 161# define TRANSACTIONS_MASTER_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(master_matrix)
165# define TRANSACTIONS_MASTER_MATRIX_REGISTRATIONS [PUT_MASTER_MATRIX] = trans_initiator2target_initializer(mmatrix.matrix), 162# define TRANSACTIONS_MASTER_MATRIX_REGISTRATIONS [PUT_MASTER_MATRIX] = trans_initiator2target_initializer(mmatrix.matrix),
166 163
167#else // SPLIT_TRANSPORT_MIRROR 164#else // SPLIT_TRANSPORT_MIRROR
@@ -196,8 +193,8 @@ static void encoder_handlers_slave(matrix_row_t master_matrix[], matrix_row_t sl
196} 193}
197 194
198// clang-format off 195// clang-format off
199# define TRANSACTIONS_ENCODERS_MASTER() TRANSACTION_HANDLER_MASTER(encoder_handlers) 196# define TRANSACTIONS_ENCODERS_MASTER() TRANSACTION_HANDLER_MASTER(encoder)
200# define TRANSACTIONS_ENCODERS_SLAVE() TRANSACTION_HANDLER_SLAVE(encoder_handlers) 197# define TRANSACTIONS_ENCODERS_SLAVE() TRANSACTION_HANDLER_SLAVE(encoder)
201# define TRANSACTIONS_ENCODERS_REGISTRATIONS \ 198# define TRANSACTIONS_ENCODERS_REGISTRATIONS \
202 [GET_ENCODERS_CHECKSUM] = trans_target2initiator_initializer(encoders.checksum), \ 199 [GET_ENCODERS_CHECKSUM] = trans_target2initiator_initializer(encoders.checksum), \
203 [GET_ENCODERS_DATA] = trans_target2initiator_initializer(encoders.state), 200 [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
238 } 235 }
239} 236}
240 237
241# define TRANSACTIONS_SYNC_TIMER_MASTER() TRANSACTION_HANDLER_MASTER(sync_timer_handlers) 238# define TRANSACTIONS_SYNC_TIMER_MASTER() TRANSACTION_HANDLER_MASTER(sync_timer)
242# define TRANSACTIONS_SYNC_TIMER_SLAVE() TRANSACTION_HANDLER_SLAVE(sync_timer_handlers) 239# define TRANSACTIONS_SYNC_TIMER_SLAVE() TRANSACTION_HANDLER_SLAVE(sync_timer)
243# define TRANSACTIONS_SYNC_TIMER_REGISTRATIONS [PUT_SYNC_TIMER] = trans_initiator2target_initializer(sync_timer), 240# define TRANSACTIONS_SYNC_TIMER_REGISTRATIONS [PUT_SYNC_TIMER] = trans_initiator2target_initializer(sync_timer),
244 241
245#else // DISABLE_SYNC_TIMER 242#else // DISABLE_SYNC_TIMER
@@ -272,8 +269,8 @@ static void layer_state_handlers_slave(matrix_row_t master_matrix[], matrix_row_
272} 269}
273 270
274// clang-format off 271// clang-format off
275# define TRANSACTIONS_LAYER_STATE_MASTER() TRANSACTION_HANDLER_MASTER(layer_state_handlers) 272# define TRANSACTIONS_LAYER_STATE_MASTER() TRANSACTION_HANDLER_MASTER(layer_state)
276# define TRANSACTIONS_LAYER_STATE_SLAVE() TRANSACTION_HANDLER_SLAVE(layer_state_handlers) 273# define TRANSACTIONS_LAYER_STATE_SLAVE() TRANSACTION_HANDLER_SLAVE(layer_state)
277# define TRANSACTIONS_LAYER_STATE_REGISTRATIONS \ 274# define TRANSACTIONS_LAYER_STATE_REGISTRATIONS \
278 [PUT_LAYER_STATE] = trans_initiator2target_initializer(layers.layer_state), \ 275 [PUT_LAYER_STATE] = trans_initiator2target_initializer(layers.layer_state), \
279 [PUT_DEFAULT_LAYER_STATE] = trans_initiator2target_initializer(layers.default_layer_state), 276 [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
303 set_split_host_keyboard_leds(split_shmem->led_state); 300 set_split_host_keyboard_leds(split_shmem->led_state);
304} 301}
305 302
306# define TRANSACTIONS_LED_STATE_MASTER() TRANSACTION_HANDLER_MASTER(led_state_handlers) 303# define TRANSACTIONS_LED_STATE_MASTER() TRANSACTION_HANDLER_MASTER(led_state)
307# define TRANSACTIONS_LED_STATE_SLAVE() TRANSACTION_HANDLER_SLAVE(led_state_handlers) 304# define TRANSACTIONS_LED_STATE_SLAVE() TRANSACTION_HANDLER_SLAVE(led_state)
308# define TRANSACTIONS_LED_STATE_REGISTRATIONS [PUT_LED_STATE] = trans_initiator2target_initializer(led_state), 305# define TRANSACTIONS_LED_STATE_REGISTRATIONS [PUT_LED_STATE] = trans_initiator2target_initializer(led_state),
309 306
310#else // SPLIT_LED_STATE_ENABLE 307#else // SPLIT_LED_STATE_ENABLE
@@ -360,8 +357,8 @@ static void mods_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave
360# endif 357# endif
361} 358}
362 359
363# define TRANSACTIONS_MODS_MASTER() TRANSACTION_HANDLER_MASTER(mods_handlers) 360# define TRANSACTIONS_MODS_MASTER() TRANSACTION_HANDLER_MASTER(mods)
364# define TRANSACTIONS_MODS_SLAVE() TRANSACTION_HANDLER_SLAVE(mods_handlers) 361# define TRANSACTIONS_MODS_SLAVE() TRANSACTION_HANDLER_SLAVE(mods)
365# define TRANSACTIONS_MODS_REGISTRATIONS [PUT_MODS] = trans_initiator2target_initializer(mods), 362# define TRANSACTIONS_MODS_REGISTRATIONS [PUT_MODS] = trans_initiator2target_initializer(mods),
366 363
367#else // SPLIT_MODS_ENABLE 364#else // SPLIT_MODS_ENABLE
@@ -385,8 +382,8 @@ static bool backlight_handlers_master(matrix_row_t master_matrix[], matrix_row_t
385 382
386static void backlight_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { backlight_set(split_shmem->backlight_level); } 383static void backlight_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { backlight_set(split_shmem->backlight_level); }
387 384
388# define TRANSACTIONS_BACKLIGHT_MASTER() TRANSACTION_HANDLER_MASTER(backlight_handlers) 385# define TRANSACTIONS_BACKLIGHT_MASTER() TRANSACTION_HANDLER_MASTER(backlight)
389# define TRANSACTIONS_BACKLIGHT_SLAVE() TRANSACTION_HANDLER_SLAVE(backlight_handlers) 386# define TRANSACTIONS_BACKLIGHT_SLAVE() TRANSACTION_HANDLER_SLAVE(backlight)
390# define TRANSACTIONS_BACKLIGHT_REGISTRATIONS [PUT_BACKLIGHT] = trans_initiator2target_initializer(backlight_level), 387# define TRANSACTIONS_BACKLIGHT_REGISTRATIONS [PUT_BACKLIGHT] = trans_initiator2target_initializer(backlight_level),
391 388
392#else // BACKLIGHT_ENABLE 389#else // BACKLIGHT_ENABLE
@@ -422,8 +419,8 @@ static void rgblight_handlers_slave(matrix_row_t master_matrix[], matrix_row_t s
422 } 419 }
423} 420}
424 421
425# define TRANSACTIONS_RGBLIGHT_MASTER() TRANSACTION_HANDLER_MASTER(rgblight_handlers) 422# define TRANSACTIONS_RGBLIGHT_MASTER() TRANSACTION_HANDLER_MASTER(rgblight)
426# define TRANSACTIONS_RGBLIGHT_SLAVE() TRANSACTION_HANDLER_SLAVE(rgblight_handlers) 423# define TRANSACTIONS_RGBLIGHT_SLAVE() TRANSACTION_HANDLER_SLAVE(rgblight)
427# define TRANSACTIONS_RGBLIGHT_REGISTRATIONS [PUT_RGBLIGHT] = trans_initiator2target_initializer(rgblight_sync), 424# define TRANSACTIONS_RGBLIGHT_REGISTRATIONS [PUT_RGBLIGHT] = trans_initiator2target_initializer(rgblight_sync),
428 425
429#else // defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) 426#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
452 led_matrix_set_suspend_state(split_shmem->led_matrix_sync.led_suspend_state); 449 led_matrix_set_suspend_state(split_shmem->led_matrix_sync.led_suspend_state);
453} 450}
454 451
455# define TRANSACTIONS_LED_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(led_matrix_handlers) 452# define TRANSACTIONS_LED_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(led_matrix)
456# define TRANSACTIONS_LED_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(led_matrix_handlers) 453# define TRANSACTIONS_LED_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(led_matrix)
457# define TRANSACTIONS_LED_MATRIX_REGISTRATIONS [PUT_LED_MATRIX] = trans_initiator2target_initializer(led_matrix_sync), 454# define TRANSACTIONS_LED_MATRIX_REGISTRATIONS [PUT_LED_MATRIX] = trans_initiator2target_initializer(led_matrix_sync),
458 455
459#else // defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) 456#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
482 rgb_matrix_set_suspend_state(split_shmem->rgb_matrix_sync.rgb_suspend_state); 479 rgb_matrix_set_suspend_state(split_shmem->rgb_matrix_sync.rgb_suspend_state);
483} 480}
484 481
485# define TRANSACTIONS_RGB_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(rgb_matrix_handlers) 482# define TRANSACTIONS_RGB_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(rgb_matrix)
486# define TRANSACTIONS_RGB_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(rgb_matrix_handlers) 483# define TRANSACTIONS_RGB_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(rgb_matrix)
487# define TRANSACTIONS_RGB_MATRIX_REGISTRATIONS [PUT_RGB_MATRIX] = trans_initiator2target_initializer(rgb_matrix_sync), 484# define TRANSACTIONS_RGB_MATRIX_REGISTRATIONS [PUT_RGB_MATRIX] = trans_initiator2target_initializer(rgb_matrix_sync),
488 485
489#else // defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) 486#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
507 504
508static void wpm_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { set_current_wpm(split_shmem->current_wpm); } 505static void wpm_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { set_current_wpm(split_shmem->current_wpm); }
509 506
510# define TRANSACTIONS_WPM_MASTER() TRANSACTION_HANDLER_MASTER(wpm_handlers) 507# define TRANSACTIONS_WPM_MASTER() TRANSACTION_HANDLER_MASTER(wpm)
511# define TRANSACTIONS_WPM_SLAVE() TRANSACTION_HANDLER_SLAVE(wpm_handlers) 508# define TRANSACTIONS_WPM_SLAVE() TRANSACTION_HANDLER_SLAVE(wpm)
512# define TRANSACTIONS_WPM_REGISTRATIONS [PUT_WPM] = trans_initiator2target_initializer(current_wpm), 509# define TRANSACTIONS_WPM_REGISTRATIONS [PUT_WPM] = trans_initiator2target_initializer(current_wpm),
513 510
514#else // defined(WPM_ENABLE) && defined(SPLIT_WPM_ENABLE) 511#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
538 } 535 }
539} 536}
540 537
541# define TRANSACTIONS_OLED_MASTER() TRANSACTION_HANDLER_MASTER(oled_handlers) 538# define TRANSACTIONS_OLED_MASTER() TRANSACTION_HANDLER_MASTER(oled)
542# define TRANSACTIONS_OLED_SLAVE() TRANSACTION_HANDLER_SLAVE(oled_handlers) 539# define TRANSACTIONS_OLED_SLAVE() TRANSACTION_HANDLER_SLAVE(oled)
543# define TRANSACTIONS_OLED_REGISTRATIONS [PUT_OLED] = trans_initiator2target_initializer(current_oled_state), 540# define TRANSACTIONS_OLED_REGISTRATIONS [PUT_OLED] = trans_initiator2target_initializer(current_oled_state),
544 541
545#else // defined(OLED_DRIVER_ENABLE) && defined(SPLIT_OLED_ENABLE) 542#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
569 } 566 }
570} 567}
571 568
572# define TRANSACTIONS_ST7565_MASTER() TRANSACTION_HANDLER_MASTER(st7565_handlers) 569# define TRANSACTIONS_ST7565_MASTER() TRANSACTION_HANDLER_MASTER(st7565)
573# define TRANSACTIONS_ST7565_SLAVE() TRANSACTION_HANDLER_SLAVE(st7565_handlers) 570# define TRANSACTIONS_ST7565_SLAVE() TRANSACTION_HANDLER_SLAVE(st7565)
574# define TRANSACTIONS_ST7565_REGISTRATIONS [PUT_ST7565] = trans_initiator2target_initializer(current_st7565_state), 571# define TRANSACTIONS_ST7565_REGISTRATIONS [PUT_ST7565] = trans_initiator2target_initializer(current_st7565_state),
575 572
576#else // defined(ST7565_ENABLE) && defined(SPLIT_ST7565_ENABLE) 573#else // defined(ST7565_ENABLE) && defined(SPLIT_ST7565_ENABLE)
@@ -618,7 +615,6 @@ split_transaction_desc_t split_transaction_table[NUM_TOTAL_TRANSACTIONS] = {
618}; 615};
619 616
620bool transactions_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { 617bool transactions_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
621 bool okay = true;
622 TRANSACTIONS_SLAVE_MATRIX_MASTER(); 618 TRANSACTIONS_SLAVE_MATRIX_MASTER();
623 TRANSACTIONS_MASTER_MATRIX_MASTER(); 619 TRANSACTIONS_MASTER_MATRIX_MASTER();
624 TRANSACTIONS_ENCODERS_MASTER(); 620 TRANSACTIONS_ENCODERS_MASTER();
@@ -633,7 +629,7 @@ bool transactions_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix
633 TRANSACTIONS_WPM_MASTER(); 629 TRANSACTIONS_WPM_MASTER();
634 TRANSACTIONS_OLED_MASTER(); 630 TRANSACTIONS_OLED_MASTER();
635 TRANSACTIONS_ST7565_MASTER(); 631 TRANSACTIONS_ST7565_MASTER();
636 return okay; 632 return true;
637} 633}
638 634
639void transactions_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { 635void 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)
666} 662}
667 663
668bool transaction_rpc_exec(int8_t transaction_id, uint8_t initiator2target_buffer_size, const void *initiator2target_buffer, uint8_t target2initiator_buffer_size, void *target2initiator_buffer) { 664bool transaction_rpc_exec(int8_t transaction_id, uint8_t initiator2target_buffer_size, const void *initiator2target_buffer, uint8_t target2initiator_buffer_size, void *target2initiator_buffer) {
665 // Prevent transaction attempts while transport is disconnected
666 if (!is_transport_connected()) {
667 return false;
668 }
669 // Prevent invoking RPC on QMK core sync data 669 // Prevent invoking RPC on QMK core sync data
670 if (transaction_id <= GET_RPC_RESP_DATA) return false; 670 if (transaction_id <= GET_RPC_RESP_DATA) return false;
671 // Prevent sizing issues 671 // Prevent sizing issues
diff --git a/quantum/split_common/transport.c b/quantum/split_common/transport.c
index a711ef85f..bcc026141 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,
115 115
116bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { return transactions_master(master_matrix, slave_matrix); } 116bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { return transactions_master(master_matrix, slave_matrix); }
117 117
118void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { transactions_slave(master_matrix, slave_matrix); } \ No newline at end of file 118void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { transactions_slave(master_matrix, slave_matrix); }