]> git.donarmstrong.com Git - qmk_firmware.git/blob - quantum/split_common/transport.c
Fix process_combo which assign -1 to uint16_t (#3697)
[qmk_firmware.git] / quantum / split_common / transport.c
1
2 #include "config.h"
3 #include "matrix.h"
4 #include "quantum.h"
5
6 #define ROWS_PER_HAND (MATRIX_ROWS/2)
7
8 #ifdef RGBLIGHT_ENABLE
9 #   include "rgblight.h"
10 #endif
11
12 #ifdef BACKLIGHT_ENABLE
13 # include "backlight.h"
14   extern backlight_config_t backlight_config;
15 #endif
16
17 #if defined(USE_I2C) || defined(EH)
18
19 #include "i2c.h"
20
21 #ifndef SLAVE_I2C_ADDRESS
22 #  define SLAVE_I2C_ADDRESS           0x32
23 #endif
24
25 #if (MATRIX_COLS > 8)
26 #  error "Currently only supports 8 COLS"
27 #endif
28
29 // Get rows from other half over i2c
30 bool transport_master(matrix_row_t matrix[]) {
31   int err = 0;
32
33   // write backlight info
34 #ifdef BACKLIGHT_ENABLE
35   if (BACKLIT_DIRTY) {
36     err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_WRITE);
37     if (err) { goto i2c_error; }
38
39     // Backlight location
40     err = i2c_master_write(I2C_BACKLIT_START);
41     if (err) { goto i2c_error; }
42
43     // Write backlight
44     i2c_master_write(get_backlight_level());
45
46     BACKLIT_DIRTY = false;
47   }
48 #endif
49
50   err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_WRITE);
51   if (err) { goto i2c_error; }
52
53   // start of matrix stored at I2C_KEYMAP_START
54   err = i2c_master_write(I2C_KEYMAP_START);
55   if (err) { goto i2c_error; }
56
57   // Start read
58   err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_READ);
59   if (err) { goto i2c_error; }
60
61   if (!err) {
62     int i;
63     for (i = 0; i < ROWS_PER_HAND-1; ++i) {
64       matrix[i] = i2c_master_read(I2C_ACK);
65     }
66     matrix[i] = i2c_master_read(I2C_NACK);
67     i2c_master_stop();
68   } else {
69 i2c_error: // the cable is disconnceted, or something else went wrong
70     i2c_reset_state();
71     return false;
72   }
73
74 #ifdef RGBLIGHT_ENABLE
75   if (RGB_DIRTY) {
76     err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_WRITE);
77     if (err) { goto i2c_error; }
78
79     // RGB Location
80     err = i2c_master_write(I2C_RGB_START);
81     if (err) { goto i2c_error; }
82
83     uint32_t dword = eeconfig_read_rgblight();
84
85     // Write RGB
86     err = i2c_master_write_data(&dword, 4);
87     if (err) { goto i2c_error; }
88
89     RGB_DIRTY = false;
90     i2c_master_stop();
91   }
92 #endif
93
94   return true;
95 }
96
97 void transport_slave(matrix_row_t matrix[]) {
98
99   for (int i = 0; i < ROWS_PER_HAND; ++i)
100   {
101     i2c_slave_buffer[I2C_KEYMAP_START + i] = matrix[i];
102   }
103   // Read Backlight Info
104   #ifdef BACKLIGHT_ENABLE
105   if (BACKLIT_DIRTY)
106   {
107     backlight_set(i2c_slave_buffer[I2C_BACKLIT_START]);
108     BACKLIT_DIRTY = false;
109   }
110   #endif
111   #ifdef RGBLIGHT_ENABLE
112   if (RGB_DIRTY)
113   {
114     // Disable interupts (RGB data is big)
115     cli();
116     // Create new DWORD for RGB data
117     uint32_t dword;
118
119     // Fill the new DWORD with the data that was sent over
120     uint8_t * dword_dat = (uint8_t *)(&dword);
121     for (int i = 0; i < 4; i++)
122     {
123       dword_dat[i] = i2c_slave_buffer[I2C_RGB_START + i];
124     }
125
126     // Update the RGB now with the new data and set RGB_DIRTY to false
127     rgblight_update_dword(dword);
128     RGB_DIRTY = false;
129     // Re-enable interupts now that RGB is set
130     sei();
131   }
132   #endif
133 }
134
135 void transport_master_init(void) {
136   i2c_master_init();
137 }
138
139 void transport_slave_init(void) {
140   i2c_slave_init(SLAVE_I2C_ADDRESS);
141 }
142
143 #else // USE_SERIAL
144
145 #include "serial.h"
146
147 typedef struct _Serial_s2m_buffer_t {
148   // TODO: if MATRIX_COLS > 8 change to uint8_t packed_matrix[] for pack/unpack
149   matrix_row_t smatrix[ROWS_PER_HAND];
150 } Serial_s2m_buffer_t;
151
152 typedef struct _Serial_m2s_buffer_t {
153 #ifdef BACKLIGHT_ENABLE
154     uint8_t backlight_level;
155 #endif
156 #if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
157     rgblight_config_t rgblight_config; //not yet use
158     //
159     // When MCUs on both sides drive their respective RGB LED chains,
160     // it is necessary to synchronize, so it is necessary to communicate RGB information.
161     // In that case, define the RGBLIGHT_SPLIT macro.
162     //
163     // Otherwise, if the master side MCU drives both sides RGB LED chains,
164     // there is no need to communicate.
165 #endif
166 } Serial_m2s_buffer_t;
167
168 volatile Serial_s2m_buffer_t serial_s2m_buffer = {};
169 volatile Serial_m2s_buffer_t serial_m2s_buffer = {};
170 uint8_t volatile status0 = 0;
171
172 SSTD_t transactions[] = {
173   { (uint8_t *)&status0,
174     sizeof(serial_m2s_buffer), (uint8_t *)&serial_m2s_buffer,
175     sizeof(serial_s2m_buffer), (uint8_t *)&serial_s2m_buffer
176   }
177 };
178
179 void transport_master_init(void)
180 { soft_serial_initiator_init(transactions, TID_LIMIT(transactions)); }
181
182 void transport_slave_init(void)
183 { soft_serial_target_init(transactions, TID_LIMIT(transactions)); }
184
185 bool transport_master(matrix_row_t matrix[]) {
186
187   if (soft_serial_transaction()) {
188     return false;
189   }
190
191   // TODO:  if MATRIX_COLS > 8 change to unpack()
192   for (int i = 0; i < ROWS_PER_HAND; ++i) {
193     matrix[i] = serial_s2m_buffer.smatrix[i];
194   }
195
196   #if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
197     // Code to send RGB over serial goes here (not implemented yet)
198   #endif
199
200   #ifdef BACKLIGHT_ENABLE
201     // Write backlight level for slave to read
202     serial_m2s_buffer.backlight_level = backlight_config.enable ? backlight_config.level : 0;
203   #endif
204
205   return true;
206 }
207
208 void transport_slave(matrix_row_t matrix[]) {
209
210   // TODO: if MATRIX_COLS > 8 change to pack()
211   for (int i = 0; i < ROWS_PER_HAND; ++i)
212   {
213     serial_s2m_buffer.smatrix[i] = matrix[i];
214   }
215   #ifdef BACKLIGHT_ENABLE
216     backlight_set(serial_m2s_buffer.backlight_level);
217   #endif
218   #if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
219   // Add serial implementation for RGB here
220   #endif
221
222 }
223
224 #endif