]> sigrok.org Git - libsigrok.git/blame - hardware/zeroplus-logic-cube/zeroplus.c
sr: adjust copyright year
[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))) {
133a37bf 200 sr_err("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
b08024a8
UH
214 sr_info("Found PID=%04X (%s)", des->idProduct,
215 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) {
133a37bf 222 sr_err("Unknown ZeroPlus device %04X", des->idProduct);
408e7199
UH
223 return -2;
224 }
225
226 /* Found it. */
69890f73 227 if (!(err = libusb_open(dev, &(zp->usb->devhdl)))) {
5a2326a7 228 (*sdi)->status = SR_ST_ACTIVE;
b08024a8 229 sr_info("opened device %d on %d.%d interface %d",
69890f73
UH
230 (*sdi)->index, zp->usb->bus,
231 zp->usb->address, USB_INTERFACE);
408e7199 232 } else {
133a37bf 233 sr_err("failed to open device: %d", err);
408e7199
UH
234 *sdi = NULL;
235 }
236 }
237
238 return 0;
239}
240
29cbfeaf 241static struct sr_device_instance *zp_open_device(int device_index)
a1bb33af 242{
a00ba012 243 struct sr_device_instance *sdi;
a1bb33af
UH
244 libusb_device **devlist;
245 struct libusb_device_descriptor des;
afc8e4de 246 int err, i;
a1bb33af 247
d32d961d 248 if (!(sdi = sr_get_device_instance(device_instances, device_index)))
a1bb33af
UH
249 return NULL;
250
251 libusb_get_device_list(usb_context, &devlist);
5a2326a7 252 if (sdi->status == SR_ST_INACTIVE) {
fed16f06 253 /* Find the device by vendor, product, bus and address. */
a1bb33af 254 libusb_get_device_list(usb_context, &devlist);
fed16f06 255 for (i = 0; devlist[i]; i++) {
408e7199 256 /* TODO: Error handling. */
9a5c6dcf 257 err = opendev4(&sdi, devlist[i], &des);
a1bb33af 258 }
fed16f06 259 } else {
5a2326a7 260 /* Status must be SR_ST_ACTIVE, i.e. already in use... */
a1bb33af
UH
261 sdi = NULL;
262 }
263 libusb_free_device_list(devlist, 1);
264
5a2326a7 265 if (sdi && sdi->status != SR_ST_ACTIVE)
a1bb33af
UH
266 sdi = NULL;
267
268 return sdi;
269}
270
a00ba012 271static void close_device(struct sr_device_instance *sdi)
a1bb33af 272{
69890f73
UH
273 struct zp *zp;
274
275 if (!(zp = sdi->priv)) {
276 sr_err("zp: %s: sdi->priv was NULL", __func__);
277 return; /* FIXME */
278 }
279
280 if (!zp->usb->devhdl)
408e7199
UH
281 return;
282
b08024a8 283 sr_info("closing device %d on %d.%d interface %d", sdi->index,
69890f73
UH
284 zp->usb->bus, zp->usb->address, USB_INTERFACE);
285 libusb_release_interface(zp->usb->devhdl, USB_INTERFACE);
185ae2c5 286 libusb_reset_device(zp->usb->devhdl);
69890f73
UH
287 libusb_close(zp->usb->devhdl);
288 zp->usb->devhdl = NULL;
185ae2c5 289 /* TODO: Call libusb_exit() here or only in hw_cleanup()? */
5a2326a7 290 sdi->status = SR_ST_INACTIVE;
a1bb33af
UH
291}
292
bf43ea23 293static int configure_probes(struct sr_device_instance *sdi, GSList *probes)
a1bb33af 294{
bf43ea23 295 struct zp *zp;
1afe8989 296 struct sr_probe *probe;
a1bb33af
UH
297 GSList *l;
298 int probe_bit, stage, i;
299 char *tc;
300
bf43ea23
UH
301 /* Note: sdi and sdi->priv are non-NULL, the caller checked this. */
302 zp = sdi->priv;
303
304 zp->probe_mask = 0;
fed16f06 305 for (i = 0; i < NUM_TRIGGER_STAGES; i++) {
bf43ea23
UH
306 zp->trigger_mask[i] = 0;
307 zp->trigger_value[i] = 0;
a1bb33af
UH
308 }
309
310 stage = -1;
fed16f06 311 for (l = probes; l; l = l->next) {
1afe8989 312 probe = (struct sr_probe *)l->data;
fed16f06 313 if (probe->enabled == FALSE)
a1bb33af
UH
314 continue;
315 probe_bit = 1 << (probe->index - 1);
bf43ea23 316 zp->probe_mask |= probe_bit;
fed16f06
UH
317
318 if (probe->trigger) {
a1bb33af 319 stage = 0;
fed16f06 320 for (tc = probe->trigger; *tc; tc++) {
bf43ea23 321 zp->trigger_mask[stage] |= probe_bit;
fed16f06 322 if (*tc == '1')
bf43ea23 323 zp->trigger_value[stage] |= probe_bit;
a1bb33af 324 stage++;
fed16f06 325 if (stage > NUM_TRIGGER_STAGES)
e46b8fb1 326 return SR_ERR;
a1bb33af
UH
327 }
328 }
329 }
330
e46b8fb1 331 return SR_OK;
a1bb33af
UH
332}
333
a1bb33af
UH
334/*
335 * API callbacks
336 */
337
54ac5277 338static int hw_init(const char *deviceinfo)
a1bb33af 339{
a00ba012 340 struct sr_device_instance *sdi;
a1bb33af
UH
341 struct libusb_device_descriptor des;
342 libusb_device **devlist;
343 int err, devcnt, i;
bf43ea23 344 struct zp *zp;
a1bb33af 345
17e1afcb 346 /* Avoid compiler warnings. */
cb93f8a9 347 (void)deviceinfo;
afc8e4de 348
bf43ea23
UH
349 /* Allocate memory for our private driver context. */
350 if (!(zp = g_try_malloc(sizeof(struct zp)))) {
351 sr_err("zp: %s: struct zp malloc failed", __func__);
352 return 0;
353 }
354
355 /* Set some sane defaults. */
356 zp->cur_samplerate = 0;
bf43ea23
UH
357 zp->limit_samples = 0;
358 zp->num_channels = 32; /* TODO: This isn't initialized before it's needed :( */
359 zp->memory_size = 0;
360 zp->probe_mask = 0;
361 memset(zp->trigger_mask, 0, NUM_TRIGGER_STAGES);
362 memset(zp->trigger_value, 0, NUM_TRIGGER_STAGES);
363 // memset(zp->trigger_buffer, 0, NUM_TRIGGER_STAGES);
364
fed16f06 365 if (libusb_init(&usb_context) != 0) {
133a37bf 366 sr_err("Failed to initialize USB.");
a1bb33af
UH
367 return 0;
368 }
369
fed16f06 370 /* Find all ZeroPlus analyzers and add them to device list. */
a1bb33af 371 devcnt = 0;
185ae2c5 372 libusb_get_device_list(usb_context, &devlist); /* TODO: Errors. */
fed16f06
UH
373
374 for (i = 0; devlist[i]; i++) {
a1bb33af 375 err = libusb_get_device_descriptor(devlist[i], &des);
fed16f06 376 if (err != 0) {
133a37bf 377 sr_err("failed to get device descriptor: %d", err);
a1bb33af
UH
378 continue;
379 }
380
fed16f06
UH
381 if (des.idVendor == USB_VENDOR) {
382 /*
383 * Definitely a Zeroplus.
384 * TODO: Any way to detect specific model/version in
385 * the zeroplus range?
386 */
bf43ea23 387 /* Register the device with libsigrok. */
a00ba012 388 sdi = sr_device_instance_new(devcnt,
5a2326a7 389 SR_ST_INACTIVE, USB_VENDOR_NAME,
fed16f06 390 USB_MODEL_NAME, USB_MODEL_VERSION);
bf43ea23
UH
391 if (!sdi) {
392 sr_err("zp: %s: sr_device_instance_new failed",
393 __func__);
a1bb33af 394 return 0;
bf43ea23
UH
395 }
396
397 sdi->priv = zp;
398
fed16f06
UH
399 device_instances =
400 g_slist_append(device_instances, sdi);
69890f73 401 zp->usb = sr_usb_device_instance_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
a1bb33af
UH
412static int hw_opendev(int device_index)
413{
a00ba012 414 struct sr_device_instance *sdi;
bf43ea23 415 struct zp *zp;
a1bb33af
UH
416 int err;
417
fed16f06 418 if (!(sdi = zp_open_device(device_index))) {
133a37bf 419 sr_err("unable to open device");
e46b8fb1 420 return SR_ERR;
a1bb33af
UH
421 }
422
bf43ea23
UH
423 /* TODO: Note: sdi is retrieved in zp_open_device(). */
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) {
133a37bf 439 sr_err("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. */
5a2326a7 465 if (hw_set_configuration(device_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
697785d1 473static int hw_closedev(int device_index)
a1bb33af 474{
a00ba012 475 struct sr_device_instance *sdi;
a1bb33af 476
697785d1 477 if (!(sdi = sr_get_device_instance(device_instances, device_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 */
483 close_device(sdi);
484
485 return SR_OK;
a1bb33af
UH
486}
487
a1bb33af
UH
488static void hw_cleanup(void)
489{
490 GSList *l;
491
408e7199 492 /* Properly close all devices... */
fed16f06 493 for (l = device_instances; l; l = l->next)
a00ba012 494 close_device((struct sr_device_instance *)l->data);
a1bb33af 495
408e7199 496 /* ...and free all their memory. */
fed16f06 497 for (l = device_instances; l; l = l->next)
a1bb33af
UH
498 g_free(l->data);
499 g_slist_free(device_instances);
500 device_instances = NULL;
501
fed16f06 502 if (usb_context)
a1bb33af
UH
503 libusb_exit(usb_context);
504 usb_context = NULL;
a1bb33af
UH
505}
506
a1bb33af
UH
507static void *hw_get_device_info(int device_index, int device_info_id)
508{
a00ba012 509 struct sr_device_instance *sdi;
bf43ea23
UH
510 struct zp *zp;
511 void *info;
a1bb33af 512
bf43ea23
UH
513 if (!(sdi = sr_get_device_instance(device_instances, device_index))) {
514 sr_err("zp: %s: sdi was NULL", __func__);
a1bb33af 515 return NULL;
bf43ea23
UH
516 }
517
518 if (!(zp = sdi->priv)) {
519 sr_err("zp: %s: sdi->priv was NULL", __func__);
520 return NULL;
521 }
a1bb33af 522
fed16f06 523 switch (device_info_id) {
5a2326a7 524 case SR_DI_INSTANCE:
a1bb33af
UH
525 info = sdi;
526 break;
5a2326a7 527 case SR_DI_NUM_PROBES:
bf43ea23 528 info = GINT_TO_POINTER(zp->num_channels);
a1bb33af 529 break;
464d12c7
KS
530 case SR_DI_PROBE_NAMES:
531 info = probe_names;
532 break;
5a2326a7 533 case SR_DI_SAMPLERATES:
a1bb33af
UH
534 info = &samplerates;
535 break;
5a2326a7 536 case SR_DI_TRIGGER_TYPES:
a1bb33af
UH
537 info = TRIGGER_TYPES;
538 break;
5a2326a7 539 case SR_DI_CUR_SAMPLERATE:
bf43ea23
UH
540 info = &zp->cur_samplerate;
541 break;
542 default:
543 /* Unknown device info ID, return NULL. */
544 sr_err("zp: %s: Unknown device info ID", __func__);
545 info = NULL;
a1bb33af
UH
546 break;
547 }
548
549 return info;
550}
551
a1bb33af
UH
552static int hw_get_status(int device_index)
553{
a00ba012 554 struct sr_device_instance *sdi;
a1bb33af 555
d32d961d 556 sdi = sr_get_device_instance(device_instances, device_index);
fed16f06 557 if (sdi)
a1bb33af
UH
558 return sdi->status;
559 else
5a2326a7 560 return SR_ST_NOT_FOUND;
a1bb33af
UH
561}
562
a1bb33af
UH
563static int *hw_get_capabilities(void)
564{
a1bb33af
UH
565 return capabilities;
566}
567
bf43ea23
UH
568static int set_configuration_samplerate(struct sr_device_instance *sdi,
569 uint64_t samplerate)
a1bb33af 570{
bf43ea23
UH
571 struct zp *zp;
572
573 if (!sdi) {
574 sr_err("zp: %s: sdi was NULL", __func__);
575 return SR_ERR_ARG;
576 }
577
578 if (!(zp = sdi->priv)) {
579 sr_err("zp: %s: sdi->priv was NULL", __func__);
580 return SR_ERR_ARG;
581 }
582
73017cf9
UH
583 sr_info("zp: Setting samplerate to %" PRIu64 "Hz.", samplerate);
584
59df0c77
UH
585 if (samplerate > SR_MHZ(1))
586 analyzer_set_freq(samplerate / SR_MHZ(1), FREQ_SCALE_MHZ);
587 else if (samplerate > SR_KHZ(1))
588 analyzer_set_freq(samplerate / SR_KHZ(1), FREQ_SCALE_KHZ);
a1bb33af 589 else
fed16f06 590 analyzer_set_freq(samplerate, FREQ_SCALE_HZ);
a1bb33af 591
bf43ea23 592 zp->cur_samplerate = samplerate;
a1bb33af 593
e46b8fb1 594 return SR_OK;
a1bb33af
UH
595}
596
597static int hw_set_configuration(int device_index, int capability, void *value)
598{
a00ba012 599 struct sr_device_instance *sdi;
a1bb33af 600 uint64_t *tmp_u64;
bf43ea23 601 struct zp *zp;
a1bb33af 602
bf43ea23
UH
603 if (!(sdi = sr_get_device_instance(device_instances, device_index))) {
604 sr_err("zp: %s: sdi was NULL", __func__);
e46b8fb1 605 return SR_ERR;
bf43ea23
UH
606 }
607
608 if (!(zp = sdi->priv)) {
609 sr_err("zp: %s: sdi->priv was NULL", __func__);
610 return SR_ERR_ARG;
611 }
a1bb33af
UH
612
613 switch (capability) {
5a2326a7 614 case SR_HWCAP_SAMPLERATE:
fed16f06 615 tmp_u64 = value;
bf43ea23 616 return set_configuration_samplerate(sdi, *tmp_u64);
5a2326a7 617 case SR_HWCAP_PROBECONFIG:
bf43ea23 618 return configure_probes(sdi, (GSList *)value);
5a2326a7 619 case SR_HWCAP_LIMIT_SAMPLES:
2458ea65 620 tmp_u64 = value;
bf43ea23 621 zp->limit_samples = *tmp_u64;
e46b8fb1 622 return SR_OK;
fed16f06 623 default:
e46b8fb1 624 return SR_ERR;
a1bb33af
UH
625 }
626}
627
9c939c51 628static int hw_start_acquisition(int device_index, gpointer session_data)
a1bb33af 629{
a00ba012 630 struct sr_device_instance *sdi;
b9c735a2 631 struct sr_datafeed_packet packet;
9c939c51 632 struct sr_datafeed_logic logic;
b9c735a2 633 struct sr_datafeed_header header;
9c939c51 634 uint64_t samples_read;
a1bb33af 635 int res;
afc8e4de 636 unsigned int packet_num;
a1bb33af 637 unsigned char *buf;
bf43ea23 638 struct zp *zp;
a1bb33af 639
bf43ea23
UH
640 if (!(sdi = sr_get_device_instance(device_instances, device_index))) {
641 sr_err("zp: %s: sdi was NULL", __func__);
e46b8fb1 642 return SR_ERR;
bf43ea23
UH
643 }
644
645 if (!(zp = sdi->priv)) {
646 sr_err("zp: %s: sdi->priv was NULL", __func__);
647 return SR_ERR_ARG;
648 }
a1bb33af 649
a143e4e5 650 /* push configured settings to device */
69890f73 651 analyzer_configure(zp->usb->devhdl);
a143e4e5 652
69890f73 653 analyzer_start(zp->usb->devhdl);
b08024a8 654 sr_info("Waiting for data");
69890f73 655 analyzer_wait_data(zp->usb->devhdl);
a1bb33af 656
69890f73
UH
657 sr_info("Stop address = 0x%x", analyzer_get_stop_address(zp->usb->devhdl));
658 sr_info("Now address = 0x%x", analyzer_get_now_address(zp->usb->devhdl));
659 sr_info("Trigger address = 0x%x", analyzer_get_trigger_address(zp->usb->devhdl));
a1bb33af 660
5a2326a7 661 packet.type = SR_DF_HEADER;
9c939c51 662 packet.payload = &header;
a1bb33af
UH
663 header.feed_version = 1;
664 gettimeofday(&header.starttime, NULL);
bf43ea23
UH
665 header.samplerate = zp->cur_samplerate;
666 header.num_logic_probes = zp->num_channels;
9c939c51 667 sr_session_bus(session_data, &packet);
a1bb33af 668
b53738ba 669 if (!(buf = g_try_malloc(PACKET_SIZE))) {
bf43ea23 670 sr_err("zp: %s: buf malloc failed", __func__);
b53738ba
UH
671 return SR_ERR_MALLOC;
672 }
673
9c939c51 674 samples_read = 0;
69890f73 675 analyzer_read_start(zp->usb->devhdl);
fed16f06 676 /* Send the incoming transfer to the session bus. */
bf43ea23 677 for (packet_num = 0; packet_num < (zp->memory_size * 4 / PACKET_SIZE);
fed16f06 678 packet_num++) {
69890f73 679 res = analyzer_read_data(zp->usb->devhdl, buf, PACKET_SIZE);
b08024a8
UH
680 sr_info("Tried to read %llx bytes, actually read %x bytes",
681 PACKET_SIZE, res);
a1bb33af 682
5a2326a7 683 packet.type = SR_DF_LOGIC;
9c939c51
BV
684 packet.payload = &logic;
685 logic.length = PACKET_SIZE;
686 logic.unitsize = 4;
687 logic.data = buf;
688 sr_session_bus(session_data, &packet);
689 samples_read += res / 4;
a1bb33af 690 }
69890f73 691 analyzer_read_stop(zp->usb->devhdl);
a1bb33af
UH
692 g_free(buf);
693
5a2326a7 694 packet.type = SR_DF_END;
9c939c51 695 sr_session_bus(session_data, &packet);
a1bb33af 696
e46b8fb1 697 return SR_OK;
a1bb33af
UH
698}
699
fed16f06 700/* This stops acquisition on ALL devices, ignoring device_index. */
a1bb33af
UH
701static void hw_stop_acquisition(int device_index, gpointer session_device_id)
702{
b9c735a2 703 struct sr_datafeed_packet packet;
a00ba012 704 struct sr_device_instance *sdi;
69890f73 705 struct zp *zp;
a1bb33af 706
5a2326a7 707 packet.type = SR_DF_END;
8a2efef2 708 sr_session_bus(session_device_id, &packet);
a1bb33af 709
69890f73
UH
710 if (!(sdi = sr_get_device_instance(device_instances, device_index))) {
711 sr_err("zp: %s: sdi was NULL", __func__);
712 return; /* FIXME */
713 }
714
715 if (!(zp = sdi->priv)) {
716 sr_err("zp: %s: sdi->priv was NULL", __func__);
717 return; /* FIXME */
718 }
a1bb33af 719
69890f73 720 analyzer_reset(zp->usb->devhdl);
fed16f06 721 /* TODO: Need to cancel and free any queued up transfers. */
a1bb33af
UH
722}
723
ca070ed9 724SR_PRIV struct sr_device_plugin zeroplus_logic_cube_plugin_info = {
e519ba86
UH
725 .name = "zeroplus-logic-cube",
726 .longname = "Zeroplus Logic Cube LAP-C series",
727 .api_version = 1,
728 .init = hw_init,
729 .cleanup = hw_cleanup,
86f5e3d8
UH
730 .opendev = hw_opendev,
731 .closedev = hw_closedev,
e519ba86
UH
732 .get_device_info = hw_get_device_info,
733 .get_status = hw_get_status,
734 .get_capabilities = hw_get_capabilities,
735 .set_configuration = hw_set_configuration,
736 .start_acquisition = hw_start_acquisition,
737 .stop_acquisition = hw_stop_acquisition,
a1bb33af 738};