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