2 * This file is part of the libsigrok project.
4 * Copyright (C) 2012 Bert Vermeulen <bert@biot.com>
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.
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.
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/>.
24 #include "libsigrok.h"
25 #include "libsigrok-internal.h"
28 #define LASCAR_VENDOR "Lascar"
29 #define LASCAR_INTERFACE 0
30 #define LASCAR_EP_IN 0x82
31 #define LASCAR_EP_OUT 2
32 /* Max 100ms for a device to positively identify. */
33 #define SCAN_TIMEOUT 100000
35 extern struct sr_dev_driver lascar_el_usb_driver_info;
36 static struct sr_dev_driver *di = &lascar_el_usb_driver_info;
38 static const struct elusb_profile profiles[] = {
39 { 1, "EL-USB-1", LOG_UNSUPPORTED },
40 { 2, "EL-USB-1", LOG_UNSUPPORTED },
41 { 3, "EL-USB-2", LOG_TEMP_RH },
42 { 4, "EL-USB-3", LOG_UNSUPPORTED },
43 { 5, "EL-USB-4", LOG_UNSUPPORTED },
44 { 6, "EL-USB-3", LOG_UNSUPPORTED },
45 { 7, "EL-USB-4", LOG_UNSUPPORTED },
46 { 8, "EL-USB-LITE", LOG_UNSUPPORTED },
47 { 9, "EL-USB-CO", LOG_CO },
48 { 10, "EL-USB-TC", LOG_UNSUPPORTED },
49 { 11, "EL-USB-CO300", LOG_UNSUPPORTED },
50 { 12, "EL-USB-2-LCD", LOG_UNSUPPORTED },
51 { 13, "EL-USB-2+", LOG_UNSUPPORTED },
52 { 14, "EL-USB-1-PRO", LOG_UNSUPPORTED },
53 { 15, "EL-USB-TC-LCD", LOG_UNSUPPORTED },
54 { 16, "EL-USB-2-LCD+", LOG_UNSUPPORTED },
55 { 17, "EL-USB-5", LOG_UNSUPPORTED },
56 { 18, "EL-USB-1-RCG", LOG_UNSUPPORTED },
57 { 19, "EL-USB-1-LCD", LOG_UNSUPPORTED },
58 { 20, "EL-OEM-3", LOG_UNSUPPORTED },
59 { 21, "EL-USB-1-LCD", LOG_UNSUPPORTED },
64 static void scan_xfer(struct libusb_transfer *xfer)
67 xfer->user_data = GINT_TO_POINTER(1);
71 static struct sr_dev_inst *lascar_identify(libusb_device_handle *dev_hdl)
73 struct drv_context *drvc;
74 const struct elusb_profile *profile;
75 struct sr_dev_inst *sdi;
76 struct libusb_transfer *xfer_in, *xfer_out;
79 int modelid, buflen, i;
80 unsigned char cmd[3], buf[256];
86 /* Some of these fail, but it needs doing -- some sort of mode
87 * setup for the SILabs F32x. */
88 libusb_control_transfer(dev_hdl, LIBUSB_REQUEST_TYPE_VENDOR,
89 0x00, 0xffff, 0x00, buf, 0, 50);
90 libusb_control_transfer(dev_hdl, LIBUSB_REQUEST_TYPE_VENDOR,
91 0x02, 0x0002, 0x00, buf, 0, 50);
92 libusb_control_transfer(dev_hdl, LIBUSB_REQUEST_TYPE_VENDOR,
93 0x02, 0x0001, 0x00, buf, 0, 50);
95 if (!(xfer_in = libusb_alloc_transfer(0)) ||
96 !(xfer_out = libusb_alloc_transfer(0)))
99 /* Flush anything the F321 still has queued. */
100 while (libusb_bulk_transfer(dev_hdl, LASCAR_EP_IN, buf, 256, &buflen,
101 5) == 0 && buflen > 0)
104 /* Keep a read request waiting in the wings, ready to pounce
105 * the moment the device sends something. */
106 libusb_fill_bulk_transfer(xfer_in, dev_hdl, LASCAR_EP_IN,
107 buf, 256, scan_xfer, 0, 10000);
108 if (libusb_submit_transfer(xfer_in) != 0)
111 /* Request device configuration structure. */
115 libusb_fill_bulk_transfer(xfer_out, dev_hdl, LASCAR_EP_OUT,
116 cmd, 3, scan_xfer, 0, 100);
117 if (libusb_submit_transfer(xfer_out) != 0)
122 start = g_get_monotonic_time();
123 while (!xfer_in->user_data || !xfer_out->user_data) {
124 if (g_get_monotonic_time() - start > SCAN_TIMEOUT) {
129 libusb_handle_events_timeout(drvc->sr_ctx->libusb_ctx, &tv);
132 sr_dbg("no response");
135 if (xfer_in->actual_length != 3) {
136 sr_dbg("expected 3-byte header, got %d bytes", xfer_in->actual_length);
140 /* Got configuration structure header. */
141 sr_spew("response to config request: 0x%.2x 0x%.2x 0x%.2x ",
142 buf[0], buf[1], buf[2]);
143 buflen = buf[1] | (buf[2] << 8);
144 if (buf[0] != 0x02 || buflen > 256) {
145 sr_dbg("Invalid response to config request: "
146 "0x%.2x 0x%.2x 0x%.2x ", buf[0], buf[1], buf[2]);
147 libusb_close(dev_hdl);
151 /* Get configuration structure. */
152 xfer_in->length = buflen;
153 xfer_in->user_data = 0;
154 if (libusb_submit_transfer(xfer_in) != 0)
156 while (!xfer_in->user_data) {
157 if (g_get_monotonic_time() - start > SCAN_TIMEOUT) {
162 libusb_handle_events_timeout(drvc->sr_ctx->libusb_ctx, &tv);
165 sr_dbg("Timeout waiting for configuration structure.");
168 if (xfer_in->actual_length != buflen) {
169 sr_dbg("expected %d-byte structure, got %d bytes", buflen,
170 xfer_in->actual_length);
176 if (!xfer_in->user_data || !xfer_in->user_data) {
177 if (!xfer_in->user_data)
178 libusb_cancel_transfer(xfer_in);
179 if (!xfer_out->user_data)
180 libusb_cancel_transfer(xfer_out);
181 start = g_get_monotonic_time();
182 while (!xfer_in->user_data || !xfer_out->user_data) {
183 if (g_get_monotonic_time() - start > 10000)
186 libusb_handle_events_timeout(drvc->sr_ctx->libusb_ctx, &tv);
189 libusb_free_transfer(xfer_in);
190 libusb_free_transfer(xfer_out);
195 for (i = 0; profiles[i].modelid; i++) {
196 if (profiles[i].modelid == modelid) {
197 profile = &profiles[i];
202 sr_dbg("unknown EL-USB modelid %d", modelid);
206 i = buf[52] | (buf[53] << 8);
207 memcpy(firmware, buf + 0x30, 4);
209 sr_dbg("found %s with firmware version %s serial %d",
210 profile->modelname, firmware, i);
212 if (profile->logformat == LOG_UNSUPPORTED) {
213 sr_dbg("unsupported EL-USB logformat for %s", profile->modelname);
217 if (!(sdi = sr_dev_inst_new(0, SR_ST_INACTIVE, LASCAR_VENDOR,
218 profile->modelname, firmware)))
226 SR_PRIV struct sr_dev_inst *lascar_scan(int bus, int address)
228 struct drv_context *drvc;
229 struct sr_dev_inst *sdi;
230 struct libusb_device **devlist;
231 struct libusb_device_descriptor des;
232 libusb_device_handle *dev_hdl;
238 libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist);
239 for (i = 0; devlist[i]; i++) {
240 if ((ret = libusb_get_device_descriptor(devlist[i], &des))) {
241 sr_err("Failed to get device descriptor: %d.", ret);
245 if (libusb_get_bus_number(devlist[i]) != bus ||
246 libusb_get_device_address(devlist[i]) != address)
249 if ((ret = libusb_open(devlist[i], &dev_hdl)) != 0) {
250 sr_dbg("failed to open device for scan: %s",
251 libusb_error_name(ret));
255 sdi = lascar_identify(dev_hdl);
256 libusb_close(dev_hdl);
263 SR_PRIV int lascar_el_usb_receive_data(int fd, int revents, void *cb_data)
265 const struct sr_dev_inst *sdi;
266 struct dev_context *devc;
268 if (!(sdi = cb_data))
271 if (!(devc = sdi->priv))
274 if (revents == G_IO_IN) {