dac.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  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. * 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_EOK;
  37. rt_dac_device_t dac = (struct rt_dac_device *)dev;
  38. if (dac->ops->enabled == RT_NULL)
  39. {
  40. return -RT_ENOSYS;
  41. }
  42. if (cmd == RT_DAC_CMD_ENABLE)
  43. {
  44. result = dac->ops->enabled(dac, (rt_uint32_t)args);
  45. }
  46. else if (cmd == RT_DAC_CMD_DISABLE)
  47. {
  48. result = dac->ops->disabled(dac, (rt_uint32_t)args);
  49. }
  50. return result;
  51. }
  52. #ifdef RT_USING_DEVICE_OPS
  53. const static struct rt_device_ops dac_ops =
  54. {
  55. RT_NULL,
  56. RT_NULL,
  57. RT_NULL,
  58. RT_NULL,
  59. _dac_write,
  60. _dac_control,
  61. };
  62. #endif
  63. 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)
  64. {
  65. rt_err_t result = RT_EOK;
  66. RT_ASSERT(ops != RT_NULL && ops->convert != RT_NULL);
  67. device->parent.type = RT_Device_Class_Miscellaneous;
  68. device->parent.rx_indicate = RT_NULL;
  69. device->parent.tx_complete = RT_NULL;
  70. #ifdef RT_USING_DEVICE_OPS
  71. device->parent.ops = &dac_ops;
  72. #else
  73. device->parent.init = RT_NULL;
  74. device->parent.open = RT_NULL;
  75. device->parent.close = RT_NULL;
  76. device->parent.read = RT_NULL;
  77. device->parent.write = _dac_write;
  78. device->parent.control = _dac_control;
  79. #endif
  80. device->ops = ops;
  81. device->parent.user_data = (void *)user_data;
  82. result = rt_device_register(&device->parent, name, RT_DEVICE_FLAG_RDWR);
  83. return result;
  84. }
  85. rt_uint32_t rt_dac_write(rt_dac_device_t dev, rt_uint32_t channel, rt_uint32_t value)
  86. {
  87. RT_ASSERT(dev);
  88. dev->ops->convert(dev, channel, &value);
  89. return RT_EOK;
  90. }
  91. rt_err_t rt_dac_enable(rt_dac_device_t dev, rt_uint32_t channel)
  92. {
  93. rt_err_t result = RT_EOK;
  94. RT_ASSERT(dev);
  95. if (dev->ops->enabled != RT_NULL)
  96. {
  97. result = dev->ops->enabled(dev, channel);
  98. }
  99. else
  100. {
  101. result = -RT_ENOSYS;
  102. }
  103. return result;
  104. }
  105. rt_err_t rt_dac_disabled(rt_dac_device_t dev, rt_uint32_t channel)
  106. {
  107. rt_err_t result = RT_EOK;
  108. RT_ASSERT(dev);
  109. if (dev->ops->disabled != RT_NULL)
  110. {
  111. result = dev->ops->disabled(dev, channel);
  112. }
  113. else
  114. {
  115. result = -RT_ENOSYS;
  116. }
  117. return result;
  118. }
  119. #ifdef FINSH_USING_MSH
  120. static int dac(int argc, char **argv)
  121. {
  122. int result = RT_EOK;
  123. static rt_dac_device_t dac_device = RT_NULL;
  124. char *result_str;
  125. if (argc > 1)
  126. {
  127. if (!strcmp(argv[1], "probe"))
  128. {
  129. if (argc == 3)
  130. {
  131. dac_device = (rt_dac_device_t)rt_device_find(argv[2]);
  132. result_str = (dac_device == RT_NULL) ? "failure" : "success";
  133. rt_kprintf("probe %s %s \n", argv[2], result_str);
  134. }
  135. else
  136. {
  137. rt_kprintf("dac probe <dac_name> - probe dac by name\n");
  138. }
  139. }
  140. else
  141. {
  142. if (dac_device == RT_NULL)
  143. {
  144. rt_kprintf("Please using 'dac probe <dac_name>' first\n");
  145. return -RT_ERROR;
  146. }
  147. if (!strcmp(argv[1], "enable"))
  148. {
  149. if (argc == 3)
  150. {
  151. result = rt_dac_enable(dac_device, atoi(argv[2]));
  152. result_str = (result == RT_EOK) ? "success" : "failure";
  153. rt_kprintf("%s channel %d enables %s \n", dac_device->parent.parent.name, atoi(argv[2]), result_str);
  154. }
  155. else
  156. {
  157. rt_kprintf("dac enable <channel> - enable dac channel\n");
  158. }
  159. }
  160. else if (!strcmp(argv[1], "write"))
  161. {
  162. if (argc == 4)
  163. {
  164. rt_dac_write(dac_device, atoi(argv[2]), atoi(argv[3]));
  165. rt_kprintf("%s channel %d write value is %d \n", dac_device->parent.parent.name, atoi(argv[2]), atoi(argv[3]));
  166. }
  167. else
  168. {
  169. rt_kprintf("dac write <channel> <value> - write dac value on the channel\n");
  170. }
  171. }
  172. else if (!strcmp(argv[1], "disable"))
  173. {
  174. if (argc == 3)
  175. {
  176. result = rt_dac_disabled(dac_device, atoi(argv[2]));
  177. result_str = (result == RT_EOK) ? "success" : "failure";
  178. rt_kprintf("%s channel %d disable %s \n", dac_device->parent.parent.name, atoi(argv[2]), result_str);
  179. }
  180. else
  181. {
  182. rt_kprintf("dac disable <channel> - disable dac channel\n");
  183. }
  184. }
  185. else
  186. {
  187. rt_kprintf("Unknown command. Please enter 'dac' for help\n");
  188. }
  189. }
  190. }
  191. else
  192. {
  193. rt_kprintf("Usage: \n");
  194. rt_kprintf("dac probe <dac_name> - probe dac by name\n");
  195. rt_kprintf("dac write <channel> <value> - write dac value on the channel\n");
  196. rt_kprintf("dac disable <channel> - disable dac channel\n");
  197. rt_kprintf("dac enable <channel> - enable dac channel\n");
  198. result = -RT_ERROR;
  199. }
  200. return RT_EOK;
  201. }
  202. MSH_CMD_EXPORT(dac, dac function);
  203. #endif /* FINSH_USING_MSH */