]> git.donarmstrong.com Git - qmk_firmware.git/blobdiff - keyboards/ergodox_ez/matrix.c
Merge pull request #1915 from dondelelcaro/ergodox_ez_left_leds
[qmk_firmware.git] / keyboards / ergodox_ez / matrix.c
index 9c1efa1d05acb4bee691f771c943316b57ac93bf..70efb43d8e4106ac3ae1ab5cf2d31bc863531974 100644 (file)
@@ -33,20 +33,34 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include "debug.h"
 #include "util.h"
 #include "matrix.h"
-#include "ergodox_ez.h"
+#include QMK_KEYBOARD_H
 #include "i2cmaster.h"
 #ifdef DEBUG_MATRIX_SCAN_RATE
 #include  "timer.h"
 #endif
 
+/*
+ * 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.
+ */
+
 #ifndef DEBOUNCE
 #   define DEBOUNCE    5
 #endif
-static uint8_t debouncing = DEBOUNCE;
 
 /* matrix state(1:on, 0:off) */
 static matrix_row_t matrix[MATRIX_ROWS];
-static matrix_row_t matrix_debouncing[MATRIX_ROWS];
+
+// Debouncing: store for each key the number of scans until it's eligible to
+// change.  When scanning the matrix, ignore any changes in keys that have
+// already changed in the last DEBOUNCE scans.
+static uint8_t debounce_matrix[MATRIX_ROWS * MATRIX_COLS];
 
 static matrix_row_t read_cols(uint8_t row);
 static void init_cols(void);
@@ -102,7 +116,9 @@ void matrix_init(void)
     // initialize matrix state: all keys off
     for (uint8_t i=0; i < MATRIX_ROWS; i++) {
         matrix[i] = 0;
-        matrix_debouncing[i] = 0;
+        for (uint8_t j=0; j < MATRIX_COLS; ++j) {
+            debounce_matrix[i * MATRIX_COLS + j] = 0;
+        }
     }
 
 #ifdef DEBUG_MATRIX_SCAN_RATE
@@ -110,7 +126,7 @@ void matrix_init(void)
     matrix_scan_count = 0;
 #endif
 
-    matrix_init_kb();
+    matrix_init_quantum();
 
 }
 
@@ -123,14 +139,36 @@ void matrix_power_up(void) {
     // initialize matrix state: all keys off
     for (uint8_t i=0; i < MATRIX_ROWS; i++) {
         matrix[i] = 0;
-        matrix_debouncing[i] = 0;
     }
 
 #ifdef DEBUG_MATRIX_SCAN_RATE
     matrix_timer = timer_read32();
     matrix_scan_count = 0;
 #endif
+}
 
+// Returns a matrix_row_t whose bits are set if the corresponding key should be
+// eligible to change in this scan.
+matrix_row_t debounce_mask(uint8_t row) {
+  matrix_row_t result = 0;
+  for (uint8_t j=0; j < MATRIX_COLS; ++j) {
+    if (debounce_matrix[row * MATRIX_COLS + j]) {
+      --debounce_matrix[row * MATRIX_COLS + j];
+    } else {
+      result |= (1 << j);
+    }
+  }
+  return result;
+}
+
+// Report changed keys in the given row.  Resets the debounce countdowns
+// corresponding to each set bit in 'change' to DEBOUNCE.
+void debounce_report(matrix_row_t change, uint8_t row) {
+  for (uint8_t i = 0; i < MATRIX_COLS; ++i) {
+    if (change & (1 << i)) {
+      debounce_matrix[row * MATRIX_COLS + i] = DEBOUNCE;
+    }
+  }
 }
 
 uint8_t matrix_scan(void)
@@ -164,28 +202,18 @@ uint8_t matrix_scan(void)
     }
 #endif
 
+#ifdef LEFT_LEDS
+     mcp23018_status = ergodox_left_leds_update();
+#endif // LEFT_LEDS
     for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
         select_row(i);
         wait_us(30);  // without this wait read unstable value.
-        matrix_row_t cols = read_cols(i);
-        if (matrix_debouncing[i] != cols) {
-            matrix_debouncing[i] = cols;
-            if (debouncing) {
-                debug("bounce!: "); debug_hex(debouncing); debug("\n");
-            }
-            debouncing = DEBOUNCE;
-        }
-        unselect_rows();
-    }
+        matrix_row_t mask = debounce_mask(i);
+        matrix_row_t cols = (read_cols(i) & mask) | (matrix[i] & ~mask);
+        debounce_report(cols ^ matrix[i], i);
+        matrix[i] = cols;
 
-    if (debouncing) {
-        if (--debouncing) {
-            wait_us(1);
-        } else {
-            for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
-                matrix[i] = matrix_debouncing[i];
-            }
-        }
+        unselect_rows();
     }
 
     matrix_scan_quantum();
@@ -193,9 +221,8 @@ uint8_t matrix_scan(void)
     return 1;
 }
 
-bool matrix_is_modified(void)
+bool matrix_is_modified(void) // deprecated and evidently not called.
 {
-    if (debouncing) return false;
     return true;
 }