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 D |
19 | #ifdef SPLIT_KEYBOARD |
20 | #include "split_util.h" | |
21 | #endif | |
85688e5b | 22 | |
63177760 X |
23 | // for memcpy |
24 | #include <string.h> | |
25 | ||
26 | ||
85688e5b JH |
27 | #ifndef ENCODER_RESOLUTION |
28 | #define ENCODER_RESOLUTION 4 | |
29 | #endif | |
30 | ||
85688e5b JH |
31 | #if !defined(ENCODERS_PAD_A) || !defined(ENCODERS_PAD_B) |
32 | #error "No encoder pads defined by ENCODERS_PAD_A and ENCODERS_PAD_B" | |
33 | #endif | |
34 | ||
f6c7e114 DJ |
35 | |
36 | #define NUMBER_OF_ENCODERS (sizeof(encoders_pad_a)/sizeof(pin_t)) | |
37 | static pin_t encoders_pad_a[] = ENCODERS_PAD_A; | |
38 | static pin_t encoders_pad_b[] = ENCODERS_PAD_B; | |
85688e5b JH |
39 | |
40 | static int8_t encoder_LUT[] = { 0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0 }; | |
41 | ||
42 | static uint8_t encoder_state[NUMBER_OF_ENCODERS] = {0}; | |
63177760 X |
43 | |
44 | #ifdef SPLIT_KEYBOARD | |
45 | // slave half encoders come over as second set of encoders | |
46 | static int8_t encoder_value[NUMBER_OF_ENCODERS * 2] = {0}; | |
47 | #else | |
85688e5b | 48 | static int8_t encoder_value[NUMBER_OF_ENCODERS] = {0}; |
63177760 | 49 | #endif |
85688e5b JH |
50 | |
51 | __attribute__ ((weak)) | |
52 | void encoder_update_user(int8_t index, bool clockwise) { } | |
53 | ||
54 | __attribute__ ((weak)) | |
55 | void encoder_update_kb(int8_t index, bool clockwise) { | |
56 | encoder_update_user(index, clockwise); | |
57 | } | |
58 | ||
59 | void encoder_init(void) { | |
36dd261d D |
60 | #if defined(SPLIT_KEYBOARD) && defined(ENCODERS_PAD_A_RIGHT) && defined(ENCODERS_PAD_B_RIGHT) |
61 | if (!isLeftHand) { | |
62 | const pin_t encoders_pad_a_right[] = ENCODERS_PAD_A_RIGHT; | |
63 | const pin_t encoders_pad_b_right[] = ENCODERS_PAD_B_RIGHT; | |
64 | for (uint8_t i = 0; i < NUMBER_OF_ENCODERS; i++) { | |
65 | encoders_pad_a[i] = encoders_pad_a_right[i]; | |
66 | encoders_pad_b[i] = encoders_pad_b_right[i]; | |
67 | } | |
68 | } | |
69 | #endif | |
70 | ||
85688e5b JH |
71 | for (int i = 0; i < NUMBER_OF_ENCODERS; i++) { |
72 | setPinInputHigh(encoders_pad_a[i]); | |
73 | setPinInputHigh(encoders_pad_b[i]); | |
74 | ||
75 | encoder_state[i] = (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1); | |
76 | } | |
77 | } | |
78 | ||
79 | void encoder_read(void) { | |
80 | for (int i = 0; i < NUMBER_OF_ENCODERS; i++) { | |
81 | encoder_state[i] <<= 2; | |
82 | encoder_state[i] |= (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1); | |
83 | encoder_value[i] += encoder_LUT[encoder_state[i] & 0xF]; | |
84 | if (encoder_value[i] >= ENCODER_RESOLUTION) { | |
63177760 | 85 | encoder_update_kb(i, false); |
85688e5b JH |
86 | } |
87 | if (encoder_value[i] <= -ENCODER_RESOLUTION) { // direction is arbitrary here, but this clockwise | |
63177760 | 88 | encoder_update_kb(i, true); |
85688e5b JH |
89 | } |
90 | encoder_value[i] %= ENCODER_RESOLUTION; | |
91 | } | |
92 | } | |
63177760 X |
93 | |
94 | #ifdef SPLIT_KEYBOARD | |
95 | void encoder_state_raw(uint8_t* slave_state) { | |
96 | memcpy(slave_state, encoder_state, sizeof(encoder_state)); | |
97 | } | |
98 | ||
99 | void encoder_update_raw(uint8_t* slave_state) { | |
100 | for (int i = 0; i < NUMBER_OF_ENCODERS; i++) { | |
101 | encoder_value[NUMBER_OF_ENCODERS + i] += encoder_LUT[slave_state[i] & 0xF]; | |
102 | if (encoder_value[NUMBER_OF_ENCODERS + i] >= ENCODER_RESOLUTION) { | |
103 | encoder_update_kb(NUMBER_OF_ENCODERS + i, false); | |
104 | } | |
105 | if (encoder_value[NUMBER_OF_ENCODERS + i] <= -ENCODER_RESOLUTION) { // direction is arbitrary here, but this clockwise | |
106 | encoder_update_kb(NUMBER_OF_ENCODERS + i, true); | |
107 | } | |
108 | encoder_value[NUMBER_OF_ENCODERS + i] %= ENCODER_RESOLUTION; | |
109 | } | |
110 | } | |
111 | #endif |