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