adc.c 5.8 KB

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