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(); |
