ab_phase_encoder.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /*
  2. * Copyright (c) 2019, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2019-08-26 sogwms The first version
  9. */
  10. #include "ab_phase_encoder.h"
  11. #define DBG_SECTION_NAME "ab_phase_encoder"
  12. #define DBG_LEVEL DBG_LOG
  13. #include <rtdbg.h>
  14. struct ab_phase_encoder
  15. {
  16. struct encoder enc;
  17. rt_base_t pin_a; /* interrupt pin */
  18. rt_base_t pin_b;
  19. rt_int16_t last_value;
  20. };
  21. static const uint8_t AB_PHASE_ENCODER_TABLE[4] = {2, 0, 3, 1};
  22. static void encoder_isr(void *args)
  23. {
  24. ab_phase_encoder_t enc_sub = (ab_phase_encoder_t)args;
  25. int val = rt_pin_read(enc_sub->pin_a) * 2 + rt_pin_read(enc_sub->pin_b);
  26. if (AB_PHASE_ENCODER_TABLE[enc_sub->last_value] == val)
  27. {
  28. enc_sub->enc.dir = ENCODER_DIR_FORWARD;
  29. enc_sub->enc.pulse_count++;
  30. }
  31. else
  32. {
  33. enc_sub->enc.dir = ENCODER_DIR_BACKWARD;
  34. enc_sub->enc.pulse_count--;
  35. }
  36. enc_sub->last_value = val;
  37. }
  38. static rt_err_t ab_phase_encoder_enable(void *enc)
  39. {
  40. ab_phase_encoder_t enc_sub = (ab_phase_encoder_t)enc;
  41. // Attach interrupts
  42. rt_pin_mode(enc_sub->pin_a, PIN_MODE_INPUT);
  43. rt_pin_mode(enc_sub->pin_b, PIN_MODE_INPUT);
  44. rt_pin_attach_irq(enc_sub->pin_a, PIN_IRQ_MODE_RISING_FALLING, encoder_isr, enc_sub);
  45. rt_pin_attach_irq(enc_sub->pin_b, PIN_IRQ_MODE_RISING_FALLING, encoder_isr, enc_sub);
  46. enc_sub->last_value = rt_pin_read(enc_sub->pin_a) * 2 + rt_pin_read(enc_sub->pin_b);
  47. enc_sub->enc.last_time = rt_tick_get();
  48. rt_pin_irq_enable(enc_sub->pin_a, PIN_IRQ_ENABLE);
  49. rt_pin_irq_enable(enc_sub->pin_b, PIN_IRQ_ENABLE);
  50. return RT_EOK;
  51. }
  52. static rt_err_t ab_phase_encoder_disable(void *enc)
  53. {
  54. ab_phase_encoder_t enc_sub = (ab_phase_encoder_t)enc;
  55. rt_pin_irq_enable(enc_sub->pin_a, PIN_IRQ_DISABLE);
  56. rt_pin_irq_enable(enc_sub->pin_b, PIN_IRQ_DISABLE);
  57. return RT_EOK;
  58. }
  59. static rt_err_t ab_phase_encoder_destroy(void *enc)
  60. {
  61. ab_phase_encoder_disable(enc);
  62. ab_phase_encoder_t enc_sub = (ab_phase_encoder_t)enc;
  63. rt_pin_detach_irq(enc_sub->pin_a);
  64. rt_pin_detach_irq(enc_sub->pin_b);
  65. rt_free(enc_sub);
  66. return RT_EOK;
  67. }
  68. ab_phase_encoder_t ab_phase_encoder_create(rt_base_t pin_a, rt_base_t pin_b, rt_uint16_t pulse_revol, rt_uint16_t sample_time)
  69. {
  70. // Malloc memory and initialize pulse_count and pin
  71. ab_phase_encoder_t new_encoder = (ab_phase_encoder_t)encoder_create(sizeof(struct ab_phase_encoder), sample_time);
  72. if(new_encoder == RT_NULL)
  73. {
  74. return RT_NULL;
  75. }
  76. new_encoder->pin_a = pin_a;
  77. new_encoder->pin_b = pin_b;
  78. new_encoder->last_value = 0;
  79. new_encoder->enc.pulse_revol = pulse_revol;
  80. new_encoder->enc.enable = ab_phase_encoder_enable;
  81. new_encoder->enc.disable = ab_phase_encoder_disable;
  82. new_encoder->enc.destroy = ab_phase_encoder_destroy;
  83. return new_encoder;
  84. }