aboutsummaryrefslogtreecommitdiff
path: root/quantum/split_common
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/split_common')
-rw-r--r--quantum/split_common/matrix.c44
-rw-r--r--quantum/split_common/transport.c101
2 files changed, 128 insertions, 17 deletions
diff --git a/quantum/split_common/matrix.c b/quantum/split_common/matrix.c
index 51bf8b109..bad762b49 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,21 +251,33 @@ 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(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();
@@ -268,25 +286,27 @@ void matrix_post_scan(void) {
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..b45ba92c3 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,20 @@ 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
30 matrix_row_t smatrix[ROWS_PER_HAND]; 34 matrix_row_t smatrix[ROWS_PER_HAND];
31 uint8_t backlight_level; 35# ifdef SPLIT_MODS_ENABLE
36 uint8_t real_mods;
37 uint8_t weak_mods;
38# ifndef NO_ACTION_ONESHOT
39 uint8_t oneshot_mods;
40# endif
41# endif
42# ifdef BACKLIGHT_ENABLE
43 uint8_t backlight_level;
44# endif
32# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) 45# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
33 rgblight_syncinfo_t rgblight_sync; 46 rgblight_syncinfo_t rgblight_sync;
34# endif 47# endif
@@ -42,9 +55,13 @@ typedef struct _I2C_slave_buffer_t {
42 55
43static I2C_slave_buffer_t *const i2c_buffer = (I2C_slave_buffer_t *)i2c_slave_reg; 56static I2C_slave_buffer_t *const i2c_buffer = (I2C_slave_buffer_t *)i2c_slave_reg;
44 57
58# define I2C_SYNC_TIME_START offsetof(I2C_slave_buffer_t, sync_timer)
59# define I2C_KEYMAP_START offsetof(I2C_slave_buffer_t, smatrix)
60# define I2C_REAL_MODS_START offsetof(I2C_slave_buffer_t, real_mods)
61# define I2C_WEAK_MODS_START offsetof(I2C_slave_buffer_t, weak_mods)
62# define I2C_ONESHOT_MODS_START offsetof(I2C_slave_buffer_t, oneshot_mods)
45# define I2C_BACKLIGHT_START offsetof(I2C_slave_buffer_t, backlight_level) 63# define I2C_BACKLIGHT_START offsetof(I2C_slave_buffer_t, backlight_level)
46# define I2C_RGB_START offsetof(I2C_slave_buffer_t, rgblight_sync) 64# 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) 65# define I2C_ENCODER_START offsetof(I2C_slave_buffer_t, encoder_state)
49# define I2C_WPM_START offsetof(I2C_slave_buffer_t, current_wpm) 66# define I2C_WPM_START offsetof(I2C_slave_buffer_t, current_wpm)
50 67
@@ -91,10 +108,43 @@ bool transport_master(matrix_row_t matrix[]) {
91 } 108 }
92 } 109 }
93# endif 110# endif
111
112# ifdef SPLIT_MODS_ENABLE
113 uint8_t real_mods = get_mods();
114 if (real_mods != i2c_buffer->real_mods) {
115 if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_REAL_MODS_START, (void *)&real_mods, sizeof(real_mods), TIMEOUT) >= 0) {
116 i2c_buffer->real_mods = real_mods;
117 }
118 }
119
120 uint8_t weak_mods = get_weak_mods();
121 if (weak_mods != i2c_buffer->weak_mods) {
122 if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_WEAK_MODS_START, (void *)&weak_mods, sizeof(weak_mods), TIMEOUT) >= 0) {
123 i2c_buffer->weak_mods = weak_mods;
124 }
125 }
126
127# ifndef NO_ACTION_ONESHOT
128 uint8_t oneshot_mods = get_oneshot_mods();
129 if (oneshot_mods != i2c_buffer->oneshot_mods) {
130 if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_ONESHOT_MODS_START, (void *)&oneshot_mods, sizeof(oneshot_mods), TIMEOUT) >= 0) {
131 i2c_buffer->oneshot_mods = oneshot_mods;
132 }
133 }
134# endif
135# endif
136
137# ifndef DISABLE_SYNC_TIMER
138 i2c_buffer->sync_timer = sync_timer_read32() + SYNC_TIMER_OFFSET;
139 i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_SYNC_TIME_START, (void *)&i2c_buffer->sync_timer, sizeof(i2c_buffer->sync_timer), TIMEOUT);
140# endif
94 return true; 141 return true;
95} 142}
96 143
97void transport_slave(matrix_row_t matrix[]) { 144void transport_slave(matrix_row_t matrix[]) {
145# ifndef DISABLE_SYNC_TIMER
146 sync_timer_update(i2c_buffer->sync_timer);
147# endif
98 // Copy matrix to I2C buffer 148 // Copy matrix to I2C buffer
99 memcpy((void *)i2c_buffer->smatrix, (void *)matrix, sizeof(i2c_buffer->smatrix)); 149 memcpy((void *)i2c_buffer->smatrix, (void *)matrix, sizeof(i2c_buffer->smatrix));
100 150
@@ -118,6 +168,14 @@ void transport_slave(matrix_row_t matrix[]) {
118# ifdef WPM_ENABLE 168# ifdef WPM_ENABLE
119 set_current_wpm(i2c_buffer->current_wpm); 169 set_current_wpm(i2c_buffer->current_wpm);
120# endif 170# endif
171
172# ifdef SPLIT_MODS_ENABLE
173 set_mods(i2c_buffer->real_mods);
174 set_weak_mods(i2c_buffer->weak_mods);
175# ifndef NO_ACTION_ONESHOT
176 set_oneshot_mods(i2c_buffer->oneshot_mods);
177# endif
178# endif
121} 179}
122 180
123void transport_master_init(void) { i2c_init(); } 181void transport_master_init(void) { i2c_init(); }
@@ -139,11 +197,21 @@ typedef struct _Serial_s2m_buffer_t {
139} Serial_s2m_buffer_t; 197} Serial_s2m_buffer_t;
140 198
141typedef struct _Serial_m2s_buffer_t { 199typedef struct _Serial_m2s_buffer_t {
200# ifdef SPLIT_MODS_ENABLE
201 uint8_t real_mods;
202 uint8_t weak_mods;
203# ifndef NO_ACTION_ONESHOT
204 uint8_t oneshot_mods;
205# endif
206# endif
207# ifndef DISABLE_SYNC_TIMER
208 uint32_t sync_timer;
209# endif
142# ifdef BACKLIGHT_ENABLE 210# ifdef BACKLIGHT_ENABLE
143 uint8_t backlight_level; 211 uint8_t backlight_level;
144# endif 212# endif
145# ifdef WPM_ENABLE 213# ifdef WPM_ENABLE
146 uint8_t current_wpm; 214 uint8_t current_wpm;
147# endif 215# endif
148} Serial_m2s_buffer_t; 216} Serial_m2s_buffer_t;
149 217
@@ -249,13 +317,28 @@ bool transport_master(matrix_row_t matrix[]) {
249 317
250# ifdef WPM_ENABLE 318# ifdef WPM_ENABLE
251 // Write wpm to slave 319 // Write wpm to slave
252 serial_m2s_buffer.current_wpm = get_current_wpm(); 320 serial_m2s_buffer.current_wpm = get_current_wpm();
321# endif
322
323# ifdef SPLIT_MODS_ENABLE
324 serial_m2s_buffer.real_mods = get_mods();
325 serial_m2s_buffer.weak_mods = get_weak_mods();
326# ifndef NO_ACTION_ONESHOT
327 serial_m2s_buffer.oneshot_mods = get_oneshot_mods();
328# endif
329# endif
330# ifndef DISABLE_SYNC_TIMER
331 serial_m2s_buffer.sync_timer = sync_timer_read32() + SYNC_TIMER_OFFSET;
253# endif 332# endif
254 return true; 333 return true;
255} 334}
256 335
257void transport_slave(matrix_row_t matrix[]) { 336void transport_slave(matrix_row_t matrix[]) {
258 transport_rgblight_slave(); 337 transport_rgblight_slave();
338# ifndef DISABLE_SYNC_TIMER
339 sync_timer_update(serial_m2s_buffer.sync_timer);
340# endif
341
259 // TODO: if MATRIX_COLS > 8 change to pack() 342 // TODO: if MATRIX_COLS > 8 change to pack()
260 for (int i = 0; i < ROWS_PER_HAND; ++i) { 343 for (int i = 0; i < ROWS_PER_HAND; ++i) {
261 serial_s2m_buffer.smatrix[i] = matrix[i]; 344 serial_s2m_buffer.smatrix[i] = matrix[i];
@@ -271,6 +354,14 @@ void transport_slave(matrix_row_t matrix[]) {
271# ifdef WPM_ENABLE 354# ifdef WPM_ENABLE
272 set_current_wpm(serial_m2s_buffer.current_wpm); 355 set_current_wpm(serial_m2s_buffer.current_wpm);
273# endif 356# endif
357
358# ifdef SPLIT_MODS_ENABLE
359 set_mods(serial_m2s_buffer.real_mods);
360 set_weak_mods(serial_m2s_buffer.weak_mods);
361# ifndef NO_ACTION_ONESHOT
362 set_oneshot_mods(serial_m2s_buffer.oneshot_mods);
363# endif
364# endif
274} 365}
275 366
276#endif 367#endif