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