diff options
Diffstat (limited to 'quantum/split_common/transport.c')
-rw-r--r-- | quantum/split_common/transport.c | 484 |
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" | ||
21 | static 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 | |||
37 | typedef 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 | ||
74 | static 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" |
98 | bool 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) | 41 | split_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 | 43 | void 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); | 44 | void 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 | 46 | i2c_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 *)¤t_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 | |||
58 | bool 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 | ||
181 | void 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 | |||
230 | void transport_master_init(void) { i2c_init(); } | ||
231 | |||
232 | void 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 | ||
238 | typedef struct _Serial_s2m_buffer_t { | 89 | static split_shared_memory_t shared_memory; |
239 | // TODO: if MATRIX_COLS > 8 change to uint8_t packed_matrix[] for pack/unpack | 90 | split_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 | |||
248 | typedef 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 | |||
287 | typedef struct _Serial_rgblight_t { | ||
288 | rgblight_syncinfo_t rgblight_sync; | ||
289 | } Serial_rgblight_t; | ||
290 | 91 | ||
291 | volatile Serial_rgblight_t serial_rgblight = {}; | 92 | void transport_master_init(void) { soft_serial_initiator_init(); } |
292 | uint8_t volatile status_rgblight = 0; | 93 | void transport_slave_init(void) { soft_serial_target_init(); } |
293 | # endif | ||
294 | |||
295 | volatile Serial_s2m_buffer_t serial_s2m_buffer = {}; | ||
296 | volatile Serial_m2s_buffer_t serial_m2s_buffer = {}; | ||
297 | uint8_t volatile status0 = 0; | ||
298 | |||
299 | enum serial_transaction_id { | ||
300 | GET_SLAVE_MATRIX = 0, | ||
301 | # if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) | ||
302 | PUT_RGBLIGHT, | ||
303 | # endif | ||
304 | }; | ||
305 | |||
306 | SSTD_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 | |||
323 | void transport_master_init(void) { soft_serial_initiator_init(transactions, TID_LIMIT(transactions)); } | ||
324 | |||
325 | void transport_slave_init(void) { soft_serial_target_init(transactions, TID_LIMIT(transactions)); } | ||
326 | 94 | ||
327 | # if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) | 95 | bool 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; | |
331 | void 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 | |||
340 | void 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 | |||
352 | bool 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 | ||
409 | void 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 | 116 | bool 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 | 118 | 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 |