]> sigrok.org Git - libsigrok.git/blame - src/hardware/kingst-la2016/api.c
kingst-la2016: adjust config param checks, threshold range check
[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,
331277e0 42 SR_CONF_SIGNAL_GENERATOR,
f2cd2deb
FS
43};
44
45static const uint32_t devopts[] = {
46 /* TODO: SR_CONF_CONTINUOUS, */
47 SR_CONF_CONN | SR_CONF_GET,
48 SR_CONF_SAMPLERATE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
a38f0f5e
GS
49 SR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
50 SR_CONF_LIMIT_MSEC | SR_CONF_GET | SR_CONF_SET,
f2cd2deb
FS
51 SR_CONF_VOLTAGE_THRESHOLD | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
52 SR_CONF_LOGIC_THRESHOLD | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
53 SR_CONF_LOGIC_THRESHOLD_CUSTOM | SR_CONF_GET | SR_CONF_SET,
54 SR_CONF_TRIGGER_MATCH | SR_CONF_LIST,
55 SR_CONF_CAPTURE_RATIO | SR_CONF_GET | SR_CONF_SET,
56};
57
331277e0
GS
58static const uint32_t devopts_cg_pwm[] = {
59 SR_CONF_ENABLED | SR_CONF_GET | SR_CONF_SET,
60 SR_CONF_OUTPUT_FREQUENCY | SR_CONF_GET | SR_CONF_SET,
61 SR_CONF_DUTY_CYCLE | SR_CONF_GET | SR_CONF_SET,
62};
63
f2cd2deb
FS
64static const int32_t trigger_matches[] = {
65 SR_TRIGGER_ZERO,
66 SR_TRIGGER_ONE,
67 SR_TRIGGER_RISING,
68 SR_TRIGGER_FALLING,
69};
70
d466f61c 71static const char *channel_names_logic[] = {
da25c287
GS
72 "CH0", "CH1", "CH2", "CH3", "CH4", "CH5", "CH6", "CH7",
73 "CH8", "CH9", "CH10", "CH11", "CH12", "CH13", "CH14", "CH15",
d466f61c
GS
74 "CH16", "CH17", "CH18", "CH19", "CH20", "CH21", "CH22", "CH23",
75 "CH24", "CH25", "CH26", "CH27", "CH28", "CH29", "CH30", "CH31",
f2cd2deb
FS
76};
77
331277e0
GS
78static const char *channel_names_pwm[] = {
79 "PWM1", "PWM2",
80};
81
ea436ba7 82/*
330853ba 83 * The hardware uses a 100/200/500MHz base clock (model dependent) and
ea436ba7
GS
84 * a 16bit divider (common across all models). The range from 10kHz to
85 * 100/200/500MHz should be applicable to all devices. High rates may
86 * suffer from coarse resolution (e.g. in the "500MHz div 2" case) and
330853ba
GS
87 * may not provide the desired 1/2/5 steps. Fortunately this exclusively
88 * affects the 500MHz model where 250MHz is used instead of 200MHz and
89 * the 166MHz and 125MHz rates are not presented to users. Deep memory
90 * of these models and hardware compression reduce the necessity to let
91 * users pick from a huge list of possible rates.
92 *
ea436ba7
GS
93 */
94
330853ba
GS
95static const uint64_t rates_500mhz[] = {
96 SR_KHZ(10),
97 SR_KHZ(20),
98 SR_KHZ(50),
99 SR_KHZ(100),
100 SR_KHZ(200),
101 SR_KHZ(500),
102 SR_MHZ(1),
103 SR_MHZ(2),
104 SR_MHZ(5),
105 SR_MHZ(10),
106 SR_MHZ(20),
107 SR_MHZ(50),
108 SR_MHZ(100),
109 SR_MHZ(250),
110 SR_MHZ(500),
111};
112
113static const uint64_t rates_200mhz[] = {
ea436ba7 114 SR_KHZ(10),
f2cd2deb
FS
115 SR_KHZ(20),
116 SR_KHZ(50),
117 SR_KHZ(100),
118 SR_KHZ(200),
119 SR_KHZ(500),
120 SR_MHZ(1),
121 SR_MHZ(2),
f2cd2deb 122 SR_MHZ(5),
f2cd2deb
FS
123 SR_MHZ(10),
124 SR_MHZ(20),
125 SR_MHZ(50),
126 SR_MHZ(100),
127 SR_MHZ(200),
128};
129
330853ba 130static const uint64_t rates_100mhz[] = {
ea436ba7 131 SR_KHZ(10),
8b172e78
KG
132 SR_KHZ(20),
133 SR_KHZ(50),
134 SR_KHZ(100),
135 SR_KHZ(200),
136 SR_KHZ(500),
137 SR_MHZ(1),
138 SR_MHZ(2),
8b172e78 139 SR_MHZ(5),
8b172e78
KG
140 SR_MHZ(10),
141 SR_MHZ(20),
142 SR_MHZ(50),
143 SR_MHZ(100),
144};
145
f2cd2deb
FS
146static const float logic_threshold_value[] = {
147 1.58,
148 2.5,
149 1.165,
150 1.5,
151 1.25,
152 0.9,
153 0.75,
154 0.60,
155 0.45,
156};
157
158static const char *logic_threshold[] = {
159 "TTL 5V",
160 "CMOS 5V",
161 "CMOS 3.3V",
162 "CMOS 3.0V",
163 "CMOS 2.5V",
164 "CMOS 1.8V",
165 "CMOS 1.5V",
166 "CMOS 1.2V",
167 "CMOS 0.9V",
168 "USER",
169};
170
da2cb50d 171#define LOGIC_THRESHOLD_IDX_USER (ARRAY_SIZE(logic_threshold) - 1)
f2cd2deb 172
d466f61c
GS
173/* Convenience. Release an allocated devc from error paths. */
174static void kingst_la2016_free_devc(struct dev_context *devc)
175{
176 if (!devc)
177 return;
178 g_free(devc->mcu_firmware);
179 g_free(devc->fpga_bitstream);
180 g_free(devc);
181}
182
183/* Convenience. Release an allocated sdi from error paths. */
184static void kingst_la2016_free_sdi(struct sr_dev_inst *sdi)
185{
186 if (!sdi)
187 return;
188 g_free(sdi->vendor);
189 g_free(sdi->model);
190 g_free(sdi->version);
191 g_free(sdi->serial_num);
192 g_free(sdi->connection_id);
193 sr_usb_dev_inst_free(sdi->conn);
194 kingst_la2016_free_devc(sdi->priv);
195}
196
197/* Convenience. Open a USB device (including claiming an interface). */
198static int la2016_open_usb(struct sr_usb_dev_inst *usb,
199 libusb_device *dev, gboolean show_message)
200{
201 int ret;
202
203 ret = libusb_open(dev, &usb->devhdl);
204 if (ret != 0) {
205 if (show_message) {
206 sr_err("Cannot open device: %s.",
207 libusb_error_name(ret));
208 }
209 return SR_ERR_IO;
210 }
211
212 if (usb->address == 0xff) {
213 /*
214 * First encounter after firmware upload.
215 * Grab current address after enumeration.
216 */
217 usb->address = libusb_get_device_address(dev);
218 }
219
220 ret = libusb_claim_interface(usb->devhdl, USB_INTERFACE);
221 if (ret == LIBUSB_ERROR_BUSY) {
222 sr_err("Cannot claim USB interface. Another program or driver using it?");
223 return SR_ERR_IO;
224 } else if (ret == LIBUSB_ERROR_NO_DEVICE) {
225 sr_err("Device has been disconnected.");
226 return SR_ERR_IO;
227 } else if (ret != 0) {
228 sr_err("Cannot claim USB interface: %s.",
229 libusb_error_name(ret));
230 return SR_ERR_IO;
231 }
232
233 return SR_OK;
234}
235
236/* Convenience. Close an opened USB device (and release the interface). */
237static void la2016_close_usb(struct sr_usb_dev_inst *usb)
238{
239
240 if (!usb)
241 return;
242
243 if (usb->devhdl) {
244 libusb_release_interface(usb->devhdl, USB_INTERFACE);
245 libusb_close(usb->devhdl);
246 usb->devhdl = NULL;
247 }
248}
249
250/* Communicate to an USB device to identify the Kingst LA model. */
251static int la2016_identify_read(struct sr_dev_inst *sdi,
252 struct sr_usb_dev_inst *usb, libusb_device *dev,
253 gboolean show_message)
254{
255 int ret;
256
257 ret = la2016_open_usb(usb, dev, show_message);
258 if (ret != SR_OK) {
259 if (show_message)
260 sr_err("Cannot communicate to MCU firmware.");
261 return ret;
262 }
6d53e949
GS
263
264 /*
265 * Also complete the hardware configuration (FPGA bitstream)
266 * when MCU firmware communication became operational. Either
267 * failure is considered fatal when probing for the device.
268 */
d466f61c 269 ret = la2016_identify_device(sdi, show_message);
6d53e949
GS
270 if (ret == SR_OK) {
271 ret = la2016_init_hardware(sdi);
272 }
273
d466f61c
GS
274 la2016_close_usb(usb);
275
276 return ret;
277}
278
279/* Find given conn_id in another USB enum. Identify Kingst LA model. */
280static int la2016_identify_enum(struct sr_dev_inst *sdi)
281{
282 struct sr_dev_driver *di;
283 struct drv_context *drvc;
284 struct sr_context *ctx;
285 libusb_device **devlist, *dev;
286 struct libusb_device_descriptor des;
287 int ret, id_ret;
288 size_t device_count, dev_idx;
289 char conn_id[64];
290
291 di = sdi->driver;
292 drvc = di->context;
293 ctx = drvc->sr_ctx;;
294
295 ret = libusb_get_device_list(ctx->libusb_ctx, &devlist);
296 if (ret < 0)
297 return SR_ERR_IO;
298 device_count = ret;
299 if (!device_count)
300 return SR_ERR_IO;
301 id_ret = SR_ERR_IO;
302 for (dev_idx = 0; dev_idx < device_count; dev_idx++) {
303 dev = devlist[dev_idx];
304 libusb_get_device_descriptor(dev, &des);
305 if (des.idVendor != LA2016_VID || des.idProduct != LA2016_PID)
306 continue;
307 if (des.iProduct != LA2016_IPRODUCT_INDEX)
308 continue;
309 ret = usb_get_port_path(dev, conn_id, sizeof(conn_id));
310 if (ret < 0)
311 continue;
312 if (strcmp(sdi->connection_id, conn_id) != 0)
313 continue;
314 id_ret = la2016_identify_read(sdi, sdi->conn, dev, FALSE);
315 break;
316 }
317 libusb_free_device_list(devlist, 1);
318
319 return id_ret;
320}
321
322/* Wait for a device to re-appear after firmware upload. */
323static int la2016_identify_wait(struct sr_dev_inst *sdi)
324{
325 struct dev_context *devc;
326 uint64_t reset_done, now, elapsed_ms;
327 int ret;
328
329 devc = sdi->priv;
330
331 sr_info("Waiting for device to reset after firmware upload.");
332 now = g_get_monotonic_time();
333 reset_done = devc->fw_uploaded + RENUM_GONE_DELAY_MS * 1000;
334 if (now < reset_done)
335 g_usleep(reset_done - now);
336 do {
337 now = g_get_monotonic_time();
338 elapsed_ms = (now - devc->fw_uploaded) / 1000;
339 sr_spew("Waited %" PRIu64 "ms.", elapsed_ms);
340 ret = la2016_identify_enum(sdi);
341 if (ret == SR_OK) {
342 devc->fw_uploaded = 0;
343 break;
344 }
345 g_usleep(RENUM_POLL_INTERVAL_MS * 1000);
346 } while (elapsed_ms < RENUM_CHECK_PERIOD_MS);
347 if (ret != SR_OK) {
348 sr_err("Device failed to re-enumerate.");
349 return ret;
350 }
351 sr_info("Device came back after %" PRIi64 "ms.", elapsed_ms);
352
353 return SR_OK;
354}
355
356/*
357 * Open given conn_id from another USB enum. Used by dev_open(). Similar
358 * to, and should be kept in sync with la2016_identify_enum().
359 */
360static int la2016_open_enum(struct sr_dev_inst *sdi)
361{
362 struct sr_dev_driver *di;
363 struct drv_context *drvc;
364 struct sr_context *ctx;
365 libusb_device **devlist, *dev;
366 struct libusb_device_descriptor des;
367 int ret, open_ret;
368 size_t device_count, dev_idx;
369 char conn_id[64];
370
371 di = sdi->driver;
372 drvc = di->context;
373 ctx = drvc->sr_ctx;;
374
375 ret = libusb_get_device_list(ctx->libusb_ctx, &devlist);
376 if (ret < 0)
377 return SR_ERR_IO;
378 device_count = ret;
379 if (!device_count)
380 return SR_ERR_IO;
381 open_ret = SR_ERR_IO;
382 for (dev_idx = 0; dev_idx < device_count; dev_idx++) {
383 dev = devlist[dev_idx];
384 libusb_get_device_descriptor(dev, &des);
385 if (des.idVendor != LA2016_VID || des.idProduct != LA2016_PID)
386 continue;
387 if (des.iProduct != LA2016_IPRODUCT_INDEX)
388 continue;
389 ret = usb_get_port_path(dev, conn_id, sizeof(conn_id));
390 if (ret < 0)
391 continue;
392 if (strcmp(sdi->connection_id, conn_id) != 0)
393 continue;
394 open_ret = la2016_open_usb(sdi->conn, dev, TRUE);
395 break;
396 }
397 libusb_free_device_list(devlist, 1);
398
399 return open_ret;
400}
401
f2cd2deb
FS
402static GSList *scan(struct sr_dev_driver *di, GSList *options)
403{
404 struct drv_context *drvc;
520a20e9 405 struct sr_context *ctx;
f2cd2deb
FS
406 struct dev_context *devc;
407 struct sr_dev_inst *sdi;
408 struct sr_usb_dev_inst *usb;
409 struct sr_config *src;
410 GSList *l;
d466f61c 411 GSList *devices, *found_devices, *renum_devices;
f2cd2deb
FS
412 GSList *conn_devices;
413 struct libusb_device_descriptor des;
520a20e9
GS
414 libusb_device **devlist, *dev;
415 size_t dev_count, dev_idx, ch_idx;
416 uint8_t bus, addr;
d466f61c 417 uint16_t pid;
f2cd2deb 418 const char *conn;
520a20e9 419 char conn_id[64];
520a20e9 420 int ret;
d466f61c 421 size_t ch_off, ch_max;
331277e0
GS
422 struct sr_channel *ch;
423 struct sr_channel_group *cg;
f2cd2deb
FS
424
425 drvc = di->context;
520a20e9 426 ctx = drvc->sr_ctx;;
f2cd2deb
FS
427
428 conn = NULL;
d466f61c 429 conn_devices = NULL;
f2cd2deb
FS
430 for (l = options; l; l = l->next) {
431 src = l->data;
432 switch (src->key) {
433 case SR_CONF_CONN:
434 conn = g_variant_get_string(src->data, NULL);
435 break;
436 }
437 }
438 if (conn)
520a20e9 439 conn_devices = sr_usb_find(ctx->libusb_ctx, conn);
d466f61c
GS
440 if (conn && !conn_devices) {
441 sr_err("Cannot find the specified connection '%s'.", conn);
442 return NULL;
443 }
f2cd2deb 444
d466f61c
GS
445 /*
446 * Find all LA2016 devices, optionally upload firmware to them.
447 * Defer completion of sdi/devc creation until all (selected)
448 * devices were found in a usable state, and their models got
449 * identified which affect their feature set. It appears that
450 * we cannot communicate to the device within the same USB enum
451 * cycle, needs another USB enumeration after firmware upload.
452 */
f2cd2deb 453 devices = NULL;
d466f61c
GS
454 found_devices = NULL;
455 renum_devices = NULL;
520a20e9
GS
456 ret = libusb_get_device_list(ctx->libusb_ctx, &devlist);
457 if (ret < 0) {
458 sr_err("Cannot get device list: %s.", libusb_error_name(ret));
459 return devices;
460 }
461 dev_count = ret;
462 for (dev_idx = 0; dev_idx < dev_count; dev_idx++) {
463 dev = devlist[dev_idx];
464 bus = libusb_get_bus_number(dev);
465 addr = libusb_get_device_address(dev);
d466f61c
GS
466
467 /* Filter by connection when externally specified. */
468 for (l = conn_devices; l; l = l->next) {
469 usb = l->data;
470 if (usb->bus == bus && usb->address == addr)
471 break;
472 }
473 if (conn_devices && !l) {
474 sr_spew("Bus %hhu, addr %hhu do not match specified filter.",
475 bus, addr);
476 continue;
f2cd2deb
FS
477 }
478
d466f61c 479 /* Check USB VID:PID. Get the connection string. */
520a20e9 480 libusb_get_device_descriptor(dev, &des);
d466f61c
GS
481 if (des.idVendor != LA2016_VID || des.idProduct != LA2016_PID)
482 continue;
483 pid = des.idProduct;
520a20e9
GS
484 ret = usb_get_port_path(dev, conn_id, sizeof(conn_id));
485 if (ret < 0)
f2cd2deb 486 continue;
d466f61c
GS
487 sr_dbg("USB enum found %04x:%04x at path %s, %d.%d.",
488 des.idVendor, des.idProduct, conn_id, bus, addr);
489 usb = sr_usb_dev_inst_new(bus, addr, NULL);
f2cd2deb 490
520a20e9 491 sdi = g_malloc0(sizeof(*sdi));
d466f61c 492 sdi->driver = di;
f2cd2deb 493 sdi->status = SR_ST_INITIALIZING;
d466f61c 494 sdi->inst_type = SR_INST_USB;
520a20e9 495 sdi->connection_id = g_strdup(conn_id);
d466f61c 496 sdi->conn = usb;
f2cd2deb 497
d466f61c
GS
498 devc = g_malloc0(sizeof(*devc));
499 sdi->priv = devc;
f2cd2deb 500
d466f61c
GS
501 /*
502 * Load MCU firmware if it is currently missing. Which
503 * makes the device disappear and renumerate in USB.
504 * We need to come back another time to communicate to
505 * this device.
506 */
507 devc->fw_uploaded = 0;
508 if (des.iProduct != LA2016_IPRODUCT_INDEX) {
509 sr_info("Uploading MCU firmware to '%s'.", conn_id);
510 ret = la2016_upload_firmware(sdi, ctx, dev, pid);
520a20e9 511 if (ret != SR_OK) {
91f73872 512 sr_err("MCU firmware upload failed.");
d466f61c 513 kingst_la2016_free_sdi(sdi);
f2cd2deb
FS
514 continue;
515 }
d466f61c
GS
516 devc->fw_uploaded = g_get_monotonic_time();
517 usb->address = 0xff;
518 renum_devices = g_slist_append(renum_devices, sdi);
519 continue;
f2cd2deb
FS
520 }
521
d466f61c
GS
522 /*
523 * Communicate to the MCU firmware to access EEPROM data
524 * which lets us identify the device type. Then stop, to
525 * share remaining sdi/devc creation with those devices
526 * which had their MCU firmware uploaded above and which
527 * get revisited later.
528 */
529 ret = la2016_identify_read(sdi, usb, dev, TRUE);
530 if (ret != SR_OK || !devc->model) {
531 sr_err("Unknown or unsupported device type.");
532 kingst_la2016_free_sdi(sdi);
533 continue;
534 }
535 found_devices = g_slist_append(found_devices, sdi);
536 }
537 libusb_free_device_list(devlist, 1);
538 g_slist_free_full(conn_devices, sr_usb_dev_inst_free_cb);
f2cd2deb 539
d466f61c
GS
540 /*
541 * Wait for devices to re-appear after firmware upload. Append
542 * the yet unidentified device to the list of found devices, or
543 * release the previously allocated sdi/devc.
544 */
545 for (l = renum_devices; l; l = l->next) {
546 sdi = l->data;
547 devc = sdi->priv;
548 ret = la2016_identify_wait(sdi);
549 if (ret != SR_OK || !devc->model) {
550 sr_dbg("Skipping unusable '%s'.", sdi->connection_id);
551 kingst_la2016_free_sdi(sdi);
552 continue;
520a20e9 553 }
d466f61c
GS
554 found_devices = g_slist_append(found_devices, sdi);
555 }
556 g_slist_free(renum_devices);
f2cd2deb 557
d466f61c
GS
558 /*
559 * All found devices got identified, their type is known here.
560 * Complete the sdi/devc creation. Assign default settings
561 * because the vendor firmware would not let us read back the
562 * previously written configuration.
563 */
564 for (l = found_devices; l; l = l->next) {
565 sdi = l->data;
566 devc = sdi->priv;
567
568 sdi->vendor = g_strdup("Kingst");
569 sdi->model = g_strdup(devc->model->name);
570 ch_off = 0;
571
331277e0 572 /* Create the "Logic" channel group. */
d466f61c
GS
573 ch_max = ARRAY_SIZE(channel_names_logic);
574 if (ch_max > devc->model->channel_count)
575 ch_max = devc->model->channel_count;
331277e0
GS
576 cg = sr_channel_group_new(sdi, "Logic", NULL);
577 devc->cg_logic = cg;
d466f61c 578 for (ch_idx = 0; ch_idx < ch_max; ch_idx++) {
331277e0 579 ch = sr_channel_new(sdi, ch_off,
d466f61c
GS
580 SR_CHANNEL_LOGIC, TRUE,
581 channel_names_logic[ch_idx]);
582 ch_off++;
331277e0
GS
583 cg->channels = g_slist_append(cg->channels, ch);
584 }
585
586 /* Create the "PWMx" channel groups. */
587 ch_max = ARRAY_SIZE(channel_names_pwm);
588 for (ch_idx = 0; ch_idx < ch_max; ch_idx++) {
589 const char *name;
590 name = channel_names_pwm[ch_idx];
591 cg = sr_channel_group_new(sdi, name, NULL);
592 if (!devc->cg_pwm)
593 devc->cg_pwm = cg;
594 ch = sr_channel_new(sdi, ch_off,
595 SR_CHANNEL_ANALOG, FALSE, name);
596 ch_off++;
597 cg->channels = g_slist_append(cg->channels, ch);
d466f61c 598 }
f2cd2deb 599
08a49848
GS
600 /*
601 * Ideally we'd get the previous configuration from the
602 * hardware, but this device is write-only. So we have
603 * to assign a fixed set of initial configuration values.
604 */
a38f0f5e 605 sr_sw_limits_init(&devc->sw_limits);
d8fbfcd9
GS
606 devc->sw_limits.limit_samples = 0;
607 devc->capture_ratio = 50;
608 devc->cur_samplerate = devc->model->samplerate;
f2cd2deb
FS
609 devc->threshold_voltage_idx = 0;
610 devc->threshold_voltage = logic_threshold_value[devc->threshold_voltage_idx];
08a49848
GS
611 if (ARRAY_SIZE(devc->pwm_setting) >= 1) {
612 devc->pwm_setting[0].enabled = FALSE;
613 devc->pwm_setting[0].freq = SR_KHZ(1);
614 devc->pwm_setting[0].duty = 50;
615 }
616 if (ARRAY_SIZE(devc->pwm_setting) >= 2) {
617 devc->pwm_setting[1].enabled = FALSE;
618 devc->pwm_setting[1].freq = SR_KHZ(100);
619 devc->pwm_setting[1].duty = 50;
620 }
f2cd2deb
FS
621
622 sdi->status = SR_ST_INACTIVE;
d466f61c 623 devices = g_slist_append(devices, sdi);
f2cd2deb 624 }
d466f61c 625 g_slist_free(found_devices);
f2cd2deb
FS
626
627 return std_scan_complete(di, devices);
628}
629
f2cd2deb
FS
630static int dev_open(struct sr_dev_inst *sdi)
631{
08a49848 632 struct dev_context *devc;
f2cd2deb 633 int ret;
08a49848
GS
634 size_t ch;
635
636 devc = sdi->priv;
f2cd2deb 637
d466f61c 638 ret = la2016_open_enum(sdi);
f2cd2deb 639 if (ret != SR_OK) {
91f73872 640 sr_err("Cannot open device.");
520a20e9 641 return ret;
f2cd2deb
FS
642 }
643
08a49848
GS
644 /* Send most recent PWM configuration to the device. */
645 for (ch = 0; ch < ARRAY_SIZE(devc->pwm_setting); ch++) {
646 ret = la2016_write_pwm_config(sdi, ch);
647 if (ret != SR_OK)
648 return ret;
6d53e949
GS
649 }
650
f2cd2deb
FS
651 return SR_OK;
652}
653
654static int dev_close(struct sr_dev_inst *sdi)
655{
656 struct sr_usb_dev_inst *usb;
657
658 usb = sdi->conn;
659
660 if (!usb->devhdl)
661 return SR_ERR_BUG;
662
6d53e949 663 la2016_deinit_hardware(sdi);
f2cd2deb
FS
664
665 sr_info("Closing device on %d.%d (logical) / %s (physical) interface %d.",
666 usb->bus, usb->address, sdi->connection_id, USB_INTERFACE);
d466f61c 667 la2016_close_usb(sdi->conn);
f2cd2deb
FS
668
669 return SR_OK;
670}
671
331277e0
GS
672/* Config API helper. Get type and index of a channel group. */
673static int get_cg_index(const struct sr_dev_inst *sdi,
674 const struct sr_channel_group *cg,
675 int *type, size_t *logic, size_t *analog)
676{
677 struct dev_context *devc;
678 GSList *l;
679 size_t idx;
680
681 /* Preset return values. */
682 if (type)
683 *type = 0;
684 if (logic)
685 *logic = 0;
686 if (analog)
687 *analog = 0;
688
689 /* Start categorizing the received cg. */
690 if (!sdi)
691 return SR_ERR_ARG;
692 devc = sdi->priv;
693 if (!cg)
694 return SR_OK;
695 l = sdi->channel_groups;
696
697 /* First sdi->channelgroups item is "Logic". */
698 if (!l)
699 return SR_ERR_BUG;
700 if (cg == l->data) {
701 if (type)
702 *type = SR_CHANNEL_LOGIC;
703 if (logic)
704 *logic = 0;
705 return SR_OK;
706 }
707 l = l->next;
708
709 /* Next sdi->channelgroups items are "PWMx". */
710 idx = 0;
711 while (l && l->data != cg) {
712 idx++;
713 l = l->next;
714 }
715 if (l && idx < ARRAY_SIZE(devc->pwm_setting)) {
716 if (type)
717 *type = SR_CHANNEL_ANALOG;
718 if (analog)
719 *analog = idx;
720 return SR_OK;
721 }
722
723 return SR_ERR_ARG;
724}
725
955ab604
GS
726static int config_get(uint32_t key, GVariant **data,
727 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
f2cd2deb
FS
728{
729 struct dev_context *devc;
331277e0
GS
730 int ret, cg_type;
731 size_t logic_idx, analog_idx;
732 struct pwm_setting *pwm;
f2cd2deb
FS
733 struct sr_usb_dev_inst *usb;
734 double rounded;
da2cb50d 735 const char *label;
f2cd2deb 736
f2cd2deb
FS
737 if (!sdi)
738 return SR_ERR_ARG;
739 devc = sdi->priv;
740
331277e0
GS
741 /* Check for types (and index) of channel groups. */
742 ret = get_cg_index(sdi, cg, &cg_type, &logic_idx, &analog_idx);
743 if (cg && ret != SR_OK)
744 return SR_ERR_ARG;
745
746 /* Handle requests for the "Logic" channel group. */
747 if (cg && cg_type == SR_CHANNEL_LOGIC) {
748 /* TODO */
749 return SR_ERR_NA;
750 }
751
752 /* Handle requests for the "PWMx" channel groups. */
753 if (cg && cg_type == SR_CHANNEL_ANALOG) {
754 pwm = &devc->pwm_setting[analog_idx];
755 switch (key) {
756 case SR_CONF_ENABLED:
757 *data = g_variant_new_boolean(pwm->enabled);
758 break;
759 case SR_CONF_OUTPUT_FREQUENCY:
760 *data = g_variant_new_double(pwm->freq);
761 break;
762 case SR_CONF_DUTY_CYCLE:
763 *data = g_variant_new_double(pwm->duty);
764 break;
765 default:
766 return SR_ERR_NA;
767 }
768 return SR_OK;
769 }
770
f2cd2deb
FS
771 switch (key) {
772 case SR_CONF_CONN:
f2cd2deb 773 usb = sdi->conn;
f2cd2deb
FS
774 *data = g_variant_new_printf("%d.%d", usb->bus, usb->address);
775 break;
776 case SR_CONF_SAMPLERATE:
777 *data = g_variant_new_uint64(devc->cur_samplerate);
778 break;
779 case SR_CONF_LIMIT_SAMPLES:
a38f0f5e
GS
780 case SR_CONF_LIMIT_MSEC:
781 return sr_sw_limits_config_get(&devc->sw_limits, key, data);
f2cd2deb
FS
782 case SR_CONF_CAPTURE_RATIO:
783 *data = g_variant_new_uint64(devc->capture_ratio);
784 break;
785 case SR_CONF_VOLTAGE_THRESHOLD:
786 rounded = (int)(devc->threshold_voltage / 0.1) * 0.1;
787 *data = std_gvar_tuple_double(rounded, rounded + 0.1);
788 return SR_OK;
789 case SR_CONF_LOGIC_THRESHOLD:
da2cb50d
GS
790 label = logic_threshold[devc->threshold_voltage_idx];
791 *data = g_variant_new_string(label);
f2cd2deb
FS
792 break;
793 case SR_CONF_LOGIC_THRESHOLD_CUSTOM:
794 *data = g_variant_new_double(devc->threshold_voltage);
795 break;
955ab604 796
f2cd2deb
FS
797 default:
798 return SR_ERR_NA;
799 }
800
801 return SR_OK;
802}
803
955ab604
GS
804static int config_set(uint32_t key, GVariant *data,
805 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
f2cd2deb
FS
806{
807 struct dev_context *devc;
331277e0
GS
808 int ret, cg_type;
809 size_t logic_idx, analog_idx;
810 struct pwm_setting *pwm;
c35baf6e 811 double value_f;
f2cd2deb
FS
812 double low, high;
813 int idx;
814
f2cd2deb
FS
815 devc = sdi->priv;
816
331277e0
GS
817 /* Check for types (and index) of channel groups. */
818 ret = get_cg_index(sdi, cg, &cg_type, &logic_idx, &analog_idx);
819 if (cg && ret != SR_OK)
820 return SR_ERR_ARG;
821
822 /* Handle requests for the "Logic" channel group. */
823 if (cg && cg_type == SR_CHANNEL_LOGIC) {
824 /* TODO */
825 return SR_ERR_NA;
826 }
827
828 /* Handle requests for the "PWMx" channel groups. */
829 if (cg && cg_type == SR_CHANNEL_ANALOG) {
830 pwm = &devc->pwm_setting[analog_idx];
831 switch (key) {
832 case SR_CONF_ENABLED:
833 pwm->enabled = g_variant_get_boolean(data);
834 ret = la2016_write_pwm_config(sdi, analog_idx);
835 if (ret != SR_OK)
836 return ret;
837 break;
838 case SR_CONF_OUTPUT_FREQUENCY:
c35baf6e
GS
839 value_f = g_variant_get_double(data);
840 if (value_f <= 0.0 || value_f > MAX_PWM_FREQ)
841 return SR_ERR_ARG;
842 pwm->freq = value_f;
331277e0
GS
843 ret = la2016_write_pwm_config(sdi, analog_idx);
844 if (ret != SR_OK)
845 return ret;
846 break;
847 case SR_CONF_DUTY_CYCLE:
c35baf6e
GS
848 value_f = g_variant_get_double(data);
849 if (value_f <= 0.0 || value_f > 100.0)
850 return SR_ERR_ARG;
851 pwm->duty = value_f;
331277e0
GS
852 ret = la2016_write_pwm_config(sdi, analog_idx);
853 if (ret != SR_OK)
854 return ret;
855 break;
856 default:
857 return SR_ERR_NA;
858 }
859 return SR_OK;
860 }
861
f2cd2deb
FS
862 switch (key) {
863 case SR_CONF_SAMPLERATE:
864 devc->cur_samplerate = g_variant_get_uint64(data);
865 break;
866 case SR_CONF_LIMIT_SAMPLES:
a38f0f5e
GS
867 case SR_CONF_LIMIT_MSEC:
868 return sr_sw_limits_config_set(&devc->sw_limits, key, data);
f2cd2deb
FS
869 case SR_CONF_CAPTURE_RATIO:
870 devc->capture_ratio = g_variant_get_uint64(data);
871 break;
872 case SR_CONF_VOLTAGE_THRESHOLD:
873 g_variant_get(data, "(dd)", &low, &high);
874 devc->threshold_voltage = (low + high) / 2.0;
da2cb50d 875 devc->threshold_voltage_idx = LOGIC_THRESHOLD_IDX_USER;
f2cd2deb
FS
876 break;
877 case SR_CONF_LOGIC_THRESHOLD: {
411ad77c
GS
878 idx = std_str_idx(data, ARRAY_AND_SIZE(logic_threshold));
879 if (idx < 0)
f2cd2deb 880 return SR_ERR_ARG;
da2cb50d 881 if (idx != LOGIC_THRESHOLD_IDX_USER) {
f2cd2deb
FS
882 devc->threshold_voltage = logic_threshold_value[idx];
883 }
884 devc->threshold_voltage_idx = idx;
885 break;
886 }
887 case SR_CONF_LOGIC_THRESHOLD_CUSTOM:
888 devc->threshold_voltage = g_variant_get_double(data);
889 break;
890 default:
891 return SR_ERR_NA;
892 }
893
894 return SR_OK;
895}
896
955ab604
GS
897static int config_list(uint32_t key, GVariant **data,
898 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
f2cd2deb 899{
8b172e78 900 struct dev_context *devc;
331277e0
GS
901 int ret, cg_type;
902 size_t logic_idx, analog_idx;
8b172e78 903
a38f0f5e
GS
904 devc = sdi ? sdi->priv : NULL;
905
331277e0
GS
906 /* Check for types (and index) of channel groups. */
907 ret = get_cg_index(sdi, cg, &cg_type, &logic_idx, &analog_idx);
908 if (cg && ret != SR_OK)
909 return SR_ERR_ARG;
910
911 /* Handle requests for the "Logic" channel group. */
912 if (cg && cg_type == SR_CHANNEL_LOGIC) {
913 /* TODO */
914 return SR_ERR_NA;
915 }
916
917 /* Handle requests for the "PWMx" channel groups. */
918 if (cg && cg_type == SR_CHANNEL_ANALOG) {
919 switch (key) {
920 case SR_CONF_DEVICE_OPTIONS:
921 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
922 devopts_cg_pwm, ARRAY_SIZE(devopts_cg_pwm),
923 sizeof(devopts_cg_pwm[0]));
924 break;
925 default:
926 return SR_ERR_NA;
927 }
928 return SR_OK;
929 }
930
f2cd2deb
FS
931 switch (key) {
932 case SR_CONF_SCAN_OPTIONS:
933 case SR_CONF_DEVICE_OPTIONS:
411ad77c
GS
934 return STD_CONFIG_LIST(key, data, sdi, cg,
935 scanopts, drvopts, devopts);
f2cd2deb 936 case SR_CONF_SAMPLERATE:
fb28e72d
MW
937 if (!sdi)
938 return SR_ERR_ARG;
d466f61c 939 if (devc->model->samplerate == SR_MHZ(500))
330853ba 940 *data = std_gvar_samplerates(ARRAY_AND_SIZE(rates_500mhz));
d466f61c 941 else if (devc->model->samplerate == SR_MHZ(200))
330853ba
GS
942 *data = std_gvar_samplerates(ARRAY_AND_SIZE(rates_200mhz));
943 else
944 *data = std_gvar_samplerates(ARRAY_AND_SIZE(rates_100mhz));
f2cd2deb
FS
945 break;
946 case SR_CONF_LIMIT_SAMPLES:
d8fbfcd9 947 *data = std_gvar_tuple_u64(0, LA2016_NUM_SAMPLES_MAX);
f2cd2deb
FS
948 break;
949 case SR_CONF_VOLTAGE_THRESHOLD:
950 *data = std_gvar_min_max_step_thresholds(
951 LA2016_THR_VOLTAGE_MIN,
952 LA2016_THR_VOLTAGE_MAX, 0.1);
953 break;
954 case SR_CONF_TRIGGER_MATCH:
955 *data = std_gvar_array_i32(ARRAY_AND_SIZE(trigger_matches));
956 break;
957 case SR_CONF_LOGIC_THRESHOLD:
da2cb50d 958 *data = g_variant_new_strv(ARRAY_AND_SIZE(logic_threshold));
f2cd2deb
FS
959 break;
960 default:
961 return SR_ERR_NA;
962 }
963
964 return SR_OK;
965}
966
f2cd2deb
FS
967static int dev_acquisition_start(const struct sr_dev_inst *sdi)
968{
969 struct sr_dev_driver *di;
970 struct drv_context *drvc;
520a20e9 971 struct sr_context *ctx;
f2cd2deb
FS
972 struct dev_context *devc;
973 int ret;
974
975 di = sdi->driver;
976 drvc = di->context;
520a20e9 977 ctx = drvc->sr_ctx;;
f2cd2deb
FS
978 devc = sdi->priv;
979
a38f0f5e
GS
980 if (!devc->feed_queue) {
981 devc->feed_queue = feed_queue_logic_alloc(sdi,
982 LA2016_CONVBUFFER_SIZE, sizeof(uint16_t));
983 if (!devc->feed_queue) {
984 sr_err("Cannot allocate buffer for session feed.");
985 return SR_ERR_MALLOC;
986 }
f2cd2deb
FS
987 }
988
a38f0f5e
GS
989 sr_sw_limits_acquisition_start(&devc->sw_limits);
990
411ad77c
GS
991 ret = la2016_setup_acquisition(sdi);
992 if (ret != SR_OK) {
a38f0f5e
GS
993 feed_queue_logic_free(devc->feed_queue);
994 devc->feed_queue = NULL;
f2cd2deb
FS
995 return ret;
996 }
997
411ad77c
GS
998 ret = la2016_start_acquisition(sdi);
999 if (ret != SR_OK) {
3ebc1cb2 1000 la2016_abort_acquisition(sdi);
a38f0f5e
GS
1001 feed_queue_logic_free(devc->feed_queue);
1002 devc->feed_queue = NULL;
f2cd2deb
FS
1003 return ret;
1004 }
1005
cf057ac4 1006 devc->completion_seen = FALSE;
520a20e9 1007 usb_source_add(sdi->session, ctx, 50,
388438e4 1008 la2016_receive_data, (void *)sdi);
f2cd2deb
FS
1009
1010 std_session_send_df_header(sdi);
1011
1012 return SR_OK;
1013}
1014
1015static int dev_acquisition_stop(struct sr_dev_inst *sdi)
1016{
1017 int ret;
1018
1019 ret = la2016_abort_acquisition(sdi);
f2cd2deb
FS
1020
1021 return ret;
1022}
1023
1024static struct sr_dev_driver kingst_la2016_driver_info = {
1025 .name = "kingst-la2016",
1026 .longname = "Kingst LA2016",
1027 .api_version = 1,
1028 .init = std_init,
1029 .cleanup = std_cleanup,
1030 .scan = scan,
1031 .dev_list = std_dev_list,
1032 .dev_clear = std_dev_clear,
1033 .config_get = config_get,
1034 .config_set = config_set,
1035 .config_list = config_list,
1036 .dev_open = dev_open,
1037 .dev_close = dev_close,
1038 .dev_acquisition_start = dev_acquisition_start,
1039 .dev_acquisition_stop = dev_acquisition_stop,
1040 .context = NULL,
1041};
1042SR_REGISTER_DEV_DRIVER(kingst_la2016_driver_info);