add encoder matrix functionality

This commit is contained in:
Jack Humbert 2019-10-30 13:39:18 -04:00
parent f183af14ad
commit 9e64d5f6c2
2 changed files with 104 additions and 15 deletions

View file

@ -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 }
```

View file

@ -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);
#if SPLIT_KEYBOARD
encoder_update(i + thisHand, encoder_state[i]);
#else
encoder_update(i, encoder_state[i]);
#endif
#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(j+(i*NUMBER_OF_ENCODERS_C) + thisHand, encoder_state[j+(i*NUMBER_OF_ENCODERS_C)]);
#else
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