drv_adc.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /*
  2. * Copyright (c) 2021 - 2022 hpmicro
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-05-08 hpmicro the first version
  9. */
  10. #include <rtthread.h>
  11. #ifdef BSP_USING_ADC
  12. #include <rtdevice.h>
  13. #include "board.h"
  14. #include "drv_adc.h"
  15. #ifdef BSP_USING_ADC12
  16. #include "hpm_adc12_drv.h"
  17. #endif
  18. #ifdef BSP_USING_ADC16
  19. #include "hpm_adc16_drv.h"
  20. #endif
  21. #include "hpm_sysctl_drv.h"
  22. typedef struct
  23. {
  24. char *adc_name;
  25. struct rt_adc_device hpm_adc_device;
  26. uint16_t channel;
  27. #ifdef BSP_USING_ADC12
  28. ADC12_Type *adc_base;
  29. #endif
  30. #ifdef BSP_USING_ADC16
  31. ADC16_Type *adc_base;
  32. #endif
  33. }hpm_rtt_adc;
  34. static hpm_rtt_adc hpm_adc_config_tbl[] =
  35. {
  36. #ifdef BSP_USING_ADC0
  37. {
  38. .adc_name = "adc0",
  39. #ifdef BSP_USING_ADC12
  40. .adc_base = HPM_ADC0,
  41. #endif
  42. #ifdef BSP_USING_ADC16
  43. .adc_base = HPM_ADC0,
  44. #endif
  45. },
  46. #endif
  47. #ifdef BSP_USING_ADC1
  48. {
  49. .adc_name = "adc1",
  50. #ifdef BSP_USING_ADC12
  51. .adc_base = HPM_ADC1,
  52. #endif
  53. #ifdef BSP_USING_ADC16
  54. .adc_base = HPM_ADC1,
  55. #endif
  56. },
  57. #endif
  58. #ifdef BSP_USING_ADC2
  59. {
  60. .adc_name = "adc2",
  61. #ifdef BSP_USING_ADC12
  62. .adc_base = HPM_ADC2,
  63. #endif
  64. #ifdef BSP_USING_ADC16
  65. .adc_base = HPM_ADC2,
  66. #endif
  67. },
  68. #endif
  69. #ifdef BSP_USING_ADC3
  70. {
  71. .adc_name = "adc3",
  72. #ifdef BSP_USING_ADC12
  73. .adc_base = HPM_ADC3,
  74. #endif
  75. #ifdef BSP_USING_ADC16
  76. .adc_base = HPM_ADC3,
  77. #endif
  78. },
  79. #endif
  80. };
  81. static uint8_t adc_nums = sizeof(hpm_adc_config_tbl) / sizeof(hpm_rtt_adc);
  82. static rt_err_t init_adc_config(hpm_rtt_adc *adc)
  83. {
  84. #ifdef BSP_USING_ADC12
  85. adc12_config_t cfg;
  86. hpm_stat_t ret;
  87. adc12_get_default_config(&cfg);
  88. cfg.res = adc12_res_12_bits;
  89. cfg.conv_mode = adc12_conv_mode_oneshot;
  90. cfg.adc_clk_div = 1;
  91. ret = adc12_init(adc->adc_base, &cfg);
  92. if (ret != status_success) {
  93. return RT_ERROR;
  94. }
  95. #endif
  96. #ifdef BSP_USING_ADC16
  97. adc16_config_t cfg;
  98. hpm_stat_t ret;
  99. adc16_get_default_config(&cfg);
  100. cfg.conv_mode = adc16_conv_mode_oneshot;
  101. cfg.adc_clk_div = 3;
  102. cfg.sel_sync_ahb = true;
  103. ret = adc16_init(adc->adc_base, &cfg);
  104. if (ret != status_success) {
  105. return RT_ERROR;
  106. }
  107. #endif
  108. return RT_EOK;
  109. }
  110. static rt_err_t init_channel_config(hpm_rtt_adc *adc)
  111. {
  112. #ifdef BSP_USING_ADC12
  113. adc12_channel_config_t ch_cfg;;
  114. hpm_stat_t ret;
  115. ch_cfg.ch = adc->channel;
  116. ch_cfg.diff_sel = adc12_sample_signal_single_ended;
  117. ch_cfg.sample_cycle = 20;
  118. ret = adc12_init_channel(adc->adc_base, &ch_cfg);
  119. if (ret != status_success) {
  120. return RT_ERROR;
  121. }
  122. #endif
  123. #ifdef BSP_USING_ADC16
  124. adc16_channel_config_t ch_cfg;;
  125. hpm_stat_t ret;
  126. ch_cfg.ch = adc->channel;
  127. ch_cfg.sample_cycle = 20;
  128. ret = adc16_init_channel(adc->adc_base, &ch_cfg);
  129. if (ret != status_success) {
  130. return RT_ERROR;
  131. }
  132. #endif
  133. return RT_EOK;
  134. }
  135. static rt_err_t hpm_adc_enabled(struct rt_adc_device *device, rt_uint32_t channel, rt_bool_t enabled)
  136. {
  137. hpm_rtt_adc *hpm_adc_handler;
  138. rt_err_t ret;
  139. RT_ASSERT(device != RT_NULL);
  140. hpm_adc_handler = (hpm_rtt_adc *)device->parent.user_data;
  141. ret = init_adc_config(hpm_adc_handler);
  142. if (ret != RT_EOK) {
  143. return RT_ERROR;
  144. }
  145. hpm_adc_handler->channel = channel;
  146. ret = init_channel_config(hpm_adc_handler);
  147. if (ret != RT_EOK) {
  148. return RT_ERROR;
  149. }
  150. return RT_EOK;
  151. }
  152. static rt_err_t hpm_get_adc_value(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value)
  153. {
  154. hpm_rtt_adc hpm_adc_handler;
  155. rt_err_t ret;
  156. rt_uint16_t val;
  157. RT_ASSERT(device != RT_NULL);
  158. RT_ASSERT(value != RT_NULL);
  159. hpm_adc_handler = *(hpm_rtt_adc *)device->parent.user_data;
  160. hpm_adc_handler.channel = channel;
  161. #ifdef BSP_USING_ADC12
  162. adc12_get_oneshot_result(hpm_adc_handler.adc_base, hpm_adc_handler.channel, &val);
  163. *value = (val >> 4);
  164. #endif
  165. #ifdef BSP_USING_ADC16
  166. adc16_get_oneshot_result(hpm_adc_handler.adc_base, hpm_adc_handler.channel, &val);
  167. *value = val;
  168. #endif
  169. return RT_EOK;
  170. }
  171. static const struct rt_adc_ops hpm_adc_ops =
  172. {
  173. .enabled = hpm_adc_enabled,
  174. .convert = hpm_get_adc_value,
  175. };
  176. int rt_hw_adc_init(void)
  177. {
  178. rt_err_t ret = RT_EOK;
  179. for (uint32_t i = 0; i < adc_nums; i++) {
  180. ret = rt_hw_adc_register(&hpm_adc_config_tbl[i].hpm_adc_device, hpm_adc_config_tbl[i].adc_name, &hpm_adc_ops, &hpm_adc_config_tbl[i]);
  181. if (ret != RT_EOK) {
  182. ret = RT_ERROR;
  183. break;
  184. }
  185. }
  186. return ret;
  187. }
  188. INIT_BOARD_EXPORT(rt_hw_adc_init);
  189. #endif