pot.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. #include <stdint.h>
  2. #include "unicore-mx/stm32/gpio.h"
  3. #include "unicore-mx/stm32/rcc.h"
  4. #include "system.h"
  5. #include "led.h"
  6. #include "pinout.h"
  7. #include "settings.h"
  8. #include "pot.h"
  9. extern volatile uint32_t jiffies;
  10. static int pot_cs[3] = { 8, 7, 6 }; // PC6, PC7, PC8
  11. #define POT0 GPIO8 // C8
  12. #define POT1 GPIO7 // C7
  13. #define POTM GPIO6 // C6
  14. #define POTINC GPIO14 // D14
  15. #define POTUD GPIO15 // D15
  16. #define POT_CS_PINS (POT0 | POT1 | POTM)
  17. #define POT_CTRL_PINS (POTINC | POTUD)
  18. static int HWLevel[3] = {0, 0, 0};
  19. static uint32_t Pots[NUM_POTS] = { POT0, POT1, POTM };
  20. static void p_offset(int p, int offset)
  21. {
  22. uint32_t cs;
  23. int i;
  24. int sign = 0;
  25. int u_off = offset;
  26. volatile uint32_t now;
  27. if((p < 0) || (p > NUM_POTS))
  28. return;
  29. cs = Pots[p];
  30. if (offset < 0) {
  31. sign = 1;
  32. u_off = 0 - offset;
  33. }
  34. /* U/!D setting */
  35. if (sign)
  36. gpio_clear(GPIOD, POTUD);
  37. else
  38. gpio_set(GPIOD, POTUD);
  39. for (i = 0; i < u_off; i++) {
  40. /* /CS on */
  41. gpio_clear(GPIOC, cs);
  42. DMB();
  43. /* /INC on */
  44. gpio_clear(GPIOD, POTINC);
  45. DMB();
  46. /* /INC off */
  47. gpio_set(GPIOD, POTINC);
  48. /* /CS off first (no store) */
  49. gpio_set(GPIOC,cs);
  50. //WFI();
  51. for (int j = 0; j < 1000; j++)
  52. ;;
  53. }
  54. HWLevel[p] += offset;
  55. if (HWLevel[p] > 100)
  56. HWLevel[p] = 100;
  57. if (HWLevel[p] < 0)
  58. HWLevel[p] = 0;
  59. }
  60. void pot_offset(int p, int offset)
  61. {
  62. if ((HWLevel[p] + offset) > 100) {
  63. offset = 100 - HWLevel[p];
  64. }
  65. if ((HWLevel[p] + offset) < 0) {
  66. offset = 0 - HWLevel[p];
  67. }
  68. if (offset == 0)
  69. return;
  70. p_offset(p, offset);
  71. }
  72. void pot_init(void)
  73. {
  74. int i;
  75. rcc_periph_clock_enable(RCC_GPIOC);
  76. rcc_periph_clock_enable(RCC_GPIOD);
  77. gpio_mode_setup(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, POT_CS_PINS);
  78. gpio_set_output_options(GPIOC, GPIO_OTYPE_OD, GPIO_OSPEED_100MHZ, POT_CS_PINS);
  79. gpio_set(GPIOC, POT_CS_PINS);
  80. gpio_mode_setup(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, POT_CTRL_PINS);
  81. gpio_set_output_options(GPIOD, GPIO_OTYPE_OD, GPIO_OSPEED_100MHZ, POT_CTRL_PINS);
  82. gpio_set(GPIOD, POT_CTRL_PINS);
  83. for (i = 0; i < NUM_POTS; i++)
  84. p_offset(i, -100);
  85. pot_set(0,100);
  86. pot_set(1,100);
  87. }
  88. void pot_sync(int p)
  89. {
  90. pot_set(p, Settings->levels[p]);
  91. }
  92. int pot_get(int p)
  93. {
  94. return HWLevel[p];
  95. }
  96. void pot_set(int p, int val)
  97. {
  98. int old = HWLevel[p];
  99. int new = val;
  100. int off;
  101. if (val < 0)
  102. val = 0;
  103. if (val > 100)
  104. val = 100;
  105. Settings->levels[p] = val;
  106. off = val - old;
  107. if (off == 0)
  108. return;
  109. pot_offset(p, off);
  110. }