]> sigrok.org Git - libsigrok.git/blame - hardware/zeroplus-logic-cube/zeroplus.c
sr/cli/gtk/qt: s/get_dev_info/dev_info_get/.
[libsigrok.git] / hardware / zeroplus-logic-cube / zeroplus.c
CommitLineData
a1bb33af
UH
1/*
2 * This file is part of the sigrok project.
3 *
c73d2ea4 4 * Copyright (C) 2010-2012 Bert Vermeulen <bert@biot.com>
a1bb33af
UH
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 <stdio.h>
21#include <stdlib.h>
c31e9ef4 22#include <string.h>
a1bb33af
UH
23#include <sys/time.h>
24#include <inttypes.h>
25#include <glib.h>
26#include <libusb.h>
c31e9ef4 27#include "config.h"
b7f09cf8
UH
28#include "sigrok.h"
29#include "sigrok-internal.h"
a1bb33af
UH
30#include "analyzer.h"
31
fed16f06
UH
32#define USB_VENDOR 0x0c12
33#define USB_VENDOR_NAME "Zeroplus"
a1bb33af
UH
34#define USB_MODEL_NAME "Logic Cube"
35#define USB_MODEL_VERSION ""
36
37#define USB_INTERFACE 0
38#define USB_CONFIGURATION 1
39#define NUM_TRIGGER_STAGES 4
40#define TRIGGER_TYPES "01"
41
fed16f06 42#define PACKET_SIZE 2048 /* ?? */
a1bb33af
UH
43
44typedef struct {
45 unsigned short pid;
46 char model_name[64];
47 unsigned int channels;
fed16f06 48 unsigned int sample_depth; /* In Ksamples/channel */
a1bb33af
UH
49 unsigned int max_sampling_freq;
50} model_t;
51
fed16f06
UH
52/*
53 * Note -- 16032, 16064 and 16128 *usually* -- but not always -- have the
54 * same 128K sample depth.
55 */
29cbfeaf 56static model_t zeroplus_models[] = {
a1bb33af
UH
57 {0x7009, "LAP-C(16064)", 16, 64, 100},
58 {0x700A, "LAP-C(16128)", 16, 128, 200},
59 {0x700B, "LAP-C(32128)", 32, 128, 200},
60 {0x700C, "LAP-C(321000)", 32, 1024, 200},
61 {0x700D, "LAP-C(322000)", 32, 2048, 200},
62 {0x700E, "LAP-C(16032)", 16, 32, 100},
63 {0x7016, "LAP-C(162000)", 16, 2048, 200},
64};
65
ffedd0bf 66static int hwcaps[] = {
5a2326a7
UH
67 SR_HWCAP_LOGIC_ANALYZER,
68 SR_HWCAP_SAMPLERATE,
69 SR_HWCAP_PROBECONFIG,
70 SR_HWCAP_CAPTURE_RATIO,
a1bb33af 71
fed16f06 72 /* These are really implemented in the driver, not the hardware. */
5a2326a7 73 SR_HWCAP_LIMIT_SAMPLES,
fed16f06 74 0,
a1bb33af
UH
75};
76
c37d2b1b 77static const char *probe_names[] = {
464d12c7
KS
78 "0",
79 "1",
80 "2",
81 "3",
82 "4",
83 "5",
84 "6",
85 "7",
86 "8",
87 "9",
88 "10",
89 "11",
90 "12",
91 "13",
92 "14",
93 "15",
94 "16",
95 "17",
96 "18",
97 "19",
98 "20",
99 "21",
100 "22",
101 "23",
102 "24",
103 "25",
104 "26",
105 "27",
106 "28",
107 "29",
108 "30",
109 "31",
110 NULL,
111};
112
d68e2d1a
UH
113/* List of struct sr_dev_inst, maintained by opendev()/closedev(). */
114static GSList *dev_insts = NULL;
a1bb33af
UH
115
116static libusb_context *usb_context = NULL;
117
fed16f06
UH
118/*
119 * The hardware supports more samplerates than these, but these are the
120 * options hardcoded into the vendor's Windows GUI.
121 */
a1bb33af 122
fed16f06
UH
123/*
124 * TODO: We shouldn't support 150MHz and 200MHz on devices that don't go up
125 * that high.
126 */
a1bb33af 127static uint64_t supported_samplerates[] = {
c9140419
UH
128 SR_HZ(100),
129 SR_HZ(500),
59df0c77
UH
130 SR_KHZ(1),
131 SR_KHZ(5),
132 SR_KHZ(25),
133 SR_KHZ(50),
134 SR_KHZ(100),
135 SR_KHZ(200),
136 SR_KHZ(400),
137 SR_KHZ(800),
138 SR_MHZ(1),
139 SR_MHZ(10),
140 SR_MHZ(25),
141 SR_MHZ(50),
142 SR_MHZ(80),
143 SR_MHZ(100),
144 SR_MHZ(150),
145 SR_MHZ(200),
fed16f06 146 0,
a1bb33af
UH
147};
148
60679b18 149static struct sr_samplerates samplerates = {
c9140419
UH
150 SR_HZ(0),
151 SR_HZ(0),
152 SR_HZ(0),
fed16f06 153 supported_samplerates,
a1bb33af
UH
154};
155
bf43ea23
UH
156struct zp {
157 uint64_t cur_samplerate;
bf43ea23
UH
158 uint64_t limit_samples;
159 int num_channels; /* TODO: This isn't initialized before it's needed :( */
160 uint64_t memory_size;
161 uint8_t probe_mask;
162 uint8_t trigger_mask[NUM_TRIGGER_STAGES];
163 uint8_t trigger_value[NUM_TRIGGER_STAGES];
164 // uint8_t trigger_buffer[NUM_TRIGGER_STAGES];
69890f73 165
d68e2d1a 166 struct sr_usb_dev_inst *usb;
bf43ea23 167};
a1bb33af 168
a7d05fcb 169static int hw_config_set(int dev_index, int hwcap, void *value);
a1bb33af
UH
170
171static unsigned int get_memory_size(int type)
172{
fed16f06
UH
173 if (type == MEMORY_SIZE_8K)
174 return 8 * 1024;
175 else if (type == MEMORY_SIZE_64K)
176 return 64 * 1024;
177 else if (type == MEMORY_SIZE_128K)
178 return 128 * 1024;
179 else if (type == MEMORY_SIZE_512K)
180 return 512 * 1024;
181 else
182 return 0;
a1bb33af
UH
183}
184
d68e2d1a 185static int opendev4(struct sr_dev_inst **sdi, libusb_device *dev,
408e7199
UH
186 struct libusb_device_descriptor *des)
187{
bf43ea23 188 struct zp *zp;
9a498834
UH
189 unsigned int i;
190 int err;
408e7199 191
bf43ea23
UH
192 /* Note: sdi is non-NULL, the caller already checked this. */
193
194 if (!(zp = (*sdi)->priv)) {
195 sr_err("zp: %s: (*sdi)->priv was NULL", __func__);
196 return -1;
197 }
198
408e7199 199 if ((err = libusb_get_device_descriptor(dev, des))) {
7b48d6e1 200 sr_err("zp: failed to get device descriptor: %d", err);
408e7199
UH
201 return -1;
202 }
203
9a498834 204 if (des->idVendor != USB_VENDOR)
408e7199
UH
205 return 0;
206
69890f73
UH
207 if (libusb_get_bus_number(dev) == zp->usb->bus
208 && libusb_get_device_address(dev) == zp->usb->address) {
408e7199 209
9a498834
UH
210 for (i = 0; i < ARRAY_SIZE(zeroplus_models); i++) {
211 if (!(des->idProduct == zeroplus_models[i].pid))
408e7199
UH
212 continue;
213
7b48d6e1
UH
214 sr_info("zp: Found ZeroPlus device 0x%04x (%s)",
215 des->idProduct, zeroplus_models[i].model_name);
bf43ea23
UH
216 zp->num_channels = zeroplus_models[i].channels;
217 zp->memory_size = zeroplus_models[i].sample_depth * 1024;
408e7199
UH
218 break;
219 }
220
bf43ea23 221 if (zp->num_channels == 0) {
7b48d6e1
UH
222 sr_err("zp: Unknown ZeroPlus device 0x%04x",
223 des->idProduct);
408e7199
UH
224 return -2;
225 }
226
227 /* Found it. */
69890f73 228 if (!(err = libusb_open(dev, &(zp->usb->devhdl)))) {
5a2326a7 229 (*sdi)->status = SR_ST_ACTIVE;
7b48d6e1 230 sr_info("zp: opened device %d on %d.%d interface %d",
69890f73
UH
231 (*sdi)->index, zp->usb->bus,
232 zp->usb->address, USB_INTERFACE);
408e7199 233 } else {
7b48d6e1 234 sr_err("zp: failed to open device: %d", err);
408e7199
UH
235 *sdi = NULL;
236 }
237 }
238
239 return 0;
240}
241
bb7ef793 242static struct sr_dev_inst *zp_open_dev(int dev_index)
a1bb33af 243{
d68e2d1a 244 struct sr_dev_inst *sdi;
a1bb33af
UH
245 libusb_device **devlist;
246 struct libusb_device_descriptor des;
afc8e4de 247 int err, i;
a1bb33af 248
bb7ef793 249 if (!(sdi = sr_dev_inst_get(dev_insts, dev_index)))
a1bb33af
UH
250 return NULL;
251
252 libusb_get_device_list(usb_context, &devlist);
5a2326a7 253 if (sdi->status == SR_ST_INACTIVE) {
fed16f06 254 /* Find the device by vendor, product, bus and address. */
a1bb33af 255 libusb_get_device_list(usb_context, &devlist);
fed16f06 256 for (i = 0; devlist[i]; i++) {
408e7199 257 /* TODO: Error handling. */
9a5c6dcf 258 err = opendev4(&sdi, devlist[i], &des);
a1bb33af 259 }
fed16f06 260 } else {
5a2326a7 261 /* Status must be SR_ST_ACTIVE, i.e. already in use... */
a1bb33af
UH
262 sdi = NULL;
263 }
264 libusb_free_device_list(devlist, 1);
265
5a2326a7 266 if (sdi && sdi->status != SR_ST_ACTIVE)
a1bb33af
UH
267 sdi = NULL;
268
269 return sdi;
270}
271
bb7ef793 272static void close_dev(struct sr_dev_inst *sdi)
a1bb33af 273{
69890f73
UH
274 struct zp *zp;
275
276 if (!(zp = sdi->priv)) {
277 sr_err("zp: %s: sdi->priv was NULL", __func__);
278 return; /* FIXME */
279 }
280
281 if (!zp->usb->devhdl)
408e7199
UH
282 return;
283
7b48d6e1 284 sr_info("zp: closing device %d on %d.%d interface %d", sdi->index,
69890f73
UH
285 zp->usb->bus, zp->usb->address, USB_INTERFACE);
286 libusb_release_interface(zp->usb->devhdl, USB_INTERFACE);
185ae2c5 287 libusb_reset_device(zp->usb->devhdl);
69890f73
UH
288 libusb_close(zp->usb->devhdl);
289 zp->usb->devhdl = NULL;
185ae2c5 290 /* TODO: Call libusb_exit() here or only in hw_cleanup()? */
5a2326a7 291 sdi->status = SR_ST_INACTIVE;
a1bb33af
UH
292}
293
d68e2d1a 294static int configure_probes(struct sr_dev_inst *sdi, GSList *probes)
a1bb33af 295{
bf43ea23 296 struct zp *zp;
1afe8989 297 struct sr_probe *probe;
a1bb33af
UH
298 GSList *l;
299 int probe_bit, stage, i;
300 char *tc;
301
bf43ea23
UH
302 /* Note: sdi and sdi->priv are non-NULL, the caller checked this. */
303 zp = sdi->priv;
304
305 zp->probe_mask = 0;
fed16f06 306 for (i = 0; i < NUM_TRIGGER_STAGES; i++) {
bf43ea23
UH
307 zp->trigger_mask[i] = 0;
308 zp->trigger_value[i] = 0;
a1bb33af
UH
309 }
310
311 stage = -1;
fed16f06 312 for (l = probes; l; l = l->next) {
1afe8989 313 probe = (struct sr_probe *)l->data;
fed16f06 314 if (probe->enabled == FALSE)
a1bb33af
UH
315 continue;
316 probe_bit = 1 << (probe->index - 1);
bf43ea23 317 zp->probe_mask |= probe_bit;
fed16f06
UH
318
319 if (probe->trigger) {
a1bb33af 320 stage = 0;
fed16f06 321 for (tc = probe->trigger; *tc; tc++) {
bf43ea23 322 zp->trigger_mask[stage] |= probe_bit;
fed16f06 323 if (*tc == '1')
bf43ea23 324 zp->trigger_value[stage] |= probe_bit;
a1bb33af 325 stage++;
fed16f06 326 if (stage > NUM_TRIGGER_STAGES)
e46b8fb1 327 return SR_ERR;
a1bb33af
UH
328 }
329 }
330 }
331
e46b8fb1 332 return SR_OK;
a1bb33af
UH
333}
334
a1bb33af
UH
335/*
336 * API callbacks
337 */
338
bb7ef793 339static int hw_init(const char *devinfo)
a1bb33af 340{
d68e2d1a 341 struct sr_dev_inst *sdi;
a1bb33af
UH
342 struct libusb_device_descriptor des;
343 libusb_device **devlist;
344 int err, devcnt, i;
bf43ea23 345 struct zp *zp;
a1bb33af 346
17e1afcb 347 /* Avoid compiler warnings. */
bb7ef793 348 (void)devinfo;
afc8e4de 349
bf43ea23
UH
350 /* Allocate memory for our private driver context. */
351 if (!(zp = g_try_malloc(sizeof(struct zp)))) {
352 sr_err("zp: %s: struct zp malloc failed", __func__);
353 return 0;
354 }
355
356 /* Set some sane defaults. */
357 zp->cur_samplerate = 0;
bf43ea23
UH
358 zp->limit_samples = 0;
359 zp->num_channels = 32; /* TODO: This isn't initialized before it's needed :( */
360 zp->memory_size = 0;
361 zp->probe_mask = 0;
362 memset(zp->trigger_mask, 0, NUM_TRIGGER_STAGES);
363 memset(zp->trigger_value, 0, NUM_TRIGGER_STAGES);
364 // memset(zp->trigger_buffer, 0, NUM_TRIGGER_STAGES);
365
fed16f06 366 if (libusb_init(&usb_context) != 0) {
7b48d6e1 367 sr_err("zp: Failed to initialize USB.");
a1bb33af
UH
368 return 0;
369 }
370
fed16f06 371 /* Find all ZeroPlus analyzers and add them to device list. */
a1bb33af 372 devcnt = 0;
185ae2c5 373 libusb_get_device_list(usb_context, &devlist); /* TODO: Errors. */
fed16f06
UH
374
375 for (i = 0; devlist[i]; i++) {
a1bb33af 376 err = libusb_get_device_descriptor(devlist[i], &des);
fed16f06 377 if (err != 0) {
7b48d6e1 378 sr_err("zp: failed to get device descriptor: %d", err);
a1bb33af
UH
379 continue;
380 }
381
fed16f06
UH
382 if (des.idVendor == USB_VENDOR) {
383 /*
384 * Definitely a Zeroplus.
385 * TODO: Any way to detect specific model/version in
386 * the zeroplus range?
387 */
bf43ea23 388 /* Register the device with libsigrok. */
d68e2d1a 389 if (!(sdi = sr_dev_inst_new(devcnt,
5a2326a7 390 SR_ST_INACTIVE, USB_VENDOR_NAME,
d68e2d1a
UH
391 USB_MODEL_NAME, USB_MODEL_VERSION))) {
392 sr_err("zp: %s: sr_dev_inst_new failed",
bf43ea23 393 __func__);
a1bb33af 394 return 0;
bf43ea23
UH
395 }
396
397 sdi->priv = zp;
398
d68e2d1a
UH
399 dev_insts =
400 g_slist_append(dev_insts, sdi);
d3683c42 401 zp->usb = sr_usb_dev_inst_new(
fed16f06
UH
402 libusb_get_bus_number(devlist[i]),
403 libusb_get_device_address(devlist[i]), NULL);
a1bb33af
UH
404 devcnt++;
405 }
406 }
407 libusb_free_device_list(devlist, 1);
408
409 return devcnt;
410}
411
bb7ef793 412static int hw_opendev(int dev_index)
a1bb33af 413{
d68e2d1a 414 struct sr_dev_inst *sdi;
bf43ea23 415 struct zp *zp;
a1bb33af
UH
416 int err;
417
bb7ef793 418 if (!(sdi = zp_open_dev(dev_index))) {
7b48d6e1 419 sr_err("zp: unable to open device");
e46b8fb1 420 return SR_ERR;
a1bb33af
UH
421 }
422
bb7ef793 423 /* TODO: Note: sdi is retrieved in zp_open_dev(). */
bf43ea23
UH
424
425 if (!(zp = sdi->priv)) {
426 sr_err("zp: %s: sdi->priv was NULL", __func__);
427 return SR_ERR_ARG;
428 }
429
185ae2c5
UH
430 err = libusb_set_configuration(zp->usb->devhdl, USB_CONFIGURATION);
431 if (err < 0) {
133a37bf
UH
432 sr_err("zp: Unable to set USB configuration %d: %d",
433 USB_CONFIGURATION, err);
185ae2c5
UH
434 return SR_ERR;
435 }
436
69890f73 437 err = libusb_claim_interface(zp->usb->devhdl, USB_INTERFACE);
fed16f06 438 if (err != 0) {
7b48d6e1 439 sr_err("zp: Unable to claim interface: %d", err);
e46b8fb1 440 return SR_ERR;
a1bb33af 441 }
185ae2c5 442
69890f73
UH
443 analyzer_reset(zp->usb->devhdl);
444 analyzer_initialize(zp->usb->devhdl);
a1bb33af
UH
445
446 analyzer_set_memory_size(MEMORY_SIZE_512K);
fed16f06 447 // analyzer_set_freq(g_freq, g_freq_scale);
a1bb33af 448 analyzer_set_trigger_count(1);
408e7199
UH
449 // analyzer_set_ramsize_trigger_address((((100 - g_pre_trigger)
450 // * get_memory_size(g_memory_size)) / 100) >> 2);
fed16f06
UH
451 analyzer_set_ramsize_trigger_address(
452 (100 * get_memory_size(MEMORY_SIZE_512K) / 100) >> 2);
a1bb33af 453
fed16f06
UH
454#if 0
455 if (g_double_mode == 1)
a1bb33af
UH
456 analyzer_set_compression(COMPRESSION_DOUBLE);
457 else if (g_compression == 1)
458 analyzer_set_compression(COMPRESSION_ENABLE);
fed16f06
UH
459 else
460#endif
461 analyzer_set_compression(COMPRESSION_NONE);
a1bb33af 462
bf43ea23 463 if (zp->cur_samplerate == 0) {
408e7199 464 /* Samplerate hasn't been set. Default to the slowest one. */
a7d05fcb 465 if (hw_config_set(dev_index, SR_HWCAP_SAMPLERATE,
73017cf9 466 &samplerates.list[0]) == SR_ERR)
e46b8fb1 467 return SR_ERR;
a1bb33af
UH
468 }
469
e46b8fb1 470 return SR_OK;
a1bb33af
UH
471}
472
bb7ef793 473static int hw_closedev(int dev_index)
a1bb33af 474{
d68e2d1a 475 struct sr_dev_inst *sdi;
a1bb33af 476
bb7ef793 477 if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) {
bf43ea23 478 sr_err("zp: %s: sdi was NULL", __func__);
697785d1
UH
479 return SR_ERR; /* TODO: SR_ERR_ARG? */
480 }
481
482 /* TODO */
bb7ef793 483 close_dev(sdi);
697785d1
UH
484
485 return SR_OK;
a1bb33af
UH
486}
487
57ab7d9f 488static int hw_cleanup(void)
a1bb33af
UH
489{
490 GSList *l;
d68e2d1a 491 struct sr_dev_inst *sdi;
a1bb33af 492
d68e2d1a 493 for (l = dev_insts; l; l = l->next) {
341ce415
BV
494 sdi = l->data;
495 /* Properly close all devices... */
bb7ef793 496 close_dev(sdi);
341ce415
BV
497 /* ...and free all their memory. */
498 sr_dev_inst_free(sdi);
499 }
d68e2d1a
UH
500 g_slist_free(dev_insts);
501 dev_insts = NULL;
a1bb33af 502
fed16f06 503 if (usb_context)
a1bb33af
UH
504 libusb_exit(usb_context);
505 usb_context = NULL;
57ab7d9f
UH
506
507 return SR_OK;
a1bb33af
UH
508}
509
5097b0d0 510static void *hw_dev_info_get(int dev_index, int dev_info_id)
a1bb33af 511{
d68e2d1a 512 struct sr_dev_inst *sdi;
bf43ea23
UH
513 struct zp *zp;
514 void *info;
a1bb33af 515
bb7ef793 516 if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) {
bf43ea23 517 sr_err("zp: %s: sdi was NULL", __func__);
a1bb33af 518 return NULL;
bf43ea23
UH
519 }
520
521 if (!(zp = sdi->priv)) {
522 sr_err("zp: %s: sdi->priv was NULL", __func__);
523 return NULL;
524 }
a1bb33af 525
bb7ef793 526 switch (dev_info_id) {
1d9a8a5f 527 case SR_DI_INST:
a1bb33af
UH
528 info = sdi;
529 break;
5a2326a7 530 case SR_DI_NUM_PROBES:
bf43ea23 531 info = GINT_TO_POINTER(zp->num_channels);
a1bb33af 532 break;
464d12c7
KS
533 case SR_DI_PROBE_NAMES:
534 info = probe_names;
535 break;
5a2326a7 536 case SR_DI_SAMPLERATES:
a1bb33af
UH
537 info = &samplerates;
538 break;
5a2326a7 539 case SR_DI_TRIGGER_TYPES:
a1bb33af
UH
540 info = TRIGGER_TYPES;
541 break;
5a2326a7 542 case SR_DI_CUR_SAMPLERATE:
bf43ea23
UH
543 info = &zp->cur_samplerate;
544 break;
545 default:
546 /* Unknown device info ID, return NULL. */
547 sr_err("zp: %s: Unknown device info ID", __func__);
548 info = NULL;
a1bb33af
UH
549 break;
550 }
551
552 return info;
553}
554
bb7ef793 555static int hw_get_status(int dev_index)
a1bb33af 556{
d68e2d1a 557 struct sr_dev_inst *sdi;
a1bb33af 558
bb7ef793 559 sdi = sr_dev_inst_get(dev_insts, dev_index);
fed16f06 560 if (sdi)
a1bb33af
UH
561 return sdi->status;
562 else
5a2326a7 563 return SR_ST_NOT_FOUND;
a1bb33af
UH
564}
565
ffedd0bf 566static int *hw_hwcap_get_all(void)
a1bb33af 567{
ffedd0bf 568 return hwcaps;
a1bb33af
UH
569}
570
a7d05fcb 571static int config_set_samplerate(struct sr_dev_inst *sdi, uint64_t samplerate)
a1bb33af 572{
bf43ea23
UH
573 struct zp *zp;
574
575 if (!sdi) {
576 sr_err("zp: %s: sdi was NULL", __func__);
577 return SR_ERR_ARG;
578 }
579
580 if (!(zp = sdi->priv)) {
581 sr_err("zp: %s: sdi->priv was NULL", __func__);
582 return SR_ERR_ARG;
583 }
584
73017cf9
UH
585 sr_info("zp: Setting samplerate to %" PRIu64 "Hz.", samplerate);
586
59df0c77
UH
587 if (samplerate > SR_MHZ(1))
588 analyzer_set_freq(samplerate / SR_MHZ(1), FREQ_SCALE_MHZ);
589 else if (samplerate > SR_KHZ(1))
590 analyzer_set_freq(samplerate / SR_KHZ(1), FREQ_SCALE_KHZ);
a1bb33af 591 else
fed16f06 592 analyzer_set_freq(samplerate, FREQ_SCALE_HZ);
a1bb33af 593
bf43ea23 594 zp->cur_samplerate = samplerate;
a1bb33af 595
e46b8fb1 596 return SR_OK;
a1bb33af
UH
597}
598
a7d05fcb 599static int hw_config_set(int dev_index, int hwcap, void *value)
a1bb33af 600{
d68e2d1a 601 struct sr_dev_inst *sdi;
a1bb33af 602 uint64_t *tmp_u64;
bf43ea23 603 struct zp *zp;
a1bb33af 604
bb7ef793 605 if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) {
bf43ea23 606 sr_err("zp: %s: sdi was NULL", __func__);
e46b8fb1 607 return SR_ERR;
bf43ea23
UH
608 }
609
610 if (!(zp = sdi->priv)) {
611 sr_err("zp: %s: sdi->priv was NULL", __func__);
612 return SR_ERR_ARG;
613 }
a1bb33af 614
ffedd0bf 615 switch (hwcap) {
5a2326a7 616 case SR_HWCAP_SAMPLERATE:
fed16f06 617 tmp_u64 = value;
a7d05fcb 618 return config_set_samplerate(sdi, *tmp_u64);
5a2326a7 619 case SR_HWCAP_PROBECONFIG:
bf43ea23 620 return configure_probes(sdi, (GSList *)value);
5a2326a7 621 case SR_HWCAP_LIMIT_SAMPLES:
2458ea65 622 tmp_u64 = value;
bf43ea23 623 zp->limit_samples = *tmp_u64;
e46b8fb1 624 return SR_OK;
fed16f06 625 default:
e46b8fb1 626 return SR_ERR;
a1bb33af
UH
627 }
628}
629
bb7ef793 630static int hw_start_acquisition(int dev_index, gpointer session_data)
a1bb33af 631{
d68e2d1a 632 struct sr_dev_inst *sdi;
b9c735a2 633 struct sr_datafeed_packet packet;
9c939c51 634 struct sr_datafeed_logic logic;
b9c735a2 635 struct sr_datafeed_header header;
9c939c51 636 uint64_t samples_read;
a1bb33af 637 int res;
afc8e4de 638 unsigned int packet_num;
a1bb33af 639 unsigned char *buf;
bf43ea23 640 struct zp *zp;
a1bb33af 641
bb7ef793 642 if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) {
bf43ea23 643 sr_err("zp: %s: sdi was NULL", __func__);
e46b8fb1 644 return SR_ERR;
bf43ea23
UH
645 }
646
647 if (!(zp = sdi->priv)) {
648 sr_err("zp: %s: sdi->priv was NULL", __func__);
649 return SR_ERR_ARG;
650 }
a1bb33af 651
a143e4e5 652 /* push configured settings to device */
69890f73 653 analyzer_configure(zp->usb->devhdl);
a143e4e5 654
69890f73 655 analyzer_start(zp->usb->devhdl);
7b48d6e1 656 sr_info("zp: Waiting for data");
69890f73 657 analyzer_wait_data(zp->usb->devhdl);
a1bb33af 658
7b48d6e1
UH
659 sr_info("zp: Stop address = 0x%x",
660 analyzer_get_stop_address(zp->usb->devhdl));
661 sr_info("zp: Now address = 0x%x",
662 analyzer_get_now_address(zp->usb->devhdl));
663 sr_info("zp: Trigger address = 0x%x",
664 analyzer_get_trigger_address(zp->usb->devhdl));
a1bb33af 665
5a2326a7 666 packet.type = SR_DF_HEADER;
9c939c51 667 packet.payload = &header;
a1bb33af
UH
668 header.feed_version = 1;
669 gettimeofday(&header.starttime, NULL);
bf43ea23
UH
670 header.samplerate = zp->cur_samplerate;
671 header.num_logic_probes = zp->num_channels;
9c939c51 672 sr_session_bus(session_data, &packet);
a1bb33af 673
b53738ba 674 if (!(buf = g_try_malloc(PACKET_SIZE))) {
bf43ea23 675 sr_err("zp: %s: buf malloc failed", __func__);
b53738ba
UH
676 return SR_ERR_MALLOC;
677 }
678
9c939c51 679 samples_read = 0;
69890f73 680 analyzer_read_start(zp->usb->devhdl);
fed16f06 681 /* Send the incoming transfer to the session bus. */
bf43ea23 682 for (packet_num = 0; packet_num < (zp->memory_size * 4 / PACKET_SIZE);
fed16f06 683 packet_num++) {
69890f73 684 res = analyzer_read_data(zp->usb->devhdl, buf, PACKET_SIZE);
7b48d6e1 685 sr_info("zp: Tried to read %llx bytes, actually read %x bytes",
b08024a8 686 PACKET_SIZE, res);
a1bb33af 687
5a2326a7 688 packet.type = SR_DF_LOGIC;
9c939c51
BV
689 packet.payload = &logic;
690 logic.length = PACKET_SIZE;
691 logic.unitsize = 4;
692 logic.data = buf;
693 sr_session_bus(session_data, &packet);
694 samples_read += res / 4;
a1bb33af 695 }
69890f73 696 analyzer_read_stop(zp->usb->devhdl);
a1bb33af
UH
697 g_free(buf);
698
5a2326a7 699 packet.type = SR_DF_END;
9c939c51 700 sr_session_bus(session_data, &packet);
a1bb33af 701
e46b8fb1 702 return SR_OK;
a1bb33af
UH
703}
704
bb7ef793
UH
705/* This stops acquisition on ALL devices, ignoring dev_index. */
706static int hw_stop_acquisition(int dev_index, gpointer session_dev_id)
a1bb33af 707{
b9c735a2 708 struct sr_datafeed_packet packet;
d68e2d1a 709 struct sr_dev_inst *sdi;
69890f73 710 struct zp *zp;
a1bb33af 711
5a2326a7 712 packet.type = SR_DF_END;
bb7ef793 713 sr_session_bus(session_dev_id, &packet);
a1bb33af 714
bb7ef793 715 if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) {
69890f73 716 sr_err("zp: %s: sdi was NULL", __func__);
3010f21c 717 return SR_ERR_BUG;
69890f73
UH
718 }
719
720 if (!(zp = sdi->priv)) {
721 sr_err("zp: %s: sdi->priv was NULL", __func__);
3010f21c 722 return SR_ERR_BUG;
69890f73 723 }
a1bb33af 724
69890f73 725 analyzer_reset(zp->usb->devhdl);
fed16f06 726 /* TODO: Need to cancel and free any queued up transfers. */
3010f21c
UH
727
728 return SR_OK;
a1bb33af
UH
729}
730
bb7ef793 731SR_PRIV struct sr_dev_plugin zeroplus_logic_cube_plugin_info = {
e519ba86
UH
732 .name = "zeroplus-logic-cube",
733 .longname = "Zeroplus Logic Cube LAP-C series",
734 .api_version = 1,
735 .init = hw_init,
736 .cleanup = hw_cleanup,
86f5e3d8
UH
737 .opendev = hw_opendev,
738 .closedev = hw_closedev,
5097b0d0 739 .dev_info_get = hw_dev_info_get,
e519ba86 740 .get_status = hw_get_status,
ffedd0bf 741 .hwcap_get_all = hw_hwcap_get_all,
a7d05fcb 742 .config_set = hw_config_set,
e519ba86
UH
743 .start_acquisition = hw_start_acquisition,
744 .stop_acquisition = hw_stop_acquisition,
a1bb33af 745};