]> sigrok.org Git - libsigrok.git/blame - hardware/zeroplus-logic-cube/zeroplus.c
sr/cli/gtk: s/capability/hwcap/.
[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
ffedd0bf 169static int hw_set_configuration(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. */
bb7ef793 465 if (hw_set_configuration(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
bb7ef793 510static void *hw_get_dev_info(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
d68e2d1a 571static int set_configuration_samplerate(struct sr_dev_inst *sdi,
bf43ea23 572 uint64_t samplerate)
a1bb33af 573{
bf43ea23
UH
574 struct zp *zp;
575
576 if (!sdi) {
577 sr_err("zp: %s: sdi was NULL", __func__);
578 return SR_ERR_ARG;
579 }
580
581 if (!(zp = sdi->priv)) {
582 sr_err("zp: %s: sdi->priv was NULL", __func__);
583 return SR_ERR_ARG;
584 }
585
73017cf9
UH
586 sr_info("zp: Setting samplerate to %" PRIu64 "Hz.", samplerate);
587
59df0c77
UH
588 if (samplerate > SR_MHZ(1))
589 analyzer_set_freq(samplerate / SR_MHZ(1), FREQ_SCALE_MHZ);
590 else if (samplerate > SR_KHZ(1))
591 analyzer_set_freq(samplerate / SR_KHZ(1), FREQ_SCALE_KHZ);
a1bb33af 592 else
fed16f06 593 analyzer_set_freq(samplerate, FREQ_SCALE_HZ);
a1bb33af 594
bf43ea23 595 zp->cur_samplerate = samplerate;
a1bb33af 596
e46b8fb1 597 return SR_OK;
a1bb33af
UH
598}
599
ffedd0bf 600static int hw_set_configuration(int dev_index, int hwcap, void *value)
a1bb33af 601{
d68e2d1a 602 struct sr_dev_inst *sdi;
a1bb33af 603 uint64_t *tmp_u64;
bf43ea23 604 struct zp *zp;
a1bb33af 605
bb7ef793 606 if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) {
bf43ea23 607 sr_err("zp: %s: sdi was NULL", __func__);
e46b8fb1 608 return SR_ERR;
bf43ea23
UH
609 }
610
611 if (!(zp = sdi->priv)) {
612 sr_err("zp: %s: sdi->priv was NULL", __func__);
613 return SR_ERR_ARG;
614 }
a1bb33af 615
ffedd0bf 616 switch (hwcap) {
5a2326a7 617 case SR_HWCAP_SAMPLERATE:
fed16f06 618 tmp_u64 = value;
bf43ea23 619 return set_configuration_samplerate(sdi, *tmp_u64);
5a2326a7 620 case SR_HWCAP_PROBECONFIG:
bf43ea23 621 return configure_probes(sdi, (GSList *)value);
5a2326a7 622 case SR_HWCAP_LIMIT_SAMPLES:
2458ea65 623 tmp_u64 = value;
bf43ea23 624 zp->limit_samples = *tmp_u64;
e46b8fb1 625 return SR_OK;
fed16f06 626 default:
e46b8fb1 627 return SR_ERR;
a1bb33af
UH
628 }
629}
630
bb7ef793 631static int hw_start_acquisition(int dev_index, gpointer session_data)
a1bb33af 632{
d68e2d1a 633 struct sr_dev_inst *sdi;
b9c735a2 634 struct sr_datafeed_packet packet;
9c939c51 635 struct sr_datafeed_logic logic;
b9c735a2 636 struct sr_datafeed_header header;
9c939c51 637 uint64_t samples_read;
a1bb33af 638 int res;
afc8e4de 639 unsigned int packet_num;
a1bb33af 640 unsigned char *buf;
bf43ea23 641 struct zp *zp;
a1bb33af 642
bb7ef793 643 if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) {
bf43ea23 644 sr_err("zp: %s: sdi was NULL", __func__);
e46b8fb1 645 return SR_ERR;
bf43ea23
UH
646 }
647
648 if (!(zp = sdi->priv)) {
649 sr_err("zp: %s: sdi->priv was NULL", __func__);
650 return SR_ERR_ARG;
651 }
a1bb33af 652
a143e4e5 653 /* push configured settings to device */
69890f73 654 analyzer_configure(zp->usb->devhdl);
a143e4e5 655
69890f73 656 analyzer_start(zp->usb->devhdl);
7b48d6e1 657 sr_info("zp: Waiting for data");
69890f73 658 analyzer_wait_data(zp->usb->devhdl);
a1bb33af 659
7b48d6e1
UH
660 sr_info("zp: Stop address = 0x%x",
661 analyzer_get_stop_address(zp->usb->devhdl));
662 sr_info("zp: Now address = 0x%x",
663 analyzer_get_now_address(zp->usb->devhdl));
664 sr_info("zp: Trigger address = 0x%x",
665 analyzer_get_trigger_address(zp->usb->devhdl));
a1bb33af 666
5a2326a7 667 packet.type = SR_DF_HEADER;
9c939c51 668 packet.payload = &header;
a1bb33af
UH
669 header.feed_version = 1;
670 gettimeofday(&header.starttime, NULL);
bf43ea23
UH
671 header.samplerate = zp->cur_samplerate;
672 header.num_logic_probes = zp->num_channels;
9c939c51 673 sr_session_bus(session_data, &packet);
a1bb33af 674
b53738ba 675 if (!(buf = g_try_malloc(PACKET_SIZE))) {
bf43ea23 676 sr_err("zp: %s: buf malloc failed", __func__);
b53738ba
UH
677 return SR_ERR_MALLOC;
678 }
679
9c939c51 680 samples_read = 0;
69890f73 681 analyzer_read_start(zp->usb->devhdl);
fed16f06 682 /* Send the incoming transfer to the session bus. */
bf43ea23 683 for (packet_num = 0; packet_num < (zp->memory_size * 4 / PACKET_SIZE);
fed16f06 684 packet_num++) {
69890f73 685 res = analyzer_read_data(zp->usb->devhdl, buf, PACKET_SIZE);
7b48d6e1 686 sr_info("zp: Tried to read %llx bytes, actually read %x bytes",
b08024a8 687 PACKET_SIZE, res);
a1bb33af 688
5a2326a7 689 packet.type = SR_DF_LOGIC;
9c939c51
BV
690 packet.payload = &logic;
691 logic.length = PACKET_SIZE;
692 logic.unitsize = 4;
693 logic.data = buf;
694 sr_session_bus(session_data, &packet);
695 samples_read += res / 4;
a1bb33af 696 }
69890f73 697 analyzer_read_stop(zp->usb->devhdl);
a1bb33af
UH
698 g_free(buf);
699
5a2326a7 700 packet.type = SR_DF_END;
9c939c51 701 sr_session_bus(session_data, &packet);
a1bb33af 702
e46b8fb1 703 return SR_OK;
a1bb33af
UH
704}
705
bb7ef793
UH
706/* This stops acquisition on ALL devices, ignoring dev_index. */
707static int hw_stop_acquisition(int dev_index, gpointer session_dev_id)
a1bb33af 708{
b9c735a2 709 struct sr_datafeed_packet packet;
d68e2d1a 710 struct sr_dev_inst *sdi;
69890f73 711 struct zp *zp;
a1bb33af 712
5a2326a7 713 packet.type = SR_DF_END;
bb7ef793 714 sr_session_bus(session_dev_id, &packet);
a1bb33af 715
bb7ef793 716 if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) {
69890f73 717 sr_err("zp: %s: sdi was NULL", __func__);
3010f21c 718 return SR_ERR_BUG;
69890f73
UH
719 }
720
721 if (!(zp = sdi->priv)) {
722 sr_err("zp: %s: sdi->priv was NULL", __func__);
3010f21c 723 return SR_ERR_BUG;
69890f73 724 }
a1bb33af 725
69890f73 726 analyzer_reset(zp->usb->devhdl);
fed16f06 727 /* TODO: Need to cancel and free any queued up transfers. */
3010f21c
UH
728
729 return SR_OK;
a1bb33af
UH
730}
731
bb7ef793 732SR_PRIV struct sr_dev_plugin zeroplus_logic_cube_plugin_info = {
e519ba86
UH
733 .name = "zeroplus-logic-cube",
734 .longname = "Zeroplus Logic Cube LAP-C series",
735 .api_version = 1,
736 .init = hw_init,
737 .cleanup = hw_cleanup,
86f5e3d8
UH
738 .opendev = hw_opendev,
739 .closedev = hw_closedev,
bb7ef793 740 .get_dev_info = hw_get_dev_info,
e519ba86 741 .get_status = hw_get_status,
ffedd0bf 742 .hwcap_get_all = hw_hwcap_get_all,
e519ba86
UH
743 .set_configuration = hw_set_configuration,
744 .start_acquisition = hw_start_acquisition,
745 .stop_acquisition = hw_stop_acquisition,
a1bb33af 746};