]> sigrok.org Git - libsigrok.git/blob - device.c
0b59621ef08dc8876c24e3997c16d0c232023c0a
[libsigrok.git] / device.c
1 /*
2  * This file is part of the sigrok project.
3  *
4  * Copyright (C) 2010 Bert Vermeulen <bert@biot.com>
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <stdio.h>
21 #include <glib.h>
22 #include <sigrok.h>
23
24 extern struct sigrok_global *global;
25
26 GSList *devices = NULL;
27
28 void device_scan(void)
29 {
30         GSList *plugins, *l;
31         struct device_plugin *plugin;
32         int num_devices, i;
33
34         plugins = list_hwplugins();
35
36         /*
37          * Initialize all plugins first. Since the init() call may involve
38          * a firmware upload and associated delay, we may as well get all
39          * of these out of the way first.
40          */
41         for (l = plugins; l; l = l->next) {
42                 plugin = l->data;
43                 g_message("initializing %s plugin", plugin->name);
44                 num_devices = plugin->init(NULL);
45                 for (i = 0; i < num_devices; i++)
46                         device_new(plugin, i);
47         }
48 }
49
50 void device_close_all(void)
51 {
52         struct device *device;
53
54         while (devices) {
55                 device = devices->data;
56                 device->plugin->close(device->plugin_index);
57                 device_destroy(device);
58         }
59 }
60
61 GSList *device_list(void)
62 {
63         return devices;
64 }
65
66 struct device *device_new(struct device_plugin *plugin, int plugin_index)
67 {
68         struct device *device;
69         int num_probes, i;
70         char probename[16];
71
72         device = g_malloc0(sizeof(struct device));
73         device->plugin = plugin;
74         device->plugin_index = plugin_index;
75         devices = g_slist_append(devices, device);
76
77         num_probes = (int)device->plugin->get_device_info(device->plugin_index,
78                                                           DI_NUM_PROBES);
79         for (i = 0; i < num_probes; i++) {
80                 snprintf(probename, 16, "%d", i + 1);
81                 device_probe_add(device, probename);
82         }
83
84         return device;
85 }
86
87 void device_clear(struct device *device)
88 {
89         unsigned int pnum;
90
91         /* TODO: Plugin-specific clear call? */
92
93         if (!device->probes)
94                 return;
95
96         for (pnum = 1; pnum <= g_slist_length(device->probes); pnum++)
97                 device_probe_clear(device, pnum);
98 }
99
100 void device_destroy(struct device *device)
101 {
102         unsigned int pnum;
103
104         /*
105          * TODO: Plugin-specific destroy call, need to decrease refcount
106          * in plugin.
107          */
108
109         devices = g_slist_remove(devices, device);
110         if (device->probes) {
111                 for (pnum = 1; pnum <= g_slist_length(device->probes); pnum++)
112                         device_probe_clear(device, pnum);
113                 g_slist_free(device->probes);
114         }
115         g_free(device);
116 }
117
118 void device_probe_clear(struct device *device, int probenum)
119 {
120         struct probe *p;
121
122         p = probe_find(device, probenum);
123         if (!p)
124                 return;
125
126         if (p->name) {
127                 g_free(p->name);
128                 p->name = NULL;
129         }
130
131         if (p->trigger) {
132                 g_free(p->trigger);
133                 p->trigger = NULL;
134         }
135 }
136
137 void device_probe_add(struct device *device, char *name)
138 {
139         struct probe *p;
140
141         p = g_malloc0(sizeof(struct probe));
142         p->index = g_slist_length(device->probes) + 1;
143         p->enabled = TRUE;
144         p->name = g_strdup(name);
145         p->trigger = NULL;
146         device->probes = g_slist_append(device->probes, p);
147 }
148
149 struct probe *probe_find(struct device *device, int probenum)
150 {
151         GSList *l;
152         struct probe *p, *found_probe;
153
154         found_probe = NULL;
155         for (l = device->probes; l; l = l->next) {
156                 p = l->data;
157                 if (p->index == probenum) {
158                         found_probe = p;
159                         break;
160                 }
161         }
162
163         return found_probe;
164 }
165
166 void device_probe_name(struct device *device, int probenum, char *name)
167 {
168         struct probe *p;
169
170         p = probe_find(device, probenum);
171         if (!p)
172                 return;
173
174         if (p->name)
175                 g_free(p->name);
176         p->name = g_strdup(name);
177 }
178
179 void device_trigger_clear(struct device *device)
180 {
181         struct probe *p;
182         unsigned int pnum;
183
184         if (!device->probes)
185                 return;
186
187         for (pnum = 1; pnum <= g_slist_length(device->probes); pnum++) {
188                 p = probe_find(device, pnum);
189                 if (p && p->trigger) {
190                         g_free(p->trigger);
191                         p->trigger = NULL;
192                 }
193         }
194 }
195
196 void device_trigger_set(struct device *device, int probenum, char *trigger)
197 {
198         struct probe *p;
199
200         p = probe_find(device, probenum);
201         if (!p)
202                 return;
203
204         if (p->trigger)
205                 g_free(p->trigger);
206
207         p->trigger = g_strdup(trigger);
208 }