]> sigrok.org Git - libsigrok.git/blame - hardware/zeroplus-logic-cube/zeroplus.c
sr: Prefix log messages with subsystem string.
[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
66static int capabilities[] = {
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
a00ba012 113/* List of struct sr_device_instance, maintained by opendev()/closedev(). */
a1bb33af
UH
114static GSList *device_instances = NULL;
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
UH
165
166 struct sr_usb_device_instance *usb;
bf43ea23 167};
a1bb33af
UH
168
169static int hw_set_configuration(int device_index, int capability, void *value);
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
a00ba012 185static int opendev4(struct sr_device_instance **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
29cbfeaf 242static struct sr_device_instance *zp_open_device(int device_index)
a1bb33af 243{
a00ba012 244 struct sr_device_instance *sdi;
a1bb33af
UH
245 libusb_device **devlist;
246 struct libusb_device_descriptor des;
afc8e4de 247 int err, i;
a1bb33af 248
da1466d6 249 if (!(sdi = sr_dev_inst_get(device_instances, device_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
a00ba012 272static void close_device(struct sr_device_instance *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
bf43ea23 294static int configure_probes(struct sr_device_instance *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
54ac5277 339static int hw_init(const char *deviceinfo)
a1bb33af 340{
a00ba012 341 struct sr_device_instance *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. */
cb93f8a9 348 (void)deviceinfo;
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. */
d3683c42 389 sdi = sr_dev_inst_new(devcnt,
5a2326a7 390 SR_ST_INACTIVE, USB_VENDOR_NAME,
fed16f06 391 USB_MODEL_NAME, USB_MODEL_VERSION);
bf43ea23
UH
392 if (!sdi) {
393 sr_err("zp: %s: sr_device_instance_new failed",
394 __func__);
a1bb33af 395 return 0;
bf43ea23
UH
396 }
397
398 sdi->priv = zp;
399
fed16f06
UH
400 device_instances =
401 g_slist_append(device_instances, sdi);
d3683c42 402 zp->usb = sr_usb_dev_inst_new(
fed16f06
UH
403 libusb_get_bus_number(devlist[i]),
404 libusb_get_device_address(devlist[i]), NULL);
a1bb33af
UH
405 devcnt++;
406 }
407 }
408 libusb_free_device_list(devlist, 1);
409
410 return devcnt;
411}
412
a1bb33af
UH
413static int hw_opendev(int device_index)
414{
a00ba012 415 struct sr_device_instance *sdi;
bf43ea23 416 struct zp *zp;
a1bb33af
UH
417 int err;
418
fed16f06 419 if (!(sdi = zp_open_device(device_index))) {
7b48d6e1 420 sr_err("zp: unable to open device");
e46b8fb1 421 return SR_ERR;
a1bb33af
UH
422 }
423
bf43ea23
UH
424 /* TODO: Note: sdi is retrieved in zp_open_device(). */
425
426 if (!(zp = sdi->priv)) {
427 sr_err("zp: %s: sdi->priv was NULL", __func__);
428 return SR_ERR_ARG;
429 }
430
185ae2c5
UH
431 err = libusb_set_configuration(zp->usb->devhdl, USB_CONFIGURATION);
432 if (err < 0) {
133a37bf
UH
433 sr_err("zp: Unable to set USB configuration %d: %d",
434 USB_CONFIGURATION, err);
185ae2c5
UH
435 return SR_ERR;
436 }
437
69890f73 438 err = libusb_claim_interface(zp->usb->devhdl, USB_INTERFACE);
fed16f06 439 if (err != 0) {
7b48d6e1 440 sr_err("zp: Unable to claim interface: %d", err);
e46b8fb1 441 return SR_ERR;
a1bb33af 442 }
185ae2c5 443
69890f73
UH
444 analyzer_reset(zp->usb->devhdl);
445 analyzer_initialize(zp->usb->devhdl);
a1bb33af
UH
446
447 analyzer_set_memory_size(MEMORY_SIZE_512K);
fed16f06 448 // analyzer_set_freq(g_freq, g_freq_scale);
a1bb33af 449 analyzer_set_trigger_count(1);
408e7199
UH
450 // analyzer_set_ramsize_trigger_address((((100 - g_pre_trigger)
451 // * get_memory_size(g_memory_size)) / 100) >> 2);
fed16f06
UH
452 analyzer_set_ramsize_trigger_address(
453 (100 * get_memory_size(MEMORY_SIZE_512K) / 100) >> 2);
a1bb33af 454
fed16f06
UH
455#if 0
456 if (g_double_mode == 1)
a1bb33af
UH
457 analyzer_set_compression(COMPRESSION_DOUBLE);
458 else if (g_compression == 1)
459 analyzer_set_compression(COMPRESSION_ENABLE);
fed16f06
UH
460 else
461#endif
462 analyzer_set_compression(COMPRESSION_NONE);
a1bb33af 463
bf43ea23 464 if (zp->cur_samplerate == 0) {
408e7199 465 /* Samplerate hasn't been set. Default to the slowest one. */
5a2326a7 466 if (hw_set_configuration(device_index, SR_HWCAP_SAMPLERATE,
73017cf9 467 &samplerates.list[0]) == SR_ERR)
e46b8fb1 468 return SR_ERR;
a1bb33af
UH
469 }
470
e46b8fb1 471 return SR_OK;
a1bb33af
UH
472}
473
697785d1 474static int hw_closedev(int device_index)
a1bb33af 475{
a00ba012 476 struct sr_device_instance *sdi;
a1bb33af 477
da1466d6 478 if (!(sdi = sr_dev_inst_get(device_instances, device_index))) {
bf43ea23 479 sr_err("zp: %s: sdi was NULL", __func__);
697785d1
UH
480 return SR_ERR; /* TODO: SR_ERR_ARG? */
481 }
482
483 /* TODO */
484 close_device(sdi);
485
486 return SR_OK;
a1bb33af
UH
487}
488
57ab7d9f 489static int hw_cleanup(void)
a1bb33af
UH
490{
491 GSList *l;
341ce415 492 struct sr_device_instance *sdi;
a1bb33af 493
341ce415
BV
494 for (l = device_instances; l; l = l->next) {
495 sdi = l->data;
496 /* Properly close all devices... */
497 close_device(sdi);
498 /* ...and free all their memory. */
499 sr_dev_inst_free(sdi);
500 }
a1bb33af
UH
501 g_slist_free(device_instances);
502 device_instances = NULL;
503
fed16f06 504 if (usb_context)
a1bb33af
UH
505 libusb_exit(usb_context);
506 usb_context = NULL;
57ab7d9f
UH
507
508 return SR_OK;
a1bb33af
UH
509}
510
a1bb33af
UH
511static void *hw_get_device_info(int device_index, int device_info_id)
512{
a00ba012 513 struct sr_device_instance *sdi;
bf43ea23
UH
514 struct zp *zp;
515 void *info;
a1bb33af 516
da1466d6 517 if (!(sdi = sr_dev_inst_get(device_instances, device_index))) {
bf43ea23 518 sr_err("zp: %s: sdi was NULL", __func__);
a1bb33af 519 return NULL;
bf43ea23
UH
520 }
521
522 if (!(zp = sdi->priv)) {
523 sr_err("zp: %s: sdi->priv was NULL", __func__);
524 return NULL;
525 }
a1bb33af 526
fed16f06 527 switch (device_info_id) {
5a2326a7 528 case SR_DI_INSTANCE:
a1bb33af
UH
529 info = sdi;
530 break;
5a2326a7 531 case SR_DI_NUM_PROBES:
bf43ea23 532 info = GINT_TO_POINTER(zp->num_channels);
a1bb33af 533 break;
464d12c7
KS
534 case SR_DI_PROBE_NAMES:
535 info = probe_names;
536 break;
5a2326a7 537 case SR_DI_SAMPLERATES:
a1bb33af
UH
538 info = &samplerates;
539 break;
5a2326a7 540 case SR_DI_TRIGGER_TYPES:
a1bb33af
UH
541 info = TRIGGER_TYPES;
542 break;
5a2326a7 543 case SR_DI_CUR_SAMPLERATE:
bf43ea23
UH
544 info = &zp->cur_samplerate;
545 break;
546 default:
547 /* Unknown device info ID, return NULL. */
548 sr_err("zp: %s: Unknown device info ID", __func__);
549 info = NULL;
a1bb33af
UH
550 break;
551 }
552
553 return info;
554}
555
a1bb33af
UH
556static int hw_get_status(int device_index)
557{
a00ba012 558 struct sr_device_instance *sdi;
a1bb33af 559
da1466d6 560 sdi = sr_dev_inst_get(device_instances, device_index);
fed16f06 561 if (sdi)
a1bb33af
UH
562 return sdi->status;
563 else
5a2326a7 564 return SR_ST_NOT_FOUND;
a1bb33af
UH
565}
566
a1bb33af
UH
567static int *hw_get_capabilities(void)
568{
a1bb33af
UH
569 return capabilities;
570}
571
bf43ea23
UH
572static int set_configuration_samplerate(struct sr_device_instance *sdi,
573 uint64_t samplerate)
a1bb33af 574{
bf43ea23
UH
575 struct zp *zp;
576
577 if (!sdi) {
578 sr_err("zp: %s: sdi was NULL", __func__);
579 return SR_ERR_ARG;
580 }
581
582 if (!(zp = sdi->priv)) {
583 sr_err("zp: %s: sdi->priv was NULL", __func__);
584 return SR_ERR_ARG;
585 }
586
73017cf9
UH
587 sr_info("zp: Setting samplerate to %" PRIu64 "Hz.", samplerate);
588
59df0c77
UH
589 if (samplerate > SR_MHZ(1))
590 analyzer_set_freq(samplerate / SR_MHZ(1), FREQ_SCALE_MHZ);
591 else if (samplerate > SR_KHZ(1))
592 analyzer_set_freq(samplerate / SR_KHZ(1), FREQ_SCALE_KHZ);
a1bb33af 593 else
fed16f06 594 analyzer_set_freq(samplerate, FREQ_SCALE_HZ);
a1bb33af 595
bf43ea23 596 zp->cur_samplerate = samplerate;
a1bb33af 597
e46b8fb1 598 return SR_OK;
a1bb33af
UH
599}
600
601static int hw_set_configuration(int device_index, int capability, void *value)
602{
a00ba012 603 struct sr_device_instance *sdi;
a1bb33af 604 uint64_t *tmp_u64;
bf43ea23 605 struct zp *zp;
a1bb33af 606
da1466d6 607 if (!(sdi = sr_dev_inst_get(device_instances, device_index))) {
bf43ea23 608 sr_err("zp: %s: sdi was NULL", __func__);
e46b8fb1 609 return SR_ERR;
bf43ea23
UH
610 }
611
612 if (!(zp = sdi->priv)) {
613 sr_err("zp: %s: sdi->priv was NULL", __func__);
614 return SR_ERR_ARG;
615 }
a1bb33af
UH
616
617 switch (capability) {
5a2326a7 618 case SR_HWCAP_SAMPLERATE:
fed16f06 619 tmp_u64 = value;
bf43ea23 620 return set_configuration_samplerate(sdi, *tmp_u64);
5a2326a7 621 case SR_HWCAP_PROBECONFIG:
bf43ea23 622 return configure_probes(sdi, (GSList *)value);
5a2326a7 623 case SR_HWCAP_LIMIT_SAMPLES:
2458ea65 624 tmp_u64 = value;
bf43ea23 625 zp->limit_samples = *tmp_u64;
e46b8fb1 626 return SR_OK;
fed16f06 627 default:
e46b8fb1 628 return SR_ERR;
a1bb33af
UH
629 }
630}
631
9c939c51 632static int hw_start_acquisition(int device_index, gpointer session_data)
a1bb33af 633{
a00ba012 634 struct sr_device_instance *sdi;
b9c735a2 635 struct sr_datafeed_packet packet;
9c939c51 636 struct sr_datafeed_logic logic;
b9c735a2 637 struct sr_datafeed_header header;
9c939c51 638 uint64_t samples_read;
a1bb33af 639 int res;
afc8e4de 640 unsigned int packet_num;
a1bb33af 641 unsigned char *buf;
bf43ea23 642 struct zp *zp;
a1bb33af 643
da1466d6 644 if (!(sdi = sr_dev_inst_get(device_instances, device_index))) {
bf43ea23 645 sr_err("zp: %s: sdi was NULL", __func__);
e46b8fb1 646 return SR_ERR;
bf43ea23
UH
647 }
648
649 if (!(zp = sdi->priv)) {
650 sr_err("zp: %s: sdi->priv was NULL", __func__);
651 return SR_ERR_ARG;
652 }
a1bb33af 653
a143e4e5 654 /* push configured settings to device */
69890f73 655 analyzer_configure(zp->usb->devhdl);
a143e4e5 656
69890f73 657 analyzer_start(zp->usb->devhdl);
7b48d6e1 658 sr_info("zp: Waiting for data");
69890f73 659 analyzer_wait_data(zp->usb->devhdl);
a1bb33af 660
7b48d6e1
UH
661 sr_info("zp: Stop address = 0x%x",
662 analyzer_get_stop_address(zp->usb->devhdl));
663 sr_info("zp: Now address = 0x%x",
664 analyzer_get_now_address(zp->usb->devhdl));
665 sr_info("zp: Trigger address = 0x%x",
666 analyzer_get_trigger_address(zp->usb->devhdl));
a1bb33af 667
5a2326a7 668 packet.type = SR_DF_HEADER;
9c939c51 669 packet.payload = &header;
a1bb33af
UH
670 header.feed_version = 1;
671 gettimeofday(&header.starttime, NULL);
bf43ea23
UH
672 header.samplerate = zp->cur_samplerate;
673 header.num_logic_probes = zp->num_channels;
9c939c51 674 sr_session_bus(session_data, &packet);
a1bb33af 675
b53738ba 676 if (!(buf = g_try_malloc(PACKET_SIZE))) {
bf43ea23 677 sr_err("zp: %s: buf malloc failed", __func__);
b53738ba
UH
678 return SR_ERR_MALLOC;
679 }
680
9c939c51 681 samples_read = 0;
69890f73 682 analyzer_read_start(zp->usb->devhdl);
fed16f06 683 /* Send the incoming transfer to the session bus. */
bf43ea23 684 for (packet_num = 0; packet_num < (zp->memory_size * 4 / PACKET_SIZE);
fed16f06 685 packet_num++) {
69890f73 686 res = analyzer_read_data(zp->usb->devhdl, buf, PACKET_SIZE);
7b48d6e1 687 sr_info("zp: Tried to read %llx bytes, actually read %x bytes",
b08024a8 688 PACKET_SIZE, res);
a1bb33af 689
5a2326a7 690 packet.type = SR_DF_LOGIC;
9c939c51
BV
691 packet.payload = &logic;
692 logic.length = PACKET_SIZE;
693 logic.unitsize = 4;
694 logic.data = buf;
695 sr_session_bus(session_data, &packet);
696 samples_read += res / 4;
a1bb33af 697 }
69890f73 698 analyzer_read_stop(zp->usb->devhdl);
a1bb33af
UH
699 g_free(buf);
700
5a2326a7 701 packet.type = SR_DF_END;
9c939c51 702 sr_session_bus(session_data, &packet);
a1bb33af 703
e46b8fb1 704 return SR_OK;
a1bb33af
UH
705}
706
fed16f06 707/* This stops acquisition on ALL devices, ignoring device_index. */
3010f21c 708static int hw_stop_acquisition(int device_index, gpointer session_device_id)
a1bb33af 709{
b9c735a2 710 struct sr_datafeed_packet packet;
a00ba012 711 struct sr_device_instance *sdi;
69890f73 712 struct zp *zp;
a1bb33af 713
5a2326a7 714 packet.type = SR_DF_END;
8a2efef2 715 sr_session_bus(session_device_id, &packet);
a1bb33af 716
da1466d6 717 if (!(sdi = sr_dev_inst_get(device_instances, device_index))) {
69890f73 718 sr_err("zp: %s: sdi was NULL", __func__);
3010f21c 719 return SR_ERR_BUG;
69890f73
UH
720 }
721
722 if (!(zp = sdi->priv)) {
723 sr_err("zp: %s: sdi->priv was NULL", __func__);
3010f21c 724 return SR_ERR_BUG;
69890f73 725 }
a1bb33af 726
69890f73 727 analyzer_reset(zp->usb->devhdl);
fed16f06 728 /* TODO: Need to cancel and free any queued up transfers. */
3010f21c
UH
729
730 return SR_OK;
a1bb33af
UH
731}
732
ca070ed9 733SR_PRIV struct sr_device_plugin zeroplus_logic_cube_plugin_info = {
e519ba86
UH
734 .name = "zeroplus-logic-cube",
735 .longname = "Zeroplus Logic Cube LAP-C series",
736 .api_version = 1,
737 .init = hw_init,
738 .cleanup = hw_cleanup,
86f5e3d8
UH
739 .opendev = hw_opendev,
740 .closedev = hw_closedev,
e519ba86
UH
741 .get_device_info = hw_get_device_info,
742 .get_status = hw_get_status,
743 .get_capabilities = hw_get_capabilities,
744 .set_configuration = hw_set_configuration,
745 .start_acquisition = hw_start_acquisition,
746 .stop_acquisition = hw_stop_acquisition,
a1bb33af 747};