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 | |
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
-rw-r--r-- | common_features.mk | 10 | ||||
-rw-r--r-- | docs/i2c_driver.md | 2 | ||||
-rw-r--r-- | drivers/arm/i2c_master.c | 3 | ||||
-rw-r--r-- | drivers/arm/i2c_master.h | 2 | ||||
-rwxr-xr-x | drivers/avr/i2c_master.c | 160 | ||||
-rwxr-xr-x | drivers/avr/i2c_master.h | 2 | ||||
-rwxr-xr-x | drivers/avr/i2c_slave.c | 2 | ||||
-rw-r--r-- | keyboards/cannonkeys/satisfaction75/i2c_master.c | 2 | ||||
-rw-r--r-- | keyboards/dc01/left/matrix.c | 4 | ||||
-rw-r--r-- | keyboards/ergodox_ez/ergodox_ez.c | 6 | ||||
-rw-r--r-- | keyboards/ergodox_ez/matrix.c | 4 | ||||
-rw-r--r-- | keyboards/gergo/gergo.c | 4 | ||||
-rw-r--r-- | keyboards/gergo/matrix.c | 36 | ||||
-rw-r--r-- | quantum/keymap_common.c | 22 | ||||
-rw-r--r-- | quantum/quantum.c | 30 | ||||
-rw-r--r-- | quantum/quantum.h | 4 | ||||
-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 | ||||
-rw-r--r-- | tmk_core/common/avr/suspend.c | 9 |
24 files changed, 190 insertions, 617 deletions
diff --git a/common_features.mk b/common_features.mk index 20c38ae82..046f94d1d 100644 --- a/common_features.mk +++ b/common_features.mk | |||
@@ -308,16 +308,16 @@ ifeq ($(strip $(SPLIT_KEYBOARD)), yes) | |||
308 | OPT_DEFS += -DSPLIT_KEYBOARD | 308 | OPT_DEFS += -DSPLIT_KEYBOARD |
309 | 309 | ||
310 | # Include files used by all split keyboards | 310 | # Include files used by all split keyboards |
311 | QUANTUM_SRC += $(QUANTUM_DIR)/split_common/split_flags.c \ | 311 | QUANTUM_SRC += $(QUANTUM_DIR)/split_common/split_util.c |
312 | $(QUANTUM_DIR)/split_common/split_util.c | ||
313 | 312 | ||
314 | # Determine which (if any) transport files are required | 313 | # Determine which (if any) transport files are required |
315 | ifneq ($(strip $(SPLIT_TRANSPORT)), custom) | 314 | ifneq ($(strip $(SPLIT_TRANSPORT)), custom) |
316 | QUANTUM_SRC += $(QUANTUM_DIR)/split_common/transport.c | 315 | QUANTUM_SRC += $(QUANTUM_DIR)/split_common/transport.c |
317 | # Functions added via QUANTUM_LIB_SRC are only included in the final binary if they're called. | 316 | # Functions added via QUANTUM_LIB_SRC are only included in the final binary if they're called. |
318 | # Unused functions are pruned away, which is why we can add both drivers here without bloat. | 317 | # Unused functions are pruned away, which is why we can add multiple drivers here without bloat. |
319 | QUANTUM_LIB_SRC += $(QUANTUM_DIR)/split_common/i2c.c \ | 318 | QUANTUM_LIB_SRC += $(QUANTUM_DIR)/split_common/serial.c \ |
320 | $(QUANTUM_DIR)/split_common/serial.c | 319 | i2c_master.c \ |
320 | i2c_slave.c | ||
321 | endif | 321 | endif |
322 | COMMON_VPATH += $(QUANTUM_PATH)/split_common | 322 | COMMON_VPATH += $(QUANTUM_PATH)/split_common |
323 | endif | 323 | endif |
diff --git a/docs/i2c_driver.md b/docs/i2c_driver.md index 18546fc62..bb1a2d74f 100644 --- a/docs/i2c_driver.md +++ b/docs/i2c_driver.md | |||
@@ -12,7 +12,7 @@ The I2C Master drivers used in QMK have a set of common functions to allow porta | |||
12 | |`uint8_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout);` |Receive data over I2C. Address is the 7-bit slave address without the direction. Saves number of bytes specified by `length` in `data` array. Returns status of transaction. | | 12 | |`uint8_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout);` |Receive data over I2C. Address is the 7-bit slave address without the direction. Saves number of bytes specified by `length` in `data` array. Returns status of transaction. | |
13 | |`uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);` |Same as the `i2c_transmit` function but `regaddr` sets where in the slave the data will be written. | | 13 | |`uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);` |Same as the `i2c_transmit` function but `regaddr` sets where in the slave the data will be written. | |
14 | |`uint8_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);` |Same as the `i2c_receive` function but `regaddr` sets from where in the slave the data will be read. | | 14 | |`uint8_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);` |Same as the `i2c_receive` function but `regaddr` sets from where in the slave the data will be read. | |
15 | |`uint8_t i2c_stop(uint16_t timeout);` |Stops the I2C driver. | | 15 | |`uint8_t i2c_stop(void);` |Ends an I2C transaction. | |
16 | 16 | ||
17 | ### Function Return | 17 | ### Function Return |
18 | 18 | ||
diff --git a/drivers/arm/i2c_master.c b/drivers/arm/i2c_master.c index 50a30ebce..0e5edcc38 100644 --- a/drivers/arm/i2c_master.c +++ b/drivers/arm/i2c_master.c | |||
@@ -101,8 +101,7 @@ uint8_t i2c_readReg(uint8_t devaddr, uint8_t* regaddr, uint8_t* data, uint16_t l | |||
101 | return i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), regaddr, 1, data, length, MS2ST(timeout)); | 101 | return i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), regaddr, 1, data, length, MS2ST(timeout)); |
102 | } | 102 | } |
103 | 103 | ||
104 | // This is usually not needed. It releases the driver to allow pins to become GPIO again. | 104 | uint8_t i2c_stop(void) |
105 | uint8_t i2c_stop(uint16_t timeout) | ||
106 | { | 105 | { |
107 | i2cStop(&I2C_DRIVER); | 106 | i2cStop(&I2C_DRIVER); |
108 | return 0; | 107 | return 0; |
diff --git a/drivers/arm/i2c_master.h b/drivers/arm/i2c_master.h index 7a9eb32eb..4ab2301f8 100644 --- a/drivers/arm/i2c_master.h +++ b/drivers/arm/i2c_master.h | |||
@@ -47,4 +47,4 @@ uint8_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t ti | |||
47 | uint8_t i2c_transmit_receive(uint8_t address, uint8_t * tx_body, uint16_t tx_length, uint8_t * rx_body, uint16_t rx_length); | 47 | uint8_t i2c_transmit_receive(uint8_t address, uint8_t * tx_body, uint16_t tx_length, uint8_t * rx_body, uint16_t rx_length); |
48 | uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout); | 48 | uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout); |
49 | uint8_t i2c_readReg(uint8_t devaddr, uint8_t* regaddr, uint8_t* data, uint16_t length, uint16_t timeout); | 49 | uint8_t i2c_readReg(uint8_t devaddr, uint8_t* regaddr, uint8_t* data, uint16_t length, uint16_t timeout); |
50 | uint8_t i2c_stop(uint16_t timeout); | 50 | uint8_t i2c_stop(void); |
diff --git a/drivers/avr/i2c_master.c b/drivers/avr/i2c_master.c index 19bae33e9..d97a35cd6 100755 --- a/drivers/avr/i2c_master.c +++ b/drivers/avr/i2c_master.c | |||
@@ -7,43 +7,44 @@ | |||
7 | 7 | ||
8 | #include "i2c_master.h" | 8 | #include "i2c_master.h" |
9 | #include "timer.h" | 9 | #include "timer.h" |
10 | #include "wait.h" | ||
10 | 11 | ||
11 | #ifndef F_SCL | 12 | #ifndef F_SCL |
12 | #define F_SCL 400000UL // SCL frequency | 13 | # define F_SCL 400000UL // SCL frequency |
13 | #endif | 14 | #endif |
14 | #define Prescaler 1 | 15 | #define Prescaler 1 |
15 | #define TWBR_val ((((F_CPU / F_SCL) / Prescaler) - 16 ) / 2) | 16 | #define TWBR_val ((((F_CPU / F_SCL) / Prescaler) - 16) / 2) |
16 | 17 | ||
17 | void i2c_init(void) | 18 | void i2c_init(void) { |
18 | { | 19 | TWSR = 0; /* no prescaler */ |
19 | TWSR = 0; /* no prescaler */ | ||
20 | TWBR = (uint8_t)TWBR_val; | 20 | TWBR = (uint8_t)TWBR_val; |
21 | } | 21 | } |
22 | 22 | ||
23 | i2c_status_t i2c_start(uint8_t address, uint16_t timeout) | 23 | i2c_status_t i2c_start(uint8_t address, uint16_t timeout) { |
24 | { | ||
25 | // reset TWI control register | 24 | // reset TWI control register |
26 | TWCR = 0; | 25 | TWCR = 0; |
27 | // transmit START condition | 26 | // transmit START condition |
28 | TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); | 27 | TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); |
29 | 28 | ||
30 | uint16_t timeout_timer = timer_read(); | 29 | uint16_t timeout_timer = timer_read(); |
31 | while( !(TWCR & (1<<TWINT)) ) { | 30 | while (!(TWCR & (1 << TWINT))) { |
32 | if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) { | 31 | if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) { |
33 | return I2C_STATUS_TIMEOUT; | 32 | return I2C_STATUS_TIMEOUT; |
34 | } | 33 | } |
35 | } | 34 | } |
36 | 35 | ||
37 | // check if the start condition was successfully transmitted | 36 | // check if the start condition was successfully transmitted |
38 | if(((TW_STATUS & 0xF8) != TW_START) && ((TW_STATUS & 0xF8) != TW_REP_START)){ return I2C_STATUS_ERROR; } | 37 | if (((TW_STATUS & 0xF8) != TW_START) && ((TW_STATUS & 0xF8) != TW_REP_START)) { |
38 | return I2C_STATUS_ERROR; | ||
39 | } | ||
39 | 40 | ||
40 | // load slave address into data register | 41 | // load slave address into data register |
41 | TWDR = address; | 42 | TWDR = address; |
42 | // start transmission of address | 43 | // start transmission of address |
43 | TWCR = (1<<TWINT) | (1<<TWEN); | 44 | TWCR = (1 << TWINT) | (1 << TWEN); |
44 | 45 | ||
45 | timeout_timer = timer_read(); | 46 | timeout_timer = timer_read(); |
46 | while( !(TWCR & (1<<TWINT)) ) { | 47 | while (!(TWCR & (1 << TWINT))) { |
47 | if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) { | 48 | if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) { |
48 | return I2C_STATUS_TIMEOUT; | 49 | return I2C_STATUS_TIMEOUT; |
49 | } | 50 | } |
@@ -51,38 +52,39 @@ i2c_status_t i2c_start(uint8_t address, uint16_t timeout) | |||
51 | 52 | ||
52 | // check if the device has acknowledged the READ / WRITE mode | 53 | // check if the device has acknowledged the READ / WRITE mode |
53 | uint8_t twst = TW_STATUS & 0xF8; | 54 | uint8_t twst = TW_STATUS & 0xF8; |
54 | if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return I2C_STATUS_ERROR; | 55 | if ((twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK)) { |
56 | return I2C_STATUS_ERROR; | ||
57 | } | ||
55 | 58 | ||
56 | return I2C_STATUS_SUCCESS; | 59 | return I2C_STATUS_SUCCESS; |
57 | } | 60 | } |
58 | 61 | ||
59 | i2c_status_t i2c_write(uint8_t data, uint16_t timeout) | 62 | i2c_status_t i2c_write(uint8_t data, uint16_t timeout) { |
60 | { | ||
61 | // load data into data register | 63 | // load data into data register |
62 | TWDR = data; | 64 | TWDR = data; |
63 | // start transmission of data | 65 | // start transmission of data |
64 | TWCR = (1<<TWINT) | (1<<TWEN); | 66 | TWCR = (1 << TWINT) | (1 << TWEN); |
65 | 67 | ||
66 | uint16_t timeout_timer = timer_read(); | 68 | uint16_t timeout_timer = timer_read(); |
67 | while( !(TWCR & (1<<TWINT)) ) { | 69 | while (!(TWCR & (1 << TWINT))) { |
68 | if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) { | 70 | if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) { |
69 | return I2C_STATUS_TIMEOUT; | 71 | return I2C_STATUS_TIMEOUT; |
70 | } | 72 | } |
71 | } | 73 | } |
72 | 74 | ||
73 | if( (TW_STATUS & 0xF8) != TW_MT_DATA_ACK ){ return I2C_STATUS_ERROR; } | 75 | if ((TW_STATUS & 0xF8) != TW_MT_DATA_ACK) { |
76 | return I2C_STATUS_ERROR; | ||
77 | } | ||
74 | 78 | ||
75 | return I2C_STATUS_SUCCESS; | 79 | return I2C_STATUS_SUCCESS; |
76 | } | 80 | } |
77 | 81 | ||
78 | int16_t i2c_read_ack(uint16_t timeout) | 82 | int16_t i2c_read_ack(uint16_t timeout) { |
79 | { | ||
80 | |||
81 | // start TWI module and acknowledge data after reception | 83 | // start TWI module and acknowledge data after reception |
82 | TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA); | 84 | TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA); |
83 | 85 | ||
84 | uint16_t timeout_timer = timer_read(); | 86 | uint16_t timeout_timer = timer_read(); |
85 | while( !(TWCR & (1<<TWINT)) ) { | 87 | while (!(TWCR & (1 << TWINT))) { |
86 | if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) { | 88 | if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) { |
87 | return I2C_STATUS_TIMEOUT; | 89 | return I2C_STATUS_TIMEOUT; |
88 | } | 90 | } |
@@ -92,14 +94,12 @@ int16_t i2c_read_ack(uint16_t timeout) | |||
92 | return TWDR; | 94 | return TWDR; |
93 | } | 95 | } |
94 | 96 | ||
95 | int16_t i2c_read_nack(uint16_t timeout) | 97 | int16_t i2c_read_nack(uint16_t timeout) { |
96 | { | ||
97 | |||
98 | // start receiving without acknowledging reception | 98 | // start receiving without acknowledging reception |
99 | TWCR = (1<<TWINT) | (1<<TWEN); | 99 | TWCR = (1 << TWINT) | (1 << TWEN); |
100 | 100 | ||
101 | uint16_t timeout_timer = timer_read(); | 101 | uint16_t timeout_timer = timer_read(); |
102 | while( !(TWCR & (1<<TWINT)) ) { | 102 | while (!(TWCR & (1 << TWINT))) { |
103 | if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) { | 103 | if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) { |
104 | return I2C_STATUS_TIMEOUT; | 104 | return I2C_STATUS_TIMEOUT; |
105 | } | 105 | } |
@@ -109,115 +109,89 @@ int16_t i2c_read_nack(uint16_t timeout) | |||
109 | return TWDR; | 109 | return TWDR; |
110 | } | 110 | } |
111 | 111 | ||
112 | i2c_status_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout) | 112 | i2c_status_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout) { |
113 | { | ||
114 | i2c_status_t status = i2c_start(address | I2C_WRITE, timeout); | 113 | i2c_status_t status = i2c_start(address | I2C_WRITE, timeout); |
115 | if (status) return status; | ||
116 | 114 | ||
117 | for (uint16_t i = 0; i < length; i++) { | 115 | for (uint16_t i = 0; i < length && status >= 0; i++) { |
118 | status = i2c_write(data[i], timeout); | 116 | status = i2c_write(data[i], timeout); |
119 | if (status) return status; | ||
120 | } | 117 | } |
121 | 118 | ||
122 | status = i2c_stop(timeout); | 119 | i2c_stop(); |
123 | if (status) return status; | ||
124 | 120 | ||
125 | return I2C_STATUS_SUCCESS; | 121 | return status; |
126 | } | 122 | } |
127 | 123 | ||
128 | i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout) | 124 | i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout) { |
129 | { | ||
130 | i2c_status_t status = i2c_start(address | I2C_READ, timeout); | 125 | i2c_status_t status = i2c_start(address | I2C_READ, timeout); |
131 | if (status) return status; | ||
132 | 126 | ||
133 | for (uint16_t i = 0; i < (length-1); i++) { | 127 | for (uint16_t i = 0; i < (length - 1) && status >= 0; i++) { |
134 | status = i2c_read_ack(timeout); | 128 | status = i2c_read_ack(timeout); |
135 | if (status >= 0) { | 129 | if (status >= 0) { |
136 | data[i] = status; | 130 | data[i] = status; |
137 | } else { | ||
138 | return status; | ||
139 | } | 131 | } |
140 | } | 132 | } |
141 | 133 | ||
142 | status = i2c_read_nack(timeout); | 134 | if (status >= 0) { |
143 | if (status >= 0 ) { | 135 | status = i2c_read_nack(timeout); |
144 | data[(length-1)] = status; | 136 | if (status >= 0) { |
145 | } else { | 137 | data[(length - 1)] = status; |
146 | return status; | 138 | } |
147 | } | 139 | } |
148 | 140 | ||
149 | status = i2c_stop(timeout); | 141 | i2c_stop(); |
150 | if (status) return status; | ||
151 | 142 | ||
152 | return I2C_STATUS_SUCCESS; | 143 | return status; |
153 | } | 144 | } |
154 | 145 | ||
155 | i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) | 146 | i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) { |
156 | { | ||
157 | i2c_status_t status = i2c_start(devaddr | 0x00, timeout); | 147 | i2c_status_t status = i2c_start(devaddr | 0x00, timeout); |
158 | if (status) return status; | 148 | if (status >= 0) { |
159 | 149 | status = i2c_write(regaddr, timeout); | |
160 | status = i2c_write(regaddr, timeout); | ||
161 | if (status) return status; | ||
162 | 150 | ||
163 | for (uint16_t i = 0; i < length; i++) { | 151 | for (uint16_t i = 0; i < length && status >= 0; i++) { |
164 | status = i2c_write(data[i], timeout); | 152 | status = i2c_write(data[i], timeout); |
165 | if (status) return status; | 153 | } |
166 | } | 154 | } |
167 | 155 | ||
168 | status = i2c_stop(timeout); | 156 | i2c_stop(); |
169 | if (status) return status; | ||
170 | 157 | ||
171 | return I2C_STATUS_SUCCESS; | 158 | return status; |
172 | } | 159 | } |
173 | 160 | ||
174 | i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) | 161 | i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) { |
175 | { | ||
176 | i2c_status_t status = i2c_start(devaddr, timeout); | 162 | i2c_status_t status = i2c_start(devaddr, timeout); |
177 | if (status) return status; | 163 | if (status < 0) { |
164 | goto error; | ||
165 | } | ||
178 | 166 | ||
179 | status = i2c_write(regaddr, timeout); | 167 | status = i2c_write(regaddr, timeout); |
180 | if (status) return status; | 168 | if (status < 0) { |
181 | 169 | goto error; | |
182 | status = i2c_stop(timeout); | 170 | } |
183 | if (status) return status; | ||
184 | 171 | ||
185 | status = i2c_start(devaddr | 0x01, timeout); | 172 | status = i2c_start(devaddr | 0x01, timeout); |
186 | if (status) return status; | ||
187 | 173 | ||
188 | for (uint16_t i = 0; i < (length-1); i++) { | 174 | for (uint16_t i = 0; i < (length - 1) && status >= 0; i++) { |
189 | status = i2c_read_ack(timeout); | 175 | status = i2c_read_ack(timeout); |
190 | if (status >= 0) { | 176 | if (status >= 0) { |
191 | data[i] = status; | 177 | data[i] = status; |
192 | } else { | ||
193 | return status; | ||
194 | } | 178 | } |
195 | } | 179 | } |
196 | 180 | ||
197 | status = i2c_read_nack(timeout); | 181 | if (status >= 0) { |
198 | if (status >= 0 ) { | 182 | status = i2c_read_nack(timeout); |
199 | data[(length-1)] = status; | 183 | if (status >= 0) { |
200 | } else { | 184 | data[(length - 1)] = status; |
201 | return status; | 185 | } |
202 | } | 186 | } |
203 | 187 | ||
204 | status = i2c_stop(timeout); | 188 | error: |
205 | if (status) return status; | 189 | i2c_stop(); |
206 | 190 | ||
207 | return I2C_STATUS_SUCCESS; | 191 | return status; |
208 | } | 192 | } |
209 | 193 | ||
210 | i2c_status_t i2c_stop(uint16_t timeout) | 194 | void i2c_stop(void) { |
211 | { | ||
212 | // transmit STOP condition | 195 | // transmit STOP condition |
213 | TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO); | 196 | TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO); |
214 | |||
215 | uint16_t timeout_timer = timer_read(); | ||
216 | while(TWCR & (1<<TWSTO)) { | ||
217 | if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) { | ||
218 | return I2C_STATUS_TIMEOUT; | ||
219 | } | ||
220 | } | ||
221 | |||
222 | return I2C_STATUS_SUCCESS; | ||
223 | } | 197 | } |
diff --git a/drivers/avr/i2c_master.h b/drivers/avr/i2c_master.h index 89c64599c..81a7fb5e3 100755 --- a/drivers/avr/i2c_master.h +++ b/drivers/avr/i2c_master.h | |||
@@ -26,6 +26,6 @@ i2c_status_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length, uint1 | |||
26 | i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout); | 26 | i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout); |
27 | i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout); | 27 | i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout); |
28 | i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout); | 28 | i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout); |
29 | i2c_status_t i2c_stop(uint16_t timeout); | 29 | void i2c_stop(void); |
30 | 30 | ||
31 | #endif // I2C_MASTER_H \ No newline at end of file | 31 | #endif // I2C_MASTER_H \ No newline at end of file |
diff --git a/drivers/avr/i2c_slave.c b/drivers/avr/i2c_slave.c index 18a29a45a..dbb9fb0df 100755 --- a/drivers/avr/i2c_slave.c +++ b/drivers/avr/i2c_slave.c | |||
@@ -16,7 +16,7 @@ static volatile bool slave_has_register_set = false; | |||
16 | 16 | ||
17 | void i2c_slave_init(uint8_t address){ | 17 | void i2c_slave_init(uint8_t address){ |
18 | // load address into TWI address register | 18 | // load address into TWI address register |
19 | TWAR = (address << 1); | 19 | TWAR = address; |
20 | // set the TWCR to enable address matching and enable TWI, clear TWINT, enable TWI interrupt | 20 | // set the TWCR to enable address matching and enable TWI, clear TWINT, enable TWI interrupt |
21 | TWCR = (1 << TWIE) | (1 << TWEA) | (1 << TWINT) | (1 << TWEN); | 21 | TWCR = (1 << TWIE) | (1 << TWEA) | (1 << TWINT) | (1 << TWEN); |
22 | } | 22 | } |
diff --git a/keyboards/cannonkeys/satisfaction75/i2c_master.c b/keyboards/cannonkeys/satisfaction75/i2c_master.c index a19dbcc9f..d81eb92d4 100644 --- a/keyboards/cannonkeys/satisfaction75/i2c_master.c +++ b/keyboards/cannonkeys/satisfaction75/i2c_master.c | |||
@@ -109,7 +109,7 @@ uint8_t i2c_readReg(uint8_t devaddr, uint8_t* regaddr, uint8_t* data, uint16_t l | |||
109 | } | 109 | } |
110 | 110 | ||
111 | // This is usually not needed. It releases the driver to allow pins to become GPIO again. | 111 | // This is usually not needed. It releases the driver to allow pins to become GPIO again. |
112 | uint8_t i2c_stop(uint16_t timeout) | 112 | uint8_t i2c_stop(void) |
113 | { | 113 | { |
114 | i2cStop(&I2C_DRIVER); | 114 | i2cStop(&I2C_DRIVER); |
115 | return 0; | 115 | return 0; |
diff --git a/keyboards/dc01/left/matrix.c b/keyboards/dc01/left/matrix.c index cbe3b3f3d..a3db220e4 100644 --- a/keyboards/dc01/left/matrix.c +++ b/keyboards/dc01/left/matrix.c | |||
@@ -455,10 +455,10 @@ i2c_status_t i2c_transaction(uint8_t address, uint32_t mask, uint8_t col_offset) | |||
455 | matrix[MATRIX_ROWS - 1] |= ((uint32_t)err << (MATRIX_COLS_SCANNED + col_offset)); //add new bits at the end | 455 | matrix[MATRIX_ROWS - 1] |= ((uint32_t)err << (MATRIX_COLS_SCANNED + col_offset)); //add new bits at the end |
456 | 456 | ||
457 | } else { | 457 | } else { |
458 | i2c_stop(10); | 458 | i2c_stop(); |
459 | return 1; | 459 | return 1; |
460 | } | 460 | } |
461 | 461 | ||
462 | i2c_stop(10); | 462 | i2c_stop(); |
463 | return 0; | 463 | return 0; |
464 | } \ No newline at end of file | 464 | } \ No newline at end of file |
diff --git a/keyboards/ergodox_ez/ergodox_ez.c b/keyboards/ergodox_ez/ergodox_ez.c index 3b2c94350..b27a6b89d 100644 --- a/keyboards/ergodox_ez/ergodox_ez.c +++ b/keyboards/ergodox_ez/ergodox_ez.c | |||
@@ -128,7 +128,7 @@ uint8_t init_mcp23018(void) { | |||
128 | mcp23018_status = i2c_write(IODIRA, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; | 128 | mcp23018_status = i2c_write(IODIRA, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; |
129 | mcp23018_status = i2c_write(0b00000000, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; | 129 | mcp23018_status = i2c_write(0b00000000, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; |
130 | mcp23018_status = i2c_write(0b00111111, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; | 130 | mcp23018_status = i2c_write(0b00111111, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; |
131 | i2c_stop(ERGODOX_EZ_I2C_TIMEOUT); | 131 | i2c_stop(); |
132 | 132 | ||
133 | // set pull-up | 133 | // set pull-up |
134 | // - unused : on : 1 | 134 | // - unused : on : 1 |
@@ -140,7 +140,7 @@ uint8_t init_mcp23018(void) { | |||
140 | mcp23018_status = i2c_write(0b00111111, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; | 140 | mcp23018_status = i2c_write(0b00111111, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; |
141 | 141 | ||
142 | out: | 142 | out: |
143 | i2c_stop(ERGODOX_EZ_I2C_TIMEOUT); | 143 | i2c_stop(); |
144 | 144 | ||
145 | #ifdef LEFT_LEDS | 145 | #ifdef LEFT_LEDS |
146 | if (!mcp23018_status) mcp23018_status = ergodox_left_leds_update(); | 146 | if (!mcp23018_status) mcp23018_status = ergodox_left_leds_update(); |
@@ -179,7 +179,7 @@ uint8_t ergodox_left_leds_update(void) { | |||
179 | if (mcp23018_status) goto out; | 179 | if (mcp23018_status) goto out; |
180 | 180 | ||
181 | out: | 181 | out: |
182 | i2c_stop(ERGODOX_EZ_I2C_TIMEOUT); | 182 | i2c_stop(); |
183 | return mcp23018_status; | 183 | return mcp23018_status; |
184 | } | 184 | } |
185 | #endif | 185 | #endif |
diff --git a/keyboards/ergodox_ez/matrix.c b/keyboards/ergodox_ez/matrix.c index 22837d312..860cf7b22 100644 --- a/keyboards/ergodox_ez/matrix.c +++ b/keyboards/ergodox_ez/matrix.c | |||
@@ -309,7 +309,7 @@ static matrix_row_t read_cols(uint8_t row) | |||
309 | data = ~((uint8_t)mcp23018_status); | 309 | data = ~((uint8_t)mcp23018_status); |
310 | mcp23018_status = I2C_STATUS_SUCCESS; | 310 | mcp23018_status = I2C_STATUS_SUCCESS; |
311 | out: | 311 | out: |
312 | i2c_stop(ERGODOX_EZ_I2C_TIMEOUT); | 312 | i2c_stop(); |
313 | return data; | 313 | return data; |
314 | } | 314 | } |
315 | } else { | 315 | } else { |
@@ -362,7 +362,7 @@ static void select_row(uint8_t row) | |||
362 | mcp23018_status = i2c_write(GPIOA, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; | 362 | mcp23018_status = i2c_write(GPIOA, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; |
363 | mcp23018_status = i2c_write(0xFF & ~(1<<row), ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; | 363 | mcp23018_status = i2c_write(0xFF & ~(1<<row), ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; |
364 | out: | 364 | out: |
365 | i2c_stop(ERGODOX_EZ_I2C_TIMEOUT); | 365 | i2c_stop(); |
366 | } | 366 | } |
367 | } else { | 367 | } else { |
368 | // select on teensy | 368 | // select on teensy |
diff --git a/keyboards/gergo/gergo.c b/keyboards/gergo/gergo.c index d32792e2a..cc0bef391 100644 --- a/keyboards/gergo/gergo.c +++ b/keyboards/gergo/gergo.c | |||
@@ -47,7 +47,7 @@ uint8_t init_mcp23018(void) { | |||
47 | mcp23018_status = i2c_write(IODIRA, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; | 47 | mcp23018_status = i2c_write(IODIRA, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; |
48 | mcp23018_status = i2c_write(0b10000000, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; | 48 | mcp23018_status = i2c_write(0b10000000, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; |
49 | mcp23018_status = i2c_write(0b11111111, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; | 49 | mcp23018_status = i2c_write(0b11111111, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; |
50 | i2c_stop(ERGODOX_EZ_I2C_TIMEOUT); | 50 | i2c_stop(); |
51 | 51 | ||
52 | // set pull-up | 52 | // set pull-up |
53 | // - unused : on : 1 | 53 | // - unused : on : 1 |
@@ -59,7 +59,7 @@ uint8_t init_mcp23018(void) { | |||
59 | mcp23018_status = i2c_write(0b11111111, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; | 59 | mcp23018_status = i2c_write(0b11111111, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; |
60 | 60 | ||
61 | out: | 61 | out: |
62 | i2c_stop(ERGODOX_EZ_I2C_TIMEOUT); | 62 | i2c_stop(); |
63 | // SREG=sreg_prev; | 63 | // SREG=sreg_prev; |
64 | //uprintf("Init %x\n", mcp23018_status); | 64 | //uprintf("Init %x\n", mcp23018_status); |
65 | return mcp23018_status; | 65 | return mcp23018_status; |
diff --git a/keyboards/gergo/matrix.c b/keyboards/gergo/matrix.c index 29fe48ccb..9886ecf15 100644 --- a/keyboards/gergo/matrix.c +++ b/keyboards/gergo/matrix.c | |||
@@ -72,14 +72,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
72 | //Trackball pin defs | 72 | //Trackball pin defs |
73 | #define TRKUP (1<<4) | 73 | #define TRKUP (1<<4) |
74 | #define TRKDN (1<<5) | 74 | #define TRKDN (1<<5) |
75 | #define TRKLT (1<<6) | 75 | #define TRKLT (1<<6) |
76 | #define TRKRT (1<<7) | 76 | #define TRKRT (1<<7) |
77 | #define TRKBTN (1<<6) | 77 | #define TRKBTN (1<<6) |
78 | 78 | ||
79 | 79 | ||
80 | // Multiple for mouse moves | 80 | // Multiple for mouse moves |
81 | #ifndef TRKSTEP | 81 | #ifndef TRKSTEP |
82 | #define TRKSTEP 20 | 82 | #define TRKSTEP 20 |
83 | #endif | 83 | #endif |
84 | 84 | ||
85 | // multiple for mouse scroll | 85 | // multiple for mouse scroll |
@@ -98,13 +98,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
98 | 98 | ||
99 | // Trackball interrupts accumulate over here. Processed on scan | 99 | // Trackball interrupts accumulate over here. Processed on scan |
100 | // Stores prev state of mouse, high bits store direction | 100 | // Stores prev state of mouse, high bits store direction |
101 | uint8_t trkState = 0; | 101 | uint8_t trkState = 0; |
102 | uint8_t trkBtnState = 0; | 102 | uint8_t trkBtnState = 0; |
103 | 103 | ||
104 | volatile uint8_t tbUpCnt = 0; | 104 | volatile uint8_t tbUpCnt = 0; |
105 | volatile uint8_t tbDnCnt = 0; | 105 | volatile uint8_t tbDnCnt = 0; |
106 | volatile uint8_t tbLtCnt = 0; | 106 | volatile uint8_t tbLtCnt = 0; |
107 | volatile uint8_t tbRtCnt = 0; | 107 | volatile uint8_t tbRtCnt = 0; |
108 | 108 | ||
109 | /* matrix state(1:on, 0:off) */ | 109 | /* matrix state(1:on, 0:off) */ |
110 | static matrix_row_t matrix[MATRIX_ROWS]; | 110 | static matrix_row_t matrix[MATRIX_ROWS]; |
@@ -240,14 +240,14 @@ uint8_t matrix_scan(void) | |||
240 | // First we handle the mouse inputs | 240 | // First we handle the mouse inputs |
241 | #ifdef BALLER | 241 | #ifdef BALLER |
242 | uint8_t pBtn = PINE & TRKBTN; | 242 | uint8_t pBtn = PINE & TRKBTN; |
243 | 243 | ||
244 | #ifdef DEBUG_BALLER | 244 | #ifdef DEBUG_BALLER |
245 | // Compare to previous, mod report | 245 | // Compare to previous, mod report |
246 | if (tbUpCnt + tbDnCnt + tbLtCnt + tbRtCnt != 0) | 246 | if (tbUpCnt + tbDnCnt + tbLtCnt + tbRtCnt != 0) |
247 | xprintf("U: %d D: %d L: %d R: %d B: %d\n", tbUpCnt, tbDnCnt, tbLtCnt, tbRtCnt, (trkBtnState >> 6)); | 247 | xprintf("U: %d D: %d L: %d R: %d B: %d\n", tbUpCnt, tbDnCnt, tbLtCnt, tbRtCnt, (trkBtnState >> 6)); |
248 | #endif | 248 | #endif |
249 | 249 | ||
250 | // Modify the report | 250 | // Modify the report |
251 | report_mouse_t pRprt = pointing_device_get_report(); | 251 | report_mouse_t pRprt = pointing_device_get_report(); |
252 | 252 | ||
253 | // Scroll by default, move on layer | 253 | // Scroll by default, move on layer |
@@ -264,7 +264,7 @@ uint8_t matrix_scan(void) | |||
264 | } | 264 | } |
265 | 265 | ||
266 | #ifdef DEBUG_BALLER | 266 | #ifdef DEBUG_BALLER |
267 | if (pRprt.x != 0 || pRprt.y != 0) | 267 | if (pRprt.x != 0 || pRprt.y != 0) |
268 | xprintf("X: %d Y: %d\n", pRprt.x, pRprt.y); | 268 | xprintf("X: %d Y: %d\n", pRprt.x, pRprt.y); |
269 | #endif | 269 | #endif |
270 | 270 | ||
@@ -272,7 +272,7 @@ uint8_t matrix_scan(void) | |||
272 | if ((pBtn != trkBtnState) && ((pBtn >> 6) == 1)) pRprt.buttons &= ~MOUSE_BTN1; | 272 | if ((pBtn != trkBtnState) && ((pBtn >> 6) == 1)) pRprt.buttons &= ~MOUSE_BTN1; |
273 | 273 | ||
274 | // Save state, push update | 274 | // Save state, push update |
275 | if (pRprt.x != 0 || pRprt.y != 0 || pRprt.h != 0 || pRprt.v != 0 || (trkBtnState != pBtn)) | 275 | if (pRprt.x != 0 || pRprt.y != 0 || pRprt.h != 0 || pRprt.v != 0 || (trkBtnState != pBtn)) |
276 | pointing_device_set_report(pRprt); | 276 | pointing_device_set_report(pRprt); |
277 | 277 | ||
278 | trkBtnState = pBtn; | 278 | trkBtnState = pBtn; |
@@ -325,8 +325,8 @@ uint8_t matrix_scan(void) | |||
325 | enableInterrupts(); | 325 | enableInterrupts(); |
326 | 326 | ||
327 | #ifdef DEBUG_MATRIX | 327 | #ifdef DEBUG_MATRIX |
328 | for (uint8_t c = 0; c < MATRIX_COLS; c++) | 328 | for (uint8_t c = 0; c < MATRIX_COLS; c++) |
329 | for (uint8_t r = 0; r < MATRIX_ROWS; r++) | 329 | for (uint8_t r = 0; r < MATRIX_ROWS; r++) |
330 | if (matrix_is_on(r, c)) xprintf("r:%d c:%d \n", r, c); | 330 | if (matrix_is_on(r, c)) xprintf("r:%d c:%d \n", r, c); |
331 | #endif | 331 | #endif |
332 | 332 | ||
@@ -394,7 +394,7 @@ static matrix_row_t read_cols(uint8_t row) | |||
394 | data = ~((uint8_t)mcp23018_status); | 394 | data = ~((uint8_t)mcp23018_status); |
395 | mcp23018_status = I2C_STATUS_SUCCESS; | 395 | mcp23018_status = I2C_STATUS_SUCCESS; |
396 | out: | 396 | out: |
397 | i2c_stop(ERGODOX_EZ_I2C_TIMEOUT); | 397 | i2c_stop(); |
398 | 398 | ||
399 | #ifdef DEBUG_MATRIX | 399 | #ifdef DEBUG_MATRIX |
400 | if (data != 0x00) xprintf("I2C: %d\n", data); | 400 | if (data != 0x00) xprintf("I2C: %d\n", data); |
@@ -439,12 +439,12 @@ static void select_row(uint8_t row) | |||
439 | if (row < 7) { | 439 | if (row < 7) { |
440 | // select on mcp23018 | 440 | // select on mcp23018 |
441 | if (mcp23018_status) { // do nothing on error | 441 | if (mcp23018_status) { // do nothing on error |
442 | } else { // set active row low : 0 // set other rows hi-Z : 1 | 442 | } else { // set active row low : 0 // set other rows hi-Z : 1 |
443 | mcp23018_status = i2c_start(I2C_ADDR_WRITE, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; | 443 | mcp23018_status = i2c_start(I2C_ADDR_WRITE, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; |
444 | mcp23018_status = i2c_write(GPIOA, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; | 444 | mcp23018_status = i2c_write(GPIOA, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; |
445 | mcp23018_status = i2c_write(0xFF & ~(1<<row), ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; | 445 | mcp23018_status = i2c_write(0xFF & ~(1<<row), ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; |
446 | out: | 446 | out: |
447 | i2c_stop(ERGODOX_EZ_I2C_TIMEOUT); | 447 | i2c_stop(); |
448 | } | 448 | } |
449 | } else { | 449 | } else { |
450 | // Output low(DDR:1, PORT:0) to select | 450 | // Output low(DDR:1, PORT:0) to select |
diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index 9d2d331ce..eef739a14 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c | |||
@@ -29,10 +29,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
29 | #include "backlight.h" | 29 | #include "backlight.h" |
30 | #include "quantum.h" | 30 | #include "quantum.h" |
31 | 31 | ||
32 | #ifdef SPLIT_KEYBOARD | ||
33 | #include "split_flags.h" | ||
34 | #endif | ||
35 | |||
36 | #ifdef MIDI_ENABLE | 32 | #ifdef MIDI_ENABLE |
37 | #include "process_midi.h" | 33 | #include "process_midi.h" |
38 | #endif | 34 | #endif |
@@ -138,39 +134,21 @@ action_t action_for_key(uint8_t layer, keypos_t key) | |||
138 | #ifdef BACKLIGHT_ENABLE | 134 | #ifdef BACKLIGHT_ENABLE |
139 | case BL_ON: | 135 | case BL_ON: |
140 | action.code = ACTION_BACKLIGHT_ON(); | 136 | action.code = ACTION_BACKLIGHT_ON(); |
141 | #ifdef SPLIT_KEYBOARD | ||
142 | BACKLIT_DIRTY = true; | ||
143 | #endif | ||
144 | break; | 137 | break; |
145 | case BL_OFF: | 138 | case BL_OFF: |
146 | action.code = ACTION_BACKLIGHT_OFF(); | 139 | action.code = ACTION_BACKLIGHT_OFF(); |
147 | #ifdef SPLIT_KEYBOARD | ||
148 | BACKLIT_DIRTY = true; | ||
149 | #endif | ||
150 | break; | 140 | break; |
151 | case BL_DEC: | 141 | case BL_DEC: |
152 | action.code = ACTION_BACKLIGHT_DECREASE(); | 142 | action.code = ACTION_BACKLIGHT_DECREASE(); |
153 | #ifdef SPLIT_KEYBOARD | ||
154 | BACKLIT_DIRTY = true; | ||
155 | #endif | ||
156 | break; | 143 | break; |
157 | case BL_INC: | 144 | case BL_INC: |
158 | action.code = ACTION_BACKLIGHT_INCREASE(); | 145 | action.code = ACTION_BACKLIGHT_INCREASE(); |
159 | #ifdef SPLIT_KEYBOARD | ||
160 | BACKLIT_DIRTY = true; | ||
161 | #endif | ||
162 | break; | 146 | break; |
163 | case BL_TOGG: | 147 | case BL_TOGG: |
164 | action.code = ACTION_BACKLIGHT_TOGGLE(); | 148 | action.code = ACTION_BACKLIGHT_TOGGLE(); |
165 | #ifdef SPLIT_KEYBOARD | ||
166 | BACKLIT_DIRTY = true; | ||
167 | #endif | ||
168 | break; | 149 | break; |
169 | case BL_STEP: | 150 | case BL_STEP: |
170 | action.code = ACTION_BACKLIGHT_STEP(); | 151 | action.code = ACTION_BACKLIGHT_STEP(); |
171 | #ifdef SPLIT_KEYBOARD | ||
172 | BACKLIT_DIRTY = true; | ||
173 | #endif | ||
174 | break; | 152 | break; |
175 | #endif | 153 | #endif |
176 | #ifdef SWAP_HANDS_ENABLE | 154 | #ifdef SWAP_HANDS_ENABLE |
diff --git a/quantum/quantum.c b/quantum/quantum.c index 46d404029..8316d1f06 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c | |||
@@ -360,9 +360,6 @@ bool process_record_quantum(keyrecord_t *record) { | |||
360 | if (!record->event.pressed) { | 360 | if (!record->event.pressed) { |
361 | #endif | 361 | #endif |
362 | rgblight_toggle(); | 362 | rgblight_toggle(); |
363 | #ifdef SPLIT_KEYBOARD | ||
364 | RGB_DIRTY = true; | ||
365 | #endif | ||
366 | } | 363 | } |
367 | return false; | 364 | return false; |
368 | case RGB_MODE_FORWARD: | 365 | case RGB_MODE_FORWARD: |
@@ -374,9 +371,6 @@ bool process_record_quantum(keyrecord_t *record) { | |||
374 | else { | 371 | else { |
375 | rgblight_step(); | 372 | rgblight_step(); |
376 | } | 373 | } |
377 | #ifdef SPLIT_KEYBOARD | ||
378 | RGB_DIRTY = true; | ||
379 | #endif | ||
380 | } | 374 | } |
381 | return false; | 375 | return false; |
382 | case RGB_MODE_REVERSE: | 376 | case RGB_MODE_REVERSE: |
@@ -388,9 +382,6 @@ bool process_record_quantum(keyrecord_t *record) { | |||
388 | else { | 382 | else { |
389 | rgblight_step_reverse(); | 383 | rgblight_step_reverse(); |
390 | } | 384 | } |
391 | #ifdef SPLIT_KEYBOARD | ||
392 | RGB_DIRTY = true; | ||
393 | #endif | ||
394 | } | 385 | } |
395 | return false; | 386 | return false; |
396 | case RGB_HUI: | 387 | case RGB_HUI: |
@@ -401,9 +392,6 @@ bool process_record_quantum(keyrecord_t *record) { | |||
401 | if (!record->event.pressed) { | 392 | if (!record->event.pressed) { |
402 | #endif | 393 | #endif |
403 | rgblight_increase_hue(); | 394 | rgblight_increase_hue(); |
404 | #ifdef SPLIT_KEYBOARD | ||
405 | RGB_DIRTY = true; | ||
406 | #endif | ||
407 | } | 395 | } |
408 | return false; | 396 | return false; |
409 | case RGB_HUD: | 397 | case RGB_HUD: |
@@ -414,9 +402,6 @@ bool process_record_quantum(keyrecord_t *record) { | |||
414 | if (!record->event.pressed) { | 402 | if (!record->event.pressed) { |
415 | #endif | 403 | #endif |
416 | rgblight_decrease_hue(); | 404 | rgblight_decrease_hue(); |
417 | #ifdef SPLIT_KEYBOARD | ||
418 | RGB_DIRTY = true; | ||
419 | #endif | ||
420 | } | 405 | } |
421 | return false; | 406 | return false; |
422 | case RGB_SAI: | 407 | case RGB_SAI: |
@@ -427,9 +412,6 @@ bool process_record_quantum(keyrecord_t *record) { | |||
427 | if (!record->event.pressed) { | 412 | if (!record->event.pressed) { |
428 | #endif | 413 | #endif |
429 | rgblight_increase_sat(); | 414 | rgblight_increase_sat(); |
430 | #ifdef SPLIT_KEYBOARD | ||
431 | RGB_DIRTY = true; | ||
432 | #endif | ||
433 | } | 415 | } |
434 | return false; | 416 | return false; |
435 | case RGB_SAD: | 417 | case RGB_SAD: |
@@ -440,9 +422,6 @@ bool process_record_quantum(keyrecord_t *record) { | |||
440 | if (!record->event.pressed) { | 422 | if (!record->event.pressed) { |
441 | #endif | 423 | #endif |
442 | rgblight_decrease_sat(); | 424 | rgblight_decrease_sat(); |
443 | #ifdef SPLIT_KEYBOARD | ||
444 | RGB_DIRTY = true; | ||
445 | #endif | ||
446 | } | 425 | } |
447 | return false; | 426 | return false; |
448 | case RGB_VAI: | 427 | case RGB_VAI: |
@@ -453,9 +432,6 @@ bool process_record_quantum(keyrecord_t *record) { | |||
453 | if (!record->event.pressed) { | 432 | if (!record->event.pressed) { |
454 | #endif | 433 | #endif |
455 | rgblight_increase_val(); | 434 | rgblight_increase_val(); |
456 | #ifdef SPLIT_KEYBOARD | ||
457 | RGB_DIRTY = true; | ||
458 | #endif | ||
459 | } | 435 | } |
460 | return false; | 436 | return false; |
461 | case RGB_VAD: | 437 | case RGB_VAD: |
@@ -466,9 +442,6 @@ bool process_record_quantum(keyrecord_t *record) { | |||
466 | if (!record->event.pressed) { | 442 | if (!record->event.pressed) { |
467 | #endif | 443 | #endif |
468 | rgblight_decrease_val(); | 444 | rgblight_decrease_val(); |
469 | #ifdef SPLIT_KEYBOARD | ||
470 | RGB_DIRTY = true; | ||
471 | #endif | ||
472 | } | 445 | } |
473 | return false; | 446 | return false; |
474 | case RGB_SPI: | 447 | case RGB_SPI: |
@@ -484,9 +457,6 @@ bool process_record_quantum(keyrecord_t *record) { | |||
484 | case RGB_MODE_PLAIN: | 457 | case RGB_MODE_PLAIN: |
485 | if (record->event.pressed) { | 458 | if (record->event.pressed) { |
486 | rgblight_mode(RGBLIGHT_MODE_STATIC_LIGHT); | 459 | rgblight_mode(RGBLIGHT_MODE_STATIC_LIGHT); |
487 | #ifdef SPLIT_KEYBOARD | ||
488 | RGB_DIRTY = true; | ||
489 | #endif | ||
490 | } | 460 | } |
491 | return false; | 461 | return false; |
492 | case RGB_MODE_BREATHE: | 462 | case RGB_MODE_BREATHE: |
diff --git a/quantum/quantum.h b/quantum/quantum.h index d2c5862f8..c12ac9ab8 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h | |||
@@ -44,10 +44,6 @@ | |||
44 | #endif | 44 | #endif |
45 | #endif | 45 | #endif |
46 | 46 | ||
47 | #ifdef SPLIT_KEYBOARD | ||
48 | #include "split_flags.h" | ||
49 | #endif | ||
50 | |||
51 | #ifdef RGB_MATRIX_ENABLE | 47 | #ifdef RGB_MATRIX_ENABLE |
52 | #include "rgb_matrix.h" | 48 | #include "rgb_matrix.h" |
53 | #endif | 49 | #endif |
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 |
diff --git a/tmk_core/common/avr/suspend.c b/tmk_core/common/avr/suspend.c index b29447ac4..2259201b5 100644 --- a/tmk_core/common/avr/suspend.c +++ b/tmk_core/common/avr/suspend.c | |||
@@ -11,9 +11,6 @@ | |||
11 | #include "led.h" | 11 | #include "led.h" |
12 | #include "host.h" | 12 | #include "host.h" |
13 | #include "rgblight_reconfig.h" | 13 | #include "rgblight_reconfig.h" |
14 | #ifdef SPLIT_KEYBOARD | ||
15 | #include "split_flags.h" | ||
16 | #endif | ||
17 | 14 | ||
18 | #ifdef PROTOCOL_LUFA | 15 | #ifdef PROTOCOL_LUFA |
19 | #include "lufa.h" | 16 | #include "lufa.h" |
@@ -135,9 +132,6 @@ static void power_down(uint8_t wdto) { | |||
135 | is_suspended = true; | 132 | is_suspended = true; |
136 | rgblight_enabled = rgblight_config.enable; | 133 | rgblight_enabled = rgblight_config.enable; |
137 | rgblight_disable_noeeprom(); | 134 | rgblight_disable_noeeprom(); |
138 | #ifdef SPLIT_KEYBOARD | ||
139 | RGB_DIRTY = true; | ||
140 | #endif | ||
141 | } | 135 | } |
142 | #endif | 136 | #endif |
143 | suspend_power_down_kb(); | 137 | suspend_power_down_kb(); |
@@ -216,9 +210,6 @@ void suspend_wakeup_init(void) { | |||
216 | wait_ms(10); | 210 | wait_ms(10); |
217 | #endif | 211 | #endif |
218 | rgblight_enable_noeeprom(); | 212 | rgblight_enable_noeeprom(); |
219 | #ifdef SPLIT_KEYBOARD | ||
220 | RGB_DIRTY = true; | ||
221 | #endif | ||
222 | } | 213 | } |
223 | #ifdef RGBLIGHT_ANIMATIONS | 214 | #ifdef RGBLIGHT_ANIMATIONS |
224 | rgblight_timer_enable(); | 215 | rgblight_timer_enable(); |