encoder.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  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. #include "encoder.h"
  18. // this is for unit testing
  19. #if defined(ENCODER_MOCK_SINGLE)
  20. # include "encoder/tests/mock.h"
  21. #elif defined(ENCODER_MOCK_SPLIT)
  22. # include "encoder/tests/mock_split.h"
  23. #else
  24. # include <gpio.h>
  25. # ifdef SPLIT_KEYBOARD
  26. # include "split_util.h"
  27. # endif
  28. #endif
  29. // for memcpy
  30. #include <string.h>
  31. #if !defined(ENCODER_RESOLUTIONS) && !defined(ENCODER_RESOLUTION)
  32. # define ENCODER_RESOLUTION 4
  33. #endif
  34. #if (!defined(ENCODERS_PAD_A) || !defined(ENCODERS_PAD_B)) && (!defined(ENCODERS_PAD_A) || !defined(ENCODERS_PAD_B))
  35. # error "No encoder pads defined by ENCODERS_PAD_A and ENCODERS_PAD_B or ENCODERS_PAD_A_RIGHT and ENCODERS_PAD_B_RIGHT"
  36. #endif
  37. // on split keyboards, these are the pads and resolutions for the left half
  38. static pin_t encoders_pad_a[] = ENCODERS_PAD_A;
  39. static pin_t encoders_pad_b[] = ENCODERS_PAD_B;
  40. #ifdef ENCODER_RESOLUTIONS
  41. static uint8_t encoder_resolutions[] = ENCODER_RESOLUTIONS;
  42. #endif
  43. #ifndef SPLIT_KEYBOARD
  44. # define NUMBER_OF_ENCODERS (sizeof(encoders_pad_a) / sizeof(pin_t))
  45. #else
  46. // if no pads for right half are defined, we assume the keyboard is symmetric (i.e. same pads)
  47. # ifndef ENCODERS_PAD_A_RIGHT
  48. # define ENCODERS_PAD_A_RIGHT ENCODERS_PAD_A
  49. # endif
  50. # ifndef ENCODERS_PAD_B_RIGHT
  51. # define ENCODERS_PAD_B_RIGHT ENCODERS_PAD_B
  52. # endif
  53. # if defined(ENCODER_RESOLUTIONS) && !defined(ENCODER_RESOLUTIONS_RIGHT)
  54. # define ENCODER_RESOLUTIONS_RIGHT ENCODER_RESOLUTIONS
  55. # endif
  56. # define NUMBER_OF_ENCODERS ((sizeof(encoders_pad_a) + sizeof(encoders_pad_a_right)) / sizeof(pin_t))
  57. # define NUMBER_OF_ENCODERS_LEFT (sizeof(encoders_pad_a) / sizeof(pin_t))
  58. # define NUMBER_OF_ENCODERS_RIGHT (sizeof(encoders_pad_a_right) / sizeof(pin_t))
  59. static pin_t encoders_pad_a_right[] = ENCODERS_PAD_A_RIGHT;
  60. static pin_t encoders_pad_b_right[] = ENCODERS_PAD_B_RIGHT;
  61. # ifdef ENCODER_RESOLUTIONS_RIGHT
  62. static uint8_t encoder_resolutions_right[] = ENCODER_RESOLUTIONS_RIGHT;
  63. # endif
  64. #endif
  65. #ifndef ENCODER_DIRECTION_FLIP
  66. # define ENCODER_CLOCKWISE true
  67. # define ENCODER_COUNTER_CLOCKWISE false
  68. #else
  69. # define ENCODER_CLOCKWISE false
  70. # define ENCODER_COUNTER_CLOCKWISE true
  71. #endif
  72. static int8_t encoder_LUT[] = {0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0};
  73. static uint8_t encoder_state[NUMBER_OF_ENCODERS] = {0};
  74. static int8_t encoder_pulses[NUMBER_OF_ENCODERS] = {0};
  75. static uint8_t encoder_value[NUMBER_OF_ENCODERS] = {0};
  76. __attribute__((weak)) bool encoder_update_user(uint8_t index, bool clockwise) { return true; }
  77. __attribute__((weak)) bool encoder_update_kb(uint8_t index, bool clockwise) { return encoder_update_user(index, clockwise); }
  78. // number of encoders connected to this controller
  79. static uint8_t numEncodersHere;
  80. // index of the first encoder connected to this controller (only for right halves, this will be nonzero)
  81. static uint8_t firstEncoderHere;
  82. #ifdef SPLIT_KEYBOARD
  83. // index of the first encoder connected to the other half
  84. static uint8_t firstEncoderThere;
  85. #endif
  86. // the pads for this controller
  87. static pin_t* pad_a;
  88. static pin_t* pad_b;
  89. void encoder_init(void) {
  90. #ifndef SPLIT_KEYBOARD
  91. numEncodersHere = NUMBER_OF_ENCODERS;
  92. pad_a = encoders_pad_a;
  93. pad_b = encoders_pad_b;
  94. firstEncoderHere = 0;
  95. #else
  96. if (isLeftHand) {
  97. numEncodersHere = NUMBER_OF_ENCODERS_LEFT;
  98. pad_a = encoders_pad_a;
  99. pad_b = encoders_pad_b;
  100. firstEncoderHere = 0;
  101. firstEncoderThere = NUMBER_OF_ENCODERS_LEFT;
  102. } else {
  103. numEncodersHere = NUMBER_OF_ENCODERS_RIGHT;
  104. pad_a = encoders_pad_a_right;
  105. pad_b = encoders_pad_b_right;
  106. firstEncoderHere = NUMBER_OF_ENCODERS_LEFT;
  107. firstEncoderThere = 0;
  108. }
  109. #endif
  110. for (int i = 0; i < numEncodersHere; i++) {
  111. setPinInputHigh(pad_a[i]);
  112. setPinInputHigh(pad_b[i]);
  113. encoder_state[firstEncoderHere + i] = (readPin(pad_a[i]) << 0) | (readPin(pad_b[i]) << 1);
  114. }
  115. }
  116. static bool encoder_update(int8_t index, uint8_t state) {
  117. bool changed = false;
  118. #ifdef ENCODER_RESOLUTIONS
  119. # ifndef SPLIT_KEYBOARD
  120. int8_t resolution = encoder_resolutions[index];
  121. # else
  122. int8_t resolution = isLeftHand ? encoder_resolutions[index] : encoder_resolutions_right[index - NUMBER_OF_ENCODERS_LEFT];
  123. # endif
  124. #else
  125. uint8_t resolution = ENCODER_RESOLUTION;
  126. #endif
  127. encoder_pulses[index] += encoder_LUT[state & 0xF];
  128. if (encoder_pulses[index] >= resolution) {
  129. encoder_value[index]++;
  130. changed = true;
  131. encoder_update_kb(index, ENCODER_COUNTER_CLOCKWISE);
  132. }
  133. if (encoder_pulses[index] <= -resolution) { // direction is arbitrary here, but this clockwise
  134. encoder_value[index]--;
  135. changed = true;
  136. encoder_update_kb(index, ENCODER_CLOCKWISE);
  137. }
  138. encoder_pulses[index] %= resolution;
  139. #ifdef ENCODER_DEFAULT_POS
  140. if ((state & 0x3) == ENCODER_DEFAULT_POS) {
  141. encoder_pulses[index] = 0;
  142. }
  143. #endif
  144. return changed;
  145. }
  146. bool encoder_read(void) {
  147. bool changed = false;
  148. for (uint8_t i = 0; i < numEncodersHere; i++) {
  149. encoder_state[firstEncoderHere + i] <<= 2;
  150. encoder_state[firstEncoderHere + i] |= (readPin(pad_a[i]) << 0) | (readPin(pad_b[i]) << 1);
  151. changed |= encoder_update(firstEncoderHere + i, encoder_state[firstEncoderHere + i]);
  152. }
  153. return changed;
  154. }
  155. #ifdef SPLIT_KEYBOARD
  156. void last_encoder_activity_trigger(void);
  157. void encoder_state_raw(uint8_t* slave_state) { memcpy(slave_state, &encoder_value[firstEncoderHere], sizeof(uint8_t) * numEncodersHere); }
  158. void encoder_update_raw(uint8_t* slave_state) {
  159. bool changed = false;
  160. for (uint8_t i = 0; i < NUMBER_OF_ENCODERS - numEncodersHere; i++) {
  161. uint8_t index = firstEncoderThere + i;
  162. int8_t delta = slave_state[i] - encoder_value[index];
  163. while (delta > 0) {
  164. delta--;
  165. encoder_value[index]++;
  166. changed = true;
  167. encoder_update_kb(index, ENCODER_COUNTER_CLOCKWISE);
  168. }
  169. while (delta < 0) {
  170. delta++;
  171. encoder_value[index]--;
  172. changed = true;
  173. encoder_update_kb(index, ENCODER_CLOCKWISE);
  174. }
  175. }
  176. // Update the last encoder input time -- handled external to encoder_read() when we're running a split
  177. if (changed) last_encoder_activity_trigger();
  178. }
  179. #endif