aboutsummaryrefslogtreecommitdiff
path: root/quantum/split_common/transport.c
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/split_common/transport.c')
-rw-r--r--quantum/split_common/transport.c272
1 files changed, 134 insertions, 138 deletions
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