diff options
author | James Churchill <pelrun@gmail.com> | 2019-03-13 03:23:28 +1000 |
---|---|---|
committer | Drashna Jaelre <drashna@live.com> | 2019-03-12 10:23:28 -0700 |
commit | 37932c293c15011f883a91e91ee02631ead44a2e (patch) | |
tree | f1b4b3b44f816240b06580658b42b3646f121025 /quantum/split_common | |
parent | 25bb059e4e42ed2637202230ff3d8b765e1295cd (diff) | |
download | qmk_firmware-37932c293c15011f883a91e91ee02631ead44a2e.tar.gz qmk_firmware-37932c293c15011f883a91e91ee02631ead44a2e.zip |
Next set of split_common changes (#4974)
* Update split_common to use standard i2c drivers
* Eliminate RGB_DIRTY/BACKLIT_DIRTY
* Fix avr i2c_master error handling
* Fix i2c_slave addressing
* Remove unneeded timeout on i2c_stop()
* Fix RGB I2C transfers
* Remove incorrect comment
Diffstat (limited to 'quantum/split_common')
-rw-r--r-- | quantum/split_common/i2c.c | 184 | ||||
-rw-r--r-- | quantum/split_common/i2c.h | 59 | ||||
-rw-r--r-- | quantum/split_common/matrix.c | 1 | ||||
-rw-r--r-- | quantum/split_common/split_flags.c | 5 | ||||
-rw-r--r-- | quantum/split_common/split_flags.h | 15 | ||||
-rw-r--r-- | quantum/split_common/split_util.c | 5 | ||||
-rw-r--r-- | quantum/split_common/transport.c | 236 |
7 files changed, 85 insertions, 420 deletions
diff --git a/quantum/split_common/i2c.c b/quantum/split_common/i2c.c deleted file mode 100644 index 45e958b39..000000000 --- a/quantum/split_common/i2c.c +++ /dev/null | |||
@@ -1,184 +0,0 @@ | |||
1 | #include <util/twi.h> | ||
2 | #include <avr/io.h> | ||
3 | #include <stdlib.h> | ||
4 | #include <avr/interrupt.h> | ||
5 | #include <util/twi.h> | ||
6 | #include <stdbool.h> | ||
7 | #include "i2c.h" | ||
8 | #include "split_flags.h" | ||
9 | |||
10 | // Limits the amount of we wait for any one i2c transaction. | ||
11 | // Since were running SCL line 100kHz (=> 10μs/bit), and each transactions is | ||
12 | // 9 bits, a single transaction will take around 90μs to complete. | ||
13 | // | ||
14 | // (F_CPU/SCL_CLOCK) => # of μC cycles to transfer a bit | ||
15 | // poll loop takes at least 8 clock cycles to execute | ||
16 | #define I2C_LOOP_TIMEOUT (9+1)*(F_CPU/SCL_CLOCK)/8 | ||
17 | |||
18 | #define BUFFER_POS_INC() (slave_buffer_pos = (slave_buffer_pos+1)%SLAVE_BUFFER_SIZE) | ||
19 | |||
20 | volatile uint8_t i2c_slave_buffer[SLAVE_BUFFER_SIZE]; | ||
21 | |||
22 | static volatile uint8_t slave_buffer_pos; | ||
23 | static volatile bool slave_has_register_set = false; | ||
24 | |||
25 | // Wait for an i2c operation to finish | ||
26 | inline static | ||
27 | void i2c_delay(void) { | ||
28 | uint16_t lim = 0; | ||
29 | while(!(TWCR & (1<<TWINT)) && lim < I2C_LOOP_TIMEOUT) | ||
30 | lim++; | ||
31 | |||
32 | // easier way, but will wait slightly longer | ||
33 | // _delay_us(100); | ||
34 | } | ||
35 | |||
36 | // Setup twi to run at 100kHz | ||
37 | void i2c_master_init(void) { | ||
38 | // no prescaler | ||
39 | TWSR = 0; | ||
40 | // Set TWI clock frequency to SCL_CLOCK. Need TWBR>10. | ||
41 | // Check datasheets for more info. | ||
42 | TWBR = ((F_CPU/SCL_CLOCK)-16)/2; | ||
43 | } | ||
44 | |||
45 | // Start a transaction with the given i2c slave address. The direction of the | ||
46 | // transfer is set with I2C_READ and I2C_WRITE. | ||
47 | // returns: 0 => success | ||
48 | // 1 => error | ||
49 | uint8_t i2c_master_start(uint8_t address) { | ||
50 | TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTA); | ||
51 | |||
52 | i2c_delay(); | ||
53 | |||
54 | // check that we started successfully | ||
55 | if ( (TW_STATUS != TW_START) && (TW_STATUS != TW_REP_START)) | ||
56 | return 1; | ||
57 | |||
58 | TWDR = address; | ||
59 | TWCR = (1<<TWINT) | (1<<TWEN); | ||
60 | |||
61 | i2c_delay(); | ||
62 | |||
63 | if ( (TW_STATUS != TW_MT_SLA_ACK) && (TW_STATUS != TW_MR_SLA_ACK) ) | ||
64 | return 1; // slave did not acknowledge | ||
65 | else | ||
66 | return 0; // success | ||
67 | } | ||
68 | |||
69 | |||
70 | // Finish the i2c transaction. | ||
71 | void i2c_master_stop(void) { | ||
72 | TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO); | ||
73 | |||
74 | uint16_t lim = 0; | ||
75 | while(!(TWCR & (1<<TWSTO)) && lim < I2C_LOOP_TIMEOUT) | ||
76 | lim++; | ||
77 | } | ||
78 | |||
79 | // Write one byte to the i2c slave. | ||
80 | // returns 0 => slave ACK | ||
81 | // 1 => slave NACK | ||
82 | uint8_t i2c_master_write(uint8_t data) { | ||
83 | TWDR = data; | ||
84 | TWCR = (1<<TWINT) | (1<<TWEN); | ||
85 | |||
86 | i2c_delay(); | ||
87 | |||
88 | // check if the slave acknowledged us | ||
89 | return (TW_STATUS == TW_MT_DATA_ACK) ? 0 : 1; | ||
90 | } | ||
91 | |||
92 | uint8_t i2c_master_write_data(void *const TXdata, uint8_t dataLen) { | ||
93 | |||
94 | uint8_t *data = (uint8_t *)TXdata; | ||
95 | int err = 0; | ||
96 | |||
97 | for (int i = 0; i < dataLen; i++) { | ||
98 | err = i2c_master_write(data[i]); | ||
99 | |||
100 | if ( err ) | ||
101 | return err; | ||
102 | } | ||
103 | |||
104 | return err; | ||
105 | |||
106 | } | ||
107 | |||
108 | // Read one byte from the i2c slave. If ack=1 the slave is acknowledged, | ||
109 | // if ack=0 the acknowledge bit is not set. | ||
110 | // returns: byte read from i2c device | ||
111 | uint8_t i2c_master_read(int ack) { | ||
112 | TWCR = (1<<TWINT) | (1<<TWEN) | (ack<<TWEA); | ||
113 | |||
114 | i2c_delay(); | ||
115 | return TWDR; | ||
116 | } | ||
117 | |||
118 | void i2c_reset_state(void) { | ||
119 | TWCR = 0; | ||
120 | } | ||
121 | |||
122 | void i2c_slave_init(uint8_t address) { | ||
123 | TWAR = address << 0; // slave i2c address | ||
124 | // TWEN - twi enable | ||
125 | // TWEA - enable address acknowledgement | ||
126 | // TWINT - twi interrupt flag | ||
127 | // TWIE - enable the twi interrupt | ||
128 | TWCR = (1<<TWIE) | (1<<TWEA) | (1<<TWINT) | (1<<TWEN); | ||
129 | } | ||
130 | |||
131 | ISR(TWI_vect); | ||
132 | |||
133 | ISR(TWI_vect) { | ||
134 | uint8_t ack = 1; | ||
135 | switch(TW_STATUS) { | ||
136 | case TW_SR_SLA_ACK: | ||
137 | // this device has been addressed as a slave receiver | ||
138 | slave_has_register_set = false; | ||
139 | break; | ||
140 | |||
141 | case TW_SR_DATA_ACK: | ||
142 | // this device has received data as a slave receiver | ||
143 | // The first byte that we receive in this transaction sets the location | ||
144 | // of the read/write location of the slaves memory that it exposes over | ||
145 | // i2c. After that, bytes will be written at slave_buffer_pos, incrementing | ||
146 | // slave_buffer_pos after each write. | ||
147 | if(!slave_has_register_set) { | ||
148 | slave_buffer_pos = TWDR; | ||
149 | // don't acknowledge the master if this memory loctaion is out of bounds | ||
150 | if ( slave_buffer_pos >= SLAVE_BUFFER_SIZE ) { | ||
151 | ack = 0; | ||
152 | slave_buffer_pos = 0; | ||
153 | } | ||
154 | |||
155 | slave_has_register_set = true; | ||
156 | } else { | ||
157 | i2c_slave_buffer[slave_buffer_pos] = TWDR; | ||
158 | |||
159 | if ( slave_buffer_pos == I2C_BACKLIT_START) { | ||
160 | BACKLIT_DIRTY = true; | ||
161 | } else if ( slave_buffer_pos == (I2C_RGB_START+3)) { | ||
162 | RGB_DIRTY = true; | ||
163 | } | ||
164 | |||
165 | BUFFER_POS_INC(); | ||
166 | } | ||
167 | break; | ||
168 | |||
169 | case TW_ST_SLA_ACK: | ||
170 | case TW_ST_DATA_ACK: | ||
171 | // master has addressed this device as a slave transmitter and is | ||
172 | // requesting data. | ||
173 | TWDR = i2c_slave_buffer[slave_buffer_pos]; | ||
174 | BUFFER_POS_INC(); | ||
175 | break; | ||
176 | |||
177 | case TW_BUS_ERROR: // something went wrong, reset twi state | ||
178 | TWCR = 0; | ||
179 | default: | ||
180 | break; | ||
181 | } | ||
182 | // Reset everything, so we are ready for the next TWI interrupt | ||
183 | TWCR |= (1<<TWIE) | (1<<TWINT) | (ack<<TWEA) | (1<<TWEN); | ||
184 | } | ||
diff --git a/quantum/split_common/i2c.h b/quantum/split_common/i2c.h deleted file mode 100644 index 91e8e96f4..000000000 --- a/quantum/split_common/i2c.h +++ /dev/null | |||
@@ -1,59 +0,0 @@ | |||
1 | #pragma once | ||
2 | |||
3 | #include <stdint.h> | ||
4 | |||
5 | #ifndef F_CPU | ||
6 | #define F_CPU 16000000UL | ||
7 | #endif | ||
8 | |||
9 | #define I2C_READ 1 | ||
10 | #define I2C_WRITE 0 | ||
11 | |||
12 | #define I2C_ACK 1 | ||
13 | #define I2C_NACK 0 | ||
14 | |||
15 | // Address location defines (Keymap should be last, as it's size is dynamic) | ||
16 | #define I2C_BACKLIT_START 0x00 | ||
17 | // Need 4 bytes for RGB (32 bit) | ||
18 | #define I2C_RGB_START 0x01 | ||
19 | #define I2C_KEYMAP_START 0x06 | ||
20 | |||
21 | // Slave buffer (8bit per) | ||
22 | // Rows per hand + backlit space + rgb space | ||
23 | // TODO : Make this dynamically sized | ||
24 | #define SLAVE_BUFFER_SIZE 0x20 | ||
25 | |||
26 | // i2c SCL clock frequency | ||
27 | #ifndef SCL_CLOCK | ||
28 | #define SCL_CLOCK 100000L | ||
29 | #endif | ||
30 | |||
31 | // Support 8bits right now (8 cols) will need to edit to take higher (code exists in delta split?) | ||
32 | extern volatile uint8_t i2c_slave_buffer[SLAVE_BUFFER_SIZE]; | ||
33 | |||
34 | void i2c_master_init(void); | ||
35 | uint8_t i2c_master_start(uint8_t address); | ||
36 | void i2c_master_stop(void); | ||
37 | uint8_t i2c_master_write(uint8_t data); | ||
38 | uint8_t i2c_master_write_data(void *const TXdata, uint8_t dataLen); | ||
39 | uint8_t i2c_master_read(int); | ||
40 | void i2c_reset_state(void); | ||
41 | void i2c_slave_init(uint8_t address); | ||
42 | |||
43 | |||
44 | static inline unsigned char i2c_start_read(unsigned char addr) { | ||
45 | return i2c_master_start((addr << 1) | I2C_READ); | ||
46 | } | ||
47 | |||
48 | static inline unsigned char i2c_start_write(unsigned char addr) { | ||
49 | return i2c_master_start((addr << 1) | I2C_WRITE); | ||
50 | } | ||
51 | |||
52 | // from SSD1306 scrips | ||
53 | extern unsigned char i2c_rep_start(unsigned char addr); | ||
54 | extern void i2c_start_wait(unsigned char addr); | ||
55 | extern unsigned char i2c_readAck(void); | ||
56 | extern unsigned char i2c_readNak(void); | ||
57 | extern unsigned char i2c_read(unsigned char ack); | ||
58 | |||
59 | #define i2c_read(ack) (ack) ? i2c_readAck() : i2c_readNak(); | ||
diff --git a/quantum/split_common/matrix.c b/quantum/split_common/matrix.c index f2a277c69..dcb96254f 100644 --- a/quantum/split_common/matrix.c +++ b/quantum/split_common/matrix.c | |||
@@ -25,7 +25,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
25 | #include "matrix.h" | 25 | #include "matrix.h" |
26 | #include "split_util.h" | 26 | #include "split_util.h" |
27 | #include "config.h" | 27 | #include "config.h" |
28 | #include "split_flags.h" | ||
29 | #include "quantum.h" | 28 | #include "quantum.h" |
30 | #include "debounce.h" | 29 | #include "debounce.h" |
31 | #include "transport.h" | 30 | #include "transport.h" |
diff --git a/quantum/split_common/split_flags.c b/quantum/split_common/split_flags.c deleted file mode 100644 index 1f5825d65..000000000 --- a/quantum/split_common/split_flags.c +++ /dev/null | |||
@@ -1,5 +0,0 @@ | |||
1 | #include "split_flags.h" | ||
2 | |||
3 | volatile bool RGB_DIRTY = false; | ||
4 | |||
5 | volatile bool BACKLIT_DIRTY = false; \ No newline at end of file | ||
diff --git a/quantum/split_common/split_flags.h b/quantum/split_common/split_flags.h deleted file mode 100644 index aaac474a7..000000000 --- a/quantum/split_common/split_flags.h +++ /dev/null | |||
@@ -1,15 +0,0 @@ | |||
1 | #pragma once | ||
2 | |||
3 | #include <stdbool.h> | ||
4 | #include <stdint.h> | ||
5 | |||
6 | /** | ||
7 | * Global Flags | ||
8 | **/ | ||
9 | |||
10 | //RGB Stuff | ||
11 | extern volatile bool RGB_DIRTY; | ||
12 | |||
13 | |||
14 | //Backlight Stuff | ||
15 | extern volatile bool BACKLIT_DIRTY; | ||
diff --git a/quantum/split_common/split_util.c b/quantum/split_common/split_util.c index 5095cb8fd..da870f877 100644 --- a/quantum/split_common/split_util.c +++ b/quantum/split_common/split_util.c | |||
@@ -3,7 +3,6 @@ | |||
3 | #include "keyboard.h" | 3 | #include "keyboard.h" |
4 | #include "config.h" | 4 | #include "config.h" |
5 | #include "timer.h" | 5 | #include "timer.h" |
6 | #include "split_flags.h" | ||
7 | #include "transport.h" | 6 | #include "transport.h" |
8 | #include "quantum.h" | 7 | #include "quantum.h" |
9 | 8 | ||
@@ -60,10 +59,6 @@ static void keyboard_master_setup(void) { | |||
60 | #endif | 59 | #endif |
61 | #endif | 60 | #endif |
62 | transport_master_init(); | 61 | transport_master_init(); |
63 | |||
64 | // For master the Backlight info needs to be sent on startup | ||
65 | // Otherwise the salve won't start with the proper info until an update | ||
66 | BACKLIT_DIRTY = true; | ||
67 | } | 62 | } |
68 | 63 | ||
69 | static void keyboard_slave_setup(void) | 64 | static void keyboard_slave_setup(void) |
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 |