]> sigrok.org Git - libsigrok.git/blob - src/hardware/uni-t-ut32x/api.c
Fix #442 by renaming sr_dev_driver.priv to .context
[libsigrok.git] / src / hardware / uni-t-ut32x / api.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2013 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 <string.h>
21 #include "protocol.h"
22
23 static const uint32_t devopts[] = {
24         SR_CONF_THERMOMETER,
25         SR_CONF_CONTINUOUS,
26         SR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET,
27         SR_CONF_DATA_SOURCE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
28 };
29
30 static const char *channel_names[] = {
31         "T1", "T2", "T1-T2",
32 };
33
34 static const char *data_sources[] = {
35         "Live",
36         "Memory",
37 };
38
39 SR_PRIV struct sr_dev_driver uni_t_ut32x_driver_info;
40
41 static int init(struct sr_dev_driver *di, struct sr_context *sr_ctx)
42 {
43         return std_init(sr_ctx, di, LOG_PREFIX);
44 }
45
46 static GSList *scan(struct sr_dev_driver *di, GSList *options)
47 {
48         struct drv_context *drvc;
49         struct dev_context *devc;
50         struct sr_dev_inst *sdi;
51         struct sr_config *src;
52         GSList *usb_devices, *devices, *l;
53         unsigned int i;
54         const char *conn;
55
56         drvc = di->context;
57         drvc->instances = NULL;
58
59         conn = NULL;
60         for (l = options; l; l = l->next) {
61                 src = l->data;
62                 switch (src->key) {
63                 case SR_CONF_CONN:
64                         conn = g_variant_get_string(src->data, NULL);
65                         break;
66                 }
67         }
68         if (!conn)
69                 return NULL;
70
71         devices = NULL;
72         if ((usb_devices = sr_usb_find(drvc->sr_ctx->libusb_ctx, conn))) {
73                 /* We have a list of sr_usb_dev_inst matching the connection
74                  * string. Wrap them in sr_dev_inst and we're done. */
75                 for (l = usb_devices; l; l = l->next) {
76                         sdi = g_malloc0(sizeof(struct sr_dev_inst));
77                         sdi->status = SR_ST_INACTIVE;
78                         sdi->vendor = g_strdup(VENDOR);
79                         sdi->model = g_strdup(MODEL);
80                         sdi->driver = di;
81                         sdi->inst_type = SR_INST_USB;
82                         sdi->conn = l->data;
83                         for (i = 0; i < ARRAY_SIZE(channel_names); i++)
84                                 sr_channel_new(sdi, i, SR_CHANNEL_ANALOG, TRUE,
85                                                 channel_names[i]);
86                         devc = g_malloc0(sizeof(struct dev_context));
87                         sdi->priv = devc;
88                         devc->limit_samples = 0;
89                         devc->data_source = DEFAULT_DATA_SOURCE;
90                         drvc->instances = g_slist_append(drvc->instances, sdi);
91                         devices = g_slist_append(devices, sdi);
92                 }
93                 g_slist_free(usb_devices);
94         } else
95                 g_slist_free_full(usb_devices, g_free);
96
97         return devices;
98 }
99
100 static GSList *dev_list(const struct sr_dev_driver *di)
101 {
102         return ((struct drv_context *)(di->context))->instances;
103 }
104
105 static int dev_open(struct sr_dev_inst *sdi)
106 {
107         struct sr_dev_driver *di = sdi->driver;
108         struct drv_context *drvc;
109         struct sr_usb_dev_inst *usb;
110         int ret;
111
112         if (!(drvc = di->context)) {
113                 sr_err("Driver was not initialized.");
114                 return SR_ERR;
115         }
116
117         usb = sdi->conn;
118
119         if (sr_usb_open(drvc->sr_ctx->libusb_ctx, usb) != SR_OK)
120                 return SR_ERR;
121
122 /*
123  * The libusb 1.0.9 Darwin backend is broken: it can report a kernel
124  * driver being active, but detaching it always returns an error.
125  */
126 #if !defined(__APPLE__)
127         if (libusb_kernel_driver_active(usb->devhdl, USB_INTERFACE) == 1) {
128                 if ((ret = libusb_detach_kernel_driver(usb->devhdl, USB_INTERFACE)) < 0) {
129                         sr_err("failed to detach kernel driver: %s",
130                                         libusb_error_name(ret));
131                         return SR_ERR;
132                 }
133         }
134 #endif
135
136         if ((ret = libusb_set_configuration(usb->devhdl, USB_CONFIGURATION))) {
137                 sr_err("Failed to set configuration: %s.", libusb_error_name(ret));
138                 return SR_ERR;
139         }
140
141         if ((ret = libusb_claim_interface(usb->devhdl, USB_INTERFACE))) {
142                 sr_err("Failed to claim interface: %s.", libusb_error_name(ret));
143                 return SR_ERR;
144         }
145         sdi->status = SR_ST_ACTIVE;
146
147         return ret;
148 }
149
150 static int dev_close(struct sr_dev_inst *sdi)
151 {
152         struct sr_dev_driver *di = sdi->driver;
153         struct sr_usb_dev_inst *usb;
154
155         if (!di->context) {
156                 sr_err("Driver was not initialized.");
157                 return SR_ERR;
158         }
159
160         usb = sdi->conn;
161         if (!usb->devhdl)
162                 /*  Nothing to do. */
163                 return SR_OK;
164
165         libusb_release_interface(usb->devhdl, USB_INTERFACE);
166         libusb_close(usb->devhdl);
167         usb->devhdl = NULL;
168         sdi->status = SR_ST_INACTIVE;
169
170         return SR_OK;
171 }
172
173 static int cleanup(const struct sr_dev_driver *di)
174 {
175         int ret;
176         struct drv_context *drvc;
177
178         if (!(drvc = di->context))
179                 /* Can get called on an unused driver, doesn't matter. */
180                 return SR_OK;
181
182         ret = std_dev_clear(di, NULL);
183         g_free(drvc);
184
185         return ret;
186 }
187
188 static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
189                 const struct sr_channel_group *cg)
190 {
191         struct dev_context *devc;
192
193         (void)cg;
194
195         devc = sdi->priv;
196         switch (key) {
197         case SR_CONF_LIMIT_SAMPLES:
198                 *data = g_variant_new_uint64(devc->limit_samples);
199                 break;
200         case SR_CONF_DATA_SOURCE:
201                 if (devc->data_source == DATA_SOURCE_LIVE)
202                         *data = g_variant_new_string("Live");
203                 else
204                         *data = g_variant_new_string("Memory");
205                 break;
206         default:
207                 return SR_ERR_NA;
208         }
209
210         return SR_OK;
211 }
212
213 static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sdi,
214                 const struct sr_channel_group *cg)
215 {
216         struct sr_dev_driver *di = sdi->driver;
217         struct dev_context *devc;
218         const char *tmp_str;
219
220         (void)cg;
221
222         if (sdi->status != SR_ST_ACTIVE)
223                 return SR_ERR_DEV_CLOSED;
224
225         if (!di->context) {
226                 sr_err("Driver was not initialized.");
227                 return SR_ERR;
228         }
229
230         devc = sdi->priv;
231
232         switch (key) {
233         case SR_CONF_LIMIT_SAMPLES:
234                 devc->limit_samples = g_variant_get_uint64(data);
235                 break;
236         case SR_CONF_DATA_SOURCE:
237                 tmp_str = g_variant_get_string(data, NULL);
238                 if (!strcmp(tmp_str, "Live"))
239                         devc->data_source = DATA_SOURCE_LIVE;
240                 else if (!strcmp(tmp_str, "Memory"))
241                         devc->data_source = DATA_SOURCE_MEMORY;
242                 else
243                         return SR_ERR;
244                 break;
245         default:
246                 return SR_ERR_NA;
247         }
248
249         return SR_OK;
250 }
251
252 static int config_list(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
253                 const struct sr_channel_group *cg)
254 {
255         (void)sdi;
256         (void)cg;
257
258         switch (key) {
259         case SR_CONF_DEVICE_OPTIONS:
260                 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
261                                 devopts, ARRAY_SIZE(devopts), sizeof(uint32_t));
262                 break;
263         case SR_CONF_DATA_SOURCE:
264                 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources));
265                 break;
266         default:
267                 return SR_ERR_NA;
268         }
269
270         return SR_OK;
271 }
272
273 static int dev_acquisition_start(const struct sr_dev_inst *sdi,
274                                     void *cb_data)
275 {
276         struct sr_dev_driver *di = sdi->driver;
277         struct drv_context *drvc;
278         struct dev_context *devc;
279         struct sr_usb_dev_inst *usb;
280         int len, ret;
281         unsigned char cmd[2];
282
283         if (sdi->status != SR_ST_ACTIVE)
284                 return SR_ERR_DEV_CLOSED;
285
286         drvc = di->context;
287         devc = sdi->priv;
288         usb = sdi->conn;
289
290         devc->cb_data = cb_data;
291         devc->num_samples = 0;
292         devc->packet_len = 0;
293
294         /* Configure serial port parameters on USB-UART interface
295          * chip inside the device (just baudrate 2400 actually). */
296         cmd[0] = 0x09;
297         cmd[1] = 0x60;
298         ret = libusb_control_transfer(usb->devhdl, 0x21, 0x09, 0x0300, 0x00,
299                         cmd, 2, 5);
300         if (ret != 2) {
301                 sr_dbg("Failed to configure CH9325: %s", libusb_error_name(ret));
302                 return SR_ERR;
303         }
304
305         /* Send header packet to the session bus. */
306         std_session_send_df_header(cb_data, LOG_PREFIX);
307
308         if (!(devc->xfer = libusb_alloc_transfer(0)))
309                 return SR_ERR;
310
311         /* Length of payload to follow. */
312         cmd[0] = 0x01;
313         if (devc->data_source == DATA_SOURCE_LIVE)
314                 cmd[1] = CMD_GET_LIVE;
315         else
316                 cmd[1] = CMD_GET_STORED;
317
318         ret = libusb_bulk_transfer(usb->devhdl, EP_OUT, cmd, 2, &len, 5);
319         if (ret != 0 || len != 2) {
320                 sr_dbg("Failed to start acquisition: %s", libusb_error_name(ret));
321                 libusb_free_transfer(devc->xfer);
322                 return SR_ERR;
323         }
324
325         libusb_fill_bulk_transfer(devc->xfer, usb->devhdl, EP_IN, devc->buf,
326                         8, uni_t_ut32x_receive_transfer, (void *)sdi, 15);
327         if (libusb_submit_transfer(devc->xfer) != 0) {
328                 libusb_free_transfer(devc->xfer);
329                 return SR_ERR;
330         }
331
332         usb_source_add(sdi->session, drvc->sr_ctx, 10,
333                         uni_t_ut32x_handle_events, (void *)sdi);
334
335         return SR_OK;
336 }
337
338 static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
339 {
340
341         (void)cb_data;
342
343         if (sdi->status != SR_ST_ACTIVE)
344                 return SR_ERR_DEV_CLOSED;
345
346         /* Signal USB transfer handler to clean up and stop. */
347         sdi->status = SR_ST_STOPPING;
348
349         return SR_OK;
350 }
351
352 SR_PRIV struct sr_dev_driver uni_t_ut32x_driver_info = {
353         .name = "uni-t-ut32x",
354         .longname = "UNI-T UT32x",
355         .api_version = 1,
356         .init = init,
357         .cleanup = cleanup,
358         .scan = scan,
359         .dev_list = dev_list,
360         .dev_clear = NULL,
361         .config_get = config_get,
362         .config_set = config_set,
363         .config_list = config_list,
364         .dev_open = dev_open,
365         .dev_close = dev_close,
366         .dev_acquisition_start = dev_acquisition_start,
367         .dev_acquisition_stop = dev_acquisition_stop,
368         .context = NULL,
369 };