]> sigrok.org Git - libsigrok.git/blob - hardware/saleae-logic16/api.c
saleae-logic16: Detect the hardware.
[libsigrok.git] / hardware / saleae-logic16 / api.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2013 Marcus Comstedt <marcus@mc.pp.se>
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 <glib.h>
21 #include <libusb.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include "libsigrok.h"
25 #include "libsigrok-internal.h"
26 #include "protocol.h"
27
28 #define LOGIC16_VID 0x21a9
29 #define LOGIC16_PID 0x1001
30 #define NUM_PROBES  16
31
32 SR_PRIV struct sr_dev_driver saleae_logic16_driver_info;
33 static struct sr_dev_driver *di = &saleae_logic16_driver_info;
34
35 static const char *probe_names[NUM_PROBES + 1] = {
36         "0", "1", "2", "3", "4", "5", "6", "7", "8",
37         "9", "10", "11", "12", "13", "14", "15",
38         NULL,
39 };
40
41 static int init(struct sr_context *sr_ctx)
42 {
43         return std_init(sr_ctx, di, LOG_PREFIX);
44 }
45
46 static GSList *scan(GSList *options)
47 {
48         struct drv_context *drvc;
49         struct dev_context *devc;
50         struct sr_dev_inst *sdi;
51         struct sr_probe *probe;
52         struct libusb_device_descriptor des;
53         libusb_device **devlist;
54         GSList *devices;
55         int ret, devcnt, i, j;
56
57         (void)options;
58
59         drvc = di->priv;
60
61         devices = NULL;
62         libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist);
63         for (i = 0; devlist[i]; i++) {
64                 if ((ret = libusb_get_device_descriptor(devlist[i], &des)) != 0) {
65                         sr_warn("Failed to get device descriptor: %s",
66                                         libusb_error_name(ret));
67                         continue;
68                 }
69
70                 if (des.idVendor != LOGIC16_VID || des.idProduct != LOGIC16_PID)
71                         continue;
72
73                 devcnt = g_slist_length(drvc->instances);
74                 if (!(sdi = sr_dev_inst_new(devcnt, SR_ST_INACTIVE,
75                                             "Saleae", "Logic16", NULL)))
76                         return NULL;
77                 sdi->driver = di;
78
79                 if (!(devc = g_try_malloc0(sizeof(struct dev_context))))
80                         return NULL;
81                 sdi->priv = devc;
82
83                 for (j = 0; probe_names[j]; j++) {
84                         if (!(probe = sr_probe_new(j, SR_PROBE_LOGIC, TRUE,
85                                                    probe_names[j])))
86                                 return NULL;
87                         sdi->probes = g_slist_append(sdi->probes, probe);
88                 }
89
90                 if (!(sdi->conn = sr_usb_dev_inst_new(libusb_get_bus_number(devlist[i]),
91                                                       libusb_get_device_address(devlist[i]), NULL)))
92                         return NULL;
93                 sdi->inst_type = SR_INST_USB;
94
95                 drvc->instances = g_slist_append(drvc->instances, sdi);
96                 devices = g_slist_append(devices, sdi);
97         }
98         libusb_free_device_list(devlist, 1);
99
100         return devices;
101 }
102
103 static GSList *dev_list(void)
104 {
105         struct drv_context *drvc;
106
107         drvc = di->priv;
108
109         return drvc->instances;
110 }
111
112 static int dev_clear(void)
113 {
114         return std_dev_clear(di, NULL);
115 }
116
117 static int dev_open(struct sr_dev_inst *sdi)
118 {
119         (void)sdi;
120
121         /* TODO: get handle from sdi->conn and open it. */
122
123         sdi->status = SR_ST_ACTIVE;
124
125         return SR_OK;
126 }
127
128 static int dev_close(struct sr_dev_inst *sdi)
129 {
130         (void)sdi;
131
132         /* TODO: get handle from sdi->conn and close it. */
133
134         sdi->status = SR_ST_INACTIVE;
135
136         return SR_OK;
137 }
138
139 static int cleanup(void)
140 {
141         int ret;
142         struct drv_context *drvc;
143
144         if (!(drvc = di->priv))
145                 /* Can get called on an unused driver, doesn't matter. */
146                 return SR_OK;
147
148         ret = dev_clear();
149         g_free(drvc);
150         di->priv = NULL;
151
152         return ret;
153 }
154
155 static int config_get(int key, GVariant **data, const struct sr_dev_inst *sdi)
156 {
157         int ret;
158
159         (void)sdi;
160         (void)data;
161
162         ret = SR_OK;
163         switch (key) {
164         /* TODO */
165         default:
166                 return SR_ERR_NA;
167         }
168
169         return ret;
170 }
171
172 static int config_set(int key, GVariant *data, const struct sr_dev_inst *sdi)
173 {
174         int ret;
175
176         (void)data;
177
178         if (sdi->status != SR_ST_ACTIVE)
179                 return SR_ERR_DEV_CLOSED;
180
181         ret = SR_OK;
182         switch (key) {
183         /* TODO */
184         default:
185                 ret = SR_ERR_NA;
186         }
187
188         return ret;
189 }
190
191 static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi)
192 {
193         int ret;
194
195         (void)sdi;
196         (void)data;
197
198         ret = SR_OK;
199         switch (key) {
200         /* TODO */
201         default:
202                 return SR_ERR_NA;
203         }
204
205         return ret;
206 }
207
208 static int dev_acquisition_start(const struct sr_dev_inst *sdi,
209                                     void *cb_data)
210 {
211         (void)sdi;
212         (void)cb_data;
213
214         if (sdi->status != SR_ST_ACTIVE)
215                 return SR_ERR_DEV_CLOSED;
216
217         /* TODO: configure hardware, reset acquisition state, set up
218          * callbacks and send header packet. */
219
220         return SR_OK;
221 }
222
223 static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
224 {
225         (void)cb_data;
226
227         if (sdi->status != SR_ST_ACTIVE)
228                 return SR_ERR_DEV_CLOSED;
229
230         /* TODO: stop acquisition. */
231
232         return SR_OK;
233 }
234
235 SR_PRIV struct sr_dev_driver saleae_logic16_driver_info = {
236         .name = "saleae-logic16",
237         .longname = "Saleae Logic16",
238         .api_version = 1,
239         .init = init,
240         .cleanup = cleanup,
241         .scan = scan,
242         .dev_list = dev_list,
243         .dev_clear = dev_clear,
244         .config_get = config_get,
245         .config_set = config_set,
246         .config_list = config_list,
247         .dev_open = dev_open,
248         .dev_close = dev_close,
249         .dev_acquisition_start = dev_acquisition_start,
250         .dev_acquisition_stop = dev_acquisition_stop,
251         .priv = NULL,
252 };