From 37932c293c15011f883a91e91ee02631ead44a2e Mon Sep 17 00:00:00 2001 From: James Churchill Date: Wed, 13 Mar 2019 03:23:28 +1000 Subject: [PATCH] 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 --- common_features.mk | 10 +- docs/i2c_driver.md | 2 +- drivers/arm/i2c_master.c | 3 +- drivers/arm/i2c_master.h | 2 +- drivers/avr/i2c_master.c | 160 +++++------- drivers/avr/i2c_master.h | 2 +- drivers/avr/i2c_slave.c | 2 +- .../cannonkeys/satisfaction75/i2c_master.c | 2 +- keyboards/dc01/left/matrix.c | 4 +- keyboards/ergodox_ez/ergodox_ez.c | 6 +- keyboards/ergodox_ez/matrix.c | 4 +- keyboards/gergo/gergo.c | 4 +- keyboards/gergo/matrix.c | 36 +-- quantum/keymap_common.c | 22 -- quantum/quantum.c | 30 --- quantum/quantum.h | 4 - quantum/split_common/i2c.c | 184 -------------- quantum/split_common/i2c.h | 59 ----- quantum/split_common/matrix.c | 1 - quantum/split_common/split_flags.c | 5 - quantum/split_common/split_flags.h | 15 -- quantum/split_common/split_util.c | 5 - quantum/split_common/transport.c | 230 +++++++----------- tmk_core/common/avr/suspend.c | 9 - 24 files changed, 187 insertions(+), 614 deletions(-) delete mode 100644 quantum/split_common/i2c.c delete mode 100644 quantum/split_common/i2c.h delete mode 100644 quantum/split_common/split_flags.c delete mode 100644 quantum/split_common/split_flags.h 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) OPT_DEFS += -DSPLIT_KEYBOARD # Include files used by all split keyboards - QUANTUM_SRC += $(QUANTUM_DIR)/split_common/split_flags.c \ - $(QUANTUM_DIR)/split_common/split_util.c + QUANTUM_SRC += $(QUANTUM_DIR)/split_common/split_util.c # Determine which (if any) transport files are required ifneq ($(strip $(SPLIT_TRANSPORT)), custom) QUANTUM_SRC += $(QUANTUM_DIR)/split_common/transport.c # Functions added via QUANTUM_LIB_SRC are only included in the final binary if they're called. - # Unused functions are pruned away, which is why we can add both drivers here without bloat. - QUANTUM_LIB_SRC += $(QUANTUM_DIR)/split_common/i2c.c \ - $(QUANTUM_DIR)/split_common/serial.c + # Unused functions are pruned away, which is why we can add multiple drivers here without bloat. + QUANTUM_LIB_SRC += $(QUANTUM_DIR)/split_common/serial.c \ + i2c_master.c \ + i2c_slave.c endif COMMON_VPATH += $(QUANTUM_PATH)/split_common 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 |`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. | |`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. | |`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. | -|`uint8_t i2c_stop(uint16_t timeout);` |Stops the I2C driver. | +|`uint8_t i2c_stop(void);` |Ends an I2C transaction. | ### Function Return 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 return i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), regaddr, 1, data, length, MS2ST(timeout)); } -// This is usually not needed. It releases the driver to allow pins to become GPIO again. -uint8_t i2c_stop(uint16_t timeout) +uint8_t i2c_stop(void) { i2cStop(&I2C_DRIVER); 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 uint8_t i2c_transmit_receive(uint8_t address, uint8_t * tx_body, uint16_t tx_length, uint8_t * rx_body, uint16_t rx_length); uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout); uint8_t i2c_readReg(uint8_t devaddr, uint8_t* regaddr, uint8_t* data, uint16_t length, uint16_t timeout); -uint8_t i2c_stop(uint16_t timeout); +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 @@ #include "i2c_master.h" #include "timer.h" +#include "wait.h" #ifndef F_SCL -#define F_SCL 400000UL // SCL frequency +# define F_SCL 400000UL // SCL frequency #endif #define Prescaler 1 -#define TWBR_val ((((F_CPU / F_SCL) / Prescaler) - 16 ) / 2) +#define TWBR_val ((((F_CPU / F_SCL) / Prescaler) - 16) / 2) -void i2c_init(void) -{ - TWSR = 0; /* no prescaler */ +void i2c_init(void) { + TWSR = 0; /* no prescaler */ TWBR = (uint8_t)TWBR_val; } -i2c_status_t i2c_start(uint8_t address, uint16_t timeout) -{ +i2c_status_t i2c_start(uint8_t address, uint16_t timeout) { // reset TWI control register TWCR = 0; // transmit START condition - TWCR = (1<= timeout)) { return I2C_STATUS_TIMEOUT; } } // check if the start condition was successfully transmitted - if(((TW_STATUS & 0xF8) != TW_START) && ((TW_STATUS & 0xF8) != TW_REP_START)){ return I2C_STATUS_ERROR; } + if (((TW_STATUS & 0xF8) != TW_START) && ((TW_STATUS & 0xF8) != TW_REP_START)) { + return I2C_STATUS_ERROR; + } // load slave address into data register TWDR = address; // start transmission of address - TWCR = (1<= timeout)) { return I2C_STATUS_TIMEOUT; } @@ -51,38 +52,39 @@ i2c_status_t i2c_start(uint8_t address, uint16_t timeout) // check if the device has acknowledged the READ / WRITE mode uint8_t twst = TW_STATUS & 0xF8; - if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return I2C_STATUS_ERROR; + if ((twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK)) { + return I2C_STATUS_ERROR; + } return I2C_STATUS_SUCCESS; } -i2c_status_t i2c_write(uint8_t data, uint16_t timeout) -{ +i2c_status_t i2c_write(uint8_t data, uint16_t timeout) { // load data into data register TWDR = data; // start transmission of data - TWCR = (1<= timeout)) { return I2C_STATUS_TIMEOUT; } } - if( (TW_STATUS & 0xF8) != TW_MT_DATA_ACK ){ return I2C_STATUS_ERROR; } + if ((TW_STATUS & 0xF8) != TW_MT_DATA_ACK) { + return I2C_STATUS_ERROR; + } return I2C_STATUS_SUCCESS; } -int16_t i2c_read_ack(uint16_t timeout) -{ - +int16_t i2c_read_ack(uint16_t timeout) { // start TWI module and acknowledge data after reception - TWCR = (1<= timeout)) { return I2C_STATUS_TIMEOUT; } @@ -92,14 +94,12 @@ int16_t i2c_read_ack(uint16_t timeout) return TWDR; } -int16_t i2c_read_nack(uint16_t timeout) -{ - +int16_t i2c_read_nack(uint16_t timeout) { // start receiving without acknowledging reception - TWCR = (1<= timeout)) { return I2C_STATUS_TIMEOUT; } @@ -109,115 +109,89 @@ int16_t i2c_read_nack(uint16_t timeout) return TWDR; } -i2c_status_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout) -{ +i2c_status_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout) { i2c_status_t status = i2c_start(address | I2C_WRITE, timeout); - if (status) return status; - for (uint16_t i = 0; i < length; i++) { + for (uint16_t i = 0; i < length && status >= 0; i++) { status = i2c_write(data[i], timeout); - if (status) return status; } - status = i2c_stop(timeout); - if (status) return status; + i2c_stop(); - return I2C_STATUS_SUCCESS; + return status; } -i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout) -{ +i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout) { i2c_status_t status = i2c_start(address | I2C_READ, timeout); - if (status) return status; - for (uint16_t i = 0; i < (length-1); i++) { + for (uint16_t i = 0; i < (length - 1) && status >= 0; i++) { status = i2c_read_ack(timeout); if (status >= 0) { data[i] = status; - } else { - return status; } } - status = i2c_read_nack(timeout); - if (status >= 0 ) { - data[(length-1)] = status; - } else { - return status; + if (status >= 0) { + status = i2c_read_nack(timeout); + if (status >= 0) { + data[(length - 1)] = status; + } } - status = i2c_stop(timeout); - if (status) return status; + i2c_stop(); - return I2C_STATUS_SUCCESS; + return status; } -i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) -{ +i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) { i2c_status_t status = i2c_start(devaddr | 0x00, timeout); - if (status) return status; + if (status >= 0) { + status = i2c_write(regaddr, timeout); - status = i2c_write(regaddr, timeout); - if (status) return status; - - for (uint16_t i = 0; i < length; i++) { - status = i2c_write(data[i], timeout); - if (status) return status; + for (uint16_t i = 0; i < length && status >= 0; i++) { + status = i2c_write(data[i], timeout); + } } - status = i2c_stop(timeout); - if (status) return status; + i2c_stop(); - return I2C_STATUS_SUCCESS; + return status; } -i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) -{ +i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) { i2c_status_t status = i2c_start(devaddr, timeout); - if (status) return status; + if (status < 0) { + goto error; + } status = i2c_write(regaddr, timeout); - if (status) return status; - - status = i2c_stop(timeout); - if (status) return status; + if (status < 0) { + goto error; + } status = i2c_start(devaddr | 0x01, timeout); - if (status) return status; - for (uint16_t i = 0; i < (length-1); i++) { + for (uint16_t i = 0; i < (length - 1) && status >= 0; i++) { status = i2c_read_ack(timeout); if (status >= 0) { data[i] = status; - } else { - return status; } } - status = i2c_read_nack(timeout); - if (status >= 0 ) { - data[(length-1)] = status; - } else { - return status; + if (status >= 0) { + status = i2c_read_nack(timeout); + if (status >= 0) { + data[(length - 1)] = status; + } } - status = i2c_stop(timeout); - if (status) return status; +error: + i2c_stop(); - return I2C_STATUS_SUCCESS; + return status; } -i2c_status_t i2c_stop(uint16_t timeout) -{ +void i2c_stop(void) { // transmit STOP condition - TWCR = (1<= timeout)) { - return I2C_STATUS_TIMEOUT; - } - } - - return I2C_STATUS_SUCCESS; + TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO); } 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 i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout); i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout); i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout); -i2c_status_t i2c_stop(uint16_t timeout); +void i2c_stop(void); #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; void i2c_slave_init(uint8_t address){ // load address into TWI address register - TWAR = (address << 1); + TWAR = address; // set the TWCR to enable address matching and enable TWI, clear TWINT, enable TWI interrupt TWCR = (1 << TWIE) | (1 << TWEA) | (1 << TWINT) | (1 << TWEN); } 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 } // This is usually not needed. It releases the driver to allow pins to become GPIO again. -uint8_t i2c_stop(uint16_t timeout) +uint8_t i2c_stop(void) { i2cStop(&I2C_DRIVER); 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) matrix[MATRIX_ROWS - 1] |= ((uint32_t)err << (MATRIX_COLS_SCANNED + col_offset)); //add new bits at the end } else { - i2c_stop(10); + i2c_stop(); return 1; } - i2c_stop(10); + i2c_stop(); return 0; } \ 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) { mcp23018_status = i2c_write(IODIRA, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; mcp23018_status = i2c_write(0b00000000, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; mcp23018_status = i2c_write(0b00111111, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - i2c_stop(ERGODOX_EZ_I2C_TIMEOUT); + i2c_stop(); // set pull-up // - unused : on : 1 @@ -140,7 +140,7 @@ uint8_t init_mcp23018(void) { mcp23018_status = i2c_write(0b00111111, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; out: - i2c_stop(ERGODOX_EZ_I2C_TIMEOUT); + i2c_stop(); #ifdef LEFT_LEDS if (!mcp23018_status) mcp23018_status = ergodox_left_leds_update(); @@ -179,7 +179,7 @@ uint8_t ergodox_left_leds_update(void) { if (mcp23018_status) goto out; out: - i2c_stop(ERGODOX_EZ_I2C_TIMEOUT); + i2c_stop(); return mcp23018_status; } #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) data = ~((uint8_t)mcp23018_status); mcp23018_status = I2C_STATUS_SUCCESS; out: - i2c_stop(ERGODOX_EZ_I2C_TIMEOUT); + i2c_stop(); return data; } } else { @@ -362,7 +362,7 @@ static void select_row(uint8_t row) mcp23018_status = i2c_write(GPIOA, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; mcp23018_status = i2c_write(0xFF & ~(1<. //Trackball pin defs #define TRKUP (1<<4) #define TRKDN (1<<5) -#define TRKLT (1<<6) +#define TRKLT (1<<6) #define TRKRT (1<<7) #define TRKBTN (1<<6) // Multiple for mouse moves #ifndef TRKSTEP -#define TRKSTEP 20 +#define TRKSTEP 20 #endif // multiple for mouse scroll @@ -98,13 +98,13 @@ along with this program. If not, see . // Trackball interrupts accumulate over here. Processed on scan // Stores prev state of mouse, high bits store direction -uint8_t trkState = 0; -uint8_t trkBtnState = 0; +uint8_t trkState = 0; +uint8_t trkBtnState = 0; -volatile uint8_t tbUpCnt = 0; -volatile uint8_t tbDnCnt = 0; -volatile uint8_t tbLtCnt = 0; -volatile uint8_t tbRtCnt = 0; +volatile uint8_t tbUpCnt = 0; +volatile uint8_t tbDnCnt = 0; +volatile uint8_t tbLtCnt = 0; +volatile uint8_t tbRtCnt = 0; /* matrix state(1:on, 0:off) */ static matrix_row_t matrix[MATRIX_ROWS]; @@ -240,14 +240,14 @@ uint8_t matrix_scan(void) // First we handle the mouse inputs #ifdef BALLER uint8_t pBtn = PINE & TRKBTN; - + #ifdef DEBUG_BALLER - // Compare to previous, mod report + // Compare to previous, mod report if (tbUpCnt + tbDnCnt + tbLtCnt + tbRtCnt != 0) xprintf("U: %d D: %d L: %d R: %d B: %d\n", tbUpCnt, tbDnCnt, tbLtCnt, tbRtCnt, (trkBtnState >> 6)); #endif - // Modify the report + // Modify the report report_mouse_t pRprt = pointing_device_get_report(); // Scroll by default, move on layer @@ -264,7 +264,7 @@ uint8_t matrix_scan(void) } #ifdef DEBUG_BALLER - if (pRprt.x != 0 || pRprt.y != 0) + if (pRprt.x != 0 || pRprt.y != 0) xprintf("X: %d Y: %d\n", pRprt.x, pRprt.y); #endif @@ -272,7 +272,7 @@ uint8_t matrix_scan(void) if ((pBtn != trkBtnState) && ((pBtn >> 6) == 1)) pRprt.buttons &= ~MOUSE_BTN1; // Save state, push update - if (pRprt.x != 0 || pRprt.y != 0 || pRprt.h != 0 || pRprt.v != 0 || (trkBtnState != pBtn)) + if (pRprt.x != 0 || pRprt.y != 0 || pRprt.h != 0 || pRprt.v != 0 || (trkBtnState != pBtn)) pointing_device_set_report(pRprt); trkBtnState = pBtn; @@ -325,8 +325,8 @@ uint8_t matrix_scan(void) enableInterrupts(); #ifdef DEBUG_MATRIX - for (uint8_t c = 0; c < MATRIX_COLS; c++) - for (uint8_t r = 0; r < MATRIX_ROWS; r++) + for (uint8_t c = 0; c < MATRIX_COLS; c++) + for (uint8_t r = 0; r < MATRIX_ROWS; r++) if (matrix_is_on(r, c)) xprintf("r:%d c:%d \n", r, c); #endif @@ -394,7 +394,7 @@ static matrix_row_t read_cols(uint8_t row) data = ~((uint8_t)mcp23018_status); mcp23018_status = I2C_STATUS_SUCCESS; out: - i2c_stop(ERGODOX_EZ_I2C_TIMEOUT); + i2c_stop(); #ifdef DEBUG_MATRIX if (data != 0x00) xprintf("I2C: %d\n", data); @@ -439,12 +439,12 @@ static void select_row(uint8_t row) if (row < 7) { // select on mcp23018 if (mcp23018_status) { // do nothing on error - } else { // set active row low : 0 // set other rows hi-Z : 1 + } else { // set active row low : 0 // set other rows hi-Z : 1 mcp23018_status = i2c_start(I2C_ADDR_WRITE, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; mcp23018_status = i2c_write(GPIOA, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; mcp23018_status = i2c_write(0xFF & ~(1<. #include "backlight.h" #include "quantum.h" -#ifdef SPLIT_KEYBOARD - #include "split_flags.h" -#endif - #ifdef MIDI_ENABLE #include "process_midi.h" #endif @@ -138,39 +134,21 @@ action_t action_for_key(uint8_t layer, keypos_t key) #ifdef BACKLIGHT_ENABLE case BL_ON: action.code = ACTION_BACKLIGHT_ON(); - #ifdef SPLIT_KEYBOARD - BACKLIT_DIRTY = true; - #endif break; case BL_OFF: action.code = ACTION_BACKLIGHT_OFF(); - #ifdef SPLIT_KEYBOARD - BACKLIT_DIRTY = true; - #endif break; case BL_DEC: action.code = ACTION_BACKLIGHT_DECREASE(); - #ifdef SPLIT_KEYBOARD - BACKLIT_DIRTY = true; - #endif break; case BL_INC: action.code = ACTION_BACKLIGHT_INCREASE(); - #ifdef SPLIT_KEYBOARD - BACKLIT_DIRTY = true; - #endif break; case BL_TOGG: action.code = ACTION_BACKLIGHT_TOGGLE(); - #ifdef SPLIT_KEYBOARD - BACKLIT_DIRTY = true; - #endif break; case BL_STEP: action.code = ACTION_BACKLIGHT_STEP(); - #ifdef SPLIT_KEYBOARD - BACKLIT_DIRTY = true; - #endif break; #endif #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) { if (!record->event.pressed) { #endif rgblight_toggle(); - #ifdef SPLIT_KEYBOARD - RGB_DIRTY = true; - #endif } return false; case RGB_MODE_FORWARD: @@ -374,9 +371,6 @@ bool process_record_quantum(keyrecord_t *record) { else { rgblight_step(); } - #ifdef SPLIT_KEYBOARD - RGB_DIRTY = true; - #endif } return false; case RGB_MODE_REVERSE: @@ -388,9 +382,6 @@ bool process_record_quantum(keyrecord_t *record) { else { rgblight_step_reverse(); } - #ifdef SPLIT_KEYBOARD - RGB_DIRTY = true; - #endif } return false; case RGB_HUI: @@ -401,9 +392,6 @@ bool process_record_quantum(keyrecord_t *record) { if (!record->event.pressed) { #endif rgblight_increase_hue(); - #ifdef SPLIT_KEYBOARD - RGB_DIRTY = true; - #endif } return false; case RGB_HUD: @@ -414,9 +402,6 @@ bool process_record_quantum(keyrecord_t *record) { if (!record->event.pressed) { #endif rgblight_decrease_hue(); - #ifdef SPLIT_KEYBOARD - RGB_DIRTY = true; - #endif } return false; case RGB_SAI: @@ -427,9 +412,6 @@ bool process_record_quantum(keyrecord_t *record) { if (!record->event.pressed) { #endif rgblight_increase_sat(); - #ifdef SPLIT_KEYBOARD - RGB_DIRTY = true; - #endif } return false; case RGB_SAD: @@ -440,9 +422,6 @@ bool process_record_quantum(keyrecord_t *record) { if (!record->event.pressed) { #endif rgblight_decrease_sat(); - #ifdef SPLIT_KEYBOARD - RGB_DIRTY = true; - #endif } return false; case RGB_VAI: @@ -453,9 +432,6 @@ bool process_record_quantum(keyrecord_t *record) { if (!record->event.pressed) { #endif rgblight_increase_val(); - #ifdef SPLIT_KEYBOARD - RGB_DIRTY = true; - #endif } return false; case RGB_VAD: @@ -466,9 +442,6 @@ bool process_record_quantum(keyrecord_t *record) { if (!record->event.pressed) { #endif rgblight_decrease_val(); - #ifdef SPLIT_KEYBOARD - RGB_DIRTY = true; - #endif } return false; case RGB_SPI: @@ -484,9 +457,6 @@ bool process_record_quantum(keyrecord_t *record) { case RGB_MODE_PLAIN: if (record->event.pressed) { rgblight_mode(RGBLIGHT_MODE_STATIC_LIGHT); - #ifdef SPLIT_KEYBOARD - RGB_DIRTY = true; - #endif } return false; 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 @@ #endif #endif -#ifdef SPLIT_KEYBOARD - #include "split_flags.h" -#endif - #ifdef RGB_MATRIX_ENABLE #include "rgb_matrix.h" #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 @@ -#include -#include -#include -#include -#include -#include -#include "i2c.h" -#include "split_flags.h" - -// Limits the amount of we wait for any one i2c transaction. -// Since were running SCL line 100kHz (=> 10μs/bit), and each transactions is -// 9 bits, a single transaction will take around 90μs to complete. -// -// (F_CPU/SCL_CLOCK) => # of μC cycles to transfer a bit -// poll loop takes at least 8 clock cycles to execute -#define I2C_LOOP_TIMEOUT (9+1)*(F_CPU/SCL_CLOCK)/8 - -#define BUFFER_POS_INC() (slave_buffer_pos = (slave_buffer_pos+1)%SLAVE_BUFFER_SIZE) - -volatile uint8_t i2c_slave_buffer[SLAVE_BUFFER_SIZE]; - -static volatile uint8_t slave_buffer_pos; -static volatile bool slave_has_register_set = false; - -// Wait for an i2c operation to finish -inline static -void i2c_delay(void) { - uint16_t lim = 0; - while(!(TWCR & (1<10. - // Check datasheets for more info. - TWBR = ((F_CPU/SCL_CLOCK)-16)/2; -} - -// Start a transaction with the given i2c slave address. The direction of the -// transfer is set with I2C_READ and I2C_WRITE. -// returns: 0 => success -// 1 => error -uint8_t i2c_master_start(uint8_t address) { - TWCR = (1< slave ACK -// 1 => slave NACK -uint8_t i2c_master_write(uint8_t data) { - TWDR = data; - TWCR = (1<= SLAVE_BUFFER_SIZE ) { - ack = 0; - slave_buffer_pos = 0; - } - - slave_has_register_set = true; - } else { - i2c_slave_buffer[slave_buffer_pos] = TWDR; - - if ( slave_buffer_pos == I2C_BACKLIT_START) { - BACKLIT_DIRTY = true; - } else if ( slave_buffer_pos == (I2C_RGB_START+3)) { - RGB_DIRTY = true; - } - - BUFFER_POS_INC(); - } - break; - - case TW_ST_SLA_ACK: - case TW_ST_DATA_ACK: - // master has addressed this device as a slave transmitter and is - // requesting data. - TWDR = i2c_slave_buffer[slave_buffer_pos]; - BUFFER_POS_INC(); - break; - - case TW_BUS_ERROR: // something went wrong, reset twi state - TWCR = 0; - default: - break; - } - // Reset everything, so we are ready for the next TWI interrupt - TWCR |= (1< - -#ifndef F_CPU -#define F_CPU 16000000UL -#endif - -#define I2C_READ 1 -#define I2C_WRITE 0 - -#define I2C_ACK 1 -#define I2C_NACK 0 - -// Address location defines (Keymap should be last, as it's size is dynamic) -#define I2C_BACKLIT_START 0x00 -// Need 4 bytes for RGB (32 bit) -#define I2C_RGB_START 0x01 -#define I2C_KEYMAP_START 0x06 - -// Slave buffer (8bit per) -// Rows per hand + backlit space + rgb space -// TODO : Make this dynamically sized -#define SLAVE_BUFFER_SIZE 0x20 - -// i2c SCL clock frequency -#ifndef SCL_CLOCK -#define SCL_CLOCK 100000L -#endif - -// Support 8bits right now (8 cols) will need to edit to take higher (code exists in delta split?) -extern volatile uint8_t i2c_slave_buffer[SLAVE_BUFFER_SIZE]; - -void i2c_master_init(void); -uint8_t i2c_master_start(uint8_t address); -void i2c_master_stop(void); -uint8_t i2c_master_write(uint8_t data); -uint8_t i2c_master_write_data(void *const TXdata, uint8_t dataLen); -uint8_t i2c_master_read(int); -void i2c_reset_state(void); -void i2c_slave_init(uint8_t address); - - -static inline unsigned char i2c_start_read(unsigned char addr) { - return i2c_master_start((addr << 1) | I2C_READ); -} - -static inline unsigned char i2c_start_write(unsigned char addr) { - return i2c_master_start((addr << 1) | I2C_WRITE); -} - -// from SSD1306 scrips -extern unsigned char i2c_rep_start(unsigned char addr); -extern void i2c_start_wait(unsigned char addr); -extern unsigned char i2c_readAck(void); -extern unsigned char i2c_readNak(void); -extern unsigned char i2c_read(unsigned char ack); - -#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 . #include "matrix.h" #include "split_util.h" #include "config.h" -#include "split_flags.h" #include "quantum.h" #include "debounce.h" #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 @@ -#include "split_flags.h" - -volatile bool RGB_DIRTY = false; - -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 @@ -#pragma once - -#include -#include - -/** -* Global Flags -**/ - -//RGB Stuff -extern volatile bool RGB_DIRTY; - - -//Backlight Stuff -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 @@ #include "keyboard.h" #include "config.h" #include "timer.h" -#include "split_flags.h" #include "transport.h" #include "quantum.h" @@ -60,10 +59,6 @@ static void keyboard_master_setup(void) { #endif #endif transport_master_init(); - - // For master the Backlight info needs to be sent on startup - // Otherwise the salve won't start with the proper info until an update - BACKLIT_DIRTY = true; } 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 @@ #include "matrix.h" #include "quantum.h" -#define ROWS_PER_HAND (MATRIX_ROWS/2) +#define ROWS_PER_HAND (MATRIX_ROWS / 2) #ifdef RGBLIGHT_ENABLE -# include "rgblight.h" +# include "rgblight.h" #endif #ifdef BACKLIGHT_ENABLE -# include "backlight.h" - extern backlight_config_t backlight_config; +# include "backlight.h" +extern backlight_config_t backlight_config; #endif #if defined(USE_I2C) || defined(EH) -#include "i2c.h" +# include "i2c_master.h" +# include "i2c_slave.h" -#ifndef SLAVE_I2C_ADDRESS -# define SLAVE_I2C_ADDRESS 0x32 -#endif +# define I2C_BACKLIT_START 0x00 +// Need 4 bytes for RGB (32 bit) +# define I2C_RGB_START 0x01 +# define I2C_KEYMAP_START 0x05 -#if (MATRIX_COLS > 8) -# error "Currently only supports 8 COLS" -#endif +# define TIMEOUT 100 + +# ifndef SLAVE_I2C_ADDRESS +# define SLAVE_I2C_ADDRESS 0x32 +# endif // Get rows from other half over i2c bool transport_master(matrix_row_t matrix[]) { - int err = 0; + i2c_readReg(SLAVE_I2C_ADDRESS, I2C_KEYMAP_START, (void *)matrix, ROWS_PER_HAND * sizeof(matrix_row_t), TIMEOUT); // write backlight info -#ifdef BACKLIGHT_ENABLE - if (BACKLIT_DIRTY) { - err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_WRITE); - if (err) { goto i2c_error; } - - // Backlight location - err = i2c_master_write(I2C_BACKLIT_START); - if (err) { goto i2c_error; } - - // Write backlight - i2c_master_write(get_backlight_level()); - - BACKLIT_DIRTY = false; +# ifdef BACKLIGHT_ENABLE + static uint8_t prev_level = ~0; + uint8_t level = get_backlight_level(); + if (level != prev_level) { + i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_BACKLIT_START, (void *)&level, sizeof(level), TIMEOUT); + prev_level = level; } -#endif +# endif - err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_WRITE); - if (err) { goto i2c_error; } - - // start of matrix stored at I2C_KEYMAP_START - err = i2c_master_write(I2C_KEYMAP_START); - if (err) { goto i2c_error; } - - // Start read - err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_READ); - if (err) { goto i2c_error; } - - if (!err) { - int i; - for (i = 0; i < ROWS_PER_HAND-1; ++i) { - matrix[i] = i2c_master_read(I2C_ACK); - } - matrix[i] = i2c_master_read(I2C_NACK); - i2c_master_stop(); - } else { -i2c_error: // the cable is disconnceted, or something else went wrong - i2c_reset_state(); - return false; +# ifdef RGBLIGHT_ENABLE + static uint32_t prev_rgb = ~0; + uint32_t rgb = eeconfig_read_rgblight(); + if (rgb != prev_rgb) { + i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_START, (void *)&rgb, sizeof(rgb), TIMEOUT); + prev_rgb = rgb; } - -#ifdef RGBLIGHT_ENABLE - if (RGB_DIRTY) { - err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_WRITE); - if (err) { goto i2c_error; } - - // RGB Location - err = i2c_master_write(I2C_RGB_START); - if (err) { goto i2c_error; } - - uint32_t dword = eeconfig_read_rgblight(); - - // Write RGB - err = i2c_master_write_data(&dword, 4); - if (err) { goto i2c_error; } - - RGB_DIRTY = false; - i2c_master_stop(); - } -#endif +# endif return true; } void transport_slave(matrix_row_t matrix[]) { - - for (int i = 0; i < ROWS_PER_HAND; ++i) - { - i2c_slave_buffer[I2C_KEYMAP_START + i] = matrix[i]; + for (int i = 0; i < ROWS_PER_HAND * sizeof(matrix_row_t); ++i) { + i2c_slave_reg[I2C_KEYMAP_START + i] = matrix[i]; } - // Read Backlight Info - #ifdef BACKLIGHT_ENABLE - if (BACKLIT_DIRTY) - { - backlight_set(i2c_slave_buffer[I2C_BACKLIT_START]); - BACKLIT_DIRTY = false; - } - #endif - #ifdef RGBLIGHT_ENABLE - if (RGB_DIRTY) - { - // Disable interupts (RGB data is big) - cli(); - // Create new DWORD for RGB data - uint32_t dword; - // Fill the new DWORD with the data that was sent over - uint8_t * dword_dat = (uint8_t *)(&dword); - for (int i = 0; i < 4; i++) - { - dword_dat[i] = i2c_slave_buffer[I2C_RGB_START + i]; - } +// Read Backlight Info +# ifdef BACKLIGHT_ENABLE + backlight_set(i2c_slave_reg[I2C_BACKLIT_START]); +# endif - // Update the RGB now with the new data and set RGB_DIRTY to false - rgblight_update_dword(dword); - RGB_DIRTY = false; - // Re-enable interupts now that RGB is set - sei(); - } - #endif +# ifdef RGBLIGHT_ENABLE + uint32_t rgb = *(uint32_t *)(i2c_slave_reg + I2C_RGB_START); + // Update the RGB with the new data + rgblight_update_dword(rgb); +# endif } -void transport_master_init(void) { - i2c_master_init(); -} +void transport_master_init(void) { i2c_init(); } -void transport_slave_init(void) { - i2c_slave_init(SLAVE_I2C_ADDRESS); -} +void transport_slave_init(void) { i2c_slave_init(SLAVE_I2C_ADDRESS); } -#else // USE_SERIAL +#else // USE_SERIAL -#include "serial.h" +# include "serial.h" typedef struct _Serial_s2m_buffer_t { // TODO: if MATRIX_COLS > 8 change to uint8_t packed_matrix[] for pack/unpack @@ -150,40 +87,40 @@ typedef struct _Serial_s2m_buffer_t { } Serial_s2m_buffer_t; typedef struct _Serial_m2s_buffer_t { -#ifdef BACKLIGHT_ENABLE - uint8_t backlight_level; -#endif -#if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) - rgblight_config_t rgblight_config; //not yet use - // - // When MCUs on both sides drive their respective RGB LED chains, - // it is necessary to synchronize, so it is necessary to communicate RGB information. - // In that case, define the RGBLIGHT_SPLIT macro. - // - // Otherwise, if the master side MCU drives both sides RGB LED chains, - // there is no need to communicate. -#endif +# ifdef BACKLIGHT_ENABLE + uint8_t backlight_level; +# endif +# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) + rgblight_config_t rgblight_config; // not yet use + // + // When MCUs on both sides drive their respective RGB LED chains, + // it is necessary to synchronize, so it is necessary to communicate RGB + // information. In that case, define the RGBLIGHT_SPLIT macro. + // + // Otherwise, if the master side MCU drives both sides RGB LED chains, + // there is no need to communicate. +# endif } Serial_m2s_buffer_t; volatile Serial_s2m_buffer_t serial_s2m_buffer = {}; volatile Serial_m2s_buffer_t serial_m2s_buffer = {}; -uint8_t volatile status0 = 0; +uint8_t volatile status0 = 0; SSTD_t transactions[] = { - { (uint8_t *)&status0, - sizeof(serial_m2s_buffer), (uint8_t *)&serial_m2s_buffer, - sizeof(serial_s2m_buffer), (uint8_t *)&serial_s2m_buffer - } + { + (uint8_t *)&status0, + sizeof(serial_m2s_buffer), + (uint8_t *)&serial_m2s_buffer, + sizeof(serial_s2m_buffer), + (uint8_t *)&serial_s2m_buffer, + }, }; -void transport_master_init(void) -{ soft_serial_initiator_init(transactions, TID_LIMIT(transactions)); } +void transport_master_init(void) { soft_serial_initiator_init(transactions, TID_LIMIT(transactions)); } -void transport_slave_init(void) -{ soft_serial_target_init(transactions, TID_LIMIT(transactions)); } +void transport_slave_init(void) { soft_serial_target_init(transactions, TID_LIMIT(transactions)); } bool transport_master(matrix_row_t matrix[]) { - if (soft_serial_transaction()) { return false; } @@ -193,32 +130,29 @@ bool transport_master(matrix_row_t matrix[]) { matrix[i] = serial_s2m_buffer.smatrix[i]; } - #if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) - // Code to send RGB over serial goes here (not implemented yet) - #endif +# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) + // Code to send RGB over serial goes here (not implemented yet) +# endif - #ifdef BACKLIGHT_ENABLE - // Write backlight level for slave to read - serial_m2s_buffer.backlight_level = backlight_config.enable ? backlight_config.level : 0; - #endif +# ifdef BACKLIGHT_ENABLE + // Write backlight level for slave to read + serial_m2s_buffer.backlight_level = backlight_config.enable ? backlight_config.level : 0; +# endif return true; } void transport_slave(matrix_row_t matrix[]) { - // TODO: if MATRIX_COLS > 8 change to pack() - for (int i = 0; i < ROWS_PER_HAND; ++i) - { + for (int i = 0; i < ROWS_PER_HAND; ++i) { serial_s2m_buffer.smatrix[i] = matrix[i]; } - #ifdef BACKLIGHT_ENABLE - backlight_set(serial_m2s_buffer.backlight_level); - #endif - #if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) - // Add serial implementation for RGB here - #endif - +# ifdef BACKLIGHT_ENABLE + backlight_set(serial_m2s_buffer.backlight_level); +# endif +# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) +// Add serial implementation for RGB here +# endif } #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 @@ #include "led.h" #include "host.h" #include "rgblight_reconfig.h" -#ifdef SPLIT_KEYBOARD - #include "split_flags.h" -#endif #ifdef PROTOCOL_LUFA #include "lufa.h" @@ -135,9 +132,6 @@ static void power_down(uint8_t wdto) { is_suspended = true; rgblight_enabled = rgblight_config.enable; rgblight_disable_noeeprom(); - #ifdef SPLIT_KEYBOARD - RGB_DIRTY = true; - #endif } #endif suspend_power_down_kb(); @@ -216,9 +210,6 @@ void suspend_wakeup_init(void) { wait_ms(10); #endif rgblight_enable_noeeprom(); - #ifdef SPLIT_KEYBOARD - RGB_DIRTY = true; - #endif } #ifdef RGBLIGHT_ANIMATIONS rgblight_timer_enable();