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