xref: /nrf52832-nimble/rt-thread/components/drivers/misc/adc.c (revision 042d53a763ad75cb1465103098bb88c245d95138)
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 
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 
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 
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 
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 
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 
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 
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