]> git.friedersdorff.com Git - max/tmk_keyboard.git/commitdiff
Optimizing I2C
authorOleg Kostyuk <cub.uanic@gmail.com>
Sun, 8 Sep 2013 22:49:11 +0000 (01:49 +0300)
committerOleg Kostyuk <cub.uanic@gmail.com>
Sun, 8 Sep 2013 23:04:20 +0000 (02:04 +0300)
keyboard/ergodox/config.h
keyboard/ergodox/ergodox.c
keyboard/ergodox/ergodox.h
keyboard/ergodox/matrix.c

index 62e5ff6a81a82d0730c30c4f5d4835c1516e6b34..de32be7ecfbe881c78d1d4008d747560e0a74ae3 100644 (file)
@@ -40,7 +40,17 @@ Project located at <https://github.com/benblazak/ergodox-firmware>
 //#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
index 8aed78ecb72688df7ab2d9345292f25358d46d93..f8b3d82efb3e26f26e139c4fc92194d03fc6378b 100644 (file)
@@ -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
index d9623687143003682abd6cdd13fe8fab7cb87b03..a0511ff3448dfb7d4fec348b50b17197e5e11ebf 100644 (file)
@@ -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();
index e35b65c95af4b16410d8a20e410d3b381f2e972c..b75d7c57a038e14ae70955f74717baa02ef7654c 100644 (file)
@@ -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<<LEFT_LED_3_SHIFT)
-              );                            if (err) goto out;
+        mcp23018_status = i2c_start(I2C_ADDR_WRITE);    if (mcp23018_status) goto out;
+        mcp23018_status = i2c_write(GPIOA);             if (mcp23018_status) goto out;
+        mcp23018_status = i2c_write( 0xFF
+                              & ~(ergodox_left_led_3<<LEFT_LED_3_SHIFT)
+                          );                            if (mcp23018_status) goto out;
     out:
         i2c_stop();
     }
@@ -296,7 +293,7 @@ static void unselect_rows(uint8_t mcp23018_status)
     PORTC &= ~(1<<6);
 }
 
-static void select_row(uint8_t mcp23018_status, uint8_t row)
+static void select_row(uint8_t row)
 {
     if (row < 7) {
         // select on mcp23018
@@ -305,12 +302,11 @@ static void select_row(uint8_t mcp23018_status, uint8_t row)
         } else {
             // set active row low  : 0
             // set other 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 & ~(1<<row) 
-                    & ~(ergodox_left_led_3<<LEFT_LED_3_SHIFT)
-                  );                                if (err) goto out;
+            mcp23018_status = i2c_start(I2C_ADDR_WRITE);        if (mcp23018_status) goto out;
+            mcp23018_status = i2c_write(GPIOA);                 if (mcp23018_status) goto out;
+            mcp23018_status = i2c_write( 0xFF & ~(1<<row) 
+                                  & ~(ergodox_left_led_3<<LEFT_LED_3_SHIFT)
+                              );                                if (mcp23018_status) goto out;
         out:
             i2c_stop();
         }