Skip to content

Commit

Permalink
Revert "Rework encoders to enable asymmetric split keyboards (qmk#12090
Browse files Browse the repository at this point in the history
…)"

This reverts commit 32215d5.
  • Loading branch information
drashna committed Nov 27, 2021
1 parent 67778dc commit 96d7bde
Show file tree
Hide file tree
Showing 14 changed files with 58 additions and 575 deletions.
1 change: 0 additions & 1 deletion build_test.mk
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ include $(BUILDDEFS_PATH)/generic_features.mk
include $(PLATFORM_PATH)/common.mk
include $(TMK_PATH)/protocol.mk
include $(QUANTUM_PATH)/debounce/tests/rules.mk
include $(QUANTUM_PATH)/encoder/tests/rules.mk
include $(QUANTUM_PATH)/sequencer/tests/rules.mk
include $(PLATFORM_PATH)/test/rules.mk
ifneq ($(filter $(FULL_TESTS),$(TEST)),)
Expand Down
15 changes: 1 addition & 14 deletions docs/feature_encoders.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,27 +46,14 @@ For 4× encoders you also can assign default position if encoder skips pulses wh
## Split Keyboards
The above is enough for split keyboards that are symmetrical, i.e. the halves have the same number of encoders and they are on the same pins.
If the halves are not symmetrical, you can define the pinout (and optionally, resolutions) of the right half separately.
The left half will use the definitions above.
If you are using different pinouts for the encoders on each half of a split keyboard, you can define the pinout (and optionally, resolutions) for the right half like this:
```c
#define ENCODERS_PAD_A_RIGHT { encoder1a, encoder2a }
#define ENCODERS_PAD_B_RIGHT { encoder1b, encoder2b }
#define ENCODER_RESOLUTIONS_RIGHT { 2, 4 }
```
If only the right half has encoders, you must still define an empty array for the left pads (and resolutions, if you define `ENCODER_RESOLUTIONS_RIGHT`).
```c
#define ENCODERS_PAD_A { }
#define ENCODERS_PAD_B { }
#define ENCODER_RESOLUTIONS { }
#define ENCODERS_PAD_A_RIGHT { encoder1a, encoder2a }
#define ENCODERS_PAD_B_RIGHT { encoder1b, encoder2b }
#define ENCODER_RESOLUTIONS_RIGHT { 2, 4 }
```
## Callbacks
The callback functions can be inserted into your `<keyboard>.c`:
Expand Down
146 changes: 55 additions & 91 deletions quantum/encoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,8 @@
*/

#include "encoder.h"

// this is for unit testing
#if defined(ENCODER_MOCK_SINGLE)
# include "encoder/tests/mock.h"
#elif defined(ENCODER_MOCK_SPLIT)
# include "encoder/tests/mock_split.h"
#else
# include <gpio.h>
# ifdef SPLIT_KEYBOARD
# include "split_util.h"
# endif
#ifdef SPLIT_KEYBOARD
# include "split_util.h"
#endif

// for memcpy
Expand All @@ -36,41 +27,17 @@
# define ENCODER_RESOLUTION 4
#endif

#if (!defined(ENCODERS_PAD_A) || !defined(ENCODERS_PAD_B)) && (!defined(ENCODERS_PAD_A) || !defined(ENCODERS_PAD_B))
# error "No encoder pads defined by ENCODERS_PAD_A and ENCODERS_PAD_B or ENCODERS_PAD_A_RIGHT and ENCODERS_PAD_B_RIGHT"
#if !defined(ENCODERS_PAD_A) || !defined(ENCODERS_PAD_B)
# error "No encoder pads defined by ENCODERS_PAD_A and ENCODERS_PAD_B"
#endif

// on split keyboards, these are the pads and resolutions for the left half
#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 ENCODER_RESOLUTIONS
static uint8_t encoder_resolutions[] = ENCODER_RESOLUTIONS;
#endif

#ifndef SPLIT_KEYBOARD
# define NUMBER_OF_ENCODERS (sizeof(encoders_pad_a) / sizeof(pin_t))
#else
// if no pads for right half are defined, we assume the keyboard is symmetric (i.e. same pads)
# ifndef ENCODERS_PAD_A_RIGHT
# define ENCODERS_PAD_A_RIGHT ENCODERS_PAD_A
# endif
# ifndef ENCODERS_PAD_B_RIGHT
# define ENCODERS_PAD_B_RIGHT ENCODERS_PAD_B
# endif
# if defined(ENCODER_RESOLUTIONS) && !defined(ENCODER_RESOLUTIONS_RIGHT)
# define ENCODER_RESOLUTIONS_RIGHT ENCODER_RESOLUTIONS
# endif

