Geen omschrijving
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

encoder.c 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /*
  2. * encoder.c
  3. *
  4. * Based on https://github.com/mathertel/RotaryEncoder/blob/master/src/RotaryEncoder.cpp
  5. *
  6. * Copyright (c) 2024 Thomas Buck (thomas@xythobuz.de)
  7. *
  8. * Copyright (c) by Matthias Hertel, http://www.mathertel.de
  9. * This work is licensed under a BSD 3-Clause style license
  10. * https://www.mathertel.de/License.aspx.
  11. */
  12. #include <stdio.h>
  13. #include "pico/stdlib.h"
  14. #include "main.h"
  15. #include "encoder.h"
  16. #define LATCH0 0
  17. #define LATCH3 3
  18. #define FOUR3 1 // 4 steps, Latch at position 3 only (compatible to older versions)
  19. #define FOUR0 2 // 4 steps, Latch at position 0 (reverse wirings)
  20. #define TWO03 3 // 2 steps, Latch at position 0 and 3
  21. #define ENCODER_MODE FOUR3
  22. static const uint gpio_num_proto[2] = {
  23. 17, 18
  24. };
  25. static const uint gpio_num_v2[2] = {
  26. 19, 18
  27. };
  28. static const int8_t KNOBDIR[] = {
  29. 0, -1, 1, 0,
  30. 1, 0, 0, -1,
  31. -1, 0, 0, 1,
  32. 0, 1, -1, 0
  33. };
  34. static int8_t oldState;
  35. static int32_t position;
  36. static int32_t positionExt;
  37. static int32_t positionExtPrev;
  38. void encoder_init(void) {
  39. for (uint i = 0; i < 2; i++) {
  40. if (hw_type == HW_PROTOTYPE) {
  41. gpio_init(gpio_num_proto[i]);
  42. gpio_set_dir(gpio_num_proto[i], GPIO_IN);
  43. gpio_pull_up(gpio_num_proto[i]);
  44. } else if (hw_type == HW_V2) {
  45. gpio_init(gpio_num_v2[i]);
  46. gpio_set_dir(gpio_num_v2[i], GPIO_IN);
  47. gpio_pull_up(gpio_num_v2[i]);
  48. }
  49. }
  50. if (hw_type == HW_PROTOTYPE) {
  51. oldState = gpio_get(gpio_num_proto[0]) | (gpio_get(gpio_num_proto[1]) << 1);
  52. } else if (hw_type == HW_V2) {
  53. oldState = gpio_get(gpio_num_v2[0]) | (gpio_get(gpio_num_v2[1]) << 1);
  54. }
  55. position = 0;
  56. positionExt = 0;
  57. positionExtPrev = 0;
  58. }
  59. int32_t encoder_pos(void) {
  60. return positionExt;
  61. }
  62. int32_t encoder_get_diff(void) {
  63. static int32_t last_epos = 0;
  64. int32_t epos = encoder_pos();
  65. int32_t diff = epos - last_epos;
  66. last_epos = epos;
  67. return diff;
  68. }
  69. void encoder_run(void) {
  70. int8_t thisState = 0;
  71. if (hw_type == HW_PROTOTYPE) {
  72. thisState = gpio_get(gpio_num_proto[0]) | (gpio_get(gpio_num_proto[1]) << 1);
  73. } else if (hw_type == HW_V2) {
  74. thisState = gpio_get(gpio_num_v2[0]) | (gpio_get(gpio_num_v2[1]) << 1);
  75. }
  76. if (oldState != thisState) {
  77. position += KNOBDIR[thisState | (oldState << 2)];
  78. oldState = thisState;
  79. switch (ENCODER_MODE) {
  80. case FOUR3:
  81. if (thisState == LATCH3) {
  82. // The hardware has 4 steps with a latch on the input state 3
  83. positionExt = position >> 2;
  84. positionExt = -positionExt;
  85. }
  86. break;
  87. case FOUR0:
  88. if (thisState == LATCH0) {
  89. // The hardware has 4 steps with a latch on the input state 0
  90. positionExt = position >> 2;
  91. positionExt = -positionExt;
  92. }
  93. break;
  94. case TWO03:
  95. if ((thisState == LATCH0) || (thisState == LATCH3)) {
  96. // The hardware has 2 steps with a latch on the input state 0 and 3
  97. positionExt = position >> 1;
  98. positionExt = -positionExt;
  99. }
  100. break;
  101. }
  102. }
  103. }