aboutsummaryrefslogtreecommitdiff
path: root/quantum/split_common
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/split_common')
-rw-r--r--quantum/split_common/matrix.c332
-rw-r--r--quantum/split_common/post_config.h28
-rw-r--r--quantum/split_common/serial.c742
-rw-r--r--quantum/split_common/serial.h18
-rw-r--r--quantum/split_common/split_util.c86
-rw-r--r--quantum/split_common/split_util.h2
-rw-r--r--quantum/split_common/transport.c272
7 files changed, 716 insertions, 764 deletions
diff --git a/quantum/split_common/matrix.c b/quantum/split_common/matrix.c
index e0f094e34..313f7830b 100644
--- a/quantum/split_common/matrix.c
+++ b/quantum/split_common/matrix.c
@@ -30,24 +30,24 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
30#include "transport.h" 30#include "transport.h"
31 31
32#ifdef ENCODER_ENABLE 32#ifdef ENCODER_ENABLE
33 #include "encoder.h" 33# include "encoder.h"
34#endif 34#endif
35 35
36#if (MATRIX_COLS <= 8) 36#if (MATRIX_COLS <= 8)
37# define print_matrix_header() print("\nr/c 01234567\n") 37# define print_matrix_header() print("\nr/c 01234567\n")
38# define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row)) 38# define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row))
39# define matrix_bitpop(i) bitpop(matrix[i]) 39# define matrix_bitpop(i) bitpop(matrix[i])
40# define ROW_SHIFTER ((uint8_t)1) 40# define ROW_SHIFTER ((uint8_t)1)
41#elif (MATRIX_COLS <= 16) 41#elif (MATRIX_COLS <= 16)
42# define print_matrix_header() print("\nr/c 0123456789ABCDEF\n") 42# define print_matrix_header() print("\nr/c 0123456789ABCDEF\n")
43# define print_matrix_row(row) print_bin_reverse16(matrix_get_row(row)) 43# define print_matrix_row(row) print_bin_reverse16(matrix_get_row(row))
44# define matrix_bitpop(i) bitpop16(matrix[i]) 44# define matrix_bitpop(i) bitpop16(matrix[i])
45# define ROW_SHIFTER ((uint16_t)1) 45# define ROW_SHIFTER ((uint16_t)1)
46#elif (MATRIX_COLS <= 32) 46#elif (MATRIX_COLS <= 32)
47# define print_matrix_header() print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n") 47# define print_matrix_header() print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n")
48# define print_matrix_row(row) print_bin_reverse32(matrix_get_row(row)) 48# define print_matrix_row(row) print_bin_reverse32(matrix_get_row(row))
49# define matrix_bitpop(i) bitpop32(matrix[i]) 49# define matrix_bitpop(i) bitpop32(matrix[i])
50# define ROW_SHIFTER ((uint32_t)1) 50# define ROW_SHIFTER ((uint32_t)1)
51#endif 51#endif
52 52
53#define ERROR_DISCONNECT_COUNT 5 53#define ERROR_DISCONNECT_COUNT 5
@@ -87,8 +87,8 @@ inline uint8_t matrix_rows(void) { return MATRIX_ROWS; }
87inline uint8_t matrix_cols(void) { return MATRIX_COLS; } 87inline uint8_t matrix_cols(void) { return MATRIX_COLS; }
88 88
89bool matrix_is_modified(void) { 89bool matrix_is_modified(void) {
90 if (debounce_active()) return false; 90 if (debounce_active()) return false;
91 return true; 91 return true;
92} 92}
93 93
94inline bool matrix_is_on(uint8_t row, uint8_t col) { return (matrix[row] & ((matrix_row_t)1 << col)); } 94inline bool matrix_is_on(uint8_t row, uint8_t col) { return (matrix[row] & ((matrix_row_t)1 << col)); }
@@ -96,22 +96,22 @@ inline bool matrix_is_on(uint8_t row, uint8_t col) { return (matrix[row] & ((mat
96inline matrix_row_t matrix_get_row(uint8_t row) { return matrix[row]; } 96inline matrix_row_t matrix_get_row(uint8_t row) { return matrix[row]; }
97 97
98void matrix_print(void) { 98void matrix_print(void) {
99 print_matrix_header(); 99 print_matrix_header();
100 100
101 for (uint8_t row = 0; row < MATRIX_ROWS; row++) { 101 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
102 phex(row); 102 phex(row);
103 print(": "); 103 print(": ");
104 print_matrix_row(row); 104 print_matrix_row(row);
105 print("\n"); 105 print("\n");
106 } 106 }
107} 107}
108 108
109uint8_t matrix_key_count(void) { 109uint8_t matrix_key_count(void) {
110 uint8_t count = 0; 110 uint8_t count = 0;
111 for (uint8_t i = 0; i < MATRIX_ROWS; i++) { 111 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
112 count += matrix_bitpop(i); 112 count += matrix_bitpop(i);
113 } 113 }
114 return count; 114 return count;
115} 115}
116 116
117// matrix code 117// matrix code
@@ -119,224 +119,224 @@ uint8_t matrix_key_count(void) {
119#ifdef DIRECT_PINS 119#ifdef DIRECT_PINS
120 120
121static void init_pins(void) { 121static void init_pins(void) {
122 for (int row = 0; row < MATRIX_ROWS; row++) { 122 for (int row = 0; row < MATRIX_ROWS; row++) {
123 for (int col = 0; col < MATRIX_COLS; col++) { 123 for (int col = 0; col < MATRIX_COLS; col++) {
124 pin_t pin = direct_pins[row][col]; 124 pin_t pin = direct_pins[row][col];
125 if (pin != NO_PIN) { 125 if (pin != NO_PIN) {
126 setPinInputHigh(pin); 126 setPinInputHigh(pin);
127 } 127 }
128 }
128 } 129 }
129 }
130} 130}
131 131
132static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) { 132static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) {
133 matrix_row_t last_row_value = current_matrix[current_row]; 133 matrix_row_t last_row_value = current_matrix[current_row];
134 current_matrix[current_row] = 0; 134 current_matrix[current_row] = 0;
135 135
136 for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) { 136 for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
137 pin_t pin = direct_pins[current_row][col_index]; 137 pin_t pin = direct_pins[current_row][col_index];
138 if (pin != NO_PIN) { 138 if (pin != NO_PIN) {
139 current_matrix[current_row] |= readPin(pin) ? 0 : (ROW_SHIFTER << col_index); 139 current_matrix[current_row] |= readPin(pin) ? 0 : (ROW_SHIFTER << col_index);
140 }
140 } 141 }
141 }
142 142
143 return (last_row_value != current_matrix[current_row]); 143 return (last_row_value != current_matrix[current_row]);
144} 144}
145 145
146#elif (DIODE_DIRECTION == COL2ROW) 146#elif (DIODE_DIRECTION == COL2ROW)
147 147
148static void select_row(uint8_t row) { 148static void select_row(uint8_t row) {
149 setPinOutput(row_pins[row]); 149 setPinOutput(row_pins[row]);
150 writePinLow(row_pins[row]); 150 writePinLow(row_pins[row]);
151} 151}
152 152
153static void unselect_row(uint8_t row) { setPinInputHigh(row_pins[row]); } 153static void unselect_row(uint8_t row) { setPinInputHigh(row_pins[row]); }
154 154
155static void unselect_rows(void) { 155static void unselect_rows(void) {
156 for (uint8_t x = 0; x < ROWS_PER_HAND; x++) { 156 for (uint8_t x = 0; x < ROWS_PER_HAND; x++) {
157 setPinInputHigh(row_pins[x]); 157 setPinInputHigh(row_pins[x]);
158 } 158 }
159} 159}
160 160
161static void init_pins(void) { 161static void init_pins(void) {
162 unselect_rows(); 162 unselect_rows();
163 for (uint8_t x = 0; x < MATRIX_COLS; x++) { 163 for (uint8_t x = 0; x < MATRIX_COLS; x++) {
164 setPinInputHigh(col_pins[x]); 164 setPinInputHigh(col_pins[x]);
165 } 165 }
166} 166}
167 167
168static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) { 168static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) {
169 // Store last value of row prior to reading 169 // Store last value of row prior to reading
170 matrix_row_t last_row_value = current_matrix[current_row]; 170 matrix_row_t last_row_value = current_matrix[current_row];
171 171
172 // Clear data in matrix row 172 // Clear data in matrix row
173 current_matrix[current_row] = 0; 173 current_matrix[current_row] = 0;
174 174
175 // Select row and wait for row selecton to stabilize 175 // Select row and wait for row selecton to stabilize
176 select_row(current_row); 176 select_row(current_row);
177 wait_us(30); 177 wait_us(30);
178 178
179 // For each col... 179 // For each col...
180 for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) { 180 for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
181 // Populate the matrix row with the state of the col pin 181 // Populate the matrix row with the state of the col pin
182 current_matrix[current_row] |= readPin(col_pins[col_index]) ? 0 : (ROW_SHIFTER << col_index); 182 current_matrix[current_row] |= readPin(col_pins[col_index]) ? 0 : (ROW_SHIFTER << col_index);
183 } 183 }
184 184
185 // Unselect row 185 // Unselect row
186 unselect_row(current_row); 186 unselect_row(current_row);
187 187
188 return (last_row_value != current_matrix[current_row]); 188 return (last_row_value != current_matrix[current_row]);
189} 189}
190 190
191#elif (DIODE_DIRECTION == ROW2COL) 191#elif (DIODE_DIRECTION == ROW2COL)
192 192
193static void select_col(uint8_t col) { 193static void select_col(uint8_t col) {
194 setPinOutput(col_pins[col]); 194 setPinOutput(col_pins[col]);
195 writePinLow(col_pins[col]); 195 writePinLow(col_pins[col]);
196} 196}
197 197
198static void unselect_col(uint8_t col) { setPinInputHigh(col_pins[col]); } 198static void unselect_col(uint8_t col) { setPinInputHigh(col_pins[col]); }
199 199
200static void unselect_cols(void) { 200static void unselect_cols(void) {
201 for (uint8_t x = 0; x < MATRIX_COLS; x++) { 201 for (uint8_t x = 0; x < MATRIX_COLS; x++) {
202 setPinInputHigh(col_pins[x]); 202 setPinInputHigh(col_pins[x]);
203 } 203 }
204} 204}
205 205
206static void init_pins(void) { 206static void init_pins(void) {
207 unselect_cols(); 207 unselect_cols();
208 for (uint8_t x = 0; x < ROWS_PER_HAND; x++) { 208 for (uint8_t x = 0; x < ROWS_PER_HAND; x++) {
209 setPinInputHigh(row_pins[x]); 209 setPinInputHigh(row_pins[x]);
210 } 210 }
211} 211}
212 212
213static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) { 213static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) {
214 bool matrix_changed = false; 214 bool matrix_changed = false;
215 215
216 // Select col and wait for col selecton to stabilize 216 // Select col and wait for col selecton to stabilize
217 select_col(current_col); 217 select_col(current_col);
218 wait_us(30); 218 wait_us(30);
219 219
220 // For each row... 220 // For each row...
221 for (uint8_t row_index = 0; row_index < ROWS_PER_HAND; row_index++) { 221 for (uint8_t row_index = 0; row_index < ROWS_PER_HAND; row_index++) {
222 // Store last value of row prior to reading 222 // Store last value of row prior to reading
223 matrix_row_t last_row_value = current_matrix[row_index]; 223 matrix_row_t last_row_value = current_matrix[row_index];
224 224
225 // Check row pin state 225 // Check row pin state
226 if (readPin(row_pins[row_index])) { 226 if (readPin(row_pins[row_index])) {
227 // Pin HI, clear col bit 227 // Pin HI, clear col bit
228 current_matrix[row_index] &= ~(ROW_SHIFTER << current_col); 228 current_matrix[row_index] &= ~(ROW_SHIFTER << current_col);
229 } else { 229 } else {
230 // Pin LO, set col bit 230 // Pin LO, set col bit
231 current_matrix[row_index] |= (ROW_SHIFTER << current_col); 231 current_matrix[row_index] |= (ROW_SHIFTER << current_col);
232 } 232 }
233 233
234 // Determine if the matrix changed state 234 // Determine if the matrix changed state
235 if ((last_row_value != current_matrix[row_index]) && !(matrix_changed)) { 235 if ((last_row_value != current_matrix[row_index]) && !(matrix_changed)) {
236 matrix_changed = true; 236 matrix_changed = true;
237 }
237 } 238 }
238 }
239 239
240 // Unselect col 240 // Unselect col
241 unselect_col(current_col); 241 unselect_col(current_col);
242 242
243 return matrix_changed; 243 return matrix_changed;
244} 244}
245 245
246#endif 246#endif
247 247
248void matrix_init(void) { 248void matrix_init(void) {
249 debug_enable = true; 249 debug_enable = true;
250 debug_matrix = true; 250 debug_matrix = true;
251 debug_mouse = true; 251 debug_mouse = true;
252 252
253 // Set pinout for right half if pinout for that half is defined 253 // Set pinout for right half if pinout for that half is defined
254 if (!isLeftHand) { 254 if (!isLeftHand) {
255#ifdef DIRECT_PINS_RIGHT 255#ifdef DIRECT_PINS_RIGHT
256 const pin_t direct_pins_right[MATRIX_ROWS][MATRIX_COLS] = DIRECT_PINS_RIGHT; 256 const pin_t direct_pins_right[MATRIX_ROWS][MATRIX_COLS] = DIRECT_PINS_RIGHT;
257 for (uint8_t i = 0; i < MATRIX_ROWS; i++) { 257 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
258 for (uint8_t j = 0; j < MATRIX_COLS; j++) { 258 for (uint8_t j = 0; j < MATRIX_COLS; j++) {
259 direct_pins[i][j] = direct_pins_right[i][j]; 259 direct_pins[i][j] = direct_pins_right[i][j];
260 } 260 }
261 } 261 }
262#endif 262#endif
263#ifdef MATRIX_ROW_PINS_RIGHT 263#ifdef MATRIX_ROW_PINS_RIGHT
264 const pin_t row_pins_right[MATRIX_ROWS] = MATRIX_ROW_PINS_RIGHT; 264 const pin_t row_pins_right[MATRIX_ROWS] = MATRIX_ROW_PINS_RIGHT;
265 for (uint8_t i = 0; i < MATRIX_ROWS; i++) { 265 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
266 row_pins[i] = row_pins_right[i]; 266 row_pins[i] = row_pins_right[i];
267 } 267 }
268#endif 268#endif
269#ifdef MATRIX_COL_PINS_RIGHT 269#ifdef MATRIX_COL_PINS_RIGHT
270 const pin_t col_pins_right[MATRIX_COLS] = MATRIX_COL_PINS_RIGHT; 270 const pin_t col_pins_right[MATRIX_COLS] = MATRIX_COL_PINS_RIGHT;
271 for (uint8_t i = 0; i < MATRIX_COLS; i++) { 271 for (uint8_t i = 0; i < MATRIX_COLS; i++) {
272 col_pins[i] = col_pins_right[i]; 272 col_pins[i] = col_pins_right[i];
273 } 273 }
274#endif 274#endif
275 } 275 }
276 276
277 thisHand = isLeftHand ? 0 : (ROWS_PER_HAND); 277 thisHand = isLeftHand ? 0 : (ROWS_PER_HAND);
278 thatHand = ROWS_PER_HAND - thisHand; 278 thatHand = ROWS_PER_HAND - thisHand;
279 279
280 // initialize key pins 280 // initialize key pins
281 init_pins(); 281 init_pins();
282 282
283 // initialize matrix state: all keys off 283 // initialize matrix state: all keys off
284 for (uint8_t i = 0; i < MATRIX_ROWS; i++) { 284 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
285 matrix[i] = 0; 285 matrix[i] = 0;
286 } 286 }
287 287
288 debounce_init(ROWS_PER_HAND); 288 debounce_init(ROWS_PER_HAND);
289 289
290 matrix_init_quantum(); 290 matrix_init_quantum();
291} 291}
292 292
293uint8_t _matrix_scan(void) { 293uint8_t _matrix_scan(void) {
294 bool changed = false; 294 bool changed = false;
295 295
296#if defined(DIRECT_PINS) || (DIODE_DIRECTION == COL2ROW) 296#if defined(DIRECT_PINS) || (DIODE_DIRECTION == COL2ROW)
297 // Set row, read cols 297 // Set row, read cols
298 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++) {
299 changed |= read_cols_on_row(raw_matrix, current_row); 299 changed |= read_cols_on_row(raw_matrix, current_row);
300 } 300 }
301#elif (DIODE_DIRECTION == ROW2COL) 301#elif (DIODE_DIRECTION == ROW2COL)
302 // Set col, read rows 302 // Set col, read rows
303 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++) {
304 changed |= read_rows_on_col(raw_matrix, current_col); 304 changed |= read_rows_on_col(raw_matrix, current_col);
305 } 305 }
306#endif 306#endif
307 307
308 debounce(raw_matrix, matrix + thisHand, ROWS_PER_HAND, changed); 308 debounce(raw_matrix, matrix + thisHand, ROWS_PER_HAND, changed);
309 309
310 return (uint8_t)changed; 310 return (uint8_t)changed;
311} 311}
312 312
313uint8_t matrix_scan(void) { 313uint8_t matrix_scan(void) {
314 uint8_t ret = _matrix_scan(); 314 uint8_t ret = _matrix_scan();
315 315
316 if (is_keyboard_master()) { 316 if (is_keyboard_master()) {
317 static uint8_t error_count; 317 static uint8_t error_count;
318 318
319 if (!transport_master(matrix + thatHand)) { 319 if (!transport_master(matrix + thatHand)) {
320 error_count++; 320 error_count++;
321 321
322 if (error_count > ERROR_DISCONNECT_COUNT) { 322 if (error_count > ERROR_DISCONNECT_COUNT) {
323 // reset other half if disconnected 323 // reset other half if disconnected
324 for (int i = 0; i < ROWS_PER_HAND; ++i) { 324 for (int i = 0; i < ROWS_PER_HAND; ++i) {
325 matrix[thatHand + i] = 0; 325 matrix[thatHand + i] = 0;
326 }
327 }
328 } else {
329 error_count = 0;
326 } 330 }
327 }
328 } else {
329 error_count = 0;
330 }
331 331
332 matrix_scan_quantum(); 332 matrix_scan_quantum();
333 } else { 333 } else {
334 transport_slave(matrix + thisHand); 334 transport_slave(matrix + thisHand);
335#ifdef ENCODER_ENABLE 335#ifdef ENCODER_ENABLE
336 encoder_read(); 336 encoder_read();
337#endif 337#endif
338 matrix_slave_scan_user(); 338 matrix_slave_scan_user();
339 } 339 }
340 340
341 return ret; 341 return ret;
342} 342}
diff --git a/quantum/split_common/post_config.h b/quantum/split_common/post_config.h
index ff0fc5e19..5c0b414fb 100644
--- a/quantum/split_common/post_config.h
+++ b/quantum/split_common/post_config.h
@@ -1,19 +1,19 @@
1#if defined(USE_I2C) || defined(EH) 1#if defined(USE_I2C) || defined(EH)
2 // When using I2C, using rgblight implicitly involves split support. 2// When using I2C, using rgblight implicitly involves split support.
3 #if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_SPLIT) 3# if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_SPLIT)
4 #define RGBLIGHT_SPLIT 4# define RGBLIGHT_SPLIT
5 #endif 5# endif
6 6
7 #ifndef F_SCL 7# ifndef F_SCL
8 #define F_SCL 100000UL // SCL frequency 8# define F_SCL 100000UL // SCL frequency
9 #endif 9# endif
10 10
11#else // use serial 11#else // use serial
12 // When using serial, the user must define RGBLIGHT_SPLIT explicitly 12// When using serial, the user must define RGBLIGHT_SPLIT explicitly
13 // in config.h as needed. 13// in config.h as needed.
14 // see quantum/rgblight_post_config.h 14// see quantum/rgblight_post_config.h
15 #if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) 15# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
16 // When using serial and RGBLIGHT_SPLIT need separate transaction 16// When using serial and RGBLIGHT_SPLIT need separate transaction
17 #define SERIAL_USE_MULTI_TRANSACTION 17# define SERIAL_USE_MULTI_TRANSACTION
18 #endif 18# endif
19#endif 19#endif
diff --git a/quantum/split_common/serial.c b/quantum/split_common/serial.c
index 322ab8030..c4ef2a97e 100644
--- a/quantum/split_common/serial.c
+++ b/quantum/split_common/serial.c
@@ -8,7 +8,7 @@
8 */ 8 */
9 9
10#ifndef F_CPU 10#ifndef F_CPU
11#define F_CPU 16000000 11# define F_CPU 16000000
12#endif 12#endif
13 13
14#include <avr/io.h> 14#include <avr/io.h>
@@ -21,252 +21,224 @@
21 21
22#ifdef SOFT_SERIAL_PIN 22#ifdef SOFT_SERIAL_PIN
23 23
24#ifdef __AVR_ATmega32U4__ 24# ifdef __AVR_ATmega32U4__
25 // if using ATmega32U4 I2C, can not use PD0 and PD1 in soft serial. 25// if using ATmega32U4 I2C, can not use PD0 and PD1 in soft serial.
26 #ifdef USE_AVR_I2C 26# ifdef USE_AVR_I2C
27 #if SOFT_SERIAL_PIN == D0 || SOFT_SERIAL_PIN == D1 27# if SOFT_SERIAL_PIN == D0 || SOFT_SERIAL_PIN == D1
28 #error Using ATmega32U4 I2C, so can not use PD0, PD1 28# error Using ATmega32U4 I2C, so can not use PD0, PD1
29 #endif 29# endif
30 #endif 30# endif
31 31
32 #define setPinInputHigh(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin) & 0xF), \ 32# define setPinInputHigh(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin)&0xF), PORTx_ADDRESS(pin) |= _BV((pin)&0xF))
33 PORTx_ADDRESS(pin) |= _BV((pin) & 0xF)) 33# define setPinOutput(pin) (DDRx_ADDRESS(pin) |= _BV((pin)&0xF))
34 #define setPinOutput(pin) (DDRx_ADDRESS(pin) |= _BV((pin) & 0xF)) 34# define writePinHigh(pin) (PORTx_ADDRESS(pin) |= _BV((pin)&0xF))
35 #define writePinHigh(pin) (PORTx_ADDRESS(pin) |= _BV((pin) & 0xF)) 35# define writePinLow(pin) (PORTx_ADDRESS(pin) &= ~_BV((pin)&0xF))
36 #define writePinLow(pin) (PORTx_ADDRESS(pin) &= ~_BV((pin) & 0xF)) 36# define readPin(pin) ((bool)(PINx_ADDRESS(pin) & _BV((pin)&0xF)))
37 #define readPin(pin) ((bool)(PINx_ADDRESS(pin) & _BV((pin) & 0xF))) 37
38 38# if SOFT_SERIAL_PIN >= D0 && SOFT_SERIAL_PIN <= D3
39 #if SOFT_SERIAL_PIN >= D0 && SOFT_SERIAL_PIN <= D3 39# if SOFT_SERIAL_PIN == D0
40 #if SOFT_SERIAL_PIN == D0 40# define EIMSK_BIT _BV(INT0)
41 #define EIMSK_BIT _BV(INT0) 41# define EICRx_BIT (~(_BV(ISC00) | _BV(ISC01)))
42 #define EICRx_BIT (~(_BV(ISC00) | _BV(ISC01))) 42# define SERIAL_PIN_INTERRUPT INT0_vect
43 #define SERIAL_PIN_INTERRUPT INT0_vect 43# elif SOFT_SERIAL_PIN == D1
44 #elif SOFT_SERIAL_PIN == D1 44# define EIMSK_BIT _BV(INT1)
45 #define EIMSK_BIT _BV(INT1) 45# define EICRx_BIT (~(_BV(ISC10) | _BV(ISC11)))
46 #define EICRx_BIT (~(_BV(ISC10) | _BV(ISC11))) 46# define SERIAL_PIN_INTERRUPT INT1_vect
47 #define SERIAL_PIN_INTERRUPT INT1_vect 47# elif SOFT_SERIAL_PIN == D2
48 #elif SOFT_SERIAL_PIN == D2 48# define EIMSK_BIT _BV(INT2)
49 #define EIMSK_BIT _BV(INT2) 49# define EICRx_BIT (~(_BV(ISC20) | _BV(ISC21)))
50 #define EICRx_BIT (~(_BV(ISC20) | _BV(ISC21))) 50# define SERIAL_PIN_INTERRUPT INT2_vect
51 #define SERIAL_PIN_INTERRUPT INT2_vect 51# elif SOFT_SERIAL_PIN == D3
52 #elif SOFT_SERIAL_PIN == D3 52# define EIMSK_BIT _BV(INT3)
53 #define EIMSK_BIT _BV(INT3) 53# define EICRx_BIT (~(_BV(ISC30) | _BV(ISC31)))
54 #define EICRx_BIT (~(_BV(ISC30) | _BV(ISC31))) 54# define SERIAL_PIN_INTERRUPT INT3_vect
55 #define SERIAL_PIN_INTERRUPT INT3_vect 55# endif
56 #endif 56# elif SOFT_SERIAL_PIN == E6
57 #elif SOFT_SERIAL_PIN == E6 57# define EIMSK_BIT _BV(INT6)
58 #define EIMSK_BIT _BV(INT6) 58# define EICRx_BIT (~(_BV(ISC60) | _BV(ISC61)))
59 #define EICRx_BIT (~(_BV(ISC60) | _BV(ISC61))) 59# define SERIAL_PIN_INTERRUPT INT6_vect
60 #define SERIAL_PIN_INTERRUPT INT6_vect 60# else
61 #else 61# error invalid SOFT_SERIAL_PIN value
62 #error invalid SOFT_SERIAL_PIN value 62# endif
63 #endif 63
64 64# else
65#else 65# error serial.c now support ATmega32U4 only
66 #error serial.c now support ATmega32U4 only 66# endif
67#endif 67
68 68# define ALWAYS_INLINE __attribute__((always_inline))
69#define ALWAYS_INLINE __attribute__((always_inline)) 69# define NO_INLINE __attribute__((noinline))
70#define NO_INLINE __attribute__((noinline)) 70# define _delay_sub_us(x) __builtin_avr_delay_cycles(x)
71#define _delay_sub_us(x) __builtin_avr_delay_cycles(x)
72 71
73// parity check 72// parity check
74#define ODD_PARITY 1 73# define ODD_PARITY 1
75#define EVEN_PARITY 0 74# define EVEN_PARITY 0
76#define PARITY EVEN_PARITY 75# define PARITY EVEN_PARITY
77 76
78#ifdef SERIAL_DELAY 77# ifdef SERIAL_DELAY
79 // custom setup in config.h 78// custom setup in config.h
80 // #define TID_SEND_ADJUST 2 79// #define TID_SEND_ADJUST 2
81 // #define SERIAL_DELAY 6 // micro sec 80// #define SERIAL_DELAY 6 // micro sec
82 // #define READ_WRITE_START_ADJUST 30 // cycles 81// #define READ_WRITE_START_ADJUST 30 // cycles
83 // #define READ_WRITE_WIDTH_ADJUST 8 // cycles 82// #define READ_WRITE_WIDTH_ADJUST 8 // cycles
84#else 83# else
85// ============ Standard setups ============ 84// ============ Standard setups ============
86 85
87#ifndef SELECT_SOFT_SERIAL_SPEED 86# ifndef SELECT_SOFT_SERIAL_SPEED
88#define SELECT_SOFT_SERIAL_SPEED 1 87# define SELECT_SOFT_SERIAL_SPEED 1
89// 0: about 189kbps (Experimental only) 88// 0: about 189kbps (Experimental only)
90// 1: about 137kbps (default) 89// 1: about 137kbps (default)
91// 2: about 75kbps 90// 2: about 75kbps
92// 3: about 39kbps 91// 3: about 39kbps
93// 4: about 26kbps 92// 4: about 26kbps
94// 5: about 20kbps 93// 5: about 20kbps
95#endif 94# endif
96 95
97#if __GNUC__ < 6 96# if __GNUC__ < 6
98 #define TID_SEND_ADJUST 14 97# define TID_SEND_ADJUST 14
99#else 98# else
100 #define TID_SEND_ADJUST 2 99# define TID_SEND_ADJUST 2
101#endif 100# endif
102 101
103#if SELECT_SOFT_SERIAL_SPEED == 0 102# if SELECT_SOFT_SERIAL_SPEED == 0
104 // Very High speed 103// Very High speed
105 #define SERIAL_DELAY 4 // micro sec 104# define SERIAL_DELAY 4 // micro sec
106 #if __GNUC__ < 6 105# if __GNUC__ < 6
107 #define READ_WRITE_START_ADJUST 33 // cycles 106# define READ_WRITE_START_ADJUST 33 // cycles
108 #define READ_WRITE_WIDTH_ADJUST 3 // cycles 107# define READ_WRITE_WIDTH_ADJUST 3 // cycles
109 #else 108# else
110 #define READ_WRITE_START_ADJUST 34 // cycles 109# define READ_WRITE_START_ADJUST 34 // cycles
111 #define READ_WRITE_WIDTH_ADJUST 7 // cycles 110# define READ_WRITE_WIDTH_ADJUST 7 // cycles
112 #endif 111# endif
113#elif SELECT_SOFT_SERIAL_SPEED == 1 112# elif SELECT_SOFT_SERIAL_SPEED == 1
114 // High speed 113// High speed
115 #define SERIAL_DELAY 6 // micro sec 114# define SERIAL_DELAY 6 // micro sec
116 #if __GNUC__ < 6 115# if __GNUC__ < 6
117 #define READ_WRITE_START_ADJUST 30 // cycles 116# define READ_WRITE_START_ADJUST 30 // cycles
118 #define READ_WRITE_WIDTH_ADJUST 3 // cycles 117# define READ_WRITE_WIDTH_ADJUST 3 // cycles
119 #else 118# else
120 #define READ_WRITE_START_ADJUST 33 // cycles 119# define READ_WRITE_START_ADJUST 33 // cycles
121 #define READ_WRITE_WIDTH_ADJUST 7 // cycles 120# define READ_WRITE_WIDTH_ADJUST 7 // cycles
122 #endif 121# endif
123#elif SELECT_SOFT_SERIAL_SPEED == 2 122# elif SELECT_SOFT_SERIAL_SPEED == 2
124 // Middle speed 123// Middle speed
125 #define SERIAL_DELAY 12 // micro sec 124# define SERIAL_DELAY 12 // micro sec
126 #define READ_WRITE_START_ADJUST 30 // cycles 125# define READ_WRITE_START_ADJUST 30 // cycles
127 #if __GNUC__ < 6 126# if __GNUC__ < 6
128 #define READ_WRITE_WIDTH_ADJUST 3 // cycles 127# define READ_WRITE_WIDTH_ADJUST 3 // cycles
129 #else 128# else
130 #define READ_WRITE_WIDTH_ADJUST 7 // cycles 129# define READ_WRITE_WIDTH_ADJUST 7 // cycles
131 #endif 130# endif
132#elif SELECT_SOFT_SERIAL_SPEED == 3 131# elif SELECT_SOFT_SERIAL_SPEED == 3
133 // Low speed 132// Low speed
134 #define SERIAL_DELAY 24 // micro sec 133# define SERIAL_DELAY 24 // micro sec
135 #define READ_WRITE_START_ADJUST 30 // cycles 134# define READ_WRITE_START_ADJUST 30 // cycles
136 #if __GNUC__ < 6 135# if __GNUC__ < 6
137 #define READ_WRITE_WIDTH_ADJUST 3 // cycles 136# define READ_WRITE_WIDTH_ADJUST 3 // cycles
138 #else 137# else
139 #define READ_WRITE_WIDTH_ADJUST 7 // cycles 138# define READ_WRITE_WIDTH_ADJUST 7 // cycles
140 #endif 139# endif
141#elif SELECT_SOFT_SERIAL_SPEED == 4 140# elif SELECT_SOFT_SERIAL_SPEED == 4
142 // Very Low speed 141// Very Low speed
143 #define SERIAL_DELAY 36 // micro sec 142# define SERIAL_DELAY 36 // micro sec
144 #define READ_WRITE_START_ADJUST 30 // cycles 143# define READ_WRITE_START_ADJUST 30 // cycles
145 #if __GNUC__ < 6 144# if __GNUC__ < 6
146 #define READ_WRITE_WIDTH_ADJUST 3 // cycles 145# define READ_WRITE_WIDTH_ADJUST 3 // cycles
147 #else 146# else
148 #define READ_WRITE_WIDTH_ADJUST 7 // cycles 147# define READ_WRITE_WIDTH_ADJUST 7 // cycles
149 #endif 148# endif
150#elif SELECT_SOFT_SERIAL_SPEED == 5 149# elif SELECT_SOFT_SERIAL_SPEED == 5
151 // Ultra Low speed 150// Ultra Low speed
152 #define SERIAL_DELAY 48 // micro sec 151# define SERIAL_DELAY 48 // micro sec
153 #define READ_WRITE_START_ADJUST 30 // cycles 152# define READ_WRITE_START_ADJUST 30 // cycles
154 #if __GNUC__ < 6 153# if __GNUC__ < 6
155 #define READ_WRITE_WIDTH_ADJUST 3 // cycles 154# define READ_WRITE_WIDTH_ADJUST 3 // cycles
156 #else 155# else
157 #define READ_WRITE_WIDTH_ADJUST 7 // cycles 156# define READ_WRITE_WIDTH_ADJUST 7 // cycles
158 #endif 157# endif
159#else 158# else
160#error invalid SELECT_SOFT_SERIAL_SPEED value 159# error invalid SELECT_SOFT_SERIAL_SPEED value
161#endif /* SELECT_SOFT_SERIAL_SPEED */ 160# endif /* SELECT_SOFT_SERIAL_SPEED */
162#endif /* SERIAL_DELAY */ 161# endif /* SERIAL_DELAY */
163 162
164#define SERIAL_DELAY_HALF1 (SERIAL_DELAY/2) 163# define SERIAL_DELAY_HALF1 (SERIAL_DELAY / 2)
165#define SERIAL_DELAY_HALF2 (SERIAL_DELAY - SERIAL_DELAY/2) 164# define SERIAL_DELAY_HALF2 (SERIAL_DELAY - SERIAL_DELAY / 2)
166 165
167#define SLAVE_INT_WIDTH_US 1 166# define SLAVE_INT_WIDTH_US 1
168#ifndef SERIAL_USE_MULTI_TRANSACTION 167# ifndef SERIAL_USE_MULTI_TRANSACTION
169 #define SLAVE_INT_RESPONSE_TIME SERIAL_DELAY 168# define SLAVE_INT_RESPONSE_TIME SERIAL_DELAY
170#else 169# else
171 #define SLAVE_INT_ACK_WIDTH_UNIT 2 170# define SLAVE_INT_ACK_WIDTH_UNIT 2
172 #define SLAVE_INT_ACK_WIDTH 4 171# define SLAVE_INT_ACK_WIDTH 4
173#endif 172# endif
174 173
175static SSTD_t *Transaction_table = NULL; 174static SSTD_t *Transaction_table = NULL;
176static uint8_t Transaction_table_size = 0; 175static uint8_t Transaction_table_size = 0;
177 176
178inline static void serial_delay(void) ALWAYS_INLINE; 177inline static void serial_delay(void) ALWAYS_INLINE;
179inline static 178inline static void serial_delay(void) { _delay_us(SERIAL_DELAY); }
180void serial_delay(void) {
181 _delay_us(SERIAL_DELAY);
182}
183 179
184inline static void serial_delay_half1(void) ALWAYS_INLINE; 180inline static void serial_delay_half1(void) ALWAYS_INLINE;
185inline static 181inline static void serial_delay_half1(void) { _delay_us(SERIAL_DELAY_HALF1); }
186void serial_delay_half1(void) {
187 _delay_us(SERIAL_DELAY_HALF1);
188}
189 182
190inline static void serial_delay_half2(void) ALWAYS_INLINE; 183inline static void serial_delay_half2(void) ALWAYS_INLINE;
191inline static 184inline static void serial_delay_half2(void) { _delay_us(SERIAL_DELAY_HALF2); }
192void serial_delay_half2(void) {
193 _delay_us(SERIAL_DELAY_HALF2);
194}
195 185
196inline static void serial_output(void) ALWAYS_INLINE; 186inline static void serial_output(void) ALWAYS_INLINE;
197inline static 187inline static void serial_output(void) { setPinOutput(SOFT_SERIAL_PIN); }
198void serial_output(void) {
199 setPinOutput(SOFT_SERIAL_PIN);
200}
201 188
202// make the serial pin an input with pull-up resistor 189// make the serial pin an input with pull-up resistor
203inline static void serial_input_with_pullup(void) ALWAYS_INLINE; 190inline static void serial_input_with_pullup(void) ALWAYS_INLINE;
204inline static 191inline static void serial_input_with_pullup(void) { setPinInputHigh(SOFT_SERIAL_PIN); }
205void serial_input_with_pullup(void) {
206 setPinInputHigh(SOFT_SERIAL_PIN);
207}
208 192
209inline static uint8_t serial_read_pin(void) ALWAYS_INLINE; 193inline static uint8_t serial_read_pin(void) ALWAYS_INLINE;
210inline static 194inline static uint8_t serial_read_pin(void) { return !!readPin(SOFT_SERIAL_PIN); }
211uint8_t serial_read_pin(void) {
212 return !! readPin(SOFT_SERIAL_PIN);
213}
214 195
215inline static void serial_low(void) ALWAYS_INLINE; 196inline static void serial_low(void) ALWAYS_INLINE;
216inline static 197inline static void serial_low(void) { writePinLow(SOFT_SERIAL_PIN); }
217void serial_low(void) {
218 writePinLow(SOFT_SERIAL_PIN);
219}
220 198
221inline static void serial_high(void) ALWAYS_INLINE; 199inline static void serial_high(void) ALWAYS_INLINE;
222inline static 200inline static void serial_high(void) { writePinHigh(SOFT_SERIAL_PIN); }
223void serial_high(void) {
224 writePinHigh(SOFT_SERIAL_PIN);
225}
226 201
227void soft_serial_initiator_init(SSTD_t *sstd_table, int sstd_table_size) 202void soft_serial_initiator_init(SSTD_t *sstd_table, int sstd_table_size) {
228{ 203 Transaction_table = sstd_table;
229 Transaction_table = sstd_table;
230 Transaction_table_size = (uint8_t)sstd_table_size; 204 Transaction_table_size = (uint8_t)sstd_table_size;
231 serial_output(); 205 serial_output();
232 serial_high(); 206 serial_high();
233} 207}
234 208
235void soft_serial_target_init(SSTD_t *sstd_table, int sstd_table_size) 209void soft_serial_target_init(SSTD_t *sstd_table, int sstd_table_size) {
236{ 210 Transaction_table = sstd_table;
237 Transaction_table = sstd_table;
238 Transaction_table_size = (uint8_t)sstd_table_size; 211 Transaction_table_size = (uint8_t)sstd_table_size;
239 serial_input_with_pullup(); 212 serial_input_with_pullup();
240 213
241 // Enable INT0-INT3,INT6 214 // Enable INT0-INT3,INT6
242 EIMSK |= EIMSK_BIT; 215 EIMSK |= EIMSK_BIT;
243#if SOFT_SERIAL_PIN == E6 216# if SOFT_SERIAL_PIN == E6
244 // Trigger on falling edge of INT6 217 // Trigger on falling edge of INT6
245 EICRB &= EICRx_BIT; 218 EICRB &= EICRx_BIT;
246#else 219# else
247 // Trigger on falling edge of INT0-INT3 220 // Trigger on falling edge of INT0-INT3
248 EICRA &= EICRx_BIT; 221 EICRA &= EICRx_BIT;
249#endif 222# endif
250} 223}
251 224
252// Used by the sender to synchronize timing with the reciver. 225// Used by the sender to synchronize timing with the reciver.
253static void sync_recv(void) NO_INLINE; 226static void sync_recv(void) NO_INLINE;
254static 227static void sync_recv(void) {
255void sync_recv(void) { 228 for (uint8_t i = 0; i < SERIAL_DELAY * 5 && serial_read_pin(); i++) {
256 for (uint8_t i = 0; i < SERIAL_DELAY*5 && serial_read_pin(); i++ ) { 229 }
257 } 230 // This shouldn't hang if the target disconnects because the
258 // This shouldn't hang if the target disconnects because the 231 // serial line will float to high if the target does disconnect.
259 // serial line will float to high if the target does disconnect. 232 while (!serial_read_pin())
260 while (!serial_read_pin()); 233 ;
261} 234}
262 235
263// Used by the reciver to send a synchronization signal to the sender. 236// Used by the reciver to send a synchronization signal to the sender.
264static void sync_send(void) NO_INLINE; 237static void sync_send(void) NO_INLINE;
265static 238static void sync_send(void) {
266void sync_send(void) { 239 serial_low();
267 serial_low(); 240 serial_delay();
268 serial_delay(); 241 serial_high();
269 serial_high();
270} 242}
271 243
272// Reads a byte from the serial line 244// Reads a byte from the serial line
@@ -274,92 +246,94 @@ static uint8_t serial_read_chunk(uint8_t *pterrcount, uint8_t bit) NO_INLINE;
274static uint8_t serial_read_chunk(uint8_t *pterrcount, uint8_t bit) { 246static uint8_t serial_read_chunk(uint8_t *pterrcount, uint8_t bit) {
275 uint8_t byte, i, p, pb; 247 uint8_t byte, i, p, pb;
276 248
277 _delay_sub_us(READ_WRITE_START_ADJUST); 249 _delay_sub_us(READ_WRITE_START_ADJUST);
278 for( i = 0, byte = 0, p = PARITY; i < bit; i++ ) { 250 for (i = 0, byte = 0, p = PARITY; i < bit; i++) {
279 serial_delay_half1(); // read the middle of pulses 251 serial_delay_half1(); // read the middle of pulses
280 if( serial_read_pin() ) { 252 if (serial_read_pin()) {
281 byte = (byte << 1) | 1; p ^= 1; 253 byte = (byte << 1) | 1;
282 } else { 254 p ^= 1;
283 byte = (byte << 1) | 0; p ^= 0; 255 } else {
284 } 256 byte = (byte << 1) | 0;
285 _delay_sub_us(READ_WRITE_WIDTH_ADJUST); 257 p ^= 0;
286 serial_delay_half2(); 258 }
287 } 259 _delay_sub_us(READ_WRITE_WIDTH_ADJUST);
288 /* recive parity bit */ 260 serial_delay_half2();
289 serial_delay_half1(); // read the middle of pulses 261 }
290 pb = serial_read_pin(); 262 /* recive parity bit */
291 _delay_sub_us(READ_WRITE_WIDTH_ADJUST); 263 serial_delay_half1(); // read the middle of pulses
292 serial_delay_half2(); 264 pb = serial_read_pin();
293 265 _delay_sub_us(READ_WRITE_WIDTH_ADJUST);
294 *pterrcount += (p != pb)? 1 : 0; 266 serial_delay_half2();
295 267
296 return byte; 268 *pterrcount += (p != pb) ? 1 : 0;
269
270 return byte;
297} 271}
298 272
299// Sends a byte with MSB ordering 273// Sends a byte with MSB ordering
300void serial_write_chunk(uint8_t data, uint8_t bit) NO_INLINE; 274void serial_write_chunk(uint8_t data, uint8_t bit) NO_INLINE;
301void serial_write_chunk(uint8_t data, uint8_t bit) { 275void serial_write_chunk(uint8_t data, uint8_t bit) {
302 uint8_t b, p; 276 uint8_t b, p;
303 for( p = PARITY, b = 1<<(bit-1); b ; b >>= 1) { 277 for (p = PARITY, b = 1 << (bit - 1); b; b >>= 1) {
304 if(data & b) { 278 if (data & b) {
305 serial_high(); p ^= 1; 279 serial_high();
280 p ^= 1;
306 } else { 281 } else {
307 serial_low(); p ^= 0; 282 serial_low();
283 p ^= 0;
308 } 284 }
309 serial_delay(); 285 serial_delay();
310 } 286 }
311 /* send parity bit */ 287 /* send parity bit */
312 if(p & 1) { serial_high(); } 288 if (p & 1) {
313 else { serial_low(); } 289 serial_high();
290 } else {
291 serial_low();
292 }
314 serial_delay(); 293 serial_delay();
315 294
316 serial_low(); // sync_send() / senc_recv() need raise edge 295 serial_low(); // sync_send() / senc_recv() need raise edge
317} 296}
318 297
319static void serial_send_packet(uint8_t *buffer, uint8_t size) NO_INLINE; 298static void serial_send_packet(uint8_t *buffer, uint8_t size) NO_INLINE;
320static 299static void serial_send_packet(uint8_t *buffer, uint8_t size) {
321void serial_send_packet(uint8_t *buffer, uint8_t size) { 300 for (uint8_t i = 0; i < size; ++i) {
322 for (uint8_t i = 0; i < size; ++i) { 301 uint8_t data;
323 uint8_t data; 302 data = buffer[i];
324 data = buffer[i]; 303 sync_send();
325 sync_send(); 304 serial_write_chunk(data, 8);
326 serial_write_chunk(data,8); 305 }
327 }
328} 306}
329 307
330static uint8_t serial_recive_packet(uint8_t *buffer, uint8_t size) NO_INLINE; 308static uint8_t serial_recive_packet(uint8_t *buffer, uint8_t size) NO_INLINE;
331static 309static uint8_t serial_recive_packet(uint8_t *buffer, uint8_t size) {
332uint8_t serial_recive_packet(uint8_t *buffer, uint8_t size) { 310 uint8_t pecount = 0;
333 uint8_t pecount = 0; 311 for (uint8_t i = 0; i < size; ++i) {
334 for (uint8_t i = 0; i < size; ++i) { 312 uint8_t data;
335 uint8_t data; 313 sync_recv();
336 sync_recv(); 314 data = serial_read_chunk(&pecount, 8);
337 data = serial_read_chunk(&pecount, 8); 315 buffer[i] = data;
338 buffer[i] = data; 316 }
339 } 317 return pecount == 0;
340 return pecount == 0;
341} 318}
342 319
343inline static 320inline static void change_sender2reciver(void) {
344void change_sender2reciver(void) { 321 sync_send(); // 0
345 sync_send(); //0 322 serial_delay_half1(); // 1
346 serial_delay_half1(); //1 323 serial_low(); // 2
347 serial_low(); //2 324 serial_input_with_pullup(); // 2
348 serial_input_with_pullup(); //2 325 serial_delay_half1(); // 3
349 serial_delay_half1(); //3
350} 326}
351 327
352inline static 328inline static void change_reciver2sender(void) {
353void change_reciver2sender(void) { 329 sync_recv(); // 0
354 sync_recv(); //0 330 serial_delay(); // 1
355 serial_delay(); //1 331 serial_low(); // 3
356 serial_low(); //3 332 serial_output(); // 3
357 serial_output(); //3 333 serial_delay_half1(); // 4
358 serial_delay_half1(); //4
359} 334}
360 335
361static inline uint8_t nibble_bits_count(uint8_t bits) 336static inline uint8_t nibble_bits_count(uint8_t bits) {
362{
363 bits = (bits & 0x5) + (bits >> 1 & 0x5); 337 bits = (bits & 0x5) + (bits >> 1 & 0x5);
364 bits = (bits & 0x3) + (bits >> 2 & 0x3); 338 bits = (bits & 0x3) + (bits >> 2 & 0x3);
365 return bits; 339 return bits;
@@ -367,51 +341,47 @@ static inline uint8_t nibble_bits_count(uint8_t bits)
367 341
368// interrupt handle to be used by the target device 342// interrupt handle to be used by the target device
369ISR(SERIAL_PIN_INTERRUPT) { 343ISR(SERIAL_PIN_INTERRUPT) {
344# ifndef SERIAL_USE_MULTI_TRANSACTION
345 serial_low();
346 serial_output();
347 SSTD_t *trans = Transaction_table;
348# else
349 // recive transaction table index
350 uint8_t tid, bits;
351 uint8_t pecount = 0;
352 sync_recv();
353 bits = serial_read_chunk(&pecount, 7);
354 tid = bits >> 3;
355 bits = (bits & 7) != nibble_bits_count(tid);
356 if (bits || pecount > 0 || tid > Transaction_table_size) {
357 return;
358 }
359 serial_delay_half1();
370 360
371#ifndef SERIAL_USE_MULTI_TRANSACTION 361 serial_high(); // response step1 low->high
372 serial_low(); 362 serial_output();
373 serial_output(); 363 _delay_sub_us(SLAVE_INT_ACK_WIDTH_UNIT * SLAVE_INT_ACK_WIDTH);
374 SSTD_t *trans = Transaction_table; 364 SSTD_t *trans = &Transaction_table[tid];
375#else 365 serial_low(); // response step2 ack high->low
376 // recive transaction table index 366# endif
377 uint8_t tid, bits; 367
378 uint8_t pecount = 0; 368 // target send phase
379 sync_recv(); 369 if (trans->target2initiator_buffer_size > 0) serial_send_packet((uint8_t *)trans->target2initiator_buffer, trans->target2initiator_buffer_size);
380 bits = serial_read_chunk(&pecount,7); 370 // target switch to input
381 tid = bits>>3; 371 change_sender2reciver();
382 bits = (bits&7) != nibble_bits_count(tid); 372
383 if( bits || pecount> 0 || tid > Transaction_table_size ) { 373 // target recive phase
384 return; 374 if (trans->initiator2target_buffer_size > 0) {
385 } 375 if (serial_recive_packet((uint8_t *)trans->initiator2target_buffer, trans->initiator2target_buffer_size)) {
386 serial_delay_half1(); 376 *trans->status = TRANSACTION_ACCEPTED;
387 377 } else {
388 serial_high(); // response step1 low->high 378 *trans->status = TRANSACTION_DATA_ERROR;
389 serial_output(); 379 }
390 _delay_sub_us(SLAVE_INT_ACK_WIDTH_UNIT*SLAVE_INT_ACK_WIDTH); 380 } else {
391 SSTD_t *trans = &Transaction_table[tid]; 381 *trans->status = TRANSACTION_ACCEPTED;
392 serial_low(); // response step2 ack high->low 382 }
393#endif
394 383
395 // target send phase 384 sync_recv(); // weit initiator output to high
396 if( trans->target2initiator_buffer_size > 0 )
397 serial_send_packet((uint8_t *)trans->target2initiator_buffer,
398 trans->target2initiator_buffer_size);
399 // target switch to input
400 change_sender2reciver();
401
402 // target recive phase
403 if( trans->initiator2target_buffer_size > 0 ) {
404 if (serial_recive_packet((uint8_t *)trans->initiator2target_buffer,
405 trans->initiator2target_buffer_size) ) {
406 *trans->status = TRANSACTION_ACCEPTED;
407 } else {
408 *trans->status = TRANSACTION_DATA_ERROR;
409 }
410 } else {
411 *trans->status = TRANSACTION_ACCEPTED;
412 }
413
414 sync_recv(); //weit initiator output to high
415} 385}
416 386
417///////// 387/////////
@@ -424,105 +394,103 @@ ISR(SERIAL_PIN_INTERRUPT) {
424// TRANSACTION_NO_RESPONSE 394// TRANSACTION_NO_RESPONSE
425// TRANSACTION_DATA_ERROR 395// TRANSACTION_DATA_ERROR
426// this code is very time dependent, so we need to disable interrupts 396// this code is very time dependent, so we need to disable interrupts
427#ifndef SERIAL_USE_MULTI_TRANSACTION 397# ifndef SERIAL_USE_MULTI_TRANSACTION
428int soft_serial_transaction(void) { 398int soft_serial_transaction(void) {
429 SSTD_t *trans = Transaction_table; 399 SSTD_t *trans = Transaction_table;
430#else 400# else
431int soft_serial_transaction(int sstd_index) { 401int soft_serial_transaction(int sstd_index) {
432 if( sstd_index > Transaction_table_size ) 402 if (sstd_index > Transaction_table_size) return TRANSACTION_TYPE_ERROR;
433 return TRANSACTION_TYPE_ERROR; 403 SSTD_t *trans = &Transaction_table[sstd_index];
434 SSTD_t *trans = &Transaction_table[sstd_index]; 404# endif
435#endif 405 cli();
436 cli();
437 406
438 // signal to the target that we want to start a transaction 407 // signal to the target that we want to start a transaction
439 serial_output(); 408 serial_output();
440 serial_low(); 409 serial_low();
441 _delay_us(SLAVE_INT_WIDTH_US); 410 _delay_us(SLAVE_INT_WIDTH_US);
442 411
443#ifndef SERIAL_USE_MULTI_TRANSACTION 412# ifndef SERIAL_USE_MULTI_TRANSACTION
444 // wait for the target response 413 // wait for the target response
445 serial_input_with_pullup(); 414 serial_input_with_pullup();
446 _delay_us(SLAVE_INT_RESPONSE_TIME); 415 _delay_us(SLAVE_INT_RESPONSE_TIME);
416
417 // check if the target is present
418 if (serial_read_pin()) {
419 // target failed to pull the line low, assume not present
420 serial_output();
421 serial_high();
422 *trans->status = TRANSACTION_NO_RESPONSE;
423 sei();
424 return TRANSACTION_NO_RESPONSE;
425 }
447 426
448 // check if the target is present 427# else
449 if (serial_read_pin()) { 428 // send transaction table index
450 // target failed to pull the line low, assume not present 429 int tid = (sstd_index << 3) | (7 & nibble_bits_count(sstd_index));
451 serial_output(); 430 sync_send();
452 serial_high(); 431 _delay_sub_us(TID_SEND_ADJUST);
453 *trans->status = TRANSACTION_NO_RESPONSE; 432 serial_write_chunk(tid, 7);
454 sei(); 433 serial_delay_half1();
455 return TRANSACTION_NO_RESPONSE; 434
456 } 435 // wait for the target response (step1 low->high)
457 436 serial_input_with_pullup();
458#else 437 while (!serial_read_pin()) {
459 // send transaction table index 438 _delay_sub_us(2);
460 int tid = (sstd_index<<3) | (7 & nibble_bits_count(sstd_index)); 439 }
461 sync_send(); 440
462 _delay_sub_us(TID_SEND_ADJUST); 441 // check if the target is present (step2 high->low)
463 serial_write_chunk(tid, 7); 442 for (int i = 0; serial_read_pin(); i++) {
464 serial_delay_half1(); 443 if (i > SLAVE_INT_ACK_WIDTH + 1) {
465 444 // slave failed to pull the line low, assume not present
466 // wait for the target response (step1 low->high) 445 serial_output();
467 serial_input_with_pullup(); 446 serial_high();
468 while( !serial_read_pin() ) { 447 *trans->status = TRANSACTION_NO_RESPONSE;
469 _delay_sub_us(2); 448 sei();
470 } 449 return TRANSACTION_NO_RESPONSE;
471 450 }
472 // check if the target is present (step2 high->low) 451 _delay_sub_us(SLAVE_INT_ACK_WIDTH_UNIT);
473 for( int i = 0; serial_read_pin(); i++ ) { 452 }
474 if (i > SLAVE_INT_ACK_WIDTH + 1) { 453# endif
475 // slave failed to pull the line low, assume not present 454
476 serial_output(); 455 // initiator recive phase
477 serial_high(); 456 // if the target is present syncronize with it
478 *trans->status = TRANSACTION_NO_RESPONSE; 457 if (trans->target2initiator_buffer_size > 0) {
479 sei(); 458 if (!serial_recive_packet((uint8_t *)trans->target2initiator_buffer, trans->target2initiator_buffer_size)) {
480 return TRANSACTION_NO_RESPONSE; 459 serial_output();
481 } 460 serial_high();
482 _delay_sub_us(SLAVE_INT_ACK_WIDTH_UNIT); 461 *trans->status = TRANSACTION_DATA_ERROR;
483 } 462 sei();
484#endif 463 return TRANSACTION_DATA_ERROR;
464 }
465 }
466
467 // initiator switch to output
468 change_reciver2sender();
469
470 // initiator send phase
471 if (trans->initiator2target_buffer_size > 0) {
472 serial_send_packet((uint8_t *)trans->initiator2target_buffer, trans->initiator2target_buffer_size);
473 }
485 474
486 // initiator recive phase 475 // always, release the line when not in use
487 // if the target is present syncronize with it 476 sync_send();
488 if( trans->target2initiator_buffer_size > 0 ) { 477
489 if (!serial_recive_packet((uint8_t *)trans->target2initiator_buffer, 478 *trans->status = TRANSACTION_END;
490 trans->target2initiator_buffer_size) ) { 479 sei();
491 serial_output(); 480 return TRANSACTION_END;
492 serial_high();
493 *trans->status = TRANSACTION_DATA_ERROR;
494 sei();
495 return TRANSACTION_DATA_ERROR;
496 }
497 }
498
499 // initiator switch to output
500 change_reciver2sender();
501
502 // initiator send phase
503 if( trans->initiator2target_buffer_size > 0 ) {
504 serial_send_packet((uint8_t *)trans->initiator2target_buffer,
505 trans->initiator2target_buffer_size);
506 }
507
508 // always, release the line when not in use
509 sync_send();
510
511 *trans->status = TRANSACTION_END;
512 sei();
513 return TRANSACTION_END;
514} 481}
515 482
516#ifdef SERIAL_USE_MULTI_TRANSACTION 483# ifdef SERIAL_USE_MULTI_TRANSACTION
517int soft_serial_get_and_clean_status(int sstd_index) { 484int soft_serial_get_and_clean_status(int sstd_index) {
518 SSTD_t *trans = &Transaction_table[sstd_index]; 485 SSTD_t *trans = &Transaction_table[sstd_index];
519 cli(); 486 cli();
520 int retval = *trans->status; 487 int retval = *trans->status;
521 *trans->status = 0;; 488 *trans->status = 0;
489 ;
522 sei(); 490 sei();
523 return retval; 491 return retval;
524} 492}
525#endif 493# endif
526 494
527#endif 495#endif
528 496
diff --git a/quantum/split_common/serial.h b/quantum/split_common/serial.h
index 1c1e64006..53e66cf90 100644
--- a/quantum/split_common/serial.h
+++ b/quantum/split_common/serial.h
@@ -22,14 +22,14 @@
22// ///////////////////////////////////////////////////////////////// 22// /////////////////////////////////////////////////////////////////
23 23
24// Soft Serial Transaction Descriptor 24// Soft Serial Transaction Descriptor
25typedef struct _SSTD_t { 25typedef struct _SSTD_t {
26 uint8_t *status; 26 uint8_t *status;
27 uint8_t initiator2target_buffer_size; 27 uint8_t initiator2target_buffer_size;
28 uint8_t *initiator2target_buffer; 28 uint8_t *initiator2target_buffer;
29 uint8_t target2initiator_buffer_size; 29 uint8_t target2initiator_buffer_size;
30 uint8_t *target2initiator_buffer; 30 uint8_t *target2initiator_buffer;
31} SSTD_t; 31} SSTD_t;
32#define TID_LIMIT( table ) (sizeof(table) / sizeof(SSTD_t)) 32#define TID_LIMIT(table) (sizeof(table) / sizeof(SSTD_t))
33 33
34// initiator is transaction start side 34// initiator is transaction start side
35void soft_serial_initiator_init(SSTD_t *sstd_table, int sstd_table_size); 35void soft_serial_initiator_init(SSTD_t *sstd_table, int sstd_table_size);
@@ -39,12 +39,12 @@ void soft_serial_target_init(SSTD_t *sstd_table, int sstd_table_size);
39// initiator resullt 39// initiator resullt
40#define TRANSACTION_END 0 40#define TRANSACTION_END 0
41#define TRANSACTION_NO_RESPONSE 0x1 41#define TRANSACTION_NO_RESPONSE 0x1
42#define TRANSACTION_DATA_ERROR 0x2 42#define TRANSACTION_DATA_ERROR 0x2
43#define TRANSACTION_TYPE_ERROR 0x4 43#define TRANSACTION_TYPE_ERROR 0x4
44#ifndef SERIAL_USE_MULTI_TRANSACTION 44#ifndef SERIAL_USE_MULTI_TRANSACTION
45int soft_serial_transaction(void); 45int soft_serial_transaction(void);
46#else 46#else
47int soft_serial_transaction(int sstd_index); 47int soft_serial_transaction(int sstd_index);
48#endif 48#endif
49 49
50// target status 50// target status
@@ -58,5 +58,5 @@ int soft_serial_transaction(int sstd_index);
58// or TRANSACTION_ACCEPTED 58// or TRANSACTION_ACCEPTED
59#define TRANSACTION_ACCEPTED 0x8 59#define TRANSACTION_ACCEPTED 0x8
60#ifdef SERIAL_USE_MULTI_TRANSACTION 60#ifdef SERIAL_USE_MULTI_TRANSACTION
61int soft_serial_get_and_clean_status(int sstd_index); 61int soft_serial_get_and_clean_status(int sstd_index);
62#endif 62#endif
diff --git a/quantum/split_common/split_util.c b/quantum/split_common/split_util.c
index d7ed6989f..5114b188e 100644
--- a/quantum/split_common/split_util.c
+++ b/quantum/split_common/split_util.c
@@ -7,87 +7,75 @@
7#include "quantum.h" 7#include "quantum.h"
8 8
9#ifdef EE_HANDS 9#ifdef EE_HANDS
10# include "tmk_core/common/eeprom.h" 10# include "tmk_core/common/eeprom.h"
11# include "eeconfig.h" 11# include "eeconfig.h"
12#endif 12#endif
13 13
14#if defined(RGBLIGHT_ENABLE) && defined(RGBLED_SPLIT) 14#if defined(RGBLIGHT_ENABLE) && defined(RGBLED_SPLIT)
15#include "rgblight.h" 15# include "rgblight.h"
16#endif 16#endif
17 17
18volatile bool isLeftHand = true; 18volatile bool isLeftHand = true;
19 19
20__attribute__((weak)) 20__attribute__((weak)) bool is_keyboard_left(void) {
21bool is_keyboard_left(void) { 21#if defined(SPLIT_HAND_PIN)
22 #if defined(SPLIT_HAND_PIN)
23 // Test pin SPLIT_HAND_PIN for High/Low, if low it's right hand 22 // Test pin SPLIT_HAND_PIN for High/Low, if low it's right hand
24 setPinInput(SPLIT_HAND_PIN); 23 setPinInput(SPLIT_HAND_PIN);
25 return readPin(SPLIT_HAND_PIN); 24 return readPin(SPLIT_HAND_PIN);
26 #elif defined(EE_HANDS) 25#elif defined(EE_HANDS)
27 return eeprom_read_byte(EECONFIG_HANDEDNESS); 26 return eeprom_read_byte(EECONFIG_HANDEDNESS);
28 #elif defined(MASTER_RIGHT) 27#elif defined(MASTER_RIGHT)
29 return !is_keyboard_master(); 28 return !is_keyboard_master();
30 #endif 29#endif
31 30
32 return is_keyboard_master(); 31 return is_keyboard_master();
33} 32}
34 33
35__attribute__((weak)) 34__attribute__((weak)) bool is_keyboard_master(void) {
36bool is_keyboard_master(void)
37{
38#ifdef __AVR__ 35#ifdef __AVR__
39 static enum { UNKNOWN, MASTER, SLAVE } usbstate = UNKNOWN; 36 static enum { UNKNOWN, MASTER, SLAVE } usbstate = UNKNOWN;
40 37
41 // only check once, as this is called often 38 // only check once, as this is called often
42 if (usbstate == UNKNOWN) 39 if (usbstate == UNKNOWN) {
43 { 40 USBCON |= (1 << OTGPADE); // enables VBUS pad
44 USBCON |= (1 << OTGPADE); // enables VBUS pad 41 wait_us(5);
45 wait_us(5);
46 42
47 usbstate = (USBSTA & (1 << VBUS)) ? MASTER : SLAVE; // checks state of VBUS 43 usbstate = (USBSTA & (1 << VBUS)) ? MASTER : SLAVE; // checks state of VBUS
48 } 44 }
49 45
50 return (usbstate == MASTER); 46 return (usbstate == MASTER);
51#else 47#else
52 return true; 48 return true;
53#endif 49#endif
54} 50}
55 51
56static void keyboard_master_setup(void) { 52static void keyboard_master_setup(void) {
57#if defined(USE_I2C) || defined(EH) 53#if defined(USE_I2C) || defined(EH)
58 #ifdef SSD1306OLED 54# ifdef SSD1306OLED
59 matrix_master_OLED_init (); 55 matrix_master_OLED_init();
60 #endif 56# endif
61#endif 57#endif
62 transport_master_init(); 58 transport_master_init();
63} 59}
64 60
65static void keyboard_slave_setup(void) 61static void keyboard_slave_setup(void) { transport_slave_init(); }
66{
67 transport_slave_init();
68}
69 62
70// this code runs before the usb and keyboard is initialized 63// this code runs before the usb and keyboard is initialized
71void matrix_setup(void) 64void matrix_setup(void) {
72{ 65 isLeftHand = is_keyboard_left();
73 isLeftHand = is_keyboard_left();
74 66
75#if defined(RGBLIGHT_ENABLE) && defined(RGBLED_SPLIT) 67#if defined(RGBLIGHT_ENABLE) && defined(RGBLED_SPLIT)
76 uint8_t num_rgb_leds_split[2] = RGBLED_SPLIT; 68 uint8_t num_rgb_leds_split[2] = RGBLED_SPLIT;
77 if (isLeftHand) { 69 if (isLeftHand) {
78 rgblight_set_clipping_range(0, num_rgb_leds_split[0]); 70 rgblight_set_clipping_range(0, num_rgb_leds_split[0]);
79 } 71 } else {
80 else { 72 rgblight_set_clipping_range(num_rgb_leds_split[0], num_rgb_leds_split[1]);
81 rgblight_set_clipping_range(num_rgb_leds_split[0], num_rgb_leds_split[1]); 73 }
82 }
83#endif 74#endif
84 75
85 if (is_keyboard_master()) 76 if (is_keyboard_master()) {
86 { 77 keyboard_master_setup();
87 keyboard_master_setup(); 78 } else {
88 } 79 keyboard_slave_setup();
89 else 80 }
90 {
91 keyboard_slave_setup();
92 }
93} 81}
diff --git a/quantum/split_common/split_util.h b/quantum/split_common/split_util.h
index 20f7535bf..f41c77605 100644
--- a/quantum/split_common/split_util.h
+++ b/quantum/split_common/split_util.h
@@ -7,4 +7,4 @@
7 7
8extern volatile bool isLeftHand; 8extern volatile bool isLeftHand;
9 9
10void matrix_master_OLED_init (void); 10void matrix_master_OLED_init(void);
diff --git a/quantum/split_common/transport.c b/quantum/split_common/transport.c
index ba21d0c7b..3c783dc56 100644
--- a/quantum/split_common/transport.c
+++ b/quantum/split_common/transport.c
@@ -8,101 +8,100 @@
8#define ROWS_PER_HAND (MATRIX_ROWS / 2) 8#define ROWS_PER_HAND (MATRIX_ROWS / 2)
9 9
10#ifdef RGBLIGHT_ENABLE 10#ifdef RGBLIGHT_ENABLE
11# include "rgblight.h" 11# include "rgblight.h"
12#endif 12#endif
13 13
14#ifdef BACKLIGHT_ENABLE 14#ifdef BACKLIGHT_ENABLE
15# include "backlight.h" 15# include "backlight.h"
16#endif 16#endif
17 17
18#ifdef ENCODER_ENABLE 18#ifdef ENCODER_ENABLE
19# include "encoder.h" 19# include "encoder.h"
20static pin_t encoders_pad[] = ENCODERS_PAD_A; 20static pin_t encoders_pad[] = ENCODERS_PAD_A;
21# define NUMBER_OF_ENCODERS (sizeof(encoders_pad)/sizeof(pin_t)) 21# define NUMBER_OF_ENCODERS (sizeof(encoders_pad) / sizeof(pin_t))
22#endif 22#endif
23 23
24#if defined(USE_I2C) || defined(EH) 24#if defined(USE_I2C) || defined(EH)
25 25
26# include "i2c_master.h" 26# include "i2c_master.h"
27# include "i2c_slave.h" 27# include "i2c_slave.h"
28 28
29typedef struct _I2C_slave_buffer_t { 29typedef struct _I2C_slave_buffer_t {
30 matrix_row_t smatrix[ROWS_PER_HAND]; 30 matrix_row_t smatrix[ROWS_PER_HAND];
31 uint8_t backlight_level; 31 uint8_t backlight_level;
32#if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) 32# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
33 rgblight_syncinfo_t rgblight_sync; 33 rgblight_syncinfo_t rgblight_sync;
34#endif 34# endif
35#ifdef ENCODER_ENABLE 35# ifdef ENCODER_ENABLE
36 uint8_t encoder_state[NUMBER_OF_ENCODERS]; 36 uint8_t encoder_state[NUMBER_OF_ENCODERS];
37#endif 37# endif
38} I2C_slave_buffer_t; 38} I2C_slave_buffer_t;
39 39
40static I2C_slave_buffer_t * const i2c_buffer = (I2C_slave_buffer_t *)i2c_slave_reg; 40static I2C_slave_buffer_t *const i2c_buffer = (I2C_slave_buffer_t *)i2c_slave_reg;
41 41
42# define I2C_BACKLIGHT_START offsetof(I2C_slave_buffer_t, backlight_level) 42# define I2C_BACKLIGHT_START offsetof(I2C_slave_buffer_t, backlight_level)
43# define I2C_RGB_START offsetof(I2C_slave_buffer_t, rgblight_sync) 43# define I2C_RGB_START offsetof(I2C_slave_buffer_t, rgblight_sync)
44# define I2C_KEYMAP_START offsetof(I2C_slave_buffer_t, smatrix) 44# define I2C_KEYMAP_START offsetof(I2C_slave_buffer_t, smatrix)
45# define I2C_ENCODER_START offsetof(I2C_slave_buffer_t, encoder_state) 45# define I2C_ENCODER_START offsetof(I2C_slave_buffer_t, encoder_state)
46 46
47# define TIMEOUT 100 47# define TIMEOUT 100
48 48
49# ifndef SLAVE_I2C_ADDRESS 49# ifndef SLAVE_I2C_ADDRESS
50# define SLAVE_I2C_ADDRESS 0x32 50# define SLAVE_I2C_ADDRESS 0x32
51# endif 51# endif
52 52
53// Get rows from other half over i2c 53// Get rows from other half over i2c
54bool transport_master(matrix_row_t matrix[]) { 54bool transport_master(matrix_row_t matrix[]) {
55 i2c_readReg(SLAVE_I2C_ADDRESS, I2C_KEYMAP_START, (void *)matrix, sizeof(i2c_buffer->smatrix), TIMEOUT); 55 i2c_readReg(SLAVE_I2C_ADDRESS, I2C_KEYMAP_START, (void *)matrix, sizeof(i2c_buffer->smatrix), TIMEOUT);
56 56
57 // write backlight info 57 // write backlight info
58# ifdef BACKLIGHT_ENABLE 58# ifdef BACKLIGHT_ENABLE
59 uint8_t level = is_backlight_enabled() ? get_backlight_level() : 0; 59 uint8_t level = is_backlight_enabled() ? get_backlight_level() : 0;
60 if (level != i2c_buffer->backlight_level) { 60 if (level != i2c_buffer->backlight_level) {
61 if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_BACKLIGHT_START, (void *)&level, sizeof(level), TIMEOUT) >= 0) { 61 if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_BACKLIGHT_START, (void *)&level, sizeof(level), TIMEOUT) >= 0) {
62 i2c_buffer->backlight_level = level; 62 i2c_buffer->backlight_level = level;
63 }
63 } 64 }
64 } 65# endif
65# endif 66
66 67# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
67# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) 68 if (rgblight_get_change_flags()) {
68 if (rgblight_get_change_flags()) { 69 rgblight_syncinfo_t rgblight_sync;
69 rgblight_syncinfo_t rgblight_sync; 70 rgblight_get_syncinfo(&rgblight_sync);
70 rgblight_get_syncinfo(&rgblight_sync); 71 if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_START, (void *)&rgblight_sync, sizeof(rgblight_sync), TIMEOUT) >= 0) {
71 if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_START, 72 rgblight_clear_change_flags();
72 (void *)&rgblight_sync, sizeof(rgblight_sync), TIMEOUT) >= 0) { 73 }
73 rgblight_clear_change_flags();
74 } 74 }
75 } 75# endif
76# endif
77 76
78# ifdef ENCODER_ENABLE 77# ifdef ENCODER_ENABLE
79 i2c_readReg(SLAVE_I2C_ADDRESS, I2C_ENCODER_START, (void *)i2c_buffer->encoder_state, sizeof(i2c_buffer->encoder_state), TIMEOUT); 78 i2c_readReg(SLAVE_I2C_ADDRESS, I2C_ENCODER_START, (void *)i2c_buffer->encoder_state, sizeof(i2c_buffer->encoder_state), TIMEOUT);
80 encoder_update_raw(i2c_buffer->encoder_state); 79 encoder_update_raw(i2c_buffer->encoder_state);
81# endif 80# endif
82 81
83 return true; 82 return true;
84} 83}
85 84
86void transport_slave(matrix_row_t matrix[]) { 85void transport_slave(matrix_row_t matrix[]) {
87 // Copy matrix to I2C buffer 86 // Copy matrix to I2C buffer
88 memcpy((void*)i2c_buffer->smatrix, (void *)matrix, sizeof(i2c_buffer->smatrix)); 87 memcpy((void *)i2c_buffer->smatrix, (void *)matrix, sizeof(i2c_buffer->smatrix));
89 88
90// Read Backlight Info 89// Read Backlight Info
91# ifdef BACKLIGHT_ENABLE 90# ifdef BACKLIGHT_ENABLE
92 backlight_set(i2c_buffer->backlight_level); 91 backlight_set(i2c_buffer->backlight_level);
93# endif 92# endif
94 93
95# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) 94# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
96 // Update the RGB with the new data 95 // Update the RGB with the new data
97 if (i2c_buffer->rgblight_sync.status.change_flags != 0) { 96 if (i2c_buffer->rgblight_sync.status.change_flags != 0) {
98 rgblight_update_sync(&i2c_buffer->rgblight_sync, false); 97 rgblight_update_sync(&i2c_buffer->rgblight_sync, false);
99 i2c_buffer->rgblight_sync.status.change_flags = 0; 98 i2c_buffer->rgblight_sync.status.change_flags = 0;
100 } 99 }
101# endif 100# endif
102 101
103# ifdef ENCODER_ENABLE 102# ifdef ENCODER_ENABLE
104 encoder_state_raw(i2c_buffer->encoder_state); 103 encoder_state_raw(i2c_buffer->encoder_state);
105# endif 104# endif
106} 105}
107 106
108void transport_master_init(void) { i2c_init(); } 107void transport_master_init(void) { i2c_init(); }
@@ -111,25 +110,25 @@ void transport_slave_init(void) { i2c_slave_init(SLAVE_I2C_ADDRESS); }
111 110
112#else // USE_SERIAL 111#else // USE_SERIAL
113 112
114# include "serial.h" 113# include "serial.h"
115 114
116typedef struct _Serial_s2m_buffer_t { 115typedef struct _Serial_s2m_buffer_t {
117 // TODO: if MATRIX_COLS > 8 change to uint8_t packed_matrix[] for pack/unpack 116 // TODO: if MATRIX_COLS > 8 change to uint8_t packed_matrix[] for pack/unpack
118 matrix_row_t smatrix[ROWS_PER_HAND]; 117 matrix_row_t smatrix[ROWS_PER_HAND];
119 118
120# ifdef ENCODER_ENABLE 119# ifdef ENCODER_ENABLE
121 uint8_t encoder_state[NUMBER_OF_ENCODERS]; 120 uint8_t encoder_state[NUMBER_OF_ENCODERS];
122# endif 121# endif
123 122
124} Serial_s2m_buffer_t; 123} Serial_s2m_buffer_t;
125 124
126typedef struct _Serial_m2s_buffer_t { 125typedef struct _Serial_m2s_buffer_t {
127# ifdef BACKLIGHT_ENABLE 126# ifdef BACKLIGHT_ENABLE
128 uint8_t backlight_level; 127 uint8_t backlight_level;
129# endif 128# endif
130} Serial_m2s_buffer_t; 129} Serial_m2s_buffer_t;
131 130
132#if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) 131# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
133// When MCUs on both sides drive their respective RGB LED chains, 132// When MCUs on both sides drive their respective RGB LED chains,
134// it is necessary to synchronize, so it is necessary to communicate RGB 133// it is necessary to synchronize, so it is necessary to communicate RGB
135// information. In that case, define RGBLIGHT_SPLIT with info on the number 134// information. In that case, define RGBLIGHT_SPLIT with info on the number
@@ -144,7 +143,7 @@ typedef struct _Serial_rgblight_t {
144 143
145volatile Serial_rgblight_t serial_rgblight = {}; 144volatile Serial_rgblight_t serial_rgblight = {};
146uint8_t volatile status_rgblight = 0; 145uint8_t volatile status_rgblight = 0;
147#endif 146# endif
148 147
149volatile Serial_s2m_buffer_t serial_s2m_buffer = {}; 148volatile Serial_s2m_buffer_t serial_s2m_buffer = {};
150volatile Serial_m2s_buffer_t serial_m2s_buffer = {}; 149volatile Serial_m2s_buffer_t serial_m2s_buffer = {};
@@ -152,102 +151,99 @@ uint8_t volatile status0 = 0;
152 151
153enum serial_transaction_id { 152enum serial_transaction_id {
154 GET_SLAVE_MATRIX = 0, 153 GET_SLAVE_MATRIX = 0,
155#if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) 154# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
156 PUT_RGBLIGHT, 155 PUT_RGBLIGHT,
157#endif 156# endif
158}; 157};
159 158
160SSTD_t transactions[] = { 159SSTD_t transactions[] = {
161 [GET_SLAVE_MATRIX] = { 160 [GET_SLAVE_MATRIX] =
162 (uint8_t *)&status0, 161 {
163 sizeof(serial_m2s_buffer), 162 (uint8_t *)&status0,
164 (uint8_t *)&serial_m2s_buffer, 163 sizeof(serial_m2s_buffer),
165 sizeof(serial_s2m_buffer), 164 (uint8_t *)&serial_m2s_buffer,
166 (uint8_t *)&serial_s2m_buffer, 165 sizeof(serial_s2m_buffer),
167 }, 166 (uint8_t *)&serial_s2m_buffer,
168#if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) 167 },
169 [PUT_RGBLIGHT] = { 168# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
170 (uint8_t *)&status_rgblight, 169 [PUT_RGBLIGHT] =
171 sizeof(serial_rgblight), 170 {
172 (uint8_t *)&serial_rgblight, 171 (uint8_t *)&status_rgblight, sizeof(serial_rgblight), (uint8_t *)&serial_rgblight, 0, NULL // no slave to master transfer
173 0, NULL // no slave to master transfer 172 },
174 }, 173# endif
175#endif
176}; 174};
177 175
178void transport_master_init(void) { soft_serial_initiator_init(transactions, TID_LIMIT(transactions)); } 176void transport_master_init(void) { soft_serial_initiator_init(transactions, TID_LIMIT(transactions)); }
179 177
180void transport_slave_init(void) { soft_serial_target_init(transactions, TID_LIMIT(transactions)); } 178void transport_slave_init(void) { soft_serial_target_init(transactions, TID_LIMIT(transactions)); }
181 179
182#if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) 180# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
183 181
184// rgblight synchronization information communication. 182// rgblight synchronization information communication.
185 183
186void transport_rgblight_master(void) { 184void transport_rgblight_master(void) {
187 if (rgblight_get_change_flags()) { 185 if (rgblight_get_change_flags()) {
188 rgblight_get_syncinfo((rgblight_syncinfo_t *)&serial_rgblight.rgblight_sync); 186 rgblight_get_syncinfo((rgblight_syncinfo_t *)&serial_rgblight.rgblight_sync);
189 if (soft_serial_transaction(PUT_RGBLIGHT) == TRANSACTION_END) { 187 if (soft_serial_transaction(PUT_RGBLIGHT) == TRANSACTION_END) {
190 rgblight_clear_change_flags(); 188 rgblight_clear_change_flags();
189 }
191 } 190 }
192 }
193} 191}
194 192
195void transport_rgblight_slave(void) { 193void transport_rgblight_slave(void) {
196 if (status_rgblight == TRANSACTION_ACCEPTED) { 194 if (status_rgblight == TRANSACTION_ACCEPTED) {
197 rgblight_update_sync((rgblight_syncinfo_t *)&serial_rgblight.rgblight_sync, 195 rgblight_update_sync((rgblight_syncinfo_t *)&serial_rgblight.rgblight_sync, false);
198 false); 196 status_rgblight = TRANSACTION_END;
199 status_rgblight = TRANSACTION_END; 197 }
200 }
201} 198}
202 199
203#else 200# else
204#define transport_rgblight_master() 201# define transport_rgblight_master()
205#define transport_rgblight_slave() 202# define transport_rgblight_slave()
206#endif 203# endif
207 204
208bool transport_master(matrix_row_t matrix[]) { 205bool transport_master(matrix_row_t matrix[]) {
209#ifndef SERIAL_USE_MULTI_TRANSACTION 206# ifndef SERIAL_USE_MULTI_TRANSACTION
210 if (soft_serial_transaction() != TRANSACTION_END) { 207 if (soft_serial_transaction() != TRANSACTION_END) {
211 return false; 208 return false;
212 } 209 }
213#else 210# else
214 transport_rgblight_master(); 211 transport_rgblight_master();
215 if (soft_serial_transaction(GET_SLAVE_MATRIX) != TRANSACTION_END) { 212 if (soft_serial_transaction(GET_SLAVE_MATRIX) != TRANSACTION_END) {
216 return false; 213 return false;
217 } 214 }
218#endif 215# endif
219 216
220 // TODO: if MATRIX_COLS > 8 change to unpack() 217 // TODO: if MATRIX_COLS > 8 change to unpack()
221 for (int i = 0; i < ROWS_PER_HAND; ++i) { 218 for (int i = 0; i < ROWS_PER_HAND; ++i) {
222 matrix[i] = serial_s2m_buffer.smatrix[i]; 219 matrix[i] = serial_s2m_buffer.smatrix[i];
223 } 220 }
224 221
225# ifdef BACKLIGHT_ENABLE 222# ifdef BACKLIGHT_ENABLE
226 // Write backlight level for slave to read 223 // Write backlight level for slave to read
227 serial_m2s_buffer.backlight_level = is_backlight_enabled() ? get_backlight_level() : 0; 224 serial_m2s_buffer.backlight_level = is_backlight_enabled() ? get_backlight_level() : 0;
228# endif 225# endif
229 226
230# ifdef ENCODER_ENABLE 227# ifdef ENCODER_ENABLE
231 encoder_update_raw((uint8_t *)serial_s2m_buffer.encoder_state); 228 encoder_update_raw((uint8_t *)serial_s2m_buffer.encoder_state);
232# endif 229# endif
233 230
234 return true; 231 return true;
235} 232}
236 233
237void transport_slave(matrix_row_t matrix[]) { 234void transport_slave(matrix_row_t matrix[]) {
238 transport_rgblight_slave(); 235 transport_rgblight_slave();
239 // TODO: if MATRIX_COLS > 8 change to pack() 236 // TODO: if MATRIX_COLS > 8 change to pack()
240 for (int i = 0; i < ROWS_PER_HAND; ++i) { 237 for (int i = 0; i < ROWS_PER_HAND; ++i) {
241 serial_s2m_buffer.smatrix[i] = matrix[i]; 238 serial_s2m_buffer.smatrix[i] = matrix[i];
242 } 239 }
243# ifdef BACKLIGHT_ENABLE 240# ifdef BACKLIGHT_ENABLE
244 backlight_set(serial_m2s_buffer.backlight_level); 241 backlight_set(serial_m2s_buffer.backlight_level);
245# endif 242# endif
246
247# ifdef ENCODER_ENABLE
248 encoder_state_raw((uint8_t *)serial_s2m_buffer.encoder_state);
249# endif
250 243
244# ifdef ENCODER_ENABLE
245 encoder_state_raw((uint8_t *)serial_s2m_buffer.encoder_state);
246# endif
251} 247}
252 248
253#endif 249#endif