potentiometer.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. // Copyright 2023 QMK
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include "potentiometer.h"
  4. #include "gpio.h"
  5. #include "util.h"
  6. #include "timer.h"
  7. #include "analog.h"
  8. #ifndef POTENTIOMETER_THROTTLE_MS
  9. # define POTENTIOMETER_THROTTLE_MS 1
  10. #endif
  11. #ifndef POTENTIOMETER_OUTPUT_MIN_VALUE
  12. # define POTENTIOMETER_OUTPUT_MIN_VALUE 0
  13. #endif
  14. #ifndef POTENTIOMETER_OUTPUT_MAX_VALUE
  15. # define POTENTIOMETER_OUTPUT_MAX_VALUE 127
  16. #endif
  17. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  18. // ADC Driver
  19. // Matches default adc range
  20. #ifndef POTENTIOMETER_RAW_MIN_VALUE
  21. # define POTENTIOMETER_RAW_MIN_VALUE 0
  22. #endif
  23. #ifndef POTENTIOMETER_RAW_MAX_VALUE
  24. # define POTENTIOMETER_RAW_MAX_VALUE (1 << 10)
  25. #endif
  26. static pin_t potentiometer_pads[] = POTENTIOMETER_PINS;
  27. #define NUM_POTENTIOMETERS (ARRAY_SIZE(potentiometer_pads))
  28. __attribute__((weak)) void potentiometer_driver_init(void) {
  29. // do nothing
  30. }
  31. __attribute__((weak)) uint16_t potentiometer_driver_sample(uint8_t index) {
  32. return analogReadPin(potentiometer_pads[index]);
  33. }
  34. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  35. // Callbacks
  36. __attribute__((weak)) bool potentiometer_update_user(uint8_t index, uint16_t value) {
  37. return true;
  38. }
  39. __attribute__((weak)) bool potentiometer_update_kb(uint8_t index, uint16_t value) {
  40. return potentiometer_update_user(index, value);
  41. }
  42. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  43. // Default scanning routine
  44. __attribute__((weak)) uint16_t potentiometer_map(uint8_t index, uint16_t value) {
  45. (void)index;
  46. uint32_t a = POTENTIOMETER_OUTPUT_MIN_VALUE;
  47. uint32_t b = POTENTIOMETER_OUTPUT_MAX_VALUE;
  48. uint32_t min = POTENTIOMETER_RAW_MIN_VALUE;
  49. uint32_t max = POTENTIOMETER_RAW_MAX_VALUE;
  50. // Scale value to min/max using the adc range
  51. return ((b - a) * (value - min) / (max - min)) + a;
  52. }
  53. __attribute__((weak)) bool potentiometer_filter(uint8_t index, uint16_t value) {
  54. // ADC currently limited to max of 12 bits - init to max 16 ensures
  55. // we can correctly capture even a raw first sample at max adc bounds
  56. static uint16_t potentiometer_state[NUM_POTENTIOMETERS] = {UINT16_MAX};
  57. if (value == potentiometer_state[index]) {
  58. return false;
  59. }
  60. potentiometer_state[index] = value;
  61. return true;
  62. }
  63. __attribute__((weak)) bool potentiometer_throttle_task(void) {
  64. #if (POTENTIOMETER_THROTTLE_MS > 0)
  65. static uint32_t last_exec = 0;
  66. if (timer_elapsed32(last_exec) < POTENTIOMETER_THROTTLE_MS) {
  67. return false;
  68. }
  69. last_exec = timer_read32();
  70. #endif
  71. return true;
  72. }
  73. void potentiometer_init(void) {
  74. potentiometer_driver_init();
  75. }
  76. bool potentiometer_task(void) {
  77. if (!potentiometer_throttle_task()) {
  78. return false;
  79. }
  80. bool changed = false;
  81. for (uint8_t index = 0; index < NUM_POTENTIOMETERS; index++) {
  82. uint16_t raw = potentiometer_driver_sample(index);
  83. uint16_t value = potentiometer_map(index, raw);
  84. if (potentiometer_filter(index, value)) {
  85. changed |= true;
  86. potentiometer_update_kb(index, value);
  87. }
  88. }
  89. return changed;
  90. }