dac.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2020-06-19 thread-liu the first version
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #include <string.h>
  13. #include <stdlib.h>
  14. #define DBG_TAG "dac"
  15. #define DBG_LVL DBG_INFO
  16. #include <rtdbg.h>
  17. static rt_size_t _dac_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
  18. {
  19. rt_err_t result = RT_EOK;
  20. rt_size_t i;
  21. struct rt_dac_device *dac = (struct rt_dac_device *)dev;
  22. rt_uint32_t *value = (rt_uint32_t *)buffer;
  23. for (i = 0; i < size; i += sizeof(int))
  24. {
  25. result = dac->ops->convert(dac, pos + i, value);
  26. if (result != RT_EOK)
  27. {
  28. return 0;
  29. }
  30. value++;
  31. }
  32. return i;
  33. }
  34. static rt_err_t _dac_control(rt_device_t dev, int cmd, void *args)
  35. {
  36. rt_err_t result = -RT_EINVAL;
  37. rt_dac_device_t dac = (struct rt_dac_device *)dev;
  38. if (cmd == RT_DAC_CMD_ENABLE && dac->ops->enabled)
  39. {
  40. result = dac->ops->enabled(dac, (rt_uint32_t)args);
  41. }
  42. else if (cmd == RT_DAC_CMD_DISABLE && dac->ops->enabled)
  43. {
  44. result = dac->ops->disabled(dac, (rt_uint32_t)args);
  45. }
  46. else if (cmd == RT_DAC_CMD_GET_RESOLUTION && dac->ops->get_resolution)
  47. {
  48. rt_uint8_t resolution = dac->ops->get_resolution(dac);
  49. if(resolution != 0)
  50. {
  51. *((rt_uint8_t*)args) = resolution;
  52. LOG_D("resolution: %d bits", resolution);
  53. result = RT_EOK;
  54. }
  55. }
  56. return result;
  57. }
  58. #ifdef RT_USING_DEVICE_OPS
  59. const static struct rt_device_ops dac_ops =
  60. {
  61. RT_NULL,
  62. RT_NULL,
  63. RT_NULL,
  64. RT_NULL,
  65. _dac_write,
  66. _dac_control,
  67. };
  68. #endif
  69. rt_err_t rt_hw_dac_register(rt_dac_device_t device, const char *name, const struct rt_dac_ops *ops, const void *user_data)
  70. {
  71. rt_err_t result = RT_EOK;
  72. RT_ASSERT(ops != RT_NULL && ops->convert != RT_NULL);
  73. device->parent.type = RT_Device_Class_DAC;
  74. device->parent.rx_indicate = RT_NULL;
  75. device->parent.tx_complete = RT_NULL;
  76. #ifdef RT_USING_DEVICE_OPS
  77. device->parent.ops = &dac_ops;
  78. #else
  79. device->parent.init = RT_NULL;
  80. device->parent.open = RT_NULL;
  81. device->parent.close = RT_NULL;
  82. device->parent.read = RT_NULL;
  83. device->parent.write = _dac_write;
  84. device->parent.control = _dac_control;
  85. #endif
  86. device->ops = ops;
  87. device->parent.user_data = (void *)user_data;
  88. result = rt_device_register(&device->parent, name, RT_DEVICE_FLAG_RDWR);
  89. return result;
  90. }
  91. rt_err_t rt_dac_write(rt_dac_device_t dev, rt_uint32_t channel, rt_uint32_t value)
  92. {
  93. RT_ASSERT(dev);
  94. return dev->ops->convert(dev, channel, &value);
  95. }
  96. rt_err_t rt_dac_enable(rt_dac_device_t dev, rt_uint32_t channel)
  97. {
  98. rt_err_t result = RT_EOK;
  99. RT_ASSERT(dev);
  100. if (dev->ops->enabled != RT_NULL)
  101. {
  102. result = dev->ops->enabled(dev, channel);
  103. }
  104. else
  105. {
  106. result = -RT_ENOSYS;
  107. }
  108. return result;
  109. }
  110. rt_err_t rt_dac_disable(rt_dac_device_t dev, rt_uint32_t channel)
  111. {
  112. rt_err_t result = RT_EOK;
  113. RT_ASSERT(dev);
  114. if (dev->ops->disabled != RT_NULL)
  115. {
  116. result = dev->ops->disabled(dev, channel);
  117. }
  118. else
  119. {
  120. result = -RT_ENOSYS;
  121. }
  122. return result;
  123. }
  124. #ifdef RT_USING_FINSH
  125. static int dac(int argc, char **argv)
  126. {
  127. int result = RT_EOK;
  128. static rt_dac_device_t dac_device = RT_NULL;
  129. char *result_str;
  130. if (argc > 1)
  131. {
  132. if (!strcmp(argv[1], "probe"))
  133. {
  134. if (argc == 3)
  135. {
  136. dac_device = (rt_dac_device_t)rt_device_find(argv[2]);
  137. result_str = (dac_device == RT_NULL) ? "failure" : "success";
  138. rt_kprintf("probe %s %s \n", argv[2], result_str);
  139. }
  140. else
  141. {
  142. rt_kprintf("dac probe <dac_name> - probe dac by name\n");
  143. }
  144. }
  145. else
  146. {
  147. if (dac_device == RT_NULL)
  148. {
  149. rt_kprintf("Please using 'dac probe <dac_name>' first\n");
  150. return -RT_ERROR;
  151. }
  152. if (!strcmp(argv[1], "enable"))
  153. {
  154. if (argc == 3)
  155. {
  156. result = rt_dac_enable(dac_device, atoi(argv[2]));
  157. result_str = (result == RT_EOK) ? "success" : "failure";
  158. rt_kprintf("%s channel %d enables %s \n", dac_device->parent.parent.name, atoi(argv[2]), result_str);
  159. }
  160. else
  161. {
  162. rt_kprintf("dac enable <channel> - enable dac channel\n");
  163. }
  164. }
  165. else if (!strcmp(argv[1], "write"))
  166. {
  167. if (argc == 4)
  168. {
  169. rt_dac_write(dac_device, atoi(argv[2]), atoi(argv[3]));
  170. rt_kprintf("%s channel %d write value is %d \n", dac_device->parent.parent.name, atoi(argv[2]), atoi(argv[3]));
  171. }
  172. else
  173. {
  174. rt_kprintf("dac write <channel> <value> - write dac value on the channel\n");
  175. }
  176. }
  177. else if (!strcmp(argv[1], "disable"))
  178. {
  179. if (argc == 3)
  180. {
  181. result = rt_dac_disable(dac_device, atoi(argv[2]));
  182. result_str = (result == RT_EOK) ? "success" : "failure";
  183. rt_kprintf("%s channel %d disable %s \n", dac_device->parent.parent.name, atoi(argv[2]), result_str);
  184. }
  185. else
  186. {
  187. rt_kprintf("dac disable <channel> - disable dac channel\n");
  188. }
  189. }
  190. else
  191. {
  192. rt_kprintf("Unknown command. Please enter 'dac' for help\n");
  193. }
  194. }
  195. }
  196. else
  197. {
  198. rt_kprintf("Usage: \n");
  199. rt_kprintf("dac probe <dac_name> - probe dac by name\n");
  200. rt_kprintf("dac write <channel> <value> - write dac value on the channel\n");
  201. rt_kprintf("dac disable <channel> - disable dac channel\n");
  202. rt_kprintf("dac enable <channel> - enable dac channel\n");
  203. result = -RT_ERROR;
  204. }
  205. return RT_EOK;
  206. }
  207. MSH_CMD_EXPORT(dac, dac function);
  208. #endif /* RT_USING_FINSH */