From: Oleg Kostyuk Date: Sun, 8 Sep 2013 22:49:11 +0000 (+0300) Subject: Optimizing I2C X-Git-Url: https://git.donarmstrong.com/?p=tmk_firmware.git;a=commitdiff_plain;h=5329bbefee10503832d419733e6cfecb97e712cb Optimizing I2C --- diff --git a/keyboard/ergodox/config.h b/keyboard/ergodox/config.h index 62e5ff6..de32be7 100644 --- a/keyboard/ergodox/config.h +++ b/keyboard/ergodox/config.h @@ -40,7 +40,17 @@ Project located at //#define MATRIX_HAS_GHOST /* Set 0 if debouncing isn't needed */ -#define DEBOUNCE 5 +/* + * This constant define not debouncing time in msecs, but amount of matrix + * scan loops which should be made to get stable debounced results. + * + * On Ergodox matrix scan rate is relatively low, because of slow I2C. + * Now it's only 317 scans/second, or about 3.15 msec/scan. + * According to Cherry specs, debouncing time is 5 msec. + * + * And so, there is no sense to have DEBOUNCE higher than 2. + */ +#define DEBOUNCE 2 /* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ #define LOCKING_SUPPORT_ENABLE diff --git a/keyboard/ergodox/ergodox.c b/keyboard/ergodox/ergodox.c index 8aed78e..f8b3d82 100644 --- a/keyboard/ergodox/ergodox.c +++ b/keyboard/ergodox/ergodox.c @@ -90,6 +90,7 @@ uint8_t init_mcp23018(void) { err = i2c_write(0b00000000); if (err) goto out; err = i2c_write(0b00111111); if (err) goto out; i2c_stop(); + // set pull-up // - unused : on : 1 // - input : on : 1 @@ -98,8 +99,18 @@ uint8_t init_mcp23018(void) { err = i2c_write(GPPUA); if (err) goto out; err = i2c_write(0b00000000); if (err) goto out; err = i2c_write(0b00111111); if (err) goto out; + +out: i2c_stop(); + if (!err) err = ergodox_left_leds_update(); + + return err; +} + +uint8_t ergodox_left_leds_update(void) { + uint8_t err = 0x20; + // set logical value (doesn't matter on inputs) // - unused : hi-Z : 1 // - input : hi-Z : 1 diff --git a/keyboard/ergodox/ergodox.h b/keyboard/ergodox/ergodox.h index d962368..a0511ff 100644 --- a/keyboard/ergodox/ergodox.h +++ b/keyboard/ergodox/ergodox.h @@ -47,6 +47,7 @@ Most used files are located at void init_ergodox(void); uint8_t init_mcp23018(void); +uint8_t ergodox_left_leds_update(void); #define LED_BRIGHTNESS_LO 31 #define LED_BRIGHTNESS_HI 255 @@ -75,8 +76,6 @@ inline void ergodox_left_led_1_off(void) { ergodox_left_led_1 = 0; } inline void ergodox_left_led_2_off(void) { ergodox_left_led_2 = 0; } inline void ergodox_left_led_3_off(void) { ergodox_left_led_3 = 0; } -inline void ergodox_left_leds_update(void) { init_mcp23018(); } - inline void ergodox_led_all_on(void) { ergodox_board_led_on(); diff --git a/keyboard/ergodox/matrix.c b/keyboard/ergodox/matrix.c index e35b65c..b75d7c5 100644 --- a/keyboard/ergodox/matrix.c +++ b/keyboard/ergodox/matrix.c @@ -42,10 +42,12 @@ static uint8_t debouncing = DEBOUNCE; static matrix_row_t matrix[MATRIX_ROWS]; static matrix_row_t matrix_debouncing[MATRIX_ROWS]; -static matrix_row_t read_cols(uint8_t mcp23018_status, uint8_t row); +static matrix_row_t read_cols(uint8_t row); static void init_cols(void); -static void unselect_rows(uint8_t mcp23018_status); -static void select_row(uint8_t mcp23018_status, uint8_t row); +static void unselect_rows(); +static void select_row(uint8_t row); + +static uint8_t mcp23018_status; #ifdef DEBUG_MATRIX_FREQ uint32_t matrix_timer; @@ -68,9 +70,8 @@ void matrix_init(void) { // initialize row and col init_ergodox(); - uint8_t mcp23018_status; mcp23018_status = init_mcp23018(); - unselect_rows(mcp23018_status); + unselect_rows(); init_cols(); // initialize matrix state: all keys off @@ -139,16 +140,14 @@ uint8_t matrix_scan(void) } // not actually needed because we already calling init_mcp23018() in next line - // ergodox_left_leds_update(); + mcp23018_status = ergodox_left_leds_update(); #endif - uint8_t mcp23018_status = init_mcp23018(); - for (uint8_t i = 0; i < MATRIX_ROWS; i++) { - select_row(mcp23018_status, i); + select_row(i); _delay_us(30); // without this wait read unstable value. - matrix_row_t cols = read_cols(mcp23018_status, i); + matrix_row_t cols = read_cols(i); if (matrix_debouncing[i] != cols) { matrix_debouncing[i] = cols; if (debouncing) { @@ -156,7 +155,7 @@ uint8_t matrix_scan(void) } debouncing = DEBOUNCE; } - unselect_rows(mcp23018_status); + unselect_rows(); } if (debouncing) { @@ -230,17 +229,16 @@ static void init_cols(void) PORTF |= (1<<7 | 1<<6 | 1<<5 | 1<<4 | 1<<1 | 1<<0); } -static matrix_row_t read_cols(uint8_t mcp23018_status, uint8_t row) +static matrix_row_t read_cols(uint8_t row) { if (row < 7) { if (mcp23018_status) { // if there was an error return 0; } else { uint8_t data = 0; - uint8_t err = 0x20; - err = i2c_start(I2C_ADDR_WRITE); if (err) goto out; - err = i2c_write(GPIOB); if (err) goto out; - err = i2c_start(I2C_ADDR_READ); if (err) goto out; + mcp23018_status = i2c_start(I2C_ADDR_WRITE); if (mcp23018_status) goto out; + mcp23018_status = i2c_write(GPIOB); if (mcp23018_status) goto out; + mcp23018_status = i2c_start(I2C_ADDR_READ); if (mcp23018_status) goto out; data = i2c_readNak(); data = ~data; out: @@ -269,19 +267,18 @@ static matrix_row_t read_cols(uint8_t mcp23018_status, uint8_t row) * row: 0 1 2 3 4 5 6 * pin: A0 A1 A2 A3 A4 A5 A6 */ -static void unselect_rows(uint8_t mcp23018_status) +static void unselect_rows(void) { // unselect on mcp23018 if (mcp23018_status) { // if there was an error // do nothing } else { // set all rows hi-Z : 1 - uint8_t err = 0x20; - err = i2c_start(I2C_ADDR_WRITE); if (err) goto out; - err = i2c_write(GPIOA); if (err) goto out; - err = i2c_write( 0xFF - & ~(ergodox_left_led_3<