drv_pulse_encoder.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2019-08-23 balanceTWK first version
  9. * 2021-01-19 Leslie Lee port to imxrt series
  10. */
  11. #include <rtthread.h>
  12. #include <rtdevice.h>
  13. #ifdef BSP_USING_PULSE_ENCODER
  14. #include "fsl_common.h"
  15. #include "fsl_enc.h"
  16. #define LOG_TAG "drv.pulse_encoder"
  17. #include <drv_log.h>
  18. #if !defined(BSP_USING_PULSE_ENCODER1) && !defined(BSP_USING_PULSE_ENCODER2) && !defined(BSP_USING_PULSE_ENCODER3) \
  19. && !defined(BSP_USING_PULSE_ENCODER4)
  20. #error "Please define at least one BSP_USING_PULSE_ENCODERx"
  21. /* this driver can be disabled at menuconfig -> RT-Thread Components -> Device Drivers */
  22. #elif (defined(BSP_USING_PULSE_ENCODER2) || defined(BSP_USING_PULSE_ENCODER3) || defined(BSP_USING_PULSE_ENCODER4)) || defined(SOC_IMXRT1015_SERIES)
  23. #error "IMXRT1015 had only one quadrature decoder module"
  24. #elif (defined(BSP_USING_PULSE_ENCODER3) || defined(BSP_USING_PULSE_ENCODER4)) || defined(SOC_IMXRT1020_SERIES)
  25. #error "IMXRT1020 had only two quadrature decoder module"
  26. #endif
  27. enum
  28. {
  29. #ifdef BSP_USING_PULSE_ENCODER1
  30. PULSE_ENCODER1_INDEX,
  31. #endif
  32. #ifdef BSP_USING_PULSE_ENCODER2
  33. PULSE_ENCODER2_INDEX,
  34. #endif
  35. #ifdef BSP_USING_PULSE_ENCODER3
  36. PULSE_ENCODER3_INDEX,
  37. #endif
  38. #ifdef BSP_USING_PULSE_ENCODER4
  39. PULSE_ENCODER4_INDEX,
  40. #endif
  41. };
  42. struct imxrt_pulse_encoder_device
  43. {
  44. struct rt_pulse_encoder_device pulse_encoder;
  45. ENC_Type *base;
  46. char *name;
  47. };
  48. typedef struct imxrt_pulse_encoder_device imxrt_pulse_enccoder_device_t;
  49. static imxrt_pulse_enccoder_device_t imxrt_pulse_encoder_obj[] =
  50. {
  51. #ifdef BSP_USING_PULSE_ENCODER1
  52. {
  53. .base = ENC1,
  54. .name = "pulse1"
  55. },
  56. #endif
  57. #ifdef BSP_USING_PULSE_ENCODER2
  58. {
  59. .base = ENC2,
  60. .name = "pulse2"
  61. },
  62. #endif
  63. #ifdef BSP_USING_PULSE_ENCODER3
  64. {
  65. .base = ENC3,
  66. .name = "pulse3"
  67. },
  68. #endif
  69. #ifdef BSP_USING_PULSE_ENCODER4
  70. {
  71. .base = ENC4,
  72. .name = "pulse4"
  73. },
  74. #endif
  75. };
  76. rt_err_t pulse_encoder_init(struct rt_pulse_encoder_device *pulse_encoder)
  77. {
  78. ENC_Type *base = ((imxrt_pulse_enccoder_device_t *)(pulse_encoder->parent.user_data))->base;
  79. enc_config_t enc_config;
  80. ENC_GetDefaultConfig(&enc_config);
  81. ENC_Init(base, &enc_config);
  82. ENC_DoSoftwareLoadInitialPositionValue(base); /* Update the position counter with initial value. */
  83. return RT_EOK;
  84. }
  85. rt_err_t pulse_encoder_clear_count(struct rt_pulse_encoder_device *pulse_encoder)
  86. {
  87. ENC_SetInitialPositionValue(((imxrt_pulse_enccoder_device_t *)(pulse_encoder->parent.user_data))->base, 0);
  88. return RT_EOK;
  89. }
  90. rt_int32_t pulse_encoder_get_count(struct rt_pulse_encoder_device *pulse_encoder)
  91. {
  92. return (rt_int32_t)ENC_GetPositionValue(((imxrt_pulse_enccoder_device_t *)(pulse_encoder->parent.user_data))->base);
  93. }
  94. rt_err_t pulse_encoder_control(struct rt_pulse_encoder_device *pulse_encoder, rt_uint32_t cmd, void *args)
  95. {
  96. rt_err_t result;
  97. result = RT_EOK;
  98. switch (cmd)
  99. {
  100. case PULSE_ENCODER_CMD_ENABLE:
  101. result = pulse_encoder->ops->init(pulse_encoder);
  102. break;
  103. case PULSE_ENCODER_CMD_DISABLE:
  104. ENC_Deinit(((imxrt_pulse_enccoder_device_t *)(pulse_encoder->parent.user_data))->base);
  105. break;
  106. default:
  107. result = -RT_ENOSYS;
  108. break;
  109. }
  110. return result;
  111. }
  112. static const struct rt_pulse_encoder_ops _ops =
  113. {
  114. .init = pulse_encoder_init,
  115. .get_count = pulse_encoder_get_count,
  116. .clear_count = pulse_encoder_clear_count,
  117. .control = pulse_encoder_control,
  118. };
  119. int rt_hw_pulse_encoder_init(void)
  120. {
  121. int i;
  122. int result;
  123. result = RT_EOK;
  124. for (i = 0; i < sizeof(imxrt_pulse_encoder_obj) / sizeof(imxrt_pulse_encoder_obj[0]); i++)
  125. {
  126. imxrt_pulse_encoder_obj[i].pulse_encoder.type = AB_PHASE_PULSE_ENCODER;
  127. imxrt_pulse_encoder_obj[i].pulse_encoder.ops = &_ops;
  128. imxrt_pulse_encoder_obj[i].pulse_encoder.parent.user_data = &(imxrt_pulse_encoder_obj[i]);
  129. if (rt_device_pulse_encoder_register(&imxrt_pulse_encoder_obj[i].pulse_encoder, imxrt_pulse_encoder_obj[i].name, &imxrt_pulse_encoder_obj[i]) != RT_EOK)
  130. {
  131. LOG_E("%s register failed", imxrt_pulse_encoder_obj[i].name);
  132. result = -RT_ERROR;
  133. }
  134. }
  135. return result;
  136. }
  137. INIT_BOARD_EXPORT(rt_hw_pulse_encoder_init);
  138. #endif