diff options
Diffstat (limited to 'quantum/encoder.c')
| -rw-r--r-- | quantum/encoder.c | 146 | 
1 files changed, 91 insertions, 55 deletions
| diff --git a/quantum/encoder.c b/quantum/encoder.c index 8fb87281c2..7d4e978981 100644 --- a/quantum/encoder.c +++ b/quantum/encoder.c @@ -16,8 +16,17 @@   */  #include "encoder.h" -#ifdef SPLIT_KEYBOARD -#    include "split_util.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  #endif  // for memcpy @@ -27,17 +36,41 @@  #    define ENCODER_RESOLUTION 4  #endif -#if !defined(ENCODERS_PAD_A) || !defined(ENCODERS_PAD_B) -#    error "No encoder pads defined by ENCODERS_PAD_A and ENCODERS_PAD_B" +#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"  #endif -#define NUMBER_OF_ENCODERS (sizeof(encoders_pad_a) / sizeof(pin_t)) +// on split keyboards, these are the pads and resolutions for the left half  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 @@ -50,78 +83,81 @@ 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) { -#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 -        } +#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;      }  #endif -    for (int i = 0; i < NUMBER_OF_ENCODERS; i++) { -        setPinInputHigh(encoders_pad_a[i]); -        setPinInputHigh(encoders_pad_b[i]); +    for (int i = 0; i < numEncodersHere; i++) { +        setPinInputHigh(pad_a[i]); +        setPinInputHigh(pad_b[i]); -        encoder_state[i] = (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1); +        encoder_state[firstEncoderHere + i] = (readPin(pad_a[i]) << 0) | (readPin(pad_b[i]) << 1);      } - -#ifdef SPLIT_KEYBOARD -    thisHand = isLeftHand ? 0 : NUMBER_OF_ENCODERS; -    thatHand = NUMBER_OF_ENCODERS - thisHand; -#endif  } -static bool encoder_update(uint8_t index, uint8_t state) { -    bool    changed = false; -    uint8_t i       = index; +static bool encoder_update(int8_t index, uint8_t state) { +    bool changed = false;  #ifdef ENCODER_RESOLUTIONS -    uint8_t resolution = encoder_resolutions[i]; +#    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  #else      uint8_t resolution = ENCODER_RESOLUTION;  #endif - -#ifdef SPLIT_KEYBOARD -    index += thisHand; -#endif -    encoder_pulses[i] += encoder_LUT[state & 0xF]; -    if (encoder_pulses[i] >= resolution) { +    encoder_pulses[index] += encoder_LUT[state & 0xF]; +    if (encoder_pulses[index] >= resolution) {          encoder_value[index]++;          changed = true;          encoder_update_kb(index, ENCODER_COUNTER_CLOCKWISE);      } -    if (encoder_pulses[i] <= -resolution) {  // direction is arbitrary here, but this clockwise +    if (encoder_pulses[index] <= -resolution) {  // direction is arbitrary here, but this clockwise          encoder_value[index]--;          changed = true;          encoder_update_kb(index, ENCODER_CLOCKWISE);      } -    encoder_pulses[i] %= resolution; +    encoder_pulses[index] %= resolution;  #ifdef ENCODER_DEFAULT_POS      if ((state & 0x3) == ENCODER_DEFAULT_POS) { -        encoder_pulses[i] = 0; +        encoder_pulses[index] = 0;      }  #endif      return changed; @@ -129,10 +165,10 @@ static bool encoder_update(uint8_t index, uint8_t state) {  bool encoder_read(void) {      bool changed = false; -    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]); +    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]);      }      return changed;  } @@ -140,12 +176,12 @@ bool encoder_read(void) {  #ifdef SPLIT_KEYBOARD  void last_encoder_activity_trigger(void); -void encoder_state_raw(uint8_t* slave_state) { memcpy(slave_state, &encoder_value[thisHand], sizeof(uint8_t) * NUMBER_OF_ENCODERS); } +void encoder_state_raw(uint8_t* slave_state) { memcpy(slave_state, &encoder_value[firstEncoderHere], sizeof(uint8_t) * numEncodersHere); }  void encoder_update_raw(uint8_t* slave_state) {      bool changed = false; -    for (uint8_t i = 0; i < NUMBER_OF_ENCODERS; i++) { -        uint8_t index = i + thatHand; +    for (uint8_t i = 0; i < NUMBER_OF_ENCODERS - numEncodersHere; i++) { +        uint8_t index = firstEncoderThere + i;          int8_t  delta = slave_state[i] - encoder_value[index];          while (delta > 0) {              delta--; | 
