Commit | Line | Data |
---|---|---|
85688e5b JH |
1 | /* |
2 | * Copyright 2018 Jack Humbert <jack.humb@gmail.com> | |
3 | * | |
4 | * This program is free software: you can redistribute it and/or modify | |
5 | * it under the terms of the GNU General Public License as published by | |
6 | * the Free Software Foundation, either version 2 of the License, or | |
7 | * (at your option) any later version. | |
8 | * | |
9 | * This program is distributed in the hope that it will be useful, | |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | * GNU General Public License for more details. | |
13 | * | |
14 | * You should have received a copy of the GNU General Public License | |
15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
16 | */ | |
17 | ||
18 | #include "encoder.h" | |
36dd261d | 19 | #ifdef SPLIT_KEYBOARD |
b624f32f | 20 | # include "split_util.h" |
36dd261d | 21 | #endif |
85688e5b | 22 | |
63177760 X |
23 | // for memcpy |
24 | #include <string.h> | |
25 | ||
85688e5b | 26 | #ifndef ENCODER_RESOLUTION |
b624f32f | 27 | # define ENCODER_RESOLUTION 4 |
85688e5b JH |
28 | #endif |
29 | ||
85688e5b | 30 | #if !defined(ENCODERS_PAD_A) || !defined(ENCODERS_PAD_B) |
b624f32f | 31 | # error "No encoder pads defined by ENCODERS_PAD_A and ENCODERS_PAD_B" |
85688e5b JH |
32 | #endif |
33 | ||
b624f32f | 34 | #define NUMBER_OF_ENCODERS (sizeof(encoders_pad_a) / sizeof(pin_t)) |
f6c7e114 DJ |
35 | static pin_t encoders_pad_a[] = ENCODERS_PAD_A; |
36 | static pin_t encoders_pad_b[] = ENCODERS_PAD_B; | |
85688e5b | 37 | |
b624f32f | 38 | static int8_t encoder_LUT[] = {0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0}; |
85688e5b | 39 | |
667045b4 JC |
40 | static uint8_t encoder_state[NUMBER_OF_ENCODERS] = {0}; |
41 | static int8_t encoder_pulses[NUMBER_OF_ENCODERS] = {0}; | |
63177760 X |
42 | |
43 | #ifdef SPLIT_KEYBOARD | |
46c49ae4 | 44 | // right half encoders come over as second set of encoders |
201c5bfa | 45 | static uint8_t encoder_value[NUMBER_OF_ENCODERS * 2] = {0}; |
46c49ae4 X |
46 | // row offsets for each hand |
47 | static uint8_t thisHand, thatHand; | |
63177760 | 48 | #else |
201c5bfa | 49 | static uint8_t encoder_value[NUMBER_OF_ENCODERS] = {0}; |
63177760 | 50 | #endif |
85688e5b | 51 | |
b624f32f | 52 | __attribute__((weak)) void encoder_update_user(int8_t index, bool clockwise) {} |
85688e5b | 53 | |
b624f32f | 54 | __attribute__((weak)) void encoder_update_kb(int8_t index, bool clockwise) { encoder_update_user(index, clockwise); } |
85688e5b JH |
55 | |
56 | void encoder_init(void) { | |
36dd261d | 57 | #if defined(SPLIT_KEYBOARD) && defined(ENCODERS_PAD_A_RIGHT) && defined(ENCODERS_PAD_B_RIGHT) |
b624f32f | 58 | if (!isLeftHand) { |
59 | const pin_t encoders_pad_a_right[] = ENCODERS_PAD_A_RIGHT; | |
60 | const pin_t encoders_pad_b_right[] = ENCODERS_PAD_B_RIGHT; | |
61 | for (uint8_t i = 0; i < NUMBER_OF_ENCODERS; i++) { | |
62 | encoders_pad_a[i] = encoders_pad_a_right[i]; | |
63 | encoders_pad_b[i] = encoders_pad_b_right[i]; | |
64 | } | |
36dd261d | 65 | } |
36dd261d D |
66 | #endif |
67 | ||
b624f32f | 68 | for (int i = 0; i < NUMBER_OF_ENCODERS; i++) { |
69 | setPinInputHigh(encoders_pad_a[i]); | |
70 | setPinInputHigh(encoders_pad_b[i]); | |
85688e5b | 71 | |
b624f32f | 72 | encoder_state[i] = (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1); |
73 | } | |
46c49ae4 X |
74 | |
75 | #ifdef SPLIT_KEYBOARD | |
76 | thisHand = isLeftHand ? 0 : NUMBER_OF_ENCODERS; | |
77 | thatHand = NUMBER_OF_ENCODERS - thisHand; | |
78 | #endif | |
79 | } | |
80 | ||
81 | static void encoder_update(int8_t index, uint8_t state) { | |
201c5bfa X |
82 | uint8_t i = index; |
83 | #ifdef SPLIT_KEYBOARD | |
84 | index += thisHand; | |
85 | #endif | |
86 | encoder_pulses[i] += encoder_LUT[state & 0xF]; | |
87 | if (encoder_pulses[i] >= ENCODER_RESOLUTION) { | |
88 | encoder_value[index]++; | |
7e627058 X |
89 | encoder_update_kb(index, true); |
90 | } | |
667045b4 | 91 | if (encoder_pulses[i] <= -ENCODER_RESOLUTION) { // direction is arbitrary here, but this clockwise |
201c5bfa X |
92 | encoder_value[index]--; |
93 | encoder_update_kb(index, false); | |
94 | } | |
95 | encoder_pulses[i] %= ENCODER_RESOLUTION; | |
85688e5b JH |
96 | } |
97 | ||
98 | void encoder_read(void) { | |
201c5bfa | 99 | for (uint8_t i = 0; i < NUMBER_OF_ENCODERS; i++) { |
b624f32f | 100 | encoder_state[i] <<= 2; |
101 | encoder_state[i] |= (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1); | |
46c49ae4 | 102 | encoder_update(i, encoder_state[i]); |
85688e5b | 103 | } |
85688e5b | 104 | } |
63177760 X |
105 | |
106 | #ifdef SPLIT_KEYBOARD | |
201c5bfa | 107 | void encoder_state_raw(uint8_t* slave_state) { memcpy(slave_state, &encoder_value[thisHand], sizeof(uint8_t) * NUMBER_OF_ENCODERS); } |
63177760 X |
108 | |
109 | void encoder_update_raw(uint8_t* slave_state) { | |
201c5bfa X |
110 | for (uint8_t i = 0; i < NUMBER_OF_ENCODERS; i++) { |
111 | uint8_t index = i + thatHand; | |
667045b4 | 112 | int8_t delta = slave_state[i] - encoder_value[index]; |
201c5bfa X |
113 | while (delta > 0) { |
114 | delta--; | |
115 | encoder_value[index]++; | |
116 | encoder_update_kb(index, true); | |
117 | } | |
118 | while (delta < 0) { | |
119 | delta++; | |
120 | encoder_value[index]--; | |
121 | encoder_update_kb(index, false); | |
122 | } | |
63177760 | 123 | } |
63177760 X |
124 | } |
125 | #endif |