Răsfoiți Sursa

add encoder matrix functionality

Jack Humbert 6 ani în urmă
părinte
comite
9e64d5f6c2
2 a modificat fișierele cu 101 adăugiri și 12 ștergeri
  1. 8 0
      docs/feature_encoders.md
  2. 93 12
      quantum/encoder.c

+ 8 - 0
docs/feature_encoders.md

@@ -58,3 +58,11 @@ or `keymap.c`:
 ## Hardware
 
 The A an B lines of the encoders should be wired directly to the MCU, and the C/common lines should be wired to ground.
+
+## Encoder matrix
+
+You can also wire the C/common line through a diode (arrow towards the row) to each of the rows (or reading pin) in your matrix, and use as many encoders as you have rows (multiplied by the number of A/B lines you have hooked up). To do this, you can add this line to your `config.h` with all of the pins you use:
+
+```c
+#define ENCODERS_PAD_C { encoder1c, encoder2c }
+```

+ 93 - 12
quantum/encoder.c

@@ -31,10 +31,19 @@
 #    error "No encoder pads defined by ENCODERS_PAD_A and ENCODERS_PAD_B"
 #endif
 
-#define NUMBER_OF_ENCODERS (sizeof(encoders_pad_a) / sizeof(pin_t))
 static pin_t encoders_pad_a[] = ENCODERS_PAD_A;
 static pin_t encoders_pad_b[] = ENCODERS_PAD_B;
 
+#ifdef ENCODERS_PAD_C
+    #define NUMBER_OF_ENCODERS_AB (sizeof(encoders_pad_a) / sizeof(pin_t))
+    #define NUMBER_OF_ENCODERS_C (sizeof(encoders_pad_c) / sizeof(pin_t))
+    #define NUMBER_OF_ENCODERS (NUMBER_OF_ENCODERS_C * NUMBER_OF_ENCODERS_AB)
+    static pin_t encoders_pad_c[] = ENCODERS_PAD_C;
+#else
+    #define NUMBER_OF_ENCODERS (sizeof(encoders_pad_a) / sizeof(pin_t))
+    #define NUMBER_OF_ENCODERS_AB (sizeof(encoders_pad_a) / sizeof(pin_t))
+#endif
+
 static int8_t encoder_LUT[] = {0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0};
 
 static uint8_t encoder_state[NUMBER_OF_ENCODERS] = {0};
@@ -57,19 +66,51 @@ void encoder_init(void) {
     if (!isLeftHand) {
         const pin_t encoders_pad_a_right[] = ENCODERS_PAD_A_RIGHT;
         const pin_t encoders_pad_b_right[] = ENCODERS_PAD_B_RIGHT;
-        for (uint8_t i = 0; i < NUMBER_OF_ENCODERS; i++) {
+        for (uint8_t i = 0; i < NUMBER_OF_ENCODERS_AB; i++) {
             encoders_pad_a[i] = encoders_pad_a_right[i];
             encoders_pad_b[i] = encoders_pad_b_right[i];
         }
     }
 #endif
 
-    for (int i = 0; i < NUMBER_OF_ENCODERS; i++) {
-        setPinInputHigh(encoders_pad_a[i]);
-        setPinInputHigh(encoders_pad_b[i]);
+    #ifdef ENCODERS_PAD_C
+        for (int i = 0; i < NUMBER_OF_ENCODERS_C; i++) {
+            setPinOutput(encoders_pad_c[i]);
+            if (i != 0)
+                writePinHigh(encoders_pad_c[i]);
+            else
+                writePinLow(encoders_pad_c[i]);
+        }
 
-        encoder_state[i] = (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1);
-    }
+        for (int j = 0; j < NUMBER_OF_ENCODERS_C; j++) {
+            writePinLow(encoders_pad_c[j]);
+            wait_us(10);
+            for (int i = 0; i < NUMBER_OF_ENCODERS_AB; i++) {
+                setPinInputHigh(encoders_pad_a[i]);
+                setPinInputHigh(encoders_pad_b[i]);
+
+                encoder_state[j+(i*NUMBER_OF_ENCODERS_C)] = (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1);
+
+            }
+            writePinHigh(encoders_pad_c[j]);
+        }
+        // need to disable these pins to prevent matrix activation
+        for (int i = 0; i < NUMBER_OF_ENCODERS_AB; i++) {
+            setPinInput(encoders_pad_a[i]);
+            setPinInput(encoders_pad_b[i]);
+        }
+        for (int i = 0; i < NUMBER_OF_ENCODERS_C; i++) {
+            setPinInputLow(encoders_pad_c[i]);
+        }
+
+    #else
+        for (int i = 0; i < NUMBER_OF_ENCODERS; i++) {
+            setPinInputHigh(encoders_pad_a[i]);
+            setPinInputHigh(encoders_pad_b[i]);
+
+            encoder_state[i] = (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1);
+        }
+    #endif
 
 #ifdef SPLIT_KEYBOARD
     thisHand = isLeftHand ? 0 : NUMBER_OF_ENCODERS;
@@ -89,15 +130,55 @@ static void encoder_update(int8_t index, uint8_t state) {
 }
 
 void encoder_read(void) {
-    for (int i = 0; i < NUMBER_OF_ENCODERS; i++) {
-        encoder_state[i] <<= 2;
-        encoder_state[i] |= (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1);
+#ifdef ENCODERS_PAD_C
+    // setup row pins to act as C pins for the encoders, prep the first one
+    for (int i = 0; i < NUMBER_OF_ENCODERS_C; i++) {
+            setPinOutput(encoders_pad_c[i]);
+            if (i != 0)
+                writePinHigh(encoders_pad_c[i]);
+            else
+                writePinLow(encoders_pad_c[i]);
+    }
+    // pull these back up because we disabled them earlier
+    for (int i = 0; i < NUMBER_OF_ENCODERS_AB; i++) {
+        setPinInputHigh(encoders_pad_a[i]);
+        setPinInputHigh(encoders_pad_b[i]);
+    }
+    for (int j = 0; j < NUMBER_OF_ENCODERS_C; j++) {
+        writePinLow(encoders_pad_c[j]);
+        wait_us(10);
+        for (int i = 0; i < NUMBER_OF_ENCODERS_AB; i++) {
+            encoder_state[j+(i*NUMBER_OF_ENCODERS_C)] <<= 2;
+            encoder_state[j+(i*NUMBER_OF_ENCODERS_C)] |= (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1);
 #if SPLIT_KEYBOARD
-        encoder_update(i + thisHand, encoder_state[i]);
+            encoder_update(j+(i*NUMBER_OF_ENCODERS_C) + thisHand, encoder_state[j+(i*NUMBER_OF_ENCODERS_C)]);
 #else
-        encoder_update(i, encoder_state[i]);
+            encoder_update(j+(i*NUMBER_OF_ENCODERS_C), encoder_state[j+(i*NUMBER_OF_ENCODERS_C)]);
 #endif
+        }
+        writePinHigh(encoders_pad_c[j]);    
+    }
+    // need to disable these pins again to prevent matrix activation
+    for (int i = 0; i < NUMBER_OF_ENCODERS_AB; i++) {
+        setPinInput(encoders_pad_a[i]);
+        setPinInput(encoders_pad_b[i]);
+    }
+    // revert row pins back to input
+    for (int i = 0; i < NUMBER_OF_ENCODERS_C; i++) {
+        setPinInputLow(encoders_pad_c[i]);
     }
+
+#else
+        for (int i = 0; i < NUMBER_OF_ENCODERS; i++) {
+            encoder_state[i] <<= 2;
+            encoder_state[i] |= (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1);
+#if SPLIT_KEYBOARD
+            encoder_update(i + thisHand, encoder_state[i]);
+#else
+            encoder_update(i, encoder_state[i]);
+#endif
+        }
+#endif
 }
 
 #ifdef SPLIT_KEYBOARD