8 #define ROWS_PER_HAND (MATRIX_ROWS / 2)
10 #ifdef RGBLIGHT_ENABLE
11 # include "rgblight.h"
14 #ifdef BACKLIGHT_ENABLE
15 # include "backlight.h"
20 static pin_t encoders_pad[] = ENCODERS_PAD_A;
21 # define NUMBER_OF_ENCODERS (sizeof(encoders_pad)/sizeof(pin_t))
24 #if defined(USE_I2C) || defined(EH)
26 # include "i2c_master.h"
27 # include "i2c_slave.h"
29 typedef struct _I2C_slave_buffer_t {
30 matrix_row_t smatrix[ROWS_PER_HAND];
31 uint8_t backlight_level;
32 #if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
33 rgblight_syncinfo_t rgblight_sync;
36 uint8_t encoder_state[NUMBER_OF_ENCODERS];
40 static I2C_slave_buffer_t * const i2c_buffer = (I2C_slave_buffer_t *)i2c_slave_reg;
42 # define I2C_BACKLIGHT_START offsetof(I2C_slave_buffer_t, backlight_level)
43 # define I2C_RGB_START offsetof(I2C_slave_buffer_t, rgblight_sync)
44 # define I2C_KEYMAP_START offsetof(I2C_slave_buffer_t, smatrix)
45 # define I2C_ENCODER_START offsetof(I2C_slave_buffer_t, encoder_state)
49 # ifndef SLAVE_I2C_ADDRESS
50 # define SLAVE_I2C_ADDRESS 0x32
53 // Get rows from other half over i2c
54 bool transport_master(matrix_row_t matrix[]) {
55 i2c_readReg(SLAVE_I2C_ADDRESS, I2C_KEYMAP_START, (void *)matrix, sizeof(i2c_buffer->smatrix), TIMEOUT);
57 // write backlight info
58 # ifdef BACKLIGHT_ENABLE
59 uint8_t level = is_backlight_enabled() ? get_backlight_level() : 0;
60 if (level != i2c_buffer->backlight_level) {
61 if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_BACKLIGHT_START, (void *)&level, sizeof(level), TIMEOUT) >= 0) {
62 i2c_buffer->backlight_level = level;
67 # if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
68 if (rgblight_get_change_flags()) {
69 rgblight_syncinfo_t rgblight_sync;
70 rgblight_get_syncinfo(&rgblight_sync);
71 if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_START,
72 (void *)&rgblight_sync, sizeof(rgblight_sync), TIMEOUT) >= 0) {
73 rgblight_clear_change_flags();
78 # ifdef ENCODER_ENABLE
79 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);
86 void transport_slave(matrix_row_t matrix[]) {
87 // Copy matrix to I2C buffer
88 memcpy((void*)i2c_buffer->smatrix, (void *)matrix, sizeof(i2c_buffer->smatrix));
90 // Read Backlight Info
91 # ifdef BACKLIGHT_ENABLE
92 backlight_set(i2c_buffer->backlight_level);
95 # if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
96 // Update the RGB with the new data
97 if (i2c_buffer->rgblight_sync.status.change_flags != 0) {
98 rgblight_update_sync(&i2c_buffer->rgblight_sync, false);
99 i2c_buffer->rgblight_sync.status.change_flags = 0;
103 # ifdef ENCODER_ENABLE
104 encoder_state_raw(i2c_buffer->encoder_state);
108 void transport_master_init(void) { i2c_init(); }
110 void transport_slave_init(void) { i2c_slave_init(SLAVE_I2C_ADDRESS); }
116 typedef struct _Serial_s2m_buffer_t {
117 // TODO: if MATRIX_COLS > 8 change to uint8_t packed_matrix[] for pack/unpack
118 matrix_row_t smatrix[ROWS_PER_HAND];
120 # ifdef ENCODER_ENABLE
121 uint8_t encoder_state[NUMBER_OF_ENCODERS];
124 } Serial_s2m_buffer_t;
126 typedef struct _Serial_m2s_buffer_t {
127 # ifdef BACKLIGHT_ENABLE
128 uint8_t backlight_level;
130 } Serial_m2s_buffer_t;
132 #if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
133 // When MCUs on both sides drive their respective RGB LED chains,
134 // 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
136 // of LEDs on each half.
138 // Otherwise, if the master side MCU drives both sides RGB LED chains,
139 // there is no need to communicate.
141 typedef struct _Serial_rgblight_t {
142 rgblight_syncinfo_t rgblight_sync;
145 volatile Serial_rgblight_t serial_rgblight = {};
146 uint8_t volatile status_rgblight = 0;
149 volatile Serial_s2m_buffer_t serial_s2m_buffer = {};
150 volatile Serial_m2s_buffer_t serial_m2s_buffer = {};
151 uint8_t volatile status0 = 0;
153 enum serial_transaction_id {
154 GET_SLAVE_MATRIX = 0,
155 #if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
160 SSTD_t transactions[] = {
161 [GET_SLAVE_MATRIX] = {
163 sizeof(serial_m2s_buffer),
164 (uint8_t *)&serial_m2s_buffer,
165 sizeof(serial_s2m_buffer),
166 (uint8_t *)&serial_s2m_buffer,
168 #if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
170 (uint8_t *)&status_rgblight,
171 sizeof(serial_rgblight),
172 (uint8_t *)&serial_rgblight,
173 0, NULL // no slave to master transfer
178 void transport_master_init(void) { soft_serial_initiator_init(transactions, TID_LIMIT(transactions)); }
180 void transport_slave_init(void) { soft_serial_target_init(transactions, TID_LIMIT(transactions)); }
182 #if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
184 // rgblight synchronization information communication.
186 void transport_rgblight_master(void) {
187 if (rgblight_get_change_flags()) {
188 rgblight_get_syncinfo((rgblight_syncinfo_t *)&serial_rgblight.rgblight_sync);
189 if (soft_serial_transaction(PUT_RGBLIGHT) == TRANSACTION_END) {
190 rgblight_clear_change_flags();
195 void transport_rgblight_slave(void) {
196 if (status_rgblight == TRANSACTION_ACCEPTED) {
197 rgblight_update_sync((rgblight_syncinfo_t *)&serial_rgblight.rgblight_sync,
199 status_rgblight = TRANSACTION_END;
204 #define transport_rgblight_master()
205 #define transport_rgblight_slave()
208 bool transport_master(matrix_row_t matrix[]) {
209 #ifndef SERIAL_USE_MULTI_TRANSACTION
210 if (soft_serial_transaction() != TRANSACTION_END) {
214 transport_rgblight_master();
215 if (soft_serial_transaction(GET_SLAVE_MATRIX) != TRANSACTION_END) {
220 // TODO: if MATRIX_COLS > 8 change to unpack()
221 for (int i = 0; i < ROWS_PER_HAND; ++i) {
222 matrix[i] = serial_s2m_buffer.smatrix[i];
225 # ifdef BACKLIGHT_ENABLE
226 // Write backlight level for slave to read
227 serial_m2s_buffer.backlight_level = is_backlight_enabled() ? get_backlight_level() : 0;
230 # ifdef ENCODER_ENABLE
231 encoder_update_raw((uint8_t *)serial_s2m_buffer.encoder_state);
237 void transport_slave(matrix_row_t matrix[]) {
238 transport_rgblight_slave();
239 // TODO: if MATRIX_COLS > 8 change to pack()
240 for (int i = 0; i < ROWS_PER_HAND; ++i) {
241 serial_s2m_buffer.smatrix[i] = matrix[i];
243 # ifdef BACKLIGHT_ENABLE
244 backlight_set(serial_m2s_buffer.backlight_level);
247 # ifdef ENCODER_ENABLE
248 encoder_state_raw((uint8_t *)serial_s2m_buffer.encoder_state);