]> sigrok.org Git - libsigrok.git/blame - src/hardware/kingst-la2016/api.c
kingst-la2016: rework acquisition limits, improve CLI use
[libsigrok.git] / src / hardware / kingst-la2016 / api.c
CommitLineData
f2cd2deb
FS
1/*
2 * This file is part of the libsigrok project.
3 *
4 * Copyright (C) 2020 Florian Schmidt <schmidt_florian@gmx.de>
5 * Copyright (C) 2013 Marcus Comstedt <marcus@mc.pp.se>
6 * Copyright (C) 2013 Bert Vermeulen <bert@biot.com>
7 * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
8 *
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22
96dc954e
GS
23/*
24 * This driver implementation initially was derived from the
25 * src/hardware/saleae-logic16/ source code.
26 */
f2cd2deb
FS
27
28#include <config.h>
a7740b06 29
a7740b06 30#include <libsigrok/libsigrok.h>
f2cd2deb 31#include <string.h>
a7740b06 32
f2cd2deb
FS
33#include "libsigrok-internal.h"
34#include "protocol.h"
35
36static const uint32_t scanopts[] = {
37 SR_CONF_CONN,
38};
39
40static const uint32_t drvopts[] = {
41 SR_CONF_LOGIC_ANALYZER,
42};
43
44static const uint32_t devopts[] = {
45 /* TODO: SR_CONF_CONTINUOUS, */
46 SR_CONF_CONN | SR_CONF_GET,
47 SR_CONF_SAMPLERATE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
a38f0f5e
GS
48 SR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
49 SR_CONF_LIMIT_MSEC | SR_CONF_GET | SR_CONF_SET,
f2cd2deb
FS
50 SR_CONF_VOLTAGE_THRESHOLD | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
51 SR_CONF_LOGIC_THRESHOLD | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
52 SR_CONF_LOGIC_THRESHOLD_CUSTOM | SR_CONF_GET | SR_CONF_SET,
53 SR_CONF_TRIGGER_MATCH | SR_CONF_LIST,
54 SR_CONF_CAPTURE_RATIO | SR_CONF_GET | SR_CONF_SET,
55};
56
57static const int32_t trigger_matches[] = {
58 SR_TRIGGER_ZERO,
59 SR_TRIGGER_ONE,
60 SR_TRIGGER_RISING,
61 SR_TRIGGER_FALLING,
62};
63
d466f61c 64static const char *channel_names_logic[] = {
da25c287
GS
65 "CH0", "CH1", "CH2", "CH3", "CH4", "CH5", "CH6", "CH7",
66 "CH8", "CH9", "CH10", "CH11", "CH12", "CH13", "CH14", "CH15",
d466f61c
GS
67 "CH16", "CH17", "CH18", "CH19", "CH20", "CH21", "CH22", "CH23",
68 "CH24", "CH25", "CH26", "CH27", "CH28", "CH29", "CH30", "CH31",
f2cd2deb
FS
69};
70
ea436ba7 71/*
330853ba 72 * The hardware uses a 100/200/500MHz base clock (model dependent) and
ea436ba7
GS
73 * a 16bit divider (common across all models). The range from 10kHz to
74 * 100/200/500MHz should be applicable to all devices. High rates may
75 * suffer from coarse resolution (e.g. in the "500MHz div 2" case) and
330853ba
GS
76 * may not provide the desired 1/2/5 steps. Fortunately this exclusively
77 * affects the 500MHz model where 250MHz is used instead of 200MHz and
78 * the 166MHz and 125MHz rates are not presented to users. Deep memory
79 * of these models and hardware compression reduce the necessity to let
80 * users pick from a huge list of possible rates.
81 *
ea436ba7
GS
82 */
83
330853ba
GS
84static const uint64_t rates_500mhz[] = {
85 SR_KHZ(10),
86 SR_KHZ(20),
87 SR_KHZ(50),
88 SR_KHZ(100),
89 SR_KHZ(200),
90 SR_KHZ(500),
91 SR_MHZ(1),
92 SR_MHZ(2),
93 SR_MHZ(5),
94 SR_MHZ(10),
95 SR_MHZ(20),
96 SR_MHZ(50),
97 SR_MHZ(100),
98 SR_MHZ(250),
99 SR_MHZ(500),
100};
101
102static const uint64_t rates_200mhz[] = {
ea436ba7 103 SR_KHZ(10),
f2cd2deb
FS
104 SR_KHZ(20),
105 SR_KHZ(50),
106 SR_KHZ(100),
107 SR_KHZ(200),
108 SR_KHZ(500),
109 SR_MHZ(1),
110 SR_MHZ(2),
f2cd2deb 111 SR_MHZ(5),
f2cd2deb
FS
112 SR_MHZ(10),
113 SR_MHZ(20),
114 SR_MHZ(50),
115 SR_MHZ(100),
116 SR_MHZ(200),
117};
118
330853ba 119static const uint64_t rates_100mhz[] = {
ea436ba7 120 SR_KHZ(10),
8b172e78
KG
121 SR_KHZ(20),
122 SR_KHZ(50),
123 SR_KHZ(100),
124 SR_KHZ(200),
125 SR_KHZ(500),
126 SR_MHZ(1),
127 SR_MHZ(2),
8b172e78 128 SR_MHZ(5),
8b172e78
KG
129 SR_MHZ(10),
130 SR_MHZ(20),
131 SR_MHZ(50),
132 SR_MHZ(100),
133};
134
f2cd2deb
FS
135static const float logic_threshold_value[] = {
136 1.58,
137 2.5,
138 1.165,
139 1.5,
140 1.25,
141 0.9,
142 0.75,
143 0.60,
144 0.45,
145};
146
147static const char *logic_threshold[] = {
148 "TTL 5V",
149 "CMOS 5V",
150 "CMOS 3.3V",
151 "CMOS 3.0V",
152 "CMOS 2.5V",
153 "CMOS 1.8V",
154 "CMOS 1.5V",
155 "CMOS 1.2V",
156 "CMOS 0.9V",
157 "USER",
158};
159
da2cb50d 160#define LOGIC_THRESHOLD_IDX_USER (ARRAY_SIZE(logic_threshold) - 1)
f2cd2deb 161
d466f61c
GS
162/* Convenience. Release an allocated devc from error paths. */
163static void kingst_la2016_free_devc(struct dev_context *devc)
164{
165 if (!devc)
166 return;
167 g_free(devc->mcu_firmware);
168 g_free(devc->fpga_bitstream);
169 g_free(devc);
170}
171
172/* Convenience. Release an allocated sdi from error paths. */
173static void kingst_la2016_free_sdi(struct sr_dev_inst *sdi)
174{
175 if (!sdi)
176 return;
177 g_free(sdi->vendor);
178 g_free(sdi->model);
179 g_free(sdi->version);
180 g_free(sdi->serial_num);
181 g_free(sdi->connection_id);
182 sr_usb_dev_inst_free(sdi->conn);
183 kingst_la2016_free_devc(sdi->priv);
184}
185
186/* Convenience. Open a USB device (including claiming an interface). */
187static int la2016_open_usb(struct sr_usb_dev_inst *usb,
188 libusb_device *dev, gboolean show_message)
189{
190 int ret;
191
192 ret = libusb_open(dev, &usb->devhdl);
193 if (ret != 0) {
194 if (show_message) {
195 sr_err("Cannot open device: %s.",
196 libusb_error_name(ret));
197 }
198 return SR_ERR_IO;
199 }
200
201 if (usb->address == 0xff) {
202 /*
203 * First encounter after firmware upload.
204 * Grab current address after enumeration.
205 */
206 usb->address = libusb_get_device_address(dev);
207 }
208
209 ret = libusb_claim_interface(usb->devhdl, USB_INTERFACE);
210 if (ret == LIBUSB_ERROR_BUSY) {
211 sr_err("Cannot claim USB interface. Another program or driver using it?");
212 return SR_ERR_IO;
213 } else if (ret == LIBUSB_ERROR_NO_DEVICE) {
214 sr_err("Device has been disconnected.");
215 return SR_ERR_IO;
216 } else if (ret != 0) {
217 sr_err("Cannot claim USB interface: %s.",
218 libusb_error_name(ret));
219 return SR_ERR_IO;
220 }
221
222 return SR_OK;
223}
224
225/* Convenience. Close an opened USB device (and release the interface). */
226static void la2016_close_usb(struct sr_usb_dev_inst *usb)
227{
228
229 if (!usb)
230 return;
231
232 if (usb->devhdl) {
233 libusb_release_interface(usb->devhdl, USB_INTERFACE);
234 libusb_close(usb->devhdl);
235 usb->devhdl = NULL;
236 }
237}
238
239/* Communicate to an USB device to identify the Kingst LA model. */
240static int la2016_identify_read(struct sr_dev_inst *sdi,
241 struct sr_usb_dev_inst *usb, libusb_device *dev,
242 gboolean show_message)
243{
244 int ret;
245
246 ret = la2016_open_usb(usb, dev, show_message);
247 if (ret != SR_OK) {
248 if (show_message)
249 sr_err("Cannot communicate to MCU firmware.");
250 return ret;
251 }
252 ret = la2016_identify_device(sdi, show_message);
253 la2016_close_usb(usb);
254
255 return ret;
256}
257
258/* Find given conn_id in another USB enum. Identify Kingst LA model. */
259static int la2016_identify_enum(struct sr_dev_inst *sdi)
260{
261 struct sr_dev_driver *di;
262 struct drv_context *drvc;
263 struct sr_context *ctx;
264 libusb_device **devlist, *dev;
265 struct libusb_device_descriptor des;
266 int ret, id_ret;
267 size_t device_count, dev_idx;
268 char conn_id[64];
269
270 di = sdi->driver;
271 drvc = di->context;
272 ctx = drvc->sr_ctx;;
273
274 ret = libusb_get_device_list(ctx->libusb_ctx, &devlist);
275 if (ret < 0)
276 return SR_ERR_IO;
277 device_count = ret;
278 if (!device_count)
279 return SR_ERR_IO;
280 id_ret = SR_ERR_IO;
281 for (dev_idx = 0; dev_idx < device_count; dev_idx++) {
282 dev = devlist[dev_idx];
283 libusb_get_device_descriptor(dev, &des);
284 if (des.idVendor != LA2016_VID || des.idProduct != LA2016_PID)
285 continue;
286 if (des.iProduct != LA2016_IPRODUCT_INDEX)
287 continue;
288 ret = usb_get_port_path(dev, conn_id, sizeof(conn_id));
289 if (ret < 0)
290 continue;
291 if (strcmp(sdi->connection_id, conn_id) != 0)
292 continue;
293 id_ret = la2016_identify_read(sdi, sdi->conn, dev, FALSE);
294 break;
295 }
296 libusb_free_device_list(devlist, 1);
297
298 return id_ret;
299}
300
301/* Wait for a device to re-appear after firmware upload. */
302static int la2016_identify_wait(struct sr_dev_inst *sdi)
303{
304 struct dev_context *devc;
305 uint64_t reset_done, now, elapsed_ms;
306 int ret;
307
308 devc = sdi->priv;
309
310 sr_info("Waiting for device to reset after firmware upload.");
311 now = g_get_monotonic_time();
312 reset_done = devc->fw_uploaded + RENUM_GONE_DELAY_MS * 1000;
313 if (now < reset_done)
314 g_usleep(reset_done - now);
315 do {
316 now = g_get_monotonic_time();
317 elapsed_ms = (now - devc->fw_uploaded) / 1000;
318 sr_spew("Waited %" PRIu64 "ms.", elapsed_ms);
319 ret = la2016_identify_enum(sdi);
320 if (ret == SR_OK) {
321 devc->fw_uploaded = 0;
322 break;
323 }
324 g_usleep(RENUM_POLL_INTERVAL_MS * 1000);
325 } while (elapsed_ms < RENUM_CHECK_PERIOD_MS);
326 if (ret != SR_OK) {
327 sr_err("Device failed to re-enumerate.");
328 return ret;
329 }
330 sr_info("Device came back after %" PRIi64 "ms.", elapsed_ms);
331
332 return SR_OK;
333}
334
335/*
336 * Open given conn_id from another USB enum. Used by dev_open(). Similar
337 * to, and should be kept in sync with la2016_identify_enum().
338 */
339static int la2016_open_enum(struct sr_dev_inst *sdi)
340{
341 struct sr_dev_driver *di;
342 struct drv_context *drvc;
343 struct sr_context *ctx;
344 libusb_device **devlist, *dev;
345 struct libusb_device_descriptor des;
346 int ret, open_ret;
347 size_t device_count, dev_idx;
348 char conn_id[64];
349
350 di = sdi->driver;
351 drvc = di->context;
352 ctx = drvc->sr_ctx;;
353
354 ret = libusb_get_device_list(ctx->libusb_ctx, &devlist);
355 if (ret < 0)
356 return SR_ERR_IO;
357 device_count = ret;
358 if (!device_count)
359 return SR_ERR_IO;
360 open_ret = SR_ERR_IO;
361 for (dev_idx = 0; dev_idx < device_count; dev_idx++) {
362 dev = devlist[dev_idx];
363 libusb_get_device_descriptor(dev, &des);
364 if (des.idVendor != LA2016_VID || des.idProduct != LA2016_PID)
365 continue;
366 if (des.iProduct != LA2016_IPRODUCT_INDEX)
367 continue;
368 ret = usb_get_port_path(dev, conn_id, sizeof(conn_id));
369 if (ret < 0)
370 continue;
371 if (strcmp(sdi->connection_id, conn_id) != 0)
372 continue;
373 open_ret = la2016_open_usb(sdi->conn, dev, TRUE);
374 break;
375 }
376 libusb_free_device_list(devlist, 1);
377
378 return open_ret;
379}
380
f2cd2deb
FS
381static GSList *scan(struct sr_dev_driver *di, GSList *options)
382{
383 struct drv_context *drvc;
520a20e9 384 struct sr_context *ctx;
f2cd2deb
FS
385 struct dev_context *devc;
386 struct sr_dev_inst *sdi;
387 struct sr_usb_dev_inst *usb;
388 struct sr_config *src;
389 GSList *l;
d466f61c 390 GSList *devices, *found_devices, *renum_devices;
f2cd2deb
FS
391 GSList *conn_devices;
392 struct libusb_device_descriptor des;
520a20e9
GS
393 libusb_device **devlist, *dev;
394 size_t dev_count, dev_idx, ch_idx;
395 uint8_t bus, addr;
d466f61c 396 uint16_t pid;
f2cd2deb 397 const char *conn;
520a20e9 398 char conn_id[64];
520a20e9 399 int ret;
d466f61c 400 size_t ch_off, ch_max;
f2cd2deb
FS
401
402 drvc = di->context;
520a20e9 403 ctx = drvc->sr_ctx;;
f2cd2deb
FS
404
405 conn = NULL;
d466f61c 406 conn_devices = NULL;
f2cd2deb
FS
407 for (l = options; l; l = l->next) {
408 src = l->data;
409 switch (src->key) {
410 case SR_CONF_CONN:
411 conn = g_variant_get_string(src->data, NULL);
412 break;
413 }
414 }
415 if (conn)
520a20e9 416 conn_devices = sr_usb_find(ctx->libusb_ctx, conn);
d466f61c
GS
417 if (conn && !conn_devices) {
418 sr_err("Cannot find the specified connection '%s'.", conn);
419 return NULL;
420 }
f2cd2deb 421
d466f61c
GS
422 /*
423 * Find all LA2016 devices, optionally upload firmware to them.
424 * Defer completion of sdi/devc creation until all (selected)
425 * devices were found in a usable state, and their models got
426 * identified which affect their feature set. It appears that
427 * we cannot communicate to the device within the same USB enum
428 * cycle, needs another USB enumeration after firmware upload.
429 */
f2cd2deb 430 devices = NULL;
d466f61c
GS
431 found_devices = NULL;
432 renum_devices = NULL;
520a20e9
GS
433 ret = libusb_get_device_list(ctx->libusb_ctx, &devlist);
434 if (ret < 0) {
435 sr_err("Cannot get device list: %s.", libusb_error_name(ret));
436 return devices;
437 }
438 dev_count = ret;
439 for (dev_idx = 0; dev_idx < dev_count; dev_idx++) {
440 dev = devlist[dev_idx];
441 bus = libusb_get_bus_number(dev);
442 addr = libusb_get_device_address(dev);
d466f61c
GS
443
444 /* Filter by connection when externally specified. */
445 for (l = conn_devices; l; l = l->next) {
446 usb = l->data;
447 if (usb->bus == bus && usb->address == addr)
448 break;
449 }
450 if (conn_devices && !l) {
451 sr_spew("Bus %hhu, addr %hhu do not match specified filter.",
452 bus, addr);
453 continue;
f2cd2deb
FS
454 }
455
d466f61c 456 /* Check USB VID:PID. Get the connection string. */
520a20e9 457 libusb_get_device_descriptor(dev, &des);
d466f61c
GS
458 if (des.idVendor != LA2016_VID || des.idProduct != LA2016_PID)
459 continue;
460 pid = des.idProduct;
520a20e9
GS
461 ret = usb_get_port_path(dev, conn_id, sizeof(conn_id));
462 if (ret < 0)
f2cd2deb 463 continue;
d466f61c
GS
464 sr_dbg("USB enum found %04x:%04x at path %s, %d.%d.",
465 des.idVendor, des.idProduct, conn_id, bus, addr);
466 usb = sr_usb_dev_inst_new(bus, addr, NULL);
f2cd2deb 467
520a20e9 468 sdi = g_malloc0(sizeof(*sdi));
d466f61c 469 sdi->driver = di;
f2cd2deb 470 sdi->status = SR_ST_INITIALIZING;
d466f61c 471 sdi->inst_type = SR_INST_USB;
520a20e9 472 sdi->connection_id = g_strdup(conn_id);
d466f61c 473 sdi->conn = usb;
f2cd2deb 474
d466f61c
GS
475 devc = g_malloc0(sizeof(*devc));
476 sdi->priv = devc;
f2cd2deb 477
d466f61c
GS
478 /*
479 * Load MCU firmware if it is currently missing. Which
480 * makes the device disappear and renumerate in USB.
481 * We need to come back another time to communicate to
482 * this device.
483 */
484 devc->fw_uploaded = 0;
485 if (des.iProduct != LA2016_IPRODUCT_INDEX) {
486 sr_info("Uploading MCU firmware to '%s'.", conn_id);
487 ret = la2016_upload_firmware(sdi, ctx, dev, pid);
520a20e9 488 if (ret != SR_OK) {
91f73872 489 sr_err("MCU firmware upload failed.");
d466f61c 490 kingst_la2016_free_sdi(sdi);
f2cd2deb
FS
491 continue;
492 }
d466f61c
GS
493 devc->fw_uploaded = g_get_monotonic_time();
494 usb->address = 0xff;
495 renum_devices = g_slist_append(renum_devices, sdi);
496 continue;
f2cd2deb
FS
497 }
498
d466f61c
GS
499 /*
500 * Communicate to the MCU firmware to access EEPROM data
501 * which lets us identify the device type. Then stop, to
502 * share remaining sdi/devc creation with those devices
503 * which had their MCU firmware uploaded above and which
504 * get revisited later.
505 */
506 ret = la2016_identify_read(sdi, usb, dev, TRUE);
507 if (ret != SR_OK || !devc->model) {
508 sr_err("Unknown or unsupported device type.");
509 kingst_la2016_free_sdi(sdi);
510 continue;
511 }
512 found_devices = g_slist_append(found_devices, sdi);
513 }
514 libusb_free_device_list(devlist, 1);
515 g_slist_free_full(conn_devices, sr_usb_dev_inst_free_cb);
f2cd2deb 516
d466f61c
GS
517 /*
518 * Wait for devices to re-appear after firmware upload. Append
519 * the yet unidentified device to the list of found devices, or
520 * release the previously allocated sdi/devc.
521 */
522 for (l = renum_devices; l; l = l->next) {
523 sdi = l->data;
524 devc = sdi->priv;
525 ret = la2016_identify_wait(sdi);
526 if (ret != SR_OK || !devc->model) {
527 sr_dbg("Skipping unusable '%s'.", sdi->connection_id);
528 kingst_la2016_free_sdi(sdi);
529 continue;
520a20e9 530 }
d466f61c
GS
531 found_devices = g_slist_append(found_devices, sdi);
532 }
533 g_slist_free(renum_devices);
f2cd2deb 534
d466f61c
GS
535 /*
536 * All found devices got identified, their type is known here.
537 * Complete the sdi/devc creation. Assign default settings
538 * because the vendor firmware would not let us read back the
539 * previously written configuration.
540 */
541 for (l = found_devices; l; l = l->next) {
542 sdi = l->data;
543 devc = sdi->priv;
544
545 sdi->vendor = g_strdup("Kingst");
546 sdi->model = g_strdup(devc->model->name);
547 ch_off = 0;
548
549 /* Create the logic channels. */
550 ch_max = ARRAY_SIZE(channel_names_logic);
551 if (ch_max > devc->model->channel_count)
552 ch_max = devc->model->channel_count;
553 for (ch_idx = 0; ch_idx < ch_max; ch_idx++) {
554 sr_channel_new(sdi, ch_off,
555 SR_CHANNEL_LOGIC, TRUE,
556 channel_names_logic[ch_idx]);
557 ch_off++;
558 }
f2cd2deb 559
a38f0f5e 560 sr_sw_limits_init(&devc->sw_limits);
d8fbfcd9
GS
561 devc->sw_limits.limit_samples = 0;
562 devc->capture_ratio = 50;
563 devc->cur_samplerate = devc->model->samplerate;
f2cd2deb
FS
564 devc->threshold_voltage_idx = 0;
565 devc->threshold_voltage = logic_threshold_value[devc->threshold_voltage_idx];
566
567 sdi->status = SR_ST_INACTIVE;
d466f61c 568 devices = g_slist_append(devices, sdi);
f2cd2deb 569 }
d466f61c 570 g_slist_free(found_devices);
f2cd2deb
FS
571
572 return std_scan_complete(di, devices);
573}
574
f2cd2deb
FS
575static int dev_open(struct sr_dev_inst *sdi)
576{
f2cd2deb
FS
577 int ret;
578
d466f61c 579 ret = la2016_open_enum(sdi);
f2cd2deb 580 if (ret != SR_OK) {
91f73872 581 sr_err("Cannot open device.");
520a20e9 582 return ret;
f2cd2deb
FS
583 }
584
585 return SR_OK;
586}
587
588static int dev_close(struct sr_dev_inst *sdi)
589{
590 struct sr_usb_dev_inst *usb;
591
592 usb = sdi->conn;
593
594 if (!usb->devhdl)
595 return SR_ERR_BUG;
596
597 la2016_deinit_device(sdi);
598
599 sr_info("Closing device on %d.%d (logical) / %s (physical) interface %d.",
600 usb->bus, usb->address, sdi->connection_id, USB_INTERFACE);
d466f61c 601 la2016_close_usb(sdi->conn);
f2cd2deb
FS
602
603 return SR_OK;
604}
605
955ab604
GS
606static int config_get(uint32_t key, GVariant **data,
607 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
f2cd2deb
FS
608{
609 struct dev_context *devc;
610 struct sr_usb_dev_inst *usb;
611 double rounded;
da2cb50d 612 const char *label;
f2cd2deb
FS
613
614 (void)cg;
615
616 if (!sdi)
617 return SR_ERR_ARG;
618 devc = sdi->priv;
619
620 switch (key) {
621 case SR_CONF_CONN:
622 if (!sdi->conn)
623 return SR_ERR_ARG;
624 usb = sdi->conn;
96dc954e
GS
625 if (usb->address == 0xff) {
626 /*
627 * Device still needs to re-enumerate after firmware
628 * upload, so we don't know its (future) address.
629 */
f2cd2deb 630 return SR_ERR;
955ab604 631 }
f2cd2deb
FS
632 *data = g_variant_new_printf("%d.%d", usb->bus, usb->address);
633 break;
634 case SR_CONF_SAMPLERATE:
635 *data = g_variant_new_uint64(devc->cur_samplerate);
636 break;
637 case SR_CONF_LIMIT_SAMPLES:
a38f0f5e
GS
638 case SR_CONF_LIMIT_MSEC:
639 return sr_sw_limits_config_get(&devc->sw_limits, key, data);
f2cd2deb
FS
640 case SR_CONF_CAPTURE_RATIO:
641 *data = g_variant_new_uint64(devc->capture_ratio);
642 break;
643 case SR_CONF_VOLTAGE_THRESHOLD:
644 rounded = (int)(devc->threshold_voltage / 0.1) * 0.1;
645 *data = std_gvar_tuple_double(rounded, rounded + 0.1);
646 return SR_OK;
647 case SR_CONF_LOGIC_THRESHOLD:
da2cb50d
GS
648 label = logic_threshold[devc->threshold_voltage_idx];
649 *data = g_variant_new_string(label);
f2cd2deb
FS
650 break;
651 case SR_CONF_LOGIC_THRESHOLD_CUSTOM:
652 *data = g_variant_new_double(devc->threshold_voltage);
653 break;
955ab604 654
f2cd2deb
FS
655 default:
656 return SR_ERR_NA;
657 }
658
659 return SR_OK;
660}
661
955ab604
GS
662static int config_set(uint32_t key, GVariant *data,
663 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
f2cd2deb
FS
664{
665 struct dev_context *devc;
666 double low, high;
667 int idx;
668
669 (void)cg;
670
671 devc = sdi->priv;
672
673 switch (key) {
674 case SR_CONF_SAMPLERATE:
675 devc->cur_samplerate = g_variant_get_uint64(data);
676 break;
677 case SR_CONF_LIMIT_SAMPLES:
a38f0f5e
GS
678 case SR_CONF_LIMIT_MSEC:
679 return sr_sw_limits_config_set(&devc->sw_limits, key, data);
f2cd2deb
FS
680 case SR_CONF_CAPTURE_RATIO:
681 devc->capture_ratio = g_variant_get_uint64(data);
682 break;
683 case SR_CONF_VOLTAGE_THRESHOLD:
684 g_variant_get(data, "(dd)", &low, &high);
685 devc->threshold_voltage = (low + high) / 2.0;
da2cb50d 686 devc->threshold_voltage_idx = LOGIC_THRESHOLD_IDX_USER;
f2cd2deb
FS
687 break;
688 case SR_CONF_LOGIC_THRESHOLD: {
411ad77c
GS
689 idx = std_str_idx(data, ARRAY_AND_SIZE(logic_threshold));
690 if (idx < 0)
f2cd2deb 691 return SR_ERR_ARG;
da2cb50d 692 if (idx != LOGIC_THRESHOLD_IDX_USER) {
f2cd2deb
FS
693 devc->threshold_voltage = logic_threshold_value[idx];
694 }
695 devc->threshold_voltage_idx = idx;
696 break;
697 }
698 case SR_CONF_LOGIC_THRESHOLD_CUSTOM:
699 devc->threshold_voltage = g_variant_get_double(data);
700 break;
701 default:
702 return SR_ERR_NA;
703 }
704
705 return SR_OK;
706}
707
955ab604
GS
708static int config_list(uint32_t key, GVariant **data,
709 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
f2cd2deb 710{
8b172e78
KG
711 struct dev_context *devc;
712
a38f0f5e
GS
713 devc = sdi ? sdi->priv : NULL;
714
f2cd2deb
FS
715 switch (key) {
716 case SR_CONF_SCAN_OPTIONS:
717 case SR_CONF_DEVICE_OPTIONS:
411ad77c
GS
718 return STD_CONFIG_LIST(key, data, sdi, cg,
719 scanopts, drvopts, devopts);
f2cd2deb 720 case SR_CONF_SAMPLERATE:
fb28e72d
MW
721 if (!sdi)
722 return SR_ERR_ARG;
d466f61c 723 if (devc->model->samplerate == SR_MHZ(500))
330853ba 724 *data = std_gvar_samplerates(ARRAY_AND_SIZE(rates_500mhz));
d466f61c 725 else if (devc->model->samplerate == SR_MHZ(200))
330853ba
GS
726 *data = std_gvar_samplerates(ARRAY_AND_SIZE(rates_200mhz));
727 else
728 *data = std_gvar_samplerates(ARRAY_AND_SIZE(rates_100mhz));
f2cd2deb
FS
729 break;
730 case SR_CONF_LIMIT_SAMPLES:
d8fbfcd9 731 *data = std_gvar_tuple_u64(0, LA2016_NUM_SAMPLES_MAX);
f2cd2deb
FS
732 break;
733 case SR_CONF_VOLTAGE_THRESHOLD:
734 *data = std_gvar_min_max_step_thresholds(
735 LA2016_THR_VOLTAGE_MIN,
736 LA2016_THR_VOLTAGE_MAX, 0.1);
737 break;
738 case SR_CONF_TRIGGER_MATCH:
739 *data = std_gvar_array_i32(ARRAY_AND_SIZE(trigger_matches));
740 break;
741 case SR_CONF_LOGIC_THRESHOLD:
da2cb50d 742 *data = g_variant_new_strv(ARRAY_AND_SIZE(logic_threshold));
f2cd2deb
FS
743 break;
744 default:
745 return SR_ERR_NA;
746 }
747
748 return SR_OK;
749}
750
f2cd2deb
FS
751static int dev_acquisition_start(const struct sr_dev_inst *sdi)
752{
753 struct sr_dev_driver *di;
754 struct drv_context *drvc;
520a20e9 755 struct sr_context *ctx;
f2cd2deb
FS
756 struct dev_context *devc;
757 int ret;
758
759 di = sdi->driver;
760 drvc = di->context;
520a20e9 761 ctx = drvc->sr_ctx;;
f2cd2deb
FS
762 devc = sdi->priv;
763
a38f0f5e
GS
764 if (!devc->feed_queue) {
765 devc->feed_queue = feed_queue_logic_alloc(sdi,
766 LA2016_CONVBUFFER_SIZE, sizeof(uint16_t));
767 if (!devc->feed_queue) {
768 sr_err("Cannot allocate buffer for session feed.");
769 return SR_ERR_MALLOC;
770 }
f2cd2deb
FS
771 }
772
a38f0f5e
GS
773 sr_sw_limits_acquisition_start(&devc->sw_limits);
774
411ad77c
GS
775 ret = la2016_setup_acquisition(sdi);
776 if (ret != SR_OK) {
a38f0f5e
GS
777 feed_queue_logic_free(devc->feed_queue);
778 devc->feed_queue = NULL;
f2cd2deb
FS
779 return ret;
780 }
781
411ad77c
GS
782 ret = la2016_start_acquisition(sdi);
783 if (ret != SR_OK) {
3ebc1cb2 784 la2016_abort_acquisition(sdi);
a38f0f5e
GS
785 feed_queue_logic_free(devc->feed_queue);
786 devc->feed_queue = NULL;
f2cd2deb
FS
787 return ret;
788 }
789
cf057ac4 790 devc->completion_seen = FALSE;
520a20e9 791 usb_source_add(sdi->session, ctx, 50,
388438e4 792 la2016_receive_data, (void *)sdi);
f2cd2deb
FS
793
794 std_session_send_df_header(sdi);
795
796 return SR_OK;
797}
798
799static int dev_acquisition_stop(struct sr_dev_inst *sdi)
800{
801 int ret;
802
803 ret = la2016_abort_acquisition(sdi);
f2cd2deb
FS
804
805 return ret;
806}
807
808static struct sr_dev_driver kingst_la2016_driver_info = {
809 .name = "kingst-la2016",
810 .longname = "Kingst LA2016",
811 .api_version = 1,
812 .init = std_init,
813 .cleanup = std_cleanup,
814 .scan = scan,
815 .dev_list = std_dev_list,
816 .dev_clear = std_dev_clear,
817 .config_get = config_get,
818 .config_set = config_set,
819 .config_list = config_list,
820 .dev_open = dev_open,
821 .dev_close = dev_close,
822 .dev_acquisition_start = dev_acquisition_start,
823 .dev_acquisition_stop = dev_acquisition_stop,
824 .context = NULL,
825};
826SR_REGISTER_DEV_DRIVER(kingst_la2016_driver_info);