forked from mirrors/qmk_firmware
46c49ae4e6
* Updated encoder.c so that split encoders are indexed based on left hand encoders first. This ensures when swapping master sides that code logic based on encoder index doesn't change. PR Review fixes * Removed extra define
111 lines
3.6 KiB
C
111 lines
3.6 KiB
C
/*
|
|
* Copyright 2018 Jack Humbert <jack.humb@gmail.com>
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "encoder.h"
|
|
#ifdef SPLIT_KEYBOARD
|
|
# include "split_util.h"
|
|
#endif
|
|
|
|
// for memcpy
|
|
#include <string.h>
|
|
|
|
#ifndef ENCODER_RESOLUTION
|
|
# 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"
|
|
#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;
|
|
|
|
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};
|
|
|
|
#ifdef SPLIT_KEYBOARD
|
|
// right half encoders come over as second set of encoders
|
|
static int8_t encoder_value[NUMBER_OF_ENCODERS * 2] = {0};
|
|
// row offsets for each hand
|
|
static uint8_t thisHand, thatHand;
|
|
#else
|
|
static int8_t encoder_value[NUMBER_OF_ENCODERS] = {0};
|
|
#endif
|
|
|
|
__attribute__((weak)) void encoder_update_user(int8_t index, bool clockwise) {}
|
|
|
|
__attribute__((weak)) void encoder_update_kb(int8_t index, bool clockwise) { encoder_update_user(index, clockwise); }
|
|
|
|
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;
|
|
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];
|
|
}
|
|
}
|
|
#endif
|
|
|
|
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);
|
|
}
|
|
|
|
#ifdef SPLIT_KEYBOARD
|
|
thisHand = isLeftHand ? 0 : NUMBER_OF_ENCODERS;
|
|
thatHand = NUMBER_OF_ENCODERS - thisHand;
|
|
#endif
|
|
}
|
|
|
|
static void encoder_update(int8_t index, uint8_t state) {
|
|
encoder_value[index] += encoder_LUT[state & 0xF];
|
|
if (encoder_value[index] >= ENCODER_RESOLUTION) {
|
|
encoder_update_kb(index, false);
|
|
}
|
|
if (encoder_value[index] <= -ENCODER_RESOLUTION) { // direction is arbitrary here, but this clockwise
|
|
encoder_update_kb(index, true);
|
|
}
|
|
encoder_value[index] %= ENCODER_RESOLUTION;
|
|
}
|
|
|
|
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 SPLIT_KEYBOARD
|
|
void encoder_state_raw(uint8_t* slave_state) { memcpy(slave_state, encoder_state, sizeof(encoder_state)); }
|
|
|
|
void encoder_update_raw(uint8_t* slave_state) {
|
|
for (int i = 0; i < NUMBER_OF_ENCODERS; i++) {
|
|
encoder_update(i + thatHand, slave_state[i]);
|
|
}
|
|
}
|
|
#endif
|