adc.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /*
  2. * Copyright (c) 2006-2018, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2018-05-07 aozima the first version
  9. * 2018-11-16 Ernest Chen add finsh command and update adc function
  10. */
  11. #include <rtthread.h>
  12. #include <rtdevice.h>
  13. #include <string.h>
  14. #include <stdlib.h>
  15. #define DBG_ENABLE
  16. #define DBG_SECTION_NAME "adc"
  17. #define DBG_LEVEL DBG_INFO
  18. #define DBG_COLOR
  19. #include <rtdbg.h>
  20. static rt_size_t _adc_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
  21. {
  22. rt_err_t result = RT_EOK;
  23. rt_size_t i;
  24. struct rt_adc_device *adc = (struct rt_adc_device *)dev;
  25. rt_uint32_t *value = (rt_uint32_t *)buffer;
  26. for (i = 0; i < size; i += sizeof(int))
  27. {
  28. result = adc->ops->convert(adc, pos + i, value);
  29. if (result != RT_EOK)
  30. {
  31. return 0;
  32. }
  33. value++;
  34. }
  35. return i;
  36. }
  37. static rt_err_t _adc_control(rt_device_t dev, int cmd, void *args)
  38. {
  39. rt_err_t result = RT_EOK;
  40. rt_adc_device_t adc = (struct rt_adc_device *)dev;
  41. if (adc->ops->enabled != RT_NULL)
  42. {
  43. return -RT_ENOSYS;
  44. }
  45. if (cmd == RT_ADC_CMD_ENABLE)
  46. {
  47. result = adc->ops->enabled(adc, (rt_uint32_t)args, RT_TRUE);
  48. }
  49. else if (cmd == RT_ADC_CMD_DISABLE)
  50. {
  51. result = adc->ops->enabled(adc, (rt_uint32_t)args, RT_FALSE);
  52. }
  53. return result;
  54. }
  55. rt_err_t rt_hw_adc_register(rt_adc_device_t device, const char *name, const struct rt_adc_ops *ops, const void *user_data)
  56. {
  57. rt_err_t result = RT_EOK;
  58. RT_ASSERT(ops != RT_NULL && ops->convert != RT_NULL);
  59. device->parent.type = RT_Device_Class_Miscellaneous;
  60. device->parent.init = RT_NULL;
  61. device->parent.open = RT_NULL;
  62. device->parent.close = RT_NULL;
  63. device->parent.read = _adc_read;
  64. device->parent.write = RT_NULL;
  65. device->parent.control = _adc_control;
  66. device->ops = ops;
  67. device->parent.user_data = (void *)user_data;
  68. result = rt_device_register(&device->parent, name, RT_DEVICE_FLAG_RDWR);
  69. return result;
  70. }
  71. rt_uint32_t rt_adc_read(rt_adc_device_t dev, rt_uint32_t channel)
  72. {
  73. rt_uint32_t value;
  74. RT_ASSERT(dev);
  75. dev->ops->convert(dev, channel, &value);
  76. return value;
  77. }
  78. rt_err_t rt_adc_enable(rt_adc_device_t dev, rt_uint32_t channel)
  79. {
  80. rt_err_t result = RT_EOK;
  81. RT_ASSERT(dev);
  82. if (dev->ops->enabled != RT_NULL)
  83. {
  84. result = dev->ops->enabled(dev, channel, RT_TRUE);
  85. }
  86. else
  87. {
  88. result = -RT_ENOSYS;
  89. }
  90. return result;
  91. }
  92. rt_err_t rt_adc_disable(rt_adc_device_t dev, rt_uint32_t channel)
  93. {
  94. rt_err_t result = RT_EOK;
  95. RT_ASSERT(dev);
  96. if (dev->ops->enabled != RT_NULL)
  97. {
  98. result = dev->ops->enabled(dev, channel, RT_FALSE);
  99. }
  100. else
  101. {
  102. result = -RT_ENOSYS;
  103. }
  104. return result;
  105. }
  106. #ifdef FINSH_USING_MSH
  107. static int adc(int argc, char **argv)
  108. {
  109. int value = 0;
  110. int result = RT_EOK;
  111. static rt_adc_device_t adc_device = RT_NULL;
  112. char *result_str;
  113. if (argc > 1)
  114. {
  115. if (!strcmp(argv[1], "probe"))
  116. {
  117. if (argc == 3)
  118. {
  119. adc_device = (rt_adc_device_t)rt_device_find(argv[2]);
  120. result_str = (adc_device == RT_NULL) ? "failure" : "success";
  121. rt_kprintf("probe %s %s \n", argv[2], result_str);
  122. }
  123. else
  124. {
  125. rt_kprintf("adc probe <adc_name> - probe adc by name\n");
  126. }
  127. }
  128. else
  129. {
  130. if (adc_device == RT_NULL)
  131. {
  132. rt_kprintf("Please using 'adc probe <adc_name>' first\n");
  133. return -RT_ERROR;
  134. }
  135. if (!strcmp(argv[1], "enable"))
  136. {
  137. if (argc == 3)
  138. {
  139. result = rt_adc_enable(adc_device, atoi(argv[2]));
  140. result_str = (result == RT_EOK) ? "success" : "failure";
  141. rt_kprintf("%s channel %d enables %s \n", adc_device->parent.parent.name, atoi(argv[2]), result_str);
  142. }
  143. else
  144. {
  145. rt_kprintf("adc enable <channel> - enable adc channel\n");
  146. }
  147. }
  148. else if (!strcmp(argv[1], "read"))
  149. {
  150. if (argc == 3)
  151. {
  152. value = rt_adc_read(adc_device, atoi(argv[2]));
  153. rt_kprintf("%s channel %d read value is 0x%08X \n", adc_device->parent.parent.name, atoi(argv[2]), value);
  154. }
  155. else
  156. {
  157. rt_kprintf("adc read <channel> - read adc value on the channel\n");
  158. }
  159. }
  160. else if (!strcmp(argv[1], "disable"))
  161. {
  162. if (argc == 3)
  163. {
  164. result = rt_adc_disable(adc_device, atoi(argv[2]));
  165. result_str = (result == RT_EOK) ? "success" : "failure";
  166. rt_kprintf("%s channel %d disable %s \n", adc_device->parent.parent.name, atoi(argv[2]), result_str);
  167. }
  168. else
  169. {
  170. rt_kprintf("adc disable <channel> - disable adc channel\n");
  171. }
  172. }
  173. else
  174. {
  175. rt_kprintf("Unknown command. Please enter 'adc' for help\n");
  176. }
  177. }
  178. }
  179. else
  180. {
  181. rt_kprintf("Usage: \n");
  182. rt_kprintf("adc probe <adc_name> - probe adc by name\n");
  183. rt_kprintf("adc read <channel> - read adc value on the channel\n");
  184. rt_kprintf("adc disable <channel> - disable adc channel\n");
  185. rt_kprintf("adc enable <channel> - enable adc channel\n");
  186. result = -RT_ERROR;
  187. }
  188. return RT_EOK;
  189. }
  190. MSH_CMD_EXPORT(adc, adc function);
  191. #endif /* FINSH_USING_MSH */