aboutsummaryrefslogtreecommitdiff
path: root/quantum/split_common/transport.c
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/split_common/transport.c')
-rw-r--r--quantum/split_common/transport.c484
1 files changed, 75 insertions, 409 deletions
diff --git a/quantum/split_common/transport.c b/quantum/split_common/transport.c
index 9ed0f7591..a711ef85f 100644
--- a/quantum/split_common/transport.c
+++ b/quantum/split_common/transport.c
@@ -1,452 +1,118 @@
1#include <string.h> 1/* Copyright 2021 QMK
2#include <stddef.h> 2 *
3 3 * This program is free software: you can redistribute it and/or modify
4#include "config.h" 4 * it under the terms of the GNU General Public License as published by
5#include "matrix.h" 5 * the Free Software Foundation, either version 2 of the License, or
6#include "quantum.h" 6 * (at your option) any later version.
7 7 *
8#define ROWS_PER_HAND (MATRIX_ROWS / 2) 8 * This program is distributed in the hope that it will be useful,
9#define SYNC_TIMER_OFFSET 2 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11#ifdef RGBLIGHT_ENABLE 11 * GNU General Public License for more details.
12# include "rgblight.h" 12 *
13#endif 13 * You should have received a copy of the GNU General Public License
14 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15#ifdef BACKLIGHT_ENABLE 15 */
16# include "backlight.h"
17#endif
18
19#ifdef ENCODER_ENABLE
20# include "encoder.h"
21static pin_t encoders_pad[] = ENCODERS_PAD_A;
22# define NUMBER_OF_ENCODERS (sizeof(encoders_pad) / sizeof(pin_t))
23#endif
24
25#if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
26# include "led_matrix.h"
27#endif
28#if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
29# include "rgb_matrix.h"
30#endif
31
32#if defined(USE_I2C)
33 16
34# include "i2c_master.h" 17#include <string.h>
35# include "i2c_slave.h" 18#include <debug.h>
36
37typedef struct _I2C_slave_buffer_t {
38# ifndef DISABLE_SYNC_TIMER
39 uint32_t sync_timer;
40# endif
41# ifdef SPLIT_TRANSPORT_MIRROR
42 matrix_row_t mmatrix[ROWS_PER_HAND];
43# endif
44 matrix_row_t smatrix[ROWS_PER_HAND];
45# ifdef SPLIT_MODS_ENABLE
46 uint8_t real_mods;
47 uint8_t weak_mods;
48# ifndef NO_ACTION_ONESHOT
49 uint8_t oneshot_mods;
50# endif
51# endif
52# ifdef BACKLIGHT_ENABLE
53 uint8_t backlight_level;
54# endif
55# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
56 rgblight_syncinfo_t rgblight_sync;
57# endif
58# ifdef ENCODER_ENABLE
59 uint8_t encoder_state[NUMBER_OF_ENCODERS];
60# endif
61# ifdef WPM_ENABLE
62 uint8_t current_wpm;
63# endif
64# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
65 led_eeconfig_t led_matrix;
66 bool led_suspend_state;
67# endif
68# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
69 rgb_config_t rgb_matrix;
70 bool rgb_suspend_state;
71# endif
72} I2C_slave_buffer_t;
73 19
74static I2C_slave_buffer_t *const i2c_buffer = (I2C_slave_buffer_t *)i2c_slave_reg; 20#include "transactions.h"
21#include "transport.h"
22#include "transaction_id_define.h"
23#include "atomic_util.h"
75 24
76# define I2C_SYNC_TIME_START offsetof(I2C_slave_buffer_t, sync_timer) 25#ifdef USE_I2C
77# define I2C_KEYMAP_MASTER_START offsetof(I2C_slave_buffer_t, mmatrix)
78# define I2C_KEYMAP_SLAVE_START offsetof(I2C_slave_buffer_t, smatrix)
79# define I2C_REAL_MODS_START offsetof(I2C_slave_buffer_t, real_mods)
80# define I2C_WEAK_MODS_START offsetof(I2C_slave_buffer_t, weak_mods)
81# define I2C_ONESHOT_MODS_START offsetof(I2C_slave_buffer_t, oneshot_mods)
82# define I2C_BACKLIGHT_START offsetof(I2C_slave_buffer_t, backlight_level)
83# define I2C_RGB_START offsetof(I2C_slave_buffer_t, rgblight_sync)
84# define I2C_ENCODER_START offsetof(I2C_slave_buffer_t, encoder_state)
85# define I2C_WPM_START offsetof(I2C_slave_buffer_t, current_wpm)
86# define I2C_LED_MATRIX_START offsetof(I2C_slave_buffer_t, led_matrix)
87# define I2C_LED_SUSPEND_START offsetof(I2C_slave_buffer_t, led_suspend_state)
88# define I2C_RGB_MATRIX_START offsetof(I2C_slave_buffer_t, rgb_matrix)
89# define I2C_RGB_SUSPEND_START offsetof(I2C_slave_buffer_t, rgb_suspend_state)
90 26
91# define TIMEOUT 100 27# ifndef SLAVE_I2C_TIMEOUT
28# define SLAVE_I2C_TIMEOUT 100
29# endif // SLAVE_I2C_TIMEOUT
92 30
93# ifndef SLAVE_I2C_ADDRESS 31# ifndef SLAVE_I2C_ADDRESS
94# define SLAVE_I2C_ADDRESS 0x32 32# define SLAVE_I2C_ADDRESS 0x32
95# endif 33# endif
96 34
97// Get rows from other half over i2c 35# include "i2c_master.h"
98bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { 36# include "i2c_slave.h"
99 i2c_readReg(SLAVE_I2C_ADDRESS, I2C_KEYMAP_SLAVE_START, (void *)slave_matrix, sizeof(i2c_buffer->smatrix), TIMEOUT);
100# ifdef SPLIT_TRANSPORT_MIRROR
101 i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_KEYMAP_MASTER_START, (void *)master_matrix, sizeof(i2c_buffer->mmatrix), TIMEOUT);
102# endif
103 37
104 // write backlight info 38// Ensure the I2C buffer has enough space
105# ifdef BACKLIGHT_ENABLE 39_Static_assert(sizeof(split_shared_memory_t) <= I2C_SLAVE_REG_COUNT, "split_shared_memory_t too large for I2C_SLAVE_REG_COUNT");
106 uint8_t level = is_backlight_enabled() ? get_backlight_level() : 0;
107 if (level != i2c_buffer->backlight_level) {
108 if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_BACKLIGHT_START, (void *)&level, sizeof(level), TIMEOUT) >= 0) {
109 i2c_buffer->backlight_level = level;
110 }
111 }
112# endif
113 40
114# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) 41split_shared_memory_t *const split_shmem = (split_shared_memory_t *)i2c_slave_reg;
115 if (rgblight_get_change_flags()) {
116 rgblight_syncinfo_t rgblight_sync;
117 rgblight_get_syncinfo(&rgblight_sync);
118 if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_START, (void *)&rgblight_sync, sizeof(rgblight_sync), TIMEOUT) >= 0) {
119 rgblight_clear_change_flags();
120 }
121 }
122# endif
123 42
124# ifdef ENCODER_ENABLE 43void transport_master_init(void) { i2c_init(); }
125 i2c_readReg(SLAVE_I2C_ADDRESS, I2C_ENCODER_START, (void *)i2c_buffer->encoder_state, sizeof(i2c_buffer->encoder_state), TIMEOUT); 44void transport_slave_init(void) { i2c_slave_init(SLAVE_I2C_ADDRESS); }
126 encoder_update_raw(i2c_buffer->encoder_state);
127# endif
128 45
129# ifdef WPM_ENABLE 46i2c_status_t transport_trigger_callback(int8_t id) {
130 uint8_t current_wpm = get_current_wpm(); 47 // If there's no callback, indicate that we were successful
131 if (current_wpm != i2c_buffer->current_wpm) { 48 if (!split_transaction_table[id].slave_callback) {
132 if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_WPM_START, (void *)&current_wpm, sizeof(current_wpm), TIMEOUT) >= 0) { 49 return I2C_STATUS_SUCCESS;
133 i2c_buffer->current_wpm = current_wpm;
134 }
135 } 50 }
136# endif
137 51
138# ifdef SPLIT_MODS_ENABLE 52 // Kick off the "callback executor", now that data has been written to the slave
139 uint8_t real_mods = get_mods(); 53 split_shmem->transaction_id = id;
140 if (real_mods != i2c_buffer->real_mods) { 54 split_transaction_desc_t *trans = &split_transaction_table[I2C_EXECUTE_CALLBACK];
141 if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_REAL_MODS_START, (void *)&real_mods, sizeof(real_mods), TIMEOUT) >= 0) { 55 return i2c_writeReg(SLAVE_I2C_ADDRESS, trans->initiator2target_offset, split_trans_initiator2target_buffer(trans), trans->initiator2target_buffer_size, SLAVE_I2C_TIMEOUT);
142 i2c_buffer->real_mods = real_mods; 56}
57
58bool transport_execute_transaction(int8_t id, const void *initiator2target_buf, uint16_t initiator2target_length, void *target2initiator_buf, uint16_t target2initiator_length) {
59 i2c_status_t status;
60 split_transaction_desc_t *trans = &split_transaction_table[id];
61 if (initiator2target_length > 0) {
62 size_t len = trans->initiator2target_buffer_size < initiator2target_length ? trans->initiator2target_buffer_size : initiator2target_length;
63 memcpy(split_trans_initiator2target_buffer(trans), initiator2target_buf, len);
64 if ((status = i2c_writeReg(SLAVE_I2C_ADDRESS, trans->initiator2target_offset, split_trans_initiator2target_buffer(trans), len, SLAVE_I2C_TIMEOUT)) < 0) {
65 return false;
143 } 66 }
144 } 67 }
145 68
146 uint8_t weak_mods = get_weak_mods(); 69 // If we need to execute a callback on the slave, do so
147 if (weak_mods != i2c_buffer->weak_mods) { 70 if ((status = transport_trigger_callback(id)) < 0) {
148 if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_WEAK_MODS_START, (void *)&weak_mods, sizeof(weak_mods), TIMEOUT) >= 0) { 71 return false;
149 i2c_buffer->weak_mods = weak_mods;
150 }
151 } 72 }
152 73
153# ifndef NO_ACTION_ONESHOT 74 if (target2initiator_length > 0) {
154 uint8_t oneshot_mods = get_oneshot_mods(); 75 size_t len = trans->target2initiator_buffer_size < target2initiator_length ? trans->target2initiator_buffer_size : target2initiator_length;
155 if (oneshot_mods != i2c_buffer->oneshot_mods) { 76 if ((status = i2c_readReg(SLAVE_I2C_ADDRESS, trans->target2initiator_offset, split_trans_target2initiator_buffer(trans), len, SLAVE_I2C_TIMEOUT)) < 0) {
156 if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_ONESHOT_MODS_START, (void *)&oneshot_mods, sizeof(oneshot_mods), TIMEOUT) >= 0) { 77 return false;
157 i2c_buffer->oneshot_mods = oneshot_mods;
158 } 78 }
79 memcpy(target2initiator_buf, split_trans_target2initiator_buffer(trans), len);
159 } 80 }
160# endif
161# endif
162 81
163# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
164 i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_LED_MATRIX_START, (void *)led_matrix_eeconfig, sizeof(i2c_buffer->led_matrix), TIMEOUT);
165 bool suspend_state = led_matrix_get_suspend_state();
166 i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_LED_SUSPEND_START, (void *)suspend_state, sizeof(i2c_buffer->led_suspend_state), TIMEOUT);
167# endif
168# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
169 i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_MATRIX_START, (void *)rgb_matrix_config, sizeof(i2c_buffer->rgb_matrix), TIMEOUT);
170 bool suspend_state = rgb_matrix_get_suspend_state();
171 i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_SUSPEND_START, (void *)suspend_state, sizeof(i2c_buffer->rgb_suspend_state), TIMEOUT);
172# endif
173
174# ifndef DISABLE_SYNC_TIMER
175 i2c_buffer->sync_timer = sync_timer_read32() + SYNC_TIMER_OFFSET;
176 i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_SYNC_TIME_START, (void *)&i2c_buffer->sync_timer, sizeof(i2c_buffer->sync_timer), TIMEOUT);
177# endif
178 return true; 82 return true;
179} 83}
180 84
181void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { 85#else // USE_I2C
182# ifndef DISABLE_SYNC_TIMER
183 sync_timer_update(i2c_buffer->sync_timer);
184# endif
185 // Copy matrix to I2C buffer
186 memcpy((void *)i2c_buffer->smatrix, (void *)slave_matrix, sizeof(i2c_buffer->smatrix));
187# ifdef SPLIT_TRANSPORT_MIRROR
188 memcpy((void *)master_matrix, (void *)i2c_buffer->mmatrix, sizeof(i2c_buffer->mmatrix));
189# endif
190
191// Read Backlight Info
192# ifdef BACKLIGHT_ENABLE
193 backlight_set(i2c_buffer->backlight_level);
194# endif
195
196# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
197 // Update the RGB with the new data
198 if (i2c_buffer->rgblight_sync.status.change_flags != 0) {
199 rgblight_update_sync(&i2c_buffer->rgblight_sync, false);
200 i2c_buffer->rgblight_sync.status.change_flags = 0;
201 }
202# endif
203
204# ifdef ENCODER_ENABLE
205 encoder_state_raw(i2c_buffer->encoder_state);
206# endif
207
208# ifdef WPM_ENABLE
209 set_current_wpm(i2c_buffer->current_wpm);
210# endif
211
212# ifdef SPLIT_MODS_ENABLE
213 set_mods(i2c_buffer->real_mods);
214 set_weak_mods(i2c_buffer->weak_mods);
215# ifndef NO_ACTION_ONESHOT
216 set_oneshot_mods(i2c_buffer->oneshot_mods);
217# endif
218# endif
219
220# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
221 memcpy((void *)i2c_buffer->led_matrix, (void *)led_matrix_eeconfig, sizeof(i2c_buffer->led_matrix));
222 led_matrix_set_suspend_state(i2c_buffer->led_suspend_state);
223# endif
224# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
225 memcpy((void *)i2c_buffer->rgb_matrix, (void *)rgb_matrix_config, sizeof(i2c_buffer->rgb_matrix));
226 rgb_matrix_set_suspend_state(i2c_buffer->rgb_suspend_state);
227# endif
228}
229
230void transport_master_init(void) { i2c_init(); }
231
232void transport_slave_init(void) { i2c_slave_init(SLAVE_I2C_ADDRESS); }
233
234#else // USE_SERIAL
235 86
236# include "serial.h" 87# include "serial.h"
237 88
238typedef struct _Serial_s2m_buffer_t { 89static split_shared_memory_t shared_memory;
239 // TODO: if MATRIX_COLS > 8 change to uint8_t packed_matrix[] for pack/unpack 90split_shared_memory_t *const split_shmem = &shared_memory;
240 matrix_row_t smatrix[ROWS_PER_HAND];
241
242# ifdef ENCODER_ENABLE
243 uint8_t encoder_state[NUMBER_OF_ENCODERS];
244# endif
245
246} Serial_s2m_buffer_t;
247
248typedef struct _Serial_m2s_buffer_t {
249# ifdef SPLIT_MODS_ENABLE
250 uint8_t real_mods;
251 uint8_t weak_mods;
252# ifndef NO_ACTION_ONESHOT
253 uint8_t oneshot_mods;
254# endif
255# endif
256# ifndef DISABLE_SYNC_TIMER
257 uint32_t sync_timer;
258# endif
259# ifdef SPLIT_TRANSPORT_MIRROR
260 matrix_row_t mmatrix[ROWS_PER_HAND];
261# endif
262# ifdef BACKLIGHT_ENABLE
263 uint8_t backlight_level;
264# endif
265# ifdef WPM_ENABLE
266 uint8_t current_wpm;
267# endif
268# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
269 led_eeconfig_t led_matrix;
270 bool led_suspend_state;
271# endif
272# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
273 rgb_config_t rgb_matrix;
274 bool rgb_suspend_state;
275# endif
276} Serial_m2s_buffer_t;
277
278# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
279// When MCUs on both sides drive their respective RGB LED chains,
280// it is necessary to synchronize, so it is necessary to communicate RGB
281// information. In that case, define RGBLIGHT_SPLIT with info on the number
282// of LEDs on each half.
283//
284// Otherwise, if the master side MCU drives both sides RGB LED chains,
285// there is no need to communicate.
286
287typedef struct _Serial_rgblight_t {
288 rgblight_syncinfo_t rgblight_sync;
289} Serial_rgblight_t;
290 91
291volatile Serial_rgblight_t serial_rgblight = {}; 92void transport_master_init(void) { soft_serial_initiator_init(); }
292uint8_t volatile status_rgblight = 0; 93void transport_slave_init(void) { soft_serial_target_init(); }
293# endif
294
295volatile Serial_s2m_buffer_t serial_s2m_buffer = {};
296volatile Serial_m2s_buffer_t serial_m2s_buffer = {};
297uint8_t volatile status0 = 0;
298
299enum serial_transaction_id {
300 GET_SLAVE_MATRIX = 0,
301# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
302 PUT_RGBLIGHT,
303# endif
304};
305
306SSTD_t transactions[] = {
307 [GET_SLAVE_MATRIX] =
308 {
309 (uint8_t *)&status0,
310 sizeof(serial_m2s_buffer),
311 (uint8_t *)&serial_m2s_buffer,
312 sizeof(serial_s2m_buffer),
313 (uint8_t *)&serial_s2m_buffer,
314 },
315# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
316 [PUT_RGBLIGHT] =
317 {
318 (uint8_t *)&status_rgblight, sizeof(serial_rgblight), (uint8_t *)&serial_rgblight, 0, NULL // no slave to master transfer
319 },
320# endif
321};
322
323void transport_master_init(void) { soft_serial_initiator_init(transactions, TID_LIMIT(transactions)); }
324
325void transport_slave_init(void) { soft_serial_target_init(transactions, TID_LIMIT(transactions)); }
326 94
327# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) 95bool transport_execute_transaction(int8_t id, const void *initiator2target_buf, uint16_t initiator2target_length, void *target2initiator_buf, uint16_t target2initiator_length) {
328 96 split_transaction_desc_t *trans = &split_transaction_table[id];
329// rgblight synchronization information communication. 97 if (initiator2target_length > 0) {
330 98 size_t len = trans->initiator2target_buffer_size < initiator2target_length ? trans->initiator2target_buffer_size : initiator2target_length;
331void transport_rgblight_master(void) { 99 memcpy(split_trans_initiator2target_buffer(trans), initiator2target_buf, len);
332 if (rgblight_get_change_flags()) {
333 rgblight_get_syncinfo((rgblight_syncinfo_t *)&serial_rgblight.rgblight_sync);
334 if (soft_serial_transaction(PUT_RGBLIGHT) == TRANSACTION_END) {
335 rgblight_clear_change_flags();
336 }
337 }
338}
339
340void transport_rgblight_slave(void) {
341 if (status_rgblight == TRANSACTION_ACCEPTED) {
342 rgblight_update_sync((rgblight_syncinfo_t *)&serial_rgblight.rgblight_sync, false);
343 status_rgblight = TRANSACTION_END;
344 } 100 }
345}
346 101
347# else 102 if (soft_serial_transaction(id) != TRANSACTION_END) {
348# define transport_rgblight_master()
349# define transport_rgblight_slave()
350# endif
351
352bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
353# ifndef SERIAL_USE_MULTI_TRANSACTION
354 if (soft_serial_transaction() != TRANSACTION_END) {
355 return false;
356 }
357# else
358 transport_rgblight_master();
359 if (soft_serial_transaction(GET_SLAVE_MATRIX) != TRANSACTION_END) {
360 return false; 103 return false;
361 } 104 }
362# endif
363 105
364 // TODO: if MATRIX_COLS > 8 change to unpack() 106 if (target2initiator_length > 0) {
365 for (int i = 0; i < ROWS_PER_HAND; ++i) { 107 size_t len = trans->target2initiator_buffer_size < target2initiator_length ? trans->target2initiator_buffer_size : target2initiator_length;
366 slave_matrix[i] = serial_s2m_buffer.smatrix[i]; 108 memcpy(target2initiator_buf, split_trans_target2initiator_buffer(trans), len);
367# ifdef SPLIT_TRANSPORT_MIRROR
368 serial_m2s_buffer.mmatrix[i] = master_matrix[i];
369# endif
370 } 109 }
371 110
372# ifdef BACKLIGHT_ENABLE
373 // Write backlight level for slave to read
374 serial_m2s_buffer.backlight_level = is_backlight_enabled() ? get_backlight_level() : 0;
375# endif
376
377# ifdef ENCODER_ENABLE
378 encoder_update_raw((uint8_t *)serial_s2m_buffer.encoder_state);
379# endif
380
381# ifdef WPM_ENABLE
382 // Write wpm to slave
383 serial_m2s_buffer.current_wpm = get_current_wpm();
384# endif
385
386# ifdef SPLIT_MODS_ENABLE
387 serial_m2s_buffer.real_mods = get_mods();
388 serial_m2s_buffer.weak_mods = get_weak_mods();
389# ifndef NO_ACTION_ONESHOT
390 serial_m2s_buffer.oneshot_mods = get_oneshot_mods();
391# endif
392# endif
393
394# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
395 serial_m2s_buffer.led_matrix = led_matrix_eeconfig;
396 serial_m2s_buffer.led_suspend_state = led_matrix_get_suspend_state();
397# endif
398# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
399 serial_m2s_buffer.rgb_matrix = rgb_matrix_config;
400 serial_m2s_buffer.rgb_suspend_state = rgb_matrix_get_suspend_state();
401# endif
402
403# ifndef DISABLE_SYNC_TIMER
404 serial_m2s_buffer.sync_timer = sync_timer_read32() + SYNC_TIMER_OFFSET;
405# endif
406 return true; 111 return true;
407} 112}
408 113
409void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { 114#endif // USE_I2C
410 transport_rgblight_slave();
411# ifndef DISABLE_SYNC_TIMER
412 sync_timer_update(serial_m2s_buffer.sync_timer);
413# endif
414
415 // TODO: if MATRIX_COLS > 8 change to pack()
416 for (int i = 0; i < ROWS_PER_HAND; ++i) {
417 serial_s2m_buffer.smatrix[i] = slave_matrix[i];
418# ifdef SPLIT_TRANSPORT_MIRROR
419 master_matrix[i] = serial_m2s_buffer.mmatrix[i];
420# endif
421 }
422# ifdef BACKLIGHT_ENABLE
423 backlight_set(serial_m2s_buffer.backlight_level);
424# endif
425
426# ifdef ENCODER_ENABLE
427 encoder_state_raw((uint8_t *)serial_s2m_buffer.encoder_state);
428# endif
429 115
430# ifdef WPM_ENABLE 116bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { return transactions_master(master_matrix, slave_matrix); }
431 set_current_wpm(serial_m2s_buffer.current_wpm);
432# endif
433
434# ifdef SPLIT_MODS_ENABLE
435 set_mods(serial_m2s_buffer.real_mods);
436 set_weak_mods(serial_m2s_buffer.weak_mods);
437# ifndef NO_ACTION_ONESHOT
438 set_oneshot_mods(serial_m2s_buffer.oneshot_mods);
439# endif
440# endif
441
442# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
443 led_matrix_eeconfig = serial_m2s_buffer.led_matrix;
444 led_matrix_set_suspend_state(serial_m2s_buffer.led_suspend_state);
445# endif
446# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
447 rgb_matrix_config = serial_m2s_buffer.rgb_matrix;
448 rgb_matrix_set_suspend_state(serial_m2s_buffer.rgb_suspend_state);
449# endif
450}
451 117
452#endif 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