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 | |
26eef35f JY |
38 | #ifndef ENCODER_DIRECTION_FLIP |
39 | # define ENCODER_CLOCKWISE true | |
40 | # define ENCODER_COUNTER_CLOCKWISE false | |
41 | #else | |
42 | # define ENCODER_CLOCKWISE false | |
43 | # define ENCODER_COUNTER_CLOCKWISE true | |
44 | #endif | |
b624f32f | 45 | static int8_t encoder_LUT[] = {0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0}; |
85688e5b | 46 | |
667045b4 JC |
47 | static uint8_t encoder_state[NUMBER_OF_ENCODERS] = {0}; |
48 | static int8_t encoder_pulses[NUMBER_OF_ENCODERS] = {0}; | |
63177760 X |
49 | |
50 | #ifdef SPLIT_KEYBOARD | |
46c49ae4 | 51 | // right half encoders come over as second set of encoders |
201c5bfa | 52 | static uint8_t encoder_value[NUMBER_OF_ENCODERS * 2] = {0}; |
46c49ae4 X |
53 | // row offsets for each hand |
54 | static uint8_t thisHand, thatHand; | |
63177760 | 55 | #else |
201c5bfa | 56 | static uint8_t encoder_value[NUMBER_OF_ENCODERS] = {0}; |
63177760 | 57 | #endif |
85688e5b | 58 | |
b624f32f | 59 | __attribute__((weak)) void encoder_update_user(int8_t index, bool clockwise) {} |
85688e5b | 60 | |
b624f32f | 61 | __attribute__((weak)) void encoder_update_kb(int8_t index, bool clockwise) { encoder_update_user(index, clockwise); } |
85688e5b JH |
62 | |
63 | void encoder_init(void) { | |
36dd261d | 64 | #if defined(SPLIT_KEYBOARD) && defined(ENCODERS_PAD_A_RIGHT) && defined(ENCODERS_PAD_B_RIGHT) |
b624f32f | 65 | if (!isLeftHand) { |
66 | const pin_t encoders_pad_a_right[] = ENCODERS_PAD_A_RIGHT; | |
67 | const pin_t encoders_pad_b_right[] = ENCODERS_PAD_B_RIGHT; | |
68 | for (uint8_t i = 0; i < NUMBER_OF_ENCODERS; i++) { | |
69 | encoders_pad_a[i] = encoders_pad_a_right[i]; | |
70 | encoders_pad_b[i] = encoders_pad_b_right[i]; | |
71 | } | |
36dd261d | 72 | } |
36dd261d D |
73 | #endif |
74 | ||
b624f32f | 75 | for (int i = 0; i < NUMBER_OF_ENCODERS; i++) { |
76 | setPinInputHigh(encoders_pad_a[i]); | |
77 | setPinInputHigh(encoders_pad_b[i]); | |
85688e5b | 78 | |
b624f32f | 79 | encoder_state[i] = (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1); |
80 | } | |
46c49ae4 X |
81 | |
82 | #ifdef SPLIT_KEYBOARD | |
83 | thisHand = isLeftHand ? 0 : NUMBER_OF_ENCODERS; | |
84 | thatHand = NUMBER_OF_ENCODERS - thisHand; | |
85 | #endif | |
86 | } | |
87 | ||
88 | static void encoder_update(int8_t index, uint8_t state) { | |
201c5bfa X |
89 | uint8_t i = index; |
90 | #ifdef SPLIT_KEYBOARD | |
91 | index += thisHand; | |
92 | #endif | |
93 | encoder_pulses[i] += encoder_LUT[state & 0xF]; | |
94 | if (encoder_pulses[i] >= ENCODER_RESOLUTION) { | |
95 | encoder_value[index]++; | |
26eef35f | 96 | encoder_update_kb(index, ENCODER_COUNTER_CLOCKWISE); |
7e627058 | 97 | } |
667045b4 | 98 | if (encoder_pulses[i] <= -ENCODER_RESOLUTION) { // direction is arbitrary here, but this clockwise |
201c5bfa | 99 | encoder_value[index]--; |
26eef35f | 100 | encoder_update_kb(index, ENCODER_CLOCKWISE); |
201c5bfa X |
101 | } |
102 | encoder_pulses[i] %= ENCODER_RESOLUTION; | |
85688e5b JH |
103 | } |
104 | ||
105 | void encoder_read(void) { | |
201c5bfa | 106 | for (uint8_t i = 0; i < NUMBER_OF_ENCODERS; i++) { |
b624f32f | 107 | encoder_state[i] <<= 2; |
108 | encoder_state[i] |= (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1); | |
46c49ae4 | 109 | encoder_update(i, encoder_state[i]); |
85688e5b | 110 | } |
85688e5b | 111 | } |
63177760 X |
112 | |
113 | #ifdef SPLIT_KEYBOARD | |
201c5bfa | 114 | void encoder_state_raw(uint8_t* slave_state) { memcpy(slave_state, &encoder_value[thisHand], sizeof(uint8_t) * NUMBER_OF_ENCODERS); } |
63177760 X |
115 | |
116 | void encoder_update_raw(uint8_t* slave_state) { | |
201c5bfa X |
117 | for (uint8_t i = 0; i < NUMBER_OF_ENCODERS; i++) { |
118 | uint8_t index = i + thatHand; | |
667045b4 | 119 | int8_t delta = slave_state[i] - encoder_value[index]; |
201c5bfa X |
120 | while (delta > 0) { |
121 | delta--; | |
122 | encoder_value[index]++; | |
26eef35f | 123 | encoder_update_kb(index, ENCODER_COUNTER_CLOCKWISE); |
201c5bfa X |
124 | } |
125 | while (delta < 0) { | |
126 | delta++; | |
127 | encoder_value[index]--; | |
26eef35f | 128 | encoder_update_kb(index, ENCODER_CLOCKWISE); |
201c5bfa | 129 | } |
63177760 | 130 | } |
63177760 X |
131 | } |
132 | #endif |