diff options
Diffstat (limited to 'users/drashna/drashna_transport.c')
| -rw-r--r-- | users/drashna/drashna_transport.c | 603 |
1 files changed, 0 insertions, 603 deletions
diff --git a/users/drashna/drashna_transport.c b/users/drashna/drashna_transport.c deleted file mode 100644 index 9df11c9bd..000000000 --- a/users/drashna/drashna_transport.c +++ /dev/null | |||
| @@ -1,603 +0,0 @@ | |||
| 1 | /* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com> | ||
| 2 | * | ||
| 3 | * This program is free software: you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License as published by | ||
| 5 | * the Free Software Foundation, either version 2 of the License, or | ||
| 6 | * (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <string.h> | ||
| 18 | #include <stddef.h> | ||
| 19 | |||
| 20 | #include "matrix.h" | ||
| 21 | #include QMK_KEYBOARD_H | ||
| 22 | |||
| 23 | #define ROWS_PER_HAND (MATRIX_ROWS / 2) | ||
| 24 | #define SYNC_TIMER_OFFSET 2 | ||
| 25 | |||
| 26 | #ifdef RGBLIGHT_ENABLE | ||
| 27 | # include "rgblight.h" | ||
| 28 | #endif | ||
| 29 | |||
| 30 | #ifdef BACKLIGHT_ENABLE | ||
| 31 | # include "backlight.h" | ||
| 32 | #endif | ||
| 33 | |||
| 34 | #ifdef ENCODER_ENABLE | ||
| 35 | # include "encoder.h" | ||
| 36 | static pin_t encoders_pad[] = ENCODERS_PAD_A; | ||
| 37 | # define NUMBER_OF_ENCODERS (sizeof(encoders_pad) / sizeof(pin_t)) | ||
| 38 | #endif | ||
| 39 | |||
| 40 | #ifdef POINTING_DEVICE_ENABLE | ||
| 41 | static uint16_t device_cpi = 0; | ||
| 42 | static int8_t split_mouse_x = 0, split_mouse_y = 0; | ||
| 43 | #endif | ||
| 44 | |||
| 45 | #ifdef OLED_DRIVER_ENABLE | ||
| 46 | # include "oled_driver.h" | ||
| 47 | #endif | ||
| 48 | |||
| 49 | #if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) | ||
| 50 | # include "led_matrix.h" | ||
| 51 | #endif | ||
| 52 | #if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) | ||
| 53 | # include "rgb_matrix.h" | ||
| 54 | #endif | ||
| 55 | |||
| 56 | #if defined(USE_I2C) | ||
| 57 | |||
| 58 | # include "i2c_master.h" | ||
| 59 | # include "i2c_slave.h" | ||
| 60 | |||
| 61 | typedef struct _I2C_slave_buffer_t { | ||
| 62 | # ifndef DISABLE_SYNC_TIMER | ||
| 63 | uint32_t sync_timer; | ||
| 64 | # endif | ||
| 65 | # ifdef SPLIT_TRANSPORT_MIRROR | ||
| 66 | matrix_row_t mmatrix[ROWS_PER_HAND]; | ||
| 67 | # endif | ||
| 68 | matrix_row_t smatrix[ROWS_PER_HAND]; | ||
| 69 | # ifdef SPLIT_MODS_ENABLE | ||
| 70 | uint8_t real_mods; | ||
| 71 | uint8_t weak_mods; | ||
| 72 | # ifndef NO_ACTION_ONESHOT | ||
| 73 | uint8_t oneshot_mods; | ||
| 74 | # endif | ||
| 75 | # endif | ||
| 76 | # ifdef BACKLIGHT_ENABLE | ||
| 77 | uint8_t backlight_level; | ||
| 78 | # endif | ||
| 79 | # if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) | ||
| 80 | rgblight_syncinfo_t rgblight_sync; | ||
| 81 | # endif | ||
| 82 | # ifdef ENCODER_ENABLE | ||
| 83 | uint8_t encoder_state[NUMBER_OF_ENCODERS]; | ||
| 84 | # endif | ||
| 85 | # ifdef WPM_ENABLE | ||
| 86 | uint8_t current_wpm; | ||
| 87 | # endif | ||
| 88 | # if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) | ||
| 89 | led_eeconfig_t led_matrix; | ||
| 90 | bool led_suspend_state; | ||
| 91 | # endif | ||
| 92 | # if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) | ||
| 93 | rgb_config_t rgb_matrix; | ||
| 94 | bool rgb_suspend_state; | ||
| 95 | # endif | ||
| 96 | int8_t mouse_x; | ||
| 97 | int8_t mouse_y; | ||
| 98 | uint16_t device_cpi; | ||
| 99 | bool oled_on; | ||
| 100 | layer_state_t t_layer_state; | ||
| 101 | layer_state_t t_default_layer_state; | ||
| 102 | } __attribute__((packed)) I2C_slave_buffer_t; | ||
| 103 | |||
| 104 | static I2C_slave_buffer_t *const i2c_buffer = (I2C_slave_buffer_t *)i2c_slave_reg; | ||
| 105 | |||
| 106 | # define I2C_BACKLIGHT_START offsetof(I2C_slave_buffer_t, backlight_level) | ||
| 107 | # define I2C_RGB_START offsetof(I2C_slave_buffer_t, rgblight_sync) | ||
| 108 | # define I2C_KEYMAP_MASTER_START offsetof(I2C_slave_buffer_t, mmatrix) | ||
| 109 | # define I2C_KEYMAP_SLAVE_START offsetof(I2C_slave_buffer_t, smatrix) | ||
| 110 | # define I2C_SYNC_TIME_START offsetof(I2C_slave_buffer_t, sync_timer) | ||
| 111 | # define I2C_REAL_MODS_START offsetof(I2C_slave_buffer_t, real_mods) | ||
| 112 | # define I2C_WEAK_MODS_START offsetof(I2C_slave_buffer_t, weak_mods) | ||
| 113 | # define I2C_ONESHOT_MODS_START offsetof(I2C_slave_buffer_t, oneshot_mods) | ||
| 114 | # define I2C_ENCODER_START offsetof(I2C_slave_buffer_t, encoder_state) | ||
| 115 | # define I2C_WPM_START offsetof(I2C_slave_buffer_t, current_wpm) | ||
| 116 | # define I2C_MOUSE_X_START offsetof(I2C_slave_buffer_t, mouse_x) | ||
| 117 | # define I2C_MOUSE_Y_START offsetof(I2C_slave_buffer_t, mouse_y) | ||
| 118 | # define I2C_MOUSE_DPI_START offsetof(I2C_slave_buffer_t, device_cpi) | ||
| 119 | # define I2C_OLED_ON_START offsetof(I2C_slave_buffer_t, oled_on) | ||
| 120 | # define I2C_LAYER_STATE_START offsetof(I2C_slave_buffer_t, t_layer_state) | ||
| 121 | # define I2C_DEFAULT_LAYER_STATE_START offsetof(I2C_slave_buffer_t, t_default_layer_state) | ||
| 122 | # define I2C_LED_MATRIX_START offsetof(I2C_slave_buffer_t, led_matrix) | ||
| 123 | # define I2C_LED_SUSPEND_START offsetof(I2C_slave_buffer_t, led_suspend_state) | ||
| 124 | # define I2C_RGB_MATRIX_START offsetof(I2C_slave_buffer_t, rgb_matrix) | ||
| 125 | # define I2C_RGB_SUSPEND_START offsetof(I2C_slave_buffer_t, rgb_suspend_state) | ||
| 126 | |||
| 127 | # define TIMEOUT 100 | ||
| 128 | |||
| 129 | # ifndef SLAVE_I2C_ADDRESS | ||
| 130 | # define SLAVE_I2C_ADDRESS 0x32 | ||
| 131 | # endif | ||
| 132 | |||
| 133 | // Get rows from other half over i2c | ||
| 134 | bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { | ||
| 135 | i2c_readReg(SLAVE_I2C_ADDRESS, I2C_KEYMAP_SLAVE_START, (void *)slave_matrix, sizeof(i2c_buffer->smatrix), TIMEOUT); | ||
| 136 | # ifdef SPLIT_TRANSPORT_MIRROR | ||
| 137 | i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_KEYMAP_MASTER_START, (void *)master_matrix, sizeof(i2c_buffer->mmatrix), TIMEOUT); | ||
| 138 | # endif | ||
| 139 | // write backlight info | ||
| 140 | # ifdef BACKLIGHT_ENABLE | ||
| 141 | uint8_t level = is_backlight_enabled() ? get_backlight_level() : 0; | ||
| 142 | if (level != i2c_buffer->backlight_level) { | ||
| 143 | if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_BACKLIGHT_START, (void *)&level, sizeof(level), TIMEOUT) >= 0) { | ||
| 144 | i2c_buffer->backlight_level = level; | ||
| 145 | } | ||
| 146 | } | ||
| 147 | # endif | ||
| 148 | |||
| 149 | # if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) | ||
| 150 | if (rgblight_get_change_flags()) { | ||
| 151 | rgblight_syncinfo_t rgblight_sync; | ||
| 152 | rgblight_get_syncinfo(&rgblight_sync); | ||
| 153 | if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_START, (void *)&rgblight_sync, sizeof(rgblight_sync), TIMEOUT) >= 0) { | ||
| 154 | rgblight_clear_change_flags(); | ||
| 155 | } | ||
| 156 | } | ||
| 157 | # endif | ||
| 158 | |||
| 159 | # ifdef ENCODER_ENABLE | ||
| 160 | i2c_readReg(SLAVE_I2C_ADDRESS, I2C_ENCODER_START, (void *)i2c_buffer->encoder_state, sizeof(i2c_buffer->encoder_state), TIMEOUT); | ||
| 161 | encoder_update_raw(i2c_buffer->encoder_state); | ||
| 162 | # endif | ||
| 163 | |||
| 164 | # ifdef WPM_ENABLE | ||
| 165 | uint8_t current_wpm = get_current_wpm(); | ||
| 166 | if (current_wpm != i2c_buffer->current_wpm) { | ||
| 167 | if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_WPM_START, (void *)¤t_wpm, sizeof(current_wpm), TIMEOUT) >= 0) { | ||
| 168 | i2c_buffer->current_wpm = current_wpm; | ||
| 169 | } | ||
| 170 | } | ||
| 171 | # endif | ||
| 172 | |||
| 173 | # ifdef POINTING_DEVICE_ENABLE | ||
| 174 | if (is_keyboard_left()) { | ||
| 175 | report_mouse_t temp_report = pointing_device_get_report(); | ||
| 176 | i2c_readReg(SLAVE_I2C_ADDRESS, I2C_MOUSE_X_START, (void *)&i2c_buffer->mouse_x, sizeof(i2c_buffer->mouse_x), TIMEOUT); | ||
| 177 | temp_report.x = i2c_buffer->mouse_x; | ||
| 178 | i2c_readReg(SLAVE_I2C_ADDRESS, I2C_MOUSE_Y_START, (void *)&i2c_buffer->mouse_y, sizeof(i2c_buffer->mouse_y), TIMEOUT); | ||
| 179 | temp_report.y = i2c_buffer->mouse_y; | ||
| 180 | pointing_device_set_report(temp_report); | ||
| 181 | |||
| 182 | if (device_cpi != i2c_buffer->device_cpi) { | ||
| 183 | if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_MOUSE_DPI_START, (void *)&device_cpi, sizeof(device_cpi), TIMEOUT) >= 0) { | ||
| 184 | i2c_buffer->device_cpi = device_cpi | ||
| 185 | } | ||
| 186 | } | ||
| 187 | } | ||
| 188 | # endif | ||
| 189 | |||
| 190 | # ifdef SPLIT_MODS_ENABLE | ||
| 191 | uint8_t real_mods = get_mods(); | ||
| 192 | if (real_mods != i2c_buffer->real_mods) { | ||
| 193 | if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_REAL_MODS_START, (void *)&real_mods, sizeof(real_mods), TIMEOUT) >= 0) { | ||
| 194 | i2c_buffer->real_mods = real_mods; | ||
| 195 | } | ||
| 196 | } | ||
| 197 | |||
| 198 | uint8_t weak_mods = get_weak_mods(); | ||
| 199 | if (weak_mods != i2c_buffer->weak_mods) { | ||
| 200 | if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_WEAK_MODS_START, (void *)&weak_mods, sizeof(weak_mods), TIMEOUT) >= 0) { | ||
| 201 | i2c_buffer->weak_mods = weak_mods; | ||
| 202 | } | ||
| 203 | } | ||
| 204 | |||
| 205 | # ifndef NO_ACTION_ONESHOT | ||
| 206 | uint8_t oneshot_mods = get_oneshot_mods(); | ||
| 207 | if (oneshot_mods != i2c_buffer->oneshot_mods) { | ||
| 208 | if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_ONESHOT_MODS_START, (void *)&oneshot_mods, sizeof(oneshot_mods), TIMEOUT) >= 0) { | ||
| 209 | i2c_buffer->oneshot_mods = oneshot_mods; | ||
| 210 | } | ||
| 211 | } | ||
| 212 | # endif | ||
| 213 | # endif | ||
| 214 | |||
| 215 | if (layer_state != i2c_buffer->t_layer_state) { | ||
| 216 | if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_LAYER_STATE_START, (void *)&layer_state, sizeof(layer_state), TIMEOUT) >= 0) { | ||
| 217 | i2c_buffer->t_layer_state = layer_state; | ||
| 218 | } | ||
| 219 | } | ||
| 220 | |||
| 221 | if (default_layer_state != i2c_buffer->t_default_layer_state) { | ||
| 222 | if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_DEFAULT_LAYER_STATE_START, (void *)&default_layer_state, sizeof(default_layer_state), TIMEOUT) >= 0) { | ||
| 223 | i2c_buffer->t_default_layer_state = default_layer_state; | ||
| 224 | } | ||
| 225 | } | ||
| 226 | |||
| 227 | # ifdef OLED_DRIVER_ENABLE | ||
| 228 | bool is_oled_on = is_oled_on(); | ||
| 229 | if (is_oled_on != i2c_buffer->oled_on) { | ||
| 230 | if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_LAYER_STATE_START, (void *)&is_oled_on, sizeof(is_oled_on), TIMEOUT) >= 0) { | ||
| 231 | i2c_buffer->oled_on = is_oled_on; | ||
| 232 | } | ||
| 233 | } | ||
| 234 | # endif | ||
| 235 | |||
| 236 | # if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) | ||
| 237 | i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_LED_MATRIX_START, (void *)led_matrix_eeconfig, sizeof(i2c_buffer->led_matrix), TIMEOUT); | ||
| 238 | bool suspend_state = led_matrix_get_suspend_state(); | ||
| 239 | i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_LED_SUSPEND_START, (void *)suspend_state, sizeof(i2c_buffer->led_suspend_state), TIMEOUT); | ||
| 240 | # endif | ||
| 241 | # if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) | ||
| 242 | i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_MATRIX_START, (void *)rgb_matrix_config, sizeof(i2c_buffer->rgb_matrix), TIMEOUT); | ||
| 243 | bool suspend_state = rgb_matrix_get_suspend_state(); | ||
| 244 | i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_SUSPEND_START, (void *)suspend_state, sizeof(i2c_buffer->rgb_suspend_state), TIMEOUT); | ||
| 245 | # endif | ||
| 246 | |||
| 247 | # ifndef DISABLE_SYNC_TIMER | ||
| 248 | i2c_buffer->sync_timer = sync_timer_read32() + SYNC_TIMER_OFFSET; | ||
| 249 | i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_SYNC_TIME_START, (void *)&i2c_buffer->sync_timer, sizeof(i2c_buffer->sync_timer), TIMEOUT); | ||
| 250 | # endif | ||
| 251 | |||
| 252 | return true; | ||
| 253 | } | ||
| 254 | |||
| 255 | void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { | ||
| 256 | # ifndef DISABLE_SYNC_TIMER | ||
| 257 | sync_timer_update(i2c_buffer->sync_timer); | ||
| 258 | # endif | ||
| 259 | // Copy matrix to I2C buffer | ||
| 260 | memcpy((void *)i2c_buffer->smatrix, (void *)slave_matrix, sizeof(i2c_buffer->smatrix)); | ||
| 261 | # ifdef SPLIT_TRANSPORT_MIRROR | ||
| 262 | memcpy((void *)master_matrix, (void *)i2c_buffer->mmatrix, sizeof(i2c_buffer->mmatrix)); | ||
| 263 | # endif | ||
| 264 | |||
| 265 | // Read Backlight Info | ||
| 266 | # ifdef BACKLIGHT_ENABLE | ||
| 267 | backlight_set(i2c_buffer->backlight_level); | ||
| 268 | # endif | ||
| 269 | |||
| 270 | # if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) | ||
| 271 | // Update the RGB with the new data | ||
| 272 | if (i2c_buffer->rgblight_sync.status.change_flags != 0) { | ||
| 273 | rgblight_update_sync(&i2c_buffer->rgblight_sync, false); | ||
| 274 | i2c_buffer->rgblight_sync.status.change_flags = 0; | ||
| 275 | } | ||
| 276 | # endif | ||
| 277 | |||
| 278 | # ifdef ENCODER_ENABLE | ||
| 279 | encoder_state_raw(i2c_buffer->encoder_state); | ||
| 280 | # endif | ||
| 281 | |||
| 282 | # ifdef WPM_ENABLE | ||
| 283 | set_current_wpm(i2c_buffer->current_wpm); | ||
| 284 | # endif | ||
| 285 | |||
| 286 | # ifdef POINTING_DEVICE_ENABLE | ||
| 287 | if (!is_keyboard_left()) { | ||
| 288 | static uint16_t cpi; | ||
| 289 | if (cpi != i2c_buffer->device_cpi) { | ||
| 290 | cpi = i2c_buffer->device_cpi; | ||
| 291 | pmw_set_cpi(cpi); | ||
| 292 | } | ||
| 293 | i2c_buffer->mouse_x = split_mouse_x; | ||
| 294 | i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_MOUSE_X_START, (void *)&i2c_buffer->mouse_x, sizeof(i2c_buffer->mouse_x), TIMEOUT); | ||
| 295 | i2c_buffer->mouse_y = split_mouse_y; | ||
| 296 | i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_MOUSE_Y_START, (void *)&i2c_buffer->mouse_y, sizeof(i2c_buffer->mouse_y), TIMEOUT); | ||
| 297 | } | ||
| 298 | |||
| 299 | # endif | ||
| 300 | |||
| 301 | # ifdef SPLIT_MODS_ENABLE | ||
| 302 | set_mods(i2c_buffer->real_mods); | ||
| 303 | set_weak_mods(i2c_buffer->weak_mods); | ||
| 304 | # ifndef NO_ACTION_ONESHOT | ||
| 305 | set_oneshot_mods(i2c_buffer->oneshot_mods); | ||
| 306 | # endif | ||
| 307 | # endif | ||
| 308 | |||
| 309 | if (layer_state != i2c_buffer->t_layer_state) { | ||
| 310 | layer_state = i2c_buffer->t_layer_state; | ||
| 311 | } | ||
| 312 | if (default_layer_state != i2c_buffer->t_default_layer_state) { | ||
| 313 | default_layer_state = i2c_buffer->t_default_layer_state; | ||
| 314 | } | ||
| 315 | |||
| 316 | # ifdef OLED_DRIVER_ENABLE | ||
| 317 | if (i2c_buffer->oled_on) { | ||
| 318 | oled_on(); | ||
| 319 | } else { | ||
| 320 | oled_off(); | ||
| 321 | } | ||
| 322 | # endif | ||
| 323 | |||
| 324 | # if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) | ||
| 325 | memcpy((void *)i2c_buffer->led_matrix, (void *)led_matrix_eeconfig, sizeof(i2c_buffer->led_matrix)); | ||
| 326 | led_matrix_set_suspend_state(i2c_buffer->led_suspend_state); | ||
| 327 | # endif | ||
| 328 | # if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) | ||
| 329 | memcpy((void *)i2c_buffer->rgb_matrix, (void *)rgb_matrix_config, sizeof(i2c_buffer->rgb_matrix)); | ||
| 330 | rgb_matrix_set_suspend_state(i2c_buffer->rgb_suspend_state); | ||
| 331 | # endif | ||
| 332 | } | ||
| 333 | |||
| 334 | void transport_master_init(void) { i2c_init(); } | ||
| 335 | |||
| 336 | void transport_slave_init(void) { i2c_slave_init(SLAVE_I2C_ADDRESS); } | ||
| 337 | |||
| 338 | #else // USE_SERIAL | ||
| 339 | |||
| 340 | # include "serial.h" | ||
| 341 | |||
| 342 | typedef struct _Serial_s2m_buffer_t { | ||
| 343 | // TODO: if MATRIX_COLS > 8 change to uint8_t packed_matrix[] for pack/unpack | ||
| 344 | matrix_row_t smatrix[ROWS_PER_HAND]; | ||
| 345 | # ifdef ENCODER_ENABLE | ||
| 346 | uint8_t encoder_state[NUMBER_OF_ENCODERS]; | ||
| 347 | # endif | ||
| 348 | int8_t mouse_x; | ||
| 349 | int8_t mouse_y; | ||
| 350 | } __attribute__((packed)) Serial_s2m_buffer_t; | ||
| 351 | |||
| 352 | typedef struct _Serial_m2s_buffer_t { | ||
| 353 | # ifdef SPLIT_MODS_ENABLE | ||
| 354 | uint8_t real_mods; | ||
| 355 | uint8_t weak_mods; | ||
| 356 | # ifndef NO_ACTION_ONESHOT | ||
| 357 | uint8_t oneshot_mods; | ||
| 358 | # endif | ||
| 359 | # endif | ||
| 360 | # ifndef DISABLE_SYNC_TIMER | ||
| 361 | uint32_t sync_timer; | ||
| 362 | # endif | ||
| 363 | # ifdef SPLIT_TRANSPORT_MIRROR | ||
| 364 | matrix_row_t mmatrix[ROWS_PER_HAND]; | ||
| 365 | # endif | ||
| 366 | # ifdef BACKLIGHT_ENABLE | ||
| 367 | uint8_t backlight_level; | ||
| 368 | # endif | ||
| 369 | # ifdef WPM_ENABLE | ||
| 370 | uint8_t current_wpm; | ||
| 371 | # endif | ||
| 372 | uint16_t device_cpi; | ||
| 373 | bool oled_on; | ||
| 374 | layer_state_t t_layer_state; | ||
| 375 | layer_state_t t_default_layer_state; | ||
| 376 | # if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) | ||
| 377 | led_eeconfig_t led_matrix; | ||
| 378 | bool led_suspend_state; | ||
| 379 | # endif | ||
| 380 | # if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) | ||
| 381 | rgb_config_t rgb_matrix; | ||
| 382 | bool rgb_suspend_state; | ||
| 383 | # endif | ||
| 384 | } __attribute__((packed)) Serial_m2s_buffer_t; | ||
| 385 | |||
| 386 | # if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) | ||
| 387 | // When MCUs on both sides drive their respective RGB LED chains, | ||
| 388 | // it is necessary to synchronize, so it is necessary to communicate RGB | ||
| 389 | // information. In that case, define RGBLIGHT_SPLIT with info on the number | ||
| 390 | // of LEDs on each half. | ||
| 391 | // | ||
| 392 | // Otherwise, if the master side MCU drives both sides RGB LED chains, | ||
| 393 | // there is no need to communicate. | ||
| 394 | |||
| 395 | typedef struct _Serial_rgblight_t { | ||
| 396 | rgblight_syncinfo_t rgblight_sync; | ||
| 397 | } Serial_rgblight_t; | ||
| 398 | |||
| 399 | volatile Serial_rgblight_t serial_rgblight = {}; | ||
| 400 | uint8_t volatile status_rgblight = 0; | ||
| 401 | # endif | ||
| 402 | |||
| 403 | volatile Serial_s2m_buffer_t serial_s2m_buffer = {}; | ||
| 404 | volatile Serial_m2s_buffer_t serial_m2s_buffer = {}; | ||
| 405 | uint8_t volatile status0 = 0; | ||
| 406 | |||
| 407 | enum serial_transaction_id { | ||
| 408 | GET_SLAVE_MATRIX = 0, | ||
| 409 | # if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) | ||
| 410 | PUT_RGBLIGHT, | ||
| 411 | # endif | ||
| 412 | }; | ||
| 413 | |||
| 414 | SSTD_t transactions[] = { | ||
| 415 | [GET_SLAVE_MATRIX] = | ||
| 416 | { | ||
| 417 | (uint8_t *)&status0, | ||
| 418 | sizeof(serial_m2s_buffer), | ||
| 419 | (uint8_t *)&serial_m2s_buffer, | ||
| 420 | sizeof(serial_s2m_buffer), | ||
| 421 | (uint8_t *)&serial_s2m_buffer, | ||
| 422 | }, | ||
| 423 | # if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) | ||
| 424 | [PUT_RGBLIGHT] = | ||
| 425 | { | ||
| 426 | (uint8_t *)&status_rgblight, sizeof(serial_rgblight), (uint8_t *)&serial_rgblight, 0, NULL // no slave to master transfer | ||
| 427 | }, | ||
| 428 | # endif | ||
| 429 | }; | ||
| 430 | |||
| 431 | void transport_master_init(void) { soft_serial_initiator_init(transactions, TID_LIMIT(transactions)); } | ||
| 432 | |||
| 433 | void transport_slave_init(void) { soft_serial_target_init(transactions, TID_LIMIT(transactions)); } | ||
| 434 | |||
| 435 | # if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) | ||
| 436 | |||
| 437 | // rgblight synchronization information communication. | ||
| 438 | |||
| 439 | void transport_rgblight_master(void) { | ||
| 440 | if (rgblight_get_change_flags()) { | ||
| 441 | rgblight_get_syncinfo((rgblight_syncinfo_t *)&serial_rgblight.rgblight_sync); | ||
| 442 | if (soft_serial_transaction(PUT_RGBLIGHT) == TRANSACTION_END) { | ||
| 443 | rgblight_clear_change_flags(); | ||
| 444 | } | ||
| 445 | } | ||
| 446 | } | ||
| 447 | |||
| 448 | void transport_rgblight_slave(void) { | ||
| 449 | if (status_rgblight == TRANSACTION_ACCEPTED) { | ||
| 450 | rgblight_update_sync((rgblight_syncinfo_t *)&serial_rgblight.rgblight_sync, false); | ||
| 451 | status_rgblight = TRANSACTION_END; | ||
| 452 | } | ||
| 453 | } | ||
| 454 | |||
| 455 | # else | ||
| 456 | # define transport_rgblight_master() | ||
| 457 | # define transport_rgblight_slave() | ||
| 458 | # endif | ||
| 459 | |||
| 460 | bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { | ||
| 461 | # ifndef SERIAL_USE_MULTI_TRANSACTION | ||
| 462 | if (soft_serial_transaction() != TRANSACTION_END) { | ||
| 463 | return false; | ||
| 464 | } | ||
| 465 | # else | ||
| 466 | transport_rgblight_master(); | ||
| 467 | if (soft_serial_transaction(GET_SLAVE_MATRIX) != TRANSACTION_END) { | ||
| 468 | return false; | ||
| 469 | } | ||
| 470 | # endif | ||
| 471 | |||
| 472 | // TODO: if MATRIX_COLS > 8 change to unpack() | ||
| 473 | for (int i = 0; i < ROWS_PER_HAND; ++i) { | ||
| 474 | slave_matrix[i] = serial_s2m_buffer.smatrix[i]; | ||
| 475 | # ifdef SPLIT_TRANSPORT_MIRROR | ||
| 476 | serial_m2s_buffer.mmatrix[i] = master_matrix[i]; | ||
| 477 | # endif | ||
| 478 | } | ||
| 479 | |||
| 480 | # ifdef BACKLIGHT_ENABLE | ||
| 481 | // Write backlight level for slave to read | ||
| 482 | serial_m2s_buffer.backlight_level = is_backlight_enabled() ? get_backlight_level() : 0; | ||
| 483 | # endif | ||
| 484 | |||
| 485 | # ifdef ENCODER_ENABLE | ||
| 486 | encoder_update_raw((uint8_t *)serial_s2m_buffer.encoder_state); | ||
| 487 | # endif | ||
| 488 | |||
| 489 | # ifdef WPM_ENABLE | ||
| 490 | // Write wpm to slave | ||
| 491 | serial_m2s_buffer.current_wpm = get_current_wpm(); | ||
| 492 | # endif | ||
| 493 | |||
| 494 | # ifdef SPLIT_MODS_ENABLE | ||
| 495 | serial_m2s_buffer.real_mods = get_mods(); | ||
| 496 | serial_m2s_buffer.weak_mods = get_weak_mods(); | ||
| 497 | # ifndef NO_ACTION_ONESHOT | ||
| 498 | serial_m2s_buffer.oneshot_mods = get_oneshot_mods(); | ||
| 499 | # endif | ||
| 500 | # endif | ||
| 501 | |||
| 502 | # ifdef POINTING_DEVICE_ENABLE | ||
| 503 | if (is_keyboard_left()) { | ||
| 504 | report_mouse_t temp_report = pointing_device_get_report(); | ||
| 505 | temp_report.x = serial_s2m_buffer.mouse_x; | ||
| 506 | temp_report.y = serial_s2m_buffer.mouse_y; | ||
| 507 | pointing_device_set_report(temp_report); | ||
| 508 | serial_m2s_buffer.device_cpi = device_cpi; | ||
| 509 | } | ||
| 510 | # endif | ||
| 511 | |||
| 512 | serial_m2s_buffer.t_layer_state = layer_state; | ||
| 513 | serial_m2s_buffer.t_default_layer_state = default_layer_state; | ||
| 514 | # ifdef OLED_DRIVER_ENABLE | ||
| 515 | serial_m2s_buffer.oled_on = is_oled_on(); | ||
| 516 | # endif | ||
| 517 | |||
| 518 | # if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) | ||
| 519 | serial_m2s_buffer.led_matrix = led_matrix_eeconfig; | ||
| 520 | serial_m2s_buffer.led_suspend_state = led_matrix_get_suspend_state(); | ||
| 521 | # endif | ||
| 522 | # if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) | ||
| 523 | serial_m2s_buffer.rgb_matrix = rgb_matrix_config; | ||
| 524 | serial_m2s_buffer.rgb_suspend_state = rgb_matrix_get_suspend_state(); | ||
| 525 | # endif | ||
| 526 | |||
| 527 | # ifndef DISABLE_SYNC_TIMER | ||
| 528 | serial_m2s_buffer.sync_timer = sync_timer_read32() + SYNC_TIMER_OFFSET; | ||
| 529 | # endif | ||
| 530 | return true; | ||
| 531 | } | ||
| 532 | |||
| 533 | void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { | ||
| 534 | transport_rgblight_slave(); | ||
| 535 | # ifndef DISABLE_SYNC_TIMER | ||
| 536 | sync_timer_update(serial_m2s_buffer.sync_timer); | ||
| 537 | # endif | ||
| 538 | |||
| 539 | // TODO: if MATRIX_COLS > 8 change to pack() | ||
| 540 | for (int i = 0; i < ROWS_PER_HAND; ++i) { | ||
| 541 | serial_s2m_buffer.smatrix[i] = slave_matrix[i]; | ||
| 542 | # ifdef SPLIT_TRANSPORT_MIRROR | ||
| 543 | master_matrix[i] = serial_m2s_buffer.mmatrix[i]; | ||
| 544 | # endif | ||
| 545 | } | ||
| 546 | |||
| 547 | # ifdef BACKLIGHT_ENABLE | ||
| 548 | backlight_set(serial_m2s_buffer.backlight_level); | ||
| 549 | # endif | ||
| 550 | |||
| 551 | # ifdef ENCODER_ENABLE | ||
| 552 | encoder_state_raw((uint8_t *)serial_s2m_buffer.encoder_state); | ||
| 553 | # endif | ||
| 554 | |||
| 555 | # ifdef WPM_ENABLE | ||
| 556 | set_current_wpm(serial_m2s_buffer.current_wpm); | ||
| 557 | # endif | ||
| 558 | |||
| 559 | # ifdef SPLIT_MODS_ENABLE | ||
| 560 | set_mods(serial_m2s_buffer.real_mods); | ||
| 561 | set_weak_mods(serial_m2s_buffer.weak_mods); | ||
| 562 | # ifndef NO_ACTION_ONESHOT | ||
| 563 | set_oneshot_mods(serial_m2s_buffer.oneshot_mods); | ||
| 564 | # endif | ||
| 565 | # endif | ||
| 566 | |||
| 567 | # ifdef POINTING_DEVICE_ENABLE | ||
| 568 | if (!is_keyboard_left()) { | ||
| 569 | static uint16_t cpi; | ||
| 570 | if (cpi != serial_m2s_buffer.device_cpi) { | ||
| 571 | cpi = serial_m2s_buffer.device_cpi; | ||
| 572 | pmw_set_cpi(cpi); | ||
| 573 | } | ||
| 574 | serial_s2m_buffer.mouse_x = split_mouse_x; | ||
| 575 | serial_s2m_buffer.mouse_y = split_mouse_y; | ||
| 576 | } | ||
| 577 | # endif | ||
| 578 | |||
| 579 | if (layer_state != serial_m2s_buffer.t_layer_state) { | ||
| 580 | layer_state = serial_m2s_buffer.t_layer_state; | ||
| 581 | } | ||
| 582 | if (default_layer_state != serial_m2s_buffer.t_default_layer_state) { | ||
| 583 | default_layer_state = serial_m2s_buffer.t_default_layer_state; | ||
| 584 | } | ||
| 585 | # ifdef OLED_DRIVER_ENABLE | ||
| 586 | if (serial_m2s_buffer.oled_on) { | ||
| 587 | oled_on(); | ||
| 588 | } else { | ||
| 589 | oled_off(); | ||
| 590 | } | ||
| 591 | # endif | ||
| 592 | |||
| 593 | # if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) | ||
| 594 | led_matrix_eeconfig = serial_m2s_buffer.led_matrix; | ||
| 595 | led_matrix_set_suspend_state(serial_m2s_buffer.led_suspend_state); | ||
| 596 | # endif | ||
| 597 | # if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) | ||
| 598 | rgb_matrix_config = serial_m2s_buffer.rgb_matrix; | ||
| 599 | rgb_matrix_set_suspend_state(serial_m2s_buffer.rgb_suspend_state); | ||
| 600 | # endif | ||
| 601 | } | ||
| 602 | |||
| 603 | #endif | ||