# define NUMBER_OF_ENCODERS ((sizeof(encoders_pad_a) + sizeof(encoders_pad_a_right)) / sizeof(pin_t))
# define NUMBER_OF_ENCODERS_LEFT (sizeof(encoders_pad_a) / sizeof(pin_t))
# define NUMBER_OF_ENCODERS_RIGHT (sizeof(encoders_pad_a_right) / sizeof(pin_t))
static pin_t encoders_pad_a_right[] = ENCODERS_PAD_A_RIGHT;
static pin_t encoders_pad_b_right[] = ENCODERS_PAD_B_RIGHT;
# ifdef ENCODER_RESOLUTIONS_RIGHT
static uint8_t encoder_resolutions_right[] = ENCODER_RESOLUTIONS_RIGHT;
# endif
#endif

#ifndef ENCODER_DIRECTION_FLIP
# define ENCODER_CLOCKWISE true
# define ENCODER_COUNTER_CLOCKWISE false
Expand All @@ -83,105 +50,102 @@ static int8_t encoder_LUT[] = {0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1,
static uint8_t encoder_state[NUMBER_OF_ENCODERS] = {0};
static int8_t encoder_pulses[NUMBER_OF_ENCODERS] = {0};

#ifdef SPLIT_KEYBOARD
// right half encoders come over as second set of encoders
static uint8_t encoder_value[NUMBER_OF_ENCODERS * 2] = {0};
// row offsets for each hand
static uint8_t thisHand, thatHand;
#else
static uint8_t encoder_value[NUMBER_OF_ENCODERS] = {0};
#endif

__attribute__((weak)) bool encoder_update_user(uint8_t index, bool clockwise) { return true; }

__attribute__((weak)) bool encoder_update_kb(uint8_t index, bool clockwise) { return encoder_update_user(index, clockwise); }

// number of encoders connected to this controller
static uint8_t numEncodersHere;
// index of the first encoder connected to this controller (only for right halves, this will be nonzero)
static uint8_t firstEncoderHere;
#ifdef SPLIT_KEYBOARD
// index of the first encoder connected to the other half
static uint8_t firstEncoderThere;
#endif
// the pads for this controller
static pin_t* pad_a;
static pin_t* pad_b;

void encoder_init(void) {
#ifndef SPLIT_KEYBOARD
numEncodersHere = NUMBER_OF_ENCODERS;
pad_a = encoders_pad_a;
pad_b = encoders_pad_b;
firstEncoderHere = 0;
#else
if (isLeftHand) {
numEncodersHere = NUMBER_OF_ENCODERS_LEFT;
pad_a = encoders_pad_a;
pad_b = encoders_pad_b;
firstEncoderHere = 0;
firstEncoderThere = NUMBER_OF_ENCODERS_LEFT;
} else {
numEncodersHere = NUMBER_OF_ENCODERS_RIGHT;
pad_a = encoders_pad_a_right;
pad_b = encoders_pad_b_right;
firstEncoderHere = NUMBER_OF_ENCODERS_LEFT;
firstEncoderThere = 0;
#if defined(SPLIT_KEYBOARD) && defined(ENCODERS_PAD_A_RIGHT) && defined(ENCODERS_PAD_B_RIGHT)
if (!isLeftHand) {
const pin_t encoders_pad_a_right[] = ENCODERS_PAD_A_RIGHT;
const pin_t encoders_pad_b_right[] = ENCODERS_PAD_B_RIGHT;
# if defined(ENCODER_RESOLUTIONS_RIGHT)
const uint8_t encoder_resolutions_right[] = ENCODER_RESOLUTIONS_RIGHT;
# endif
for (uint8_t i = 0; i < NUMBER_OF_ENCODERS; i++) {
encoders_pad_a[i] = encoders_pad_a_right[i];
encoders_pad_b[i] = encoders_pad_b_right[i];
# if defined(ENCODER_RESOLUTIONS_RIGHT)
encoder_resolutions[i] = encoder_resolutions_right[i];
# endif
}
}
#endif

for (int i = 0; i < numEncodersHere; i++) {
setPinInputHigh(pad_a[i]);
setPinInputHigh(pad_b[i]);
for (int i = 0; i < NUMBER_OF_ENCODERS; i++) {
setPinInputHigh(encoders_pad_a[i]);
setPinInputHigh(encoders_pad_b[i]);

encoder_state[firstEncoderHere + i] = (readPin(pad_a[i]) << 0) | (readPin(pad_b[i]) << 1);
encoder_state[i] = (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1);
}

#ifdef SPLIT_KEYBOARD
thisHand = isLeftHand ? 0 : NUMBER_OF_ENCODERS;
thatHand = NUMBER_OF_ENCODERS - thisHand;
#endif
}

static bool encoder_update(int8_t index, uint8_t state) {
bool changed = false;
static bool encoder_update(uint8_t index, uint8_t state) {
bool changed = false;
uint8_t i = index;

#ifdef ENCODER_RESOLUTIONS
# ifndef SPLIT_KEYBOARD
int8_t resolution = encoder_resolutions[index];
# else
int8_t resolution = isLeftHand ? encoder_resolutions[index] : encoder_resolutions_right[index - NUMBER_OF_ENCODERS_LEFT];
# endif
uint8_t resolution = encoder_resolutions[i];
#else
uint8_t resolution = ENCODER_RESOLUTION;
#endif
encoder_pulses[index] += encoder_LUT[state & 0xF];
if (encoder_pulses[index] >= resolution) {

#ifdef SPLIT_KEYBOARD
index += thisHand;
#endif
encoder_pulses[i] += encoder_LUT[state & 0xF];
if (encoder_pulses[i] >= resolution) {
encoder_value[index]++;
changed = true;
encoder_update_kb(index, ENCODER_COUNTER_CLOCKWISE);
}
if (encoder_pulses[index] <= -resolution) { // direction is arbitrary here, but this clockwise
if (encoder_pulses[i] <= -resolution) { // direction is arbitrary here, but this clockwise
encoder_value[index]--;
changed = true;
encoder_update_kb(index, ENCODER_CLOCKWISE);
}
encoder_pulses[index] %= resolution;
encoder_pulses[i] %= resolution;
#ifdef ENCODER_DEFAULT_POS
if ((state & 0x3) == ENCODER_DEFAULT_POS) {
encoder_pulses[index] = 0;
encoder_pulses[i] = 0;
}
#endif
return changed;
}

bool encoder_read(void) {
bool changed = false;
for (uint8_t i = 0; i < numEncodersHere; i++) {
encoder_state[firstEncoderHere + i] <<= 2;
encoder_state[firstEncoderHere + i] |= (readPin(pad_a[i]) << 0) | (readPin(pad_b[i]) << 1);
changed |= encoder_update(firstEncoderHere + i, encoder_state[firstEncoderHere + i]);
for (uint8_t 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);
changed |= encoder_update(i, encoder_state[i]);
}
return changed;
}

#ifdef SPLIT_KEYBOARD
void last_encoder_activity_trigger(void);

void encoder_state_raw(uint8_t* slave_state) { memcpy(slave_state, &encoder_value[firstEncoderHere], sizeof(uint8_t) * numEncodersHere); }
void encoder_state_raw(uint8_t* slave_state) { memcpy(slave_state, &encoder_value[thisHand], sizeof(uint8_t) * NUMBER_OF_ENCODERS); }

void encoder_update_raw(uint8_t* slave_state) {
bool changed = false;
for (uint8_t i = 0; i < NUMBER_OF_ENCODERS - numEncodersHere; i++) {
uint8_t index = firstEncoderThere + i;
for (uint8_t i = 0; i < NUMBER_OF_ENCODERS; i++) {
uint8_t index = i + thatHand;
int8_t delta = slave_state[i] - encoder_value[index];
while (delta > 0) {
delta--;
Expand Down
3 changes: 1 addition & 2 deletions quantum/encoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@

#pragma once

#include <stdbool.h>
#include <stdint.h>
#include "quantum.h"

void encoder_init(void);
bool encoder_read(void);
Expand Down
Loading

0 comments on commit 96d7bde

Please sign in to comment.