aboutsummaryrefslogtreecommitdiff
path: root/quantum/split_common
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/split_common')
-rw-r--r--quantum/split_common/matrix.c46
-rw-r--r--quantum/split_common/transport.c136
-rw-r--r--quantum/split_common/transport.h4
3 files changed, 158 insertions, 28 deletions
diff --git a/quantum/split_common/matrix.c b/quantum/split_common/matrix.c
index 51bf8b109..d6636b886 100644
--- a/quantum/split_common/matrix.c
+++ b/quantum/split_common/matrix.c
@@ -114,9 +114,9 @@ static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
114 // Start with a clear matrix row 114 // Start with a clear matrix row
115 matrix_row_t current_row_value = 0; 115 matrix_row_t current_row_value = 0;
116 116
117 // Select row and wait for row selecton to stabilize 117 // Select row
118 select_row(current_row); 118 select_row(current_row);
119 matrix_io_delay(); 119 matrix_output_select_delay();
120 120
121 // For each col... 121 // For each col...
122 for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) { 122 for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
@@ -129,6 +129,9 @@ static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
129 129
130 // Unselect row 130 // Unselect row
131 unselect_row(current_row); 131 unselect_row(current_row);
132 if (current_row + 1 < MATRIX_ROWS) {
133 matrix_output_unselect_delay(); // wait for row signal to go HIGH
134 }
132 135
133 // If the row has changed, store the row and return the changed flag. 136 // If the row has changed, store the row and return the changed flag.
134 if (current_matrix[current_row] != current_row_value) { 137 if (current_matrix[current_row] != current_row_value) {
@@ -160,9 +163,9 @@ static void init_pins(void) {
160static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) { 163static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) {
161 bool matrix_changed = false; 164 bool matrix_changed = false;
162 165
163 // Select col and wait for col selecton to stabilize 166 // Select col
164 select_col(current_col); 167 select_col(current_col);
165 matrix_io_delay(); 168 matrix_output_select_delay();
166 169
167 // For each row... 170 // For each row...
168 for (uint8_t row_index = 0; row_index < ROWS_PER_HAND; row_index++) { 171 for (uint8_t row_index = 0; row_index < ROWS_PER_HAND; row_index++) {
@@ -188,6 +191,9 @@ static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)
188 191
189 // Unselect col 192 // Unselect col
190 unselect_col(current_col); 193 unselect_col(current_col);
194 if (current_col + 1 < MATRIX_COLS) {
195 matrix_output_unselect_delay(); // wait for col signal to go HIGH
196 }
191 197
192 return matrix_changed; 198 return matrix_changed;
193} 199}
@@ -245,48 +251,62 @@ void matrix_init(void) {
245 split_post_init(); 251 split_post_init();
246} 252}
247 253
248void matrix_post_scan(void) { 254bool matrix_post_scan(void) {
255 bool changed = false;
249 if (is_keyboard_master()) { 256 if (is_keyboard_master()) {
250 static uint8_t error_count; 257 static uint8_t error_count;
251 258
252 if (!transport_master(matrix + thatHand)) { 259 matrix_row_t slave_matrix[ROWS_PER_HAND] = {0};
260 if (!transport_master(matrix + thisHand, slave_matrix)) {
253 error_count++; 261 error_count++;
254 262
255 if (error_count > ERROR_DISCONNECT_COUNT) { 263 if (error_count > ERROR_DISCONNECT_COUNT) {
256 // reset other half if disconnected 264 // reset other half if disconnected
257 for (int i = 0; i < ROWS_PER_HAND; ++i) { 265 for (int i = 0; i < ROWS_PER_HAND; ++i) {
258 matrix[thatHand + i] = 0; 266 matrix[thatHand + i] = 0;
267 slave_matrix[i] = 0;
259 } 268 }
269
270 changed = true;
260 } 271 }
261 } else { 272 } else {
262 error_count = 0; 273 error_count = 0;
274
275 for (int i = 0; i < ROWS_PER_HAND; ++i) {
276 if (matrix[thatHand + i] != slave_matrix[i]) {
277 matrix[thatHand + i] = slave_matrix[i];
278 changed = true;
279 }
280 }
263 } 281 }
264 282
265 matrix_scan_quantum(); 283 matrix_scan_quantum();
266 } else { 284 } else {
267 transport_slave(matrix + thisHand); 285 transport_slave(matrix + thatHand, matrix + thisHand);
268 286
269 matrix_slave_scan_user(); 287 matrix_slave_scan_user();
270 } 288 }
289
290 return changed;
271} 291}
272 292
273uint8_t matrix_scan(void) { 293uint8_t matrix_scan(void) {
274 bool changed = false; 294 bool local_changed = false;
275 295
276#if defined(DIRECT_PINS) || (DIODE_DIRECTION == COL2ROW) 296#if defined(DIRECT_PINS) || (DIODE_DIRECTION == COL2ROW)
277 // Set row, read cols 297 // Set row, read cols
278 for (uint8_t current_row = 0; current_row < ROWS_PER_HAND; current_row++) { 298 for (uint8_t current_row = 0; current_row < ROWS_PER_HAND; current_row++) {
279 changed |= read_cols_on_row(raw_matrix, current_row); 299 local_changed |= read_cols_on_row(raw_matrix, current_row);
280 } 300 }
281#elif (DIODE_DIRECTION == ROW2COL) 301#elif (DIODE_DIRECTION == ROW2COL)
282 // Set col, read rows 302 // Set col, read rows
283 for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) { 303 for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
284 changed |= read_rows_on_col(raw_matrix, current_col); 304 local_changed |= read_rows_on_col(raw_matrix, current_col);
285 } 305 }
286#endif 306#endif
287 307
288 debounce(raw_matrix, matrix + thisHand, ROWS_PER_HAND, changed); 308 debounce(raw_matrix, matrix + thisHand, ROWS_PER_HAND, local_changed);
289 309
290 matrix_post_scan(); 310 bool remote_changed = matrix_post_scan();
291 return (uint8_t)changed; 311 return (uint8_t)(local_changed || remote_changed);
292} 312}
diff --git a/quantum/split_common/transport.c b/quantum/split_common/transport.c
index 467ff81a9..61b61ea08 100644
--- a/quantum/split_common/transport.c
+++ b/quantum/split_common/transport.c
@@ -6,6 +6,7 @@
6#include "quantum.h" 6#include "quantum.h"
7 7
8#define ROWS_PER_HAND (MATRIX_ROWS / 2) 8#define ROWS_PER_HAND (MATRIX_ROWS / 2)
9#define SYNC_TIMER_OFFSET 2
9 10
10#ifdef RGBLIGHT_ENABLE 11#ifdef RGBLIGHT_ENABLE
11# include "rgblight.h" 12# include "rgblight.h"
@@ -27,8 +28,23 @@ static pin_t encoders_pad[] = ENCODERS_PAD_A;
27# include "i2c_slave.h" 28# include "i2c_slave.h"
28 29
29typedef struct _I2C_slave_buffer_t { 30typedef struct _I2C_slave_buffer_t {
31# ifndef DISABLE_SYNC_TIMER
32 uint32_t sync_timer;
33# endif
34# ifdef SPLIT_TRANSPORT_MIRROR
35 matrix_row_t mmatrix[ROWS_PER_HAND];
36# endif
30 matrix_row_t smatrix[ROWS_PER_HAND]; 37 matrix_row_t smatrix[ROWS_PER_HAND];
31 uint8_t backlight_level; 38# ifdef SPLIT_MODS_ENABLE
39 uint8_t real_mods;
40 uint8_t weak_mods;
41# ifndef NO_ACTION_ONESHOT
42 uint8_t oneshot_mods;
43# endif
44# endif
45# ifdef BACKLIGHT_ENABLE
46 uint8_t backlight_level;
47# endif
32# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) 48# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
33 rgblight_syncinfo_t rgblight_sync; 49 rgblight_syncinfo_t rgblight_sync;
34# endif 50# endif
@@ -42,9 +58,14 @@ typedef struct _I2C_slave_buffer_t {
42 58
43static I2C_slave_buffer_t *const i2c_buffer = (I2C_slave_buffer_t *)i2c_slave_reg; 59static I2C_slave_buffer_t *const i2c_buffer = (I2C_slave_buffer_t *)i2c_slave_reg;
44 60
61# define I2C_SYNC_TIME_START offsetof(I2C_slave_buffer_t, sync_timer)
62# define I2C_KEYMAP_MASTER_START offsetof(I2C_slave_buffer_t, mmatrix)
63# define I2C_KEYMAP_SLAVE_START offsetof(I2C_slave_buffer_t, smatrix)
64# define I2C_REAL_MODS_START offsetof(I2C_slave_buffer_t, real_mods)
65# define I2C_WEAK_MODS_START offsetof(I2C_slave_buffer_t, weak_mods)
66# define I2C_ONESHOT_MODS_START offsetof(I2C_slave_buffer_t, oneshot_mods)
45# define I2C_BACKLIGHT_START offsetof(I2C_slave_buffer_t, backlight_level) 67# define I2C_BACKLIGHT_START offsetof(I2C_slave_buffer_t, backlight_level)
46# define I2C_RGB_START offsetof(I2C_slave_buffer_t, rgblight_sync) 68# define I2C_RGB_START offsetof(I2C_slave_buffer_t, rgblight_sync)
47# define I2C_KEYMAP_START offsetof(I2C_slave_buffer_t, smatrix)
48# define I2C_ENCODER_START offsetof(I2C_slave_buffer_t, encoder_state) 69# define I2C_ENCODER_START offsetof(I2C_slave_buffer_t, encoder_state)
49# define I2C_WPM_START offsetof(I2C_slave_buffer_t, current_wpm) 70# define I2C_WPM_START offsetof(I2C_slave_buffer_t, current_wpm)
50 71
@@ -55,8 +76,11 @@ static I2C_slave_buffer_t *const i2c_buffer = (I2C_slave_buffer_t *)i2c_slave_re
55# endif 76# endif
56 77
57// Get rows from other half over i2c 78// Get rows from other half over i2c
58bool transport_master(matrix_row_t matrix[]) { 79bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
59 i2c_readReg(SLAVE_I2C_ADDRESS, I2C_KEYMAP_START, (void *)matrix, sizeof(i2c_buffer->smatrix), TIMEOUT); 80 i2c_readReg(SLAVE_I2C_ADDRESS, I2C_KEYMAP_SLAVE_START, (void *)slave_matrix, sizeof(i2c_buffer->smatrix), TIMEOUT);
81# ifdef SPLIT_TRANSPORT_MIRROR
82 i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_KEYMAP_MASTER_START, (void *)master_matrix, sizeof(i2c_buffer->mmatrix), TIMEOUT);
83# endif
60 84
61 // write backlight info 85 // write backlight info
62# ifdef BACKLIGHT_ENABLE 86# ifdef BACKLIGHT_ENABLE
@@ -91,12 +115,48 @@ bool transport_master(matrix_row_t matrix[]) {
91 } 115 }
92 } 116 }
93# endif 117# endif
118
119# ifdef SPLIT_MODS_ENABLE
120 uint8_t real_mods = get_mods();
121 if (real_mods != i2c_buffer->real_mods) {
122 if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_REAL_MODS_START, (void *)&real_mods, sizeof(real_mods), TIMEOUT) >= 0) {
123 i2c_buffer->real_mods = real_mods;
124 }
125 }
126
127 uint8_t weak_mods = get_weak_mods();
128 if (weak_mods != i2c_buffer->weak_mods) {
129 if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_WEAK_MODS_START, (void *)&weak_mods, sizeof(weak_mods), TIMEOUT) >= 0) {
130 i2c_buffer->weak_mods = weak_mods;
131 }
132 }
133
134# ifndef NO_ACTION_ONESHOT
135 uint8_t oneshot_mods = get_oneshot_mods();
136 if (oneshot_mods != i2c_buffer->oneshot_mods) {
137 if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_ONESHOT_MODS_START, (void *)&oneshot_mods, sizeof(oneshot_mods), TIMEOUT) >= 0) {
138 i2c_buffer->oneshot_mods = oneshot_mods;
139 }
140 }
141# endif
142# endif
143
144# ifndef DISABLE_SYNC_TIMER
145 i2c_buffer->sync_timer = sync_timer_read32() + SYNC_TIMER_OFFSET;
146 i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_SYNC_TIME_START, (void *)&i2c_buffer->sync_timer, sizeof(i2c_buffer->sync_timer), TIMEOUT);
147# endif
94 return true; 148 return true;
95} 149}
96 150
97void transport_slave(matrix_row_t matrix[]) { 151void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
152# ifndef DISABLE_SYNC_TIMER
153 sync_timer_update(i2c_buffer->sync_timer);
154# endif
98 // Copy matrix to I2C buffer 155 // Copy matrix to I2C buffer
99 memcpy((void *)i2c_buffer->smatrix, (void *)matrix, sizeof(i2c_buffer->smatrix)); 156 memcpy((void *)i2c_buffer->smatrix, (void *)slave_matrix, sizeof(i2c_buffer->smatrix));
157# ifdef SPLIT_TRANSPORT_MIRROR
158 memcpy((void *)master_matrix, (void *)i2c_buffer->mmatrix, sizeof(i2c_buffer->mmatrix));
159# endif
100 160
101// Read Backlight Info 161// Read Backlight Info
102# ifdef BACKLIGHT_ENABLE 162# ifdef BACKLIGHT_ENABLE
@@ -118,6 +178,14 @@ void transport_slave(matrix_row_t matrix[]) {
118# ifdef WPM_ENABLE 178# ifdef WPM_ENABLE
119 set_current_wpm(i2c_buffer->current_wpm); 179 set_current_wpm(i2c_buffer->current_wpm);
120# endif 180# endif
181
182# ifdef SPLIT_MODS_ENABLE
183 set_mods(i2c_buffer->real_mods);
184 set_weak_mods(i2c_buffer->weak_mods);
185# ifndef NO_ACTION_ONESHOT
186 set_oneshot_mods(i2c_buffer->oneshot_mods);
187# endif
188# endif
121} 189}
122 190
123void transport_master_init(void) { i2c_init(); } 191void transport_master_init(void) { i2c_init(); }
@@ -139,11 +207,24 @@ typedef struct _Serial_s2m_buffer_t {
139} Serial_s2m_buffer_t; 207} Serial_s2m_buffer_t;
140 208
141typedef struct _Serial_m2s_buffer_t { 209typedef struct _Serial_m2s_buffer_t {
210# ifdef SPLIT_MODS_ENABLE
211 uint8_t real_mods;
212 uint8_t weak_mods;
213# ifndef NO_ACTION_ONESHOT
214 uint8_t oneshot_mods;
215# endif
216# endif
217# ifndef DISABLE_SYNC_TIMER
218 uint32_t sync_timer;
219# endif
220# ifdef SPLIT_TRANSPORT_MIRROR
221 matrix_row_t mmatrix[ROWS_PER_HAND];
222# endif
142# ifdef BACKLIGHT_ENABLE 223# ifdef BACKLIGHT_ENABLE
143 uint8_t backlight_level; 224 uint8_t backlight_level;
144# endif 225# endif
145# ifdef WPM_ENABLE 226# ifdef WPM_ENABLE
146 uint8_t current_wpm; 227 uint8_t current_wpm;
147# endif 228# endif
148} Serial_m2s_buffer_t; 229} Serial_m2s_buffer_t;
149 230
@@ -221,7 +302,7 @@ void transport_rgblight_slave(void) {
221# define transport_rgblight_slave() 302# define transport_rgblight_slave()
222# endif 303# endif
223 304
224bool transport_master(matrix_row_t matrix[]) { 305bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
225# ifndef SERIAL_USE_MULTI_TRANSACTION 306# ifndef SERIAL_USE_MULTI_TRANSACTION
226 if (soft_serial_transaction() != TRANSACTION_END) { 307 if (soft_serial_transaction() != TRANSACTION_END) {
227 return false; 308 return false;
@@ -235,7 +316,10 @@ bool transport_master(matrix_row_t matrix[]) {
235 316
236 // TODO: if MATRIX_COLS > 8 change to unpack() 317 // TODO: if MATRIX_COLS > 8 change to unpack()
237 for (int i = 0; i < ROWS_PER_HAND; ++i) { 318 for (int i = 0; i < ROWS_PER_HAND; ++i) {
238 matrix[i] = serial_s2m_buffer.smatrix[i]; 319 slave_matrix[i] = serial_s2m_buffer.smatrix[i];
320# ifdef SPLIT_TRANSPORT_MIRROR
321 serial_m2s_buffer.mmatrix[i] = master_matrix[i];
322# endif
239 } 323 }
240 324
241# ifdef BACKLIGHT_ENABLE 325# ifdef BACKLIGHT_ENABLE
@@ -249,16 +333,34 @@ bool transport_master(matrix_row_t matrix[]) {
249 333
250# ifdef WPM_ENABLE 334# ifdef WPM_ENABLE
251 // Write wpm to slave 335 // Write wpm to slave
252 serial_m2s_buffer.current_wpm = get_current_wpm(); 336 serial_m2s_buffer.current_wpm = get_current_wpm();
337# endif
338
339# ifdef SPLIT_MODS_ENABLE
340 serial_m2s_buffer.real_mods = get_mods();
341 serial_m2s_buffer.weak_mods = get_weak_mods();
342# ifndef NO_ACTION_ONESHOT
343 serial_m2s_buffer.oneshot_mods = get_oneshot_mods();
344# endif
345# endif
346# ifndef DISABLE_SYNC_TIMER
347 serial_m2s_buffer.sync_timer = sync_timer_read32() + SYNC_TIMER_OFFSET;
253# endif 348# endif
254 return true; 349 return true;
255} 350}
256 351
257void transport_slave(matrix_row_t matrix[]) { 352void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
258 transport_rgblight_slave(); 353 transport_rgblight_slave();
354# ifndef DISABLE_SYNC_TIMER
355 sync_timer_update(serial_m2s_buffer.sync_timer);
356# endif
357
259 // TODO: if MATRIX_COLS > 8 change to pack() 358 // TODO: if MATRIX_COLS > 8 change to pack()
260 for (int i = 0; i < ROWS_PER_HAND; ++i) { 359 for (int i = 0; i < ROWS_PER_HAND; ++i) {
261 serial_s2m_buffer.smatrix[i] = matrix[i]; 360 serial_s2m_buffer.smatrix[i] = slave_matrix[i];
361# ifdef SPLIT_TRANSPORT_MIRROR
362 master_matrix[i] = serial_m2s_buffer.mmatrix[i];
363# endif
262 } 364 }
263# ifdef BACKLIGHT_ENABLE 365# ifdef BACKLIGHT_ENABLE
264 backlight_set(serial_m2s_buffer.backlight_level); 366 backlight_set(serial_m2s_buffer.backlight_level);
@@ -271,6 +373,14 @@ void transport_slave(matrix_row_t matrix[]) {
271# ifdef WPM_ENABLE 373# ifdef WPM_ENABLE
272 set_current_wpm(serial_m2s_buffer.current_wpm); 374 set_current_wpm(serial_m2s_buffer.current_wpm);
273# endif 375# endif
376
377# ifdef SPLIT_MODS_ENABLE
378 set_mods(serial_m2s_buffer.real_mods);
379 set_weak_mods(serial_m2s_buffer.weak_mods);
380# ifndef NO_ACTION_ONESHOT
381 set_oneshot_mods(serial_m2s_buffer.oneshot_mods);
382# endif
383# endif
274} 384}
275 385
276#endif 386#endif
diff --git a/quantum/split_common/transport.h b/quantum/split_common/transport.h
index c667bfab8..a9f66301b 100644
--- a/quantum/split_common/transport.h
+++ b/quantum/split_common/transport.h
@@ -6,5 +6,5 @@ void transport_master_init(void);
6void transport_slave_init(void); 6void transport_slave_init(void);
7 7
8// returns false if valid data not received from slave 8// returns false if valid data not received from slave
9bool transport_master(matrix_row_t matrix[]); 9bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]);
10void transport_slave(matrix_row_t matrix[]); 10void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]);