diff options
Diffstat (limited to 'quantum/encoder.c')
| -rw-r--r-- | quantum/encoder.c | 142 | 
1 files changed, 103 insertions, 39 deletions
| diff --git a/quantum/encoder.c b/quantum/encoder.c index 438c7d8564..105bed0147 100644 --- a/quantum/encoder.c +++ b/quantum/encoder.c @@ -23,6 +23,10 @@  // for memcpy  #include <string.h> +#ifndef ENCODER_MAP_KEY_DELAY +#    define ENCODER_MAP_KEY_DELAY 2 +#endif +  #if !defined(ENCODER_RESOLUTIONS) && !defined(ENCODER_RESOLUTION)  #    define ENCODER_RESOLUTION 4  #endif @@ -31,11 +35,13 @@  #    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; +extern volatile bool isLeftHand; + +static pin_t encoders_pad_a[NUM_ENCODERS_MAX_PER_SIDE] = ENCODERS_PAD_A; +static pin_t encoders_pad_b[NUM_ENCODERS_MAX_PER_SIDE] = ENCODERS_PAD_B; +  #ifdef ENCODER_RESOLUTIONS -static uint8_t encoder_resolutions[] = ENCODER_RESOLUTIONS; +static uint8_t encoder_resolutions[NUM_ENCODERS] = ENCODER_RESOLUTIONS;  #endif  #ifndef ENCODER_DIRECTION_FLIP @@ -47,18 +53,20 @@ static uint8_t encoder_resolutions[] = ENCODER_RESOLUTIONS;  #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}; -static int8_t  encoder_pulses[NUMBER_OF_ENCODERS] = {0}; +static uint8_t encoder_state[NUM_ENCODERS]  = {0}; +static int8_t  encoder_pulses[NUM_ENCODERS] = {0}; +// encoder counts +static uint8_t thisCount;  #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 +// encoder offsets for each hand  static uint8_t thisHand, thatHand; -#else -static uint8_t encoder_value[NUMBER_OF_ENCODERS] = {0}; +// encoder counts for each hand +static uint8_t thatCount;  #endif +static uint8_t encoder_value[NUM_ENCODERS] = {0}; +  __attribute__((weak)) void encoder_wait_pullup_charge(void) {      wait_us(100);  } @@ -72,46 +80,83 @@ __attribute__((weak)) bool encoder_update_kb(uint8_t index, bool clockwise) {  }  void encoder_init(void) { +#ifdef SPLIT_KEYBOARD +    thisHand  = isLeftHand ? 0 : NUM_ENCODERS_LEFT; +    thatHand  = NUM_ENCODERS_LEFT - thisHand; +    thisCount = isLeftHand ? NUM_ENCODERS_LEFT : NUM_ENCODERS_RIGHT; +    thatCount = isLeftHand ? NUM_ENCODERS_RIGHT : NUM_ENCODERS_LEFT; +#else // SPLIT_KEYBOARD +    thisCount                = NUM_ENCODERS; +#endif + +#ifdef ENCODER_TESTS +    // Annoying that we have to clear out values during initialisation here, but +    // because all the arrays are static locals, rerunning tests in the same +    // executable doesn't reset any of these. Kinda crappy having test-only code +    // here, but it's the simplest solution. +    memset(encoder_value, 0, sizeof(encoder_value)); +    memset(encoder_state, 0, sizeof(encoder_state)); +    memset(encoder_pulses, 0, sizeof(encoder_pulses)); +    static const pin_t encoders_pad_a_left[] = ENCODERS_PAD_A; +    static const pin_t encoders_pad_b_left[] = ENCODERS_PAD_B; +    for (uint8_t i = 0; i < thisCount; i++) { +        encoders_pad_a[i] = encoders_pad_a_left[i]; +        encoders_pad_b[i] = encoders_pad_b_left[i]; +    } +#endif +  #if defined(SPLIT_KEYBOARD) && defined(ENCODERS_PAD_A_RIGHT) && defined(ENCODERS_PAD_B_RIGHT) +    // Re-initialise the pads if it's the right-hand side      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++) { +        static const pin_t encoders_pad_a_right[] = ENCODERS_PAD_A_RIGHT; +        static const pin_t encoders_pad_b_right[] = ENCODERS_PAD_B_RIGHT; +        for (uint8_t i = 0; i < thisCount; 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 +#endif // defined(SPLIT_KEYBOARD) && defined(ENCODERS_PAD_A_RIGHT) && defined(ENCODERS_PAD_B_RIGHT) -    for (int i = 0; i < NUMBER_OF_ENCODERS; i++) { +    // Encoder resolutions is handled purely master-side, so concatenate the two arrays +#if defined(SPLIT_KEYBOARD) && defined(ENCODER_RESOLUTIONS) +#    if defined(ENCODER_RESOLUTIONS_RIGHT) +    static const uint8_t encoder_resolutions_right[NUM_ENCODERS_RIGHT] = ENCODER_RESOLUTIONS_RIGHT; +#    else  // defined(ENCODER_RESOLUTIONS_RIGHT) +    static const uint8_t encoder_resolutions_right[NUM_ENCODERS_RIGHT] = ENCODER_RESOLUTIONS; +#    endif // defined(ENCODER_RESOLUTIONS_RIGHT) +    for (uint8_t i = 0; i < NUM_ENCODERS_RIGHT; i++) { +        encoder_resolutions[NUM_ENCODERS_LEFT + i] = encoder_resolutions_right[i]; +    } +#endif // defined(SPLIT_KEYBOARD) && defined(ENCODER_RESOLUTIONS) + +    for (uint8_t i = 0; i < thisCount; i++) {          setPinInputHigh(encoders_pad_a[i]);          setPinInputHigh(encoders_pad_b[i]);      }      encoder_wait_pullup_charge(); -    for (int i = 0; i < NUMBER_OF_ENCODERS; i++) { +    for (uint8_t i = 0; i < thisCount; i++) {          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 +#ifdef ENCODER_MAP_ENABLE +static void encoder_exec_mapping(uint8_t index, bool clockwise) { +    // The delays below cater for Windows and its wonderful requirements. +    action_exec(clockwise ? ENCODER_CW_EVENT(index, true) : ENCODER_CCW_EVENT(index, true)); +    wait_ms(ENCODER_MAP_KEY_DELAY); +    action_exec(clockwise ? ENCODER_CW_EVENT(index, false) : ENCODER_CCW_EVENT(index, false)); +    wait_ms(ENCODER_MAP_KEY_DELAY);  } +#endif // ENCODER_MAP_ENABLE  static bool encoder_update(uint8_t index, uint8_t state) {      bool    changed = false;      uint8_t i       = index;  #ifdef ENCODER_RESOLUTIONS -    uint8_t resolution = encoder_resolutions[i]; +    const uint8_t resolution = encoder_resolutions[i];  #else -    uint8_t resolution = ENCODER_RESOLUTION; +    const uint8_t resolution = ENCODER_RESOLUTION;  #endif  #ifdef SPLIT_KEYBOARD @@ -121,12 +166,20 @@ static bool encoder_update(uint8_t index, uint8_t state) {      if (encoder_pulses[i] >= resolution) {          encoder_value[index]++;          changed = true; +#ifdef ENCODER_MAP_ENABLE +        encoder_exec_mapping(index, ENCODER_COUNTER_CLOCKWISE); +#else  // ENCODER_MAP_ENABLE          encoder_update_kb(index, ENCODER_COUNTER_CLOCKWISE); +#endif // ENCODER_MAP_ENABLE      }      if (encoder_pulses[i] <= -resolution) { // direction is arbitrary here, but this clockwise          encoder_value[index]--;          changed = true; +#ifdef ENCODER_MAP_ENABLE +        encoder_exec_mapping(index, ENCODER_CLOCKWISE); +#else  // ENCODER_MAP_ENABLE          encoder_update_kb(index, ENCODER_CLOCKWISE); +#endif // ENCODER_MAP_ENABLE      }      encoder_pulses[i] %= resolution;  #ifdef ENCODER_DEFAULT_POS @@ -139,10 +192,13 @@ 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 < thisCount; i++) { +        uint8_t new_status = (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1); +        if ((encoder_state[i] & 0x3) != new_status) { +            encoder_state[i] <<= 2; +            encoder_state[i] |= new_status; +            changed |= encoder_update(i, encoder_state[i]); +        }      }      return changed;  } @@ -150,26 +206,34 @@ 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[thisHand], sizeof(uint8_t) * thisCount);  } -void encoder_update_raw(uint8_t* slave_state) { +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; -        int8_t  delta = slave_state[i] - encoder_value[index]; +    for (uint8_t i = 0; i < thatCount; i++) { // Note inverted logic -- we want the opposite side +        const uint8_t index = i + thatHand; +        int8_t        delta = slave_state[i] - encoder_value[index];          while (delta > 0) {              delta--;              encoder_value[index]++;              changed = true; +#    ifdef ENCODER_MAP_ENABLE +            encoder_exec_mapping(index, ENCODER_COUNTER_CLOCKWISE); +#    else  // ENCODER_MAP_ENABLE              encoder_update_kb(index, ENCODER_COUNTER_CLOCKWISE); +#    endif // ENCODER_MAP_ENABLE          }          while (delta < 0) {              delta++;              encoder_value[index]--;              changed = true; +#    ifdef ENCODER_MAP_ENABLE +            encoder_exec_mapping(index, ENCODER_CLOCKWISE); +#    else  // ENCODER_MAP_ENABLE              encoder_update_kb(index, ENCODER_CLOCKWISE); +#    endif // ENCODER_MAP_ENABLE          }      } | 
