8 #define ROWS_PER_HAND (MATRIX_ROWS / 2)
10 #ifdef RGBLIGHT_ENABLE
11 # include "rgblight.h"
14 #ifdef BACKLIGHT_ENABLE
15 # include "backlight.h"
22 #if defined(USE_I2C) || defined(EH)
24 # include "i2c_master.h"
25 # include "i2c_slave.h"
27 typedef struct _I2C_slave_buffer_t {
28 matrix_row_t smatrix[ROWS_PER_HAND];
29 uint8_t backlight_level;
30 #if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
31 rgblight_syncinfo_t rgblight_sync;
34 uint8_t encoder_state[NUMBER_OF_ENCODERS];
38 static I2C_slave_buffer_t * const i2c_buffer = (I2C_slave_buffer_t *)i2c_slave_reg;
40 # define I2C_BACKLIGHT_START offsetof(I2C_slave_buffer_t, backlight_level)
41 # define I2C_RGB_START offsetof(I2C_slave_buffer_t, rgblight_sync)
42 # define I2C_KEYMAP_START offsetof(I2C_slave_buffer_t, smatrix)
43 # define I2C_ENCODER_START offsetof(I2C_slave_buffer_t, encoder_state)
47 # ifndef SLAVE_I2C_ADDRESS
48 # define SLAVE_I2C_ADDRESS 0x32
51 // Get rows from other half over i2c
52 bool transport_master(matrix_row_t matrix[]) {
53 i2c_readReg(SLAVE_I2C_ADDRESS, I2C_KEYMAP_START, (void *)matrix, sizeof(i2c_buffer->smatrix), TIMEOUT);
55 // write backlight info
56 # ifdef BACKLIGHT_ENABLE
57 uint8_t level = is_backlight_enabled() ? get_backlight_level() : 0;
58 if (level != i2c_buffer->backlight_level) {
59 if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_BACKLIGHT_START, (void *)&level, sizeof(level), TIMEOUT) >= 0) {
60 i2c_buffer->backlight_level = level;
65 # if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
66 if (rgblight_get_change_flags()) {
67 rgblight_syncinfo_t rgblight_sync;
68 rgblight_get_syncinfo(&rgblight_sync);
69 if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_START,
70 (void *)&rgblight_sync, sizeof(rgblight_sync), TIMEOUT) >= 0) {
71 rgblight_clear_change_flags();
76 # ifdef ENCODER_ENABLE
77 i2c_readReg(SLAVE_I2C_ADDRESS, I2C_ENCODER_START, (void *)i2c_buffer->encoder_state, sizeof(i2c_buffer->encoder_state), TIMEOUT);
78 encoder_update_raw(i2c_buffer->encoder_state);
84 void transport_slave(matrix_row_t matrix[]) {
85 // Copy matrix to I2C buffer
86 memcpy((void*)i2c_buffer->smatrix, (void *)matrix, sizeof(i2c_buffer->smatrix));
88 // Read Backlight Info
89 # ifdef BACKLIGHT_ENABLE
90 backlight_set(i2c_buffer->backlight_level);
93 # if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
94 // Update the RGB with the new data
95 if (i2c_buffer->rgblight_sync.status.change_flags != 0) {
96 rgblight_update_sync(&i2c_buffer->rgblight_sync, false);
97 i2c_buffer->rgblight_sync.status.change_flags = 0;
101 # ifdef ENCODER_ENABLE
102 encoder_state_raw(i2c_buffer->encoder_state);
106 void transport_master_init(void) { i2c_init(); }
108 void transport_slave_init(void) { i2c_slave_init(SLAVE_I2C_ADDRESS); }
114 typedef struct _Serial_s2m_buffer_t {
115 // TODO: if MATRIX_COLS > 8 change to uint8_t packed_matrix[] for pack/unpack
116 matrix_row_t smatrix[ROWS_PER_HAND];
118 # ifdef ENCODER_ENABLE
119 uint8_t encoder_state[NUMBER_OF_ENCODERS];
122 } Serial_s2m_buffer_t;
124 typedef struct _Serial_m2s_buffer_t {
125 # ifdef BACKLIGHT_ENABLE
126 uint8_t backlight_level;
128 } Serial_m2s_buffer_t;
130 #if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
131 // When MCUs on both sides drive their respective RGB LED chains,
132 // it is necessary to synchronize, so it is necessary to communicate RGB
133 // information. In that case, define RGBLIGHT_SPLIT with info on the number
134 // of LEDs on each half.
136 // Otherwise, if the master side MCU drives both sides RGB LED chains,
137 // there is no need to communicate.
139 typedef struct _Serial_rgblight_t {
140 rgblight_syncinfo_t rgblight_sync;
143 volatile Serial_rgblight_t serial_rgblight = {};
144 uint8_t volatile status_rgblight = 0;
147 volatile Serial_s2m_buffer_t serial_s2m_buffer = {};
148 volatile Serial_m2s_buffer_t serial_m2s_buffer = {};
149 uint8_t volatile status0 = 0;
151 enum serial_transaction_id {
152 GET_SLAVE_MATRIX = 0,
153 #if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
158 SSTD_t transactions[] = {
159 [GET_SLAVE_MATRIX] = {
161 sizeof(serial_m2s_buffer),
162 (uint8_t *)&serial_m2s_buffer,
163 sizeof(serial_s2m_buffer),
164 (uint8_t *)&serial_s2m_buffer,
166 #if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
168 (uint8_t *)&status_rgblight,
169 sizeof(serial_rgblight),
170 (uint8_t *)&serial_rgblight,
171 0, NULL // no slave to master transfer
176 void transport_master_init(void) { soft_serial_initiator_init(transactions, TID_LIMIT(transactions)); }
178 void transport_slave_init(void) { soft_serial_target_init(transactions, TID_LIMIT(transactions)); }
180 #if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
182 // rgblight synchronization information communication.
184 void transport_rgblight_master(void) {
185 if (rgblight_get_change_flags()) {
186 rgblight_get_syncinfo((rgblight_syncinfo_t *)&serial_rgblight.rgblight_sync);
187 if (soft_serial_transaction(PUT_RGBLIGHT) == TRANSACTION_END) {
188 rgblight_clear_change_flags();
193 void transport_rgblight_slave(void) {
194 if (status_rgblight == TRANSACTION_ACCEPTED) {
195 rgblight_update_sync((rgblight_syncinfo_t *)&serial_rgblight.rgblight_sync,
197 status_rgblight = TRANSACTION_END;
202 #define transport_rgblight_master()
203 #define transport_rgblight_slave()
206 bool transport_master(matrix_row_t matrix[]) {
207 #ifndef SERIAL_USE_MULTI_TRANSACTION
208 if (soft_serial_transaction() != TRANSACTION_END) {
212 transport_rgblight_master();
213 if (soft_serial_transaction(GET_SLAVE_MATRIX) != TRANSACTION_END) {
218 // TODO: if MATRIX_COLS > 8 change to unpack()
219 for (int i = 0; i < ROWS_PER_HAND; ++i) {
220 matrix[i] = serial_s2m_buffer.smatrix[i];
223 # ifdef BACKLIGHT_ENABLE
224 // Write backlight level for slave to read
225 serial_m2s_buffer.backlight_level = is_backlight_enabled() ? get_backlight_level() : 0;
228 # ifdef ENCODER_ENABLE
229 encoder_update_raw((uint8_t *)serial_s2m_buffer.encoder_state);
235 void transport_slave(matrix_row_t matrix[]) {
236 transport_rgblight_slave();
237 // TODO: if MATRIX_COLS > 8 change to pack()
238 for (int i = 0; i < ROWS_PER_HAND; ++i) {
239 serial_s2m_buffer.smatrix[i] = matrix[i];
241 # ifdef BACKLIGHT_ENABLE
242 backlight_set(serial_m2s_buffer.backlight_level);
245 # ifdef ENCODER_ENABLE
246 encoder_state_raw((uint8_t *)serial_s2m_buffer.encoder_state);