]> sigrok.org Git - libsigrok.git/blame - hardware/zeroplus-logic-cube/zeroplus.c
zeroplus-logic-cube: 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
4ca38984 339static GSList *hw_scan(GSList *options)
a1bb33af 340{
d68e2d1a 341 struct sr_dev_inst *sdi;
a1bb33af 342 struct libusb_device_descriptor des;
4ca38984 343 GSList *devices;
a1bb33af 344 libusb_device **devlist;
ebc34738 345 int ret, devcnt, i;
ea9cfed7 346 struct context *ctx;
a1bb33af 347
4ca38984
BV
348 (void)options;
349 devices = NULL;
350
bf43ea23 351 /* Allocate memory for our private driver context. */
ea9cfed7
UH
352 if (!(ctx = g_try_malloc(sizeof(struct context)))) {
353 sr_err("zp: %s: ctx malloc failed", __func__);
bf43ea23
UH
354 return 0;
355 }
356
357 /* Set some sane defaults. */
ea9cfed7
UH
358 ctx->cur_samplerate = 0;
359 ctx->limit_samples = 0;
6752905e
UH
360 /* TODO: num_channels isn't initialized before it's needed :( */
361 ctx->num_channels = NUM_PROBES;
ea9cfed7
UH
362 ctx->memory_size = 0;
363 ctx->probe_mask = 0;
364 memset(ctx->trigger_mask, 0, NUM_TRIGGER_STAGES);
365 memset(ctx->trigger_value, 0, NUM_TRIGGER_STAGES);
366 // memset(ctx->trigger_buffer, 0, NUM_TRIGGER_STAGES);
bf43ea23 367
fed16f06 368 if (libusb_init(&usb_context) != 0) {
7b48d6e1 369 sr_err("zp: Failed to initialize USB.");
a1bb33af
UH
370 return 0;
371 }
372
8fdecced 373 /* Find all ZEROPLUS analyzers and add them to device list. */
a1bb33af 374 devcnt = 0;
185ae2c5 375 libusb_get_device_list(usb_context, &devlist); /* TODO: Errors. */
fed16f06
UH
376
377 for (i = 0; devlist[i]; i++) {
ebc34738
UH
378 ret = libusb_get_device_descriptor(devlist[i], &des);
379 if (ret != 0) {
380 sr_err("zp: failed to get device descriptor: %d", ret);
a1bb33af
UH
381 continue;
382 }
383
fed16f06
UH
384 if (des.idVendor == USB_VENDOR) {
385 /*
8fdecced 386 * Definitely a ZEROPLUS.
fed16f06 387 * TODO: Any way to detect specific model/version in
8fdecced 388 * the ZEROPLUS range?
fed16f06 389 */
bf43ea23 390 /* Register the device with libsigrok. */
d68e2d1a 391 if (!(sdi = sr_dev_inst_new(devcnt,
8fdecced
UH
392 SR_ST_INACTIVE, VENDOR_NAME,
393 MODEL_NAME, MODEL_VERSION))) {
d68e2d1a 394 sr_err("zp: %s: sr_dev_inst_new failed",
bf43ea23 395 __func__);
a1bb33af 396 return 0;
bf43ea23
UH
397 }
398
ea9cfed7 399 sdi->priv = ctx;
bf43ea23 400
4ca38984 401 devices = g_slist_append(devices, sdi);
32756547 402 zdi->instances = g_slist_append(zdi->instances, sdi);
ea9cfed7 403 ctx->usb = sr_usb_dev_inst_new(
fed16f06
UH
404 libusb_get_bus_number(devlist[i]),
405 libusb_get_device_address(devlist[i]), NULL);
a1bb33af
UH
406 devcnt++;
407 }
408 }
409 libusb_free_device_list(devlist, 1);
410
4ca38984 411 return devices;
a1bb33af
UH
412}
413
e7eb703f 414static int hw_dev_open(int dev_index)
a1bb33af 415{
d68e2d1a 416 struct sr_dev_inst *sdi;
ea9cfed7 417 struct context *ctx;
ebc34738 418 int ret;
a1bb33af 419
bb7ef793 420 if (!(sdi = zp_open_dev(dev_index))) {
7b48d6e1 421 sr_err("zp: unable to open device");
e46b8fb1 422 return SR_ERR;
a1bb33af
UH
423 }
424
bb7ef793 425 /* TODO: Note: sdi is retrieved in zp_open_dev(). */
bf43ea23 426
ea9cfed7 427 if (!(ctx = sdi->priv)) {
bf43ea23
UH
428 sr_err("zp: %s: sdi->priv was NULL", __func__);
429 return SR_ERR_ARG;
430 }
431
ebc34738
UH
432 ret = libusb_set_configuration(ctx->usb->devhdl, USB_CONFIGURATION);
433 if (ret < 0) {
133a37bf 434 sr_err("zp: Unable to set USB configuration %d: %d",
ebc34738 435 USB_CONFIGURATION, ret);
185ae2c5
UH
436 return SR_ERR;
437 }
438
ebc34738
UH
439 ret = libusb_claim_interface(ctx->usb->devhdl, USB_INTERFACE);
440 if (ret != 0) {
441 sr_err("zp: Unable to claim interface: %d", ret);
e46b8fb1 442 return SR_ERR;
a1bb33af 443 }
185ae2c5 444
ea9cfed7
UH
445 analyzer_reset(ctx->usb->devhdl);
446 analyzer_initialize(ctx->usb->devhdl);
a1bb33af
UH
447
448 analyzer_set_memory_size(MEMORY_SIZE_512K);
fed16f06 449 // analyzer_set_freq(g_freq, g_freq_scale);
a1bb33af 450 analyzer_set_trigger_count(1);
408e7199
UH
451 // analyzer_set_ramsize_trigger_address((((100 - g_pre_trigger)
452 // * get_memory_size(g_memory_size)) / 100) >> 2);
fed16f06
UH
453 analyzer_set_ramsize_trigger_address(
454 (100 * get_memory_size(MEMORY_SIZE_512K) / 100) >> 2);
a1bb33af 455
fed16f06
UH
456#if 0
457 if (g_double_mode == 1)
a1bb33af
UH
458 analyzer_set_compression(COMPRESSION_DOUBLE);
459 else if (g_compression == 1)
460 analyzer_set_compression(COMPRESSION_ENABLE);
fed16f06
UH
461 else
462#endif
463 analyzer_set_compression(COMPRESSION_NONE);
a1bb33af 464
ea9cfed7 465 if (ctx->cur_samplerate == 0) {
408e7199 466 /* Samplerate hasn't been set. Default to the slowest one. */
a9a245b4 467 if (hw_dev_config_set(dev_index, SR_HWCAP_SAMPLERATE,
73017cf9 468 &samplerates.list[0]) == SR_ERR)
e46b8fb1 469 return SR_ERR;
a1bb33af
UH
470 }
471
e46b8fb1 472 return SR_OK;
a1bb33af
UH
473}
474
e7eb703f 475static int hw_dev_close(int dev_index)
a1bb33af 476{
d68e2d1a 477 struct sr_dev_inst *sdi;
a1bb33af 478
32756547 479 if (!(sdi = sr_dev_inst_get(zdi->instances, dev_index))) {
bf43ea23 480 sr_err("zp: %s: sdi was NULL", __func__);
697785d1
UH
481 return SR_ERR; /* TODO: SR_ERR_ARG? */
482 }
483
484 /* TODO */
bb7ef793 485 close_dev(sdi);
697785d1
UH
486
487 return SR_OK;
a1bb33af
UH
488}
489
57ab7d9f 490static int hw_cleanup(void)
a1bb33af
UH
491{
492 GSList *l;
d68e2d1a 493 struct sr_dev_inst *sdi;
a1bb33af 494
32756547 495 for (l = zdi->instances; l; l = l->next) {
341ce415
BV
496 sdi = l->data;
497 /* Properly close all devices... */
bb7ef793 498 close_dev(sdi);
341ce415
BV
499 /* ...and free all their memory. */
500 sr_dev_inst_free(sdi);
501 }
32756547
BV
502 g_slist_free(zdi->instances);
503 zdi->instances = NULL;
a1bb33af 504
fed16f06 505 if (usb_context)
a1bb33af
UH
506 libusb_exit(usb_context);
507 usb_context = NULL;
57ab7d9f
UH
508
509 return SR_OK;
a1bb33af
UH
510}
511
b7f578be 512static const void *hw_dev_info_get(int dev_index, int dev_info_id)
a1bb33af 513{
d68e2d1a 514 struct sr_dev_inst *sdi;
ea9cfed7 515 struct context *ctx;
b7f578be 516 const void *info;
a1bb33af 517
32756547 518 if (!(sdi = sr_dev_inst_get(zdi->instances, dev_index))) {
bf43ea23 519 sr_err("zp: %s: sdi was NULL", __func__);
a1bb33af 520 return NULL;
bf43ea23
UH
521 }
522
ea9cfed7 523 if (!(ctx = sdi->priv)) {
bf43ea23
UH
524 sr_err("zp: %s: sdi->priv was NULL", __func__);
525 return NULL;
526 }
a1bb33af 527
6752905e
UH
528 sr_spew("zp: %s: dev_index %d, dev_info_id %d.", __func__,
529 dev_index, dev_info_id);
530
bb7ef793 531 switch (dev_info_id) {
1d9a8a5f 532 case SR_DI_INST:
a1bb33af 533 info = sdi;
6752905e 534 sr_spew("zp: %s: Returning sdi.", __func__);
a1bb33af 535 break;
5a2326a7 536 case SR_DI_NUM_PROBES:
ea9cfed7 537 info = GINT_TO_POINTER(ctx->num_channels);
6752905e
UH
538 sr_spew("zp: %s: Returning number of probes: %d.", __func__,
539 NUM_PROBES);
a1bb33af 540 break;
464d12c7
KS
541 case SR_DI_PROBE_NAMES:
542 info = probe_names;
6752905e 543 sr_spew("zp: %s: Returning probenames.", __func__);
464d12c7 544 break;
5a2326a7 545 case SR_DI_SAMPLERATES:
a1bb33af 546 info = &samplerates;
6752905e 547 sr_spew("zp: %s: Returning samplerates.", __func__);
a1bb33af 548 break;
5a2326a7 549 case SR_DI_TRIGGER_TYPES:
a1bb33af 550 info = TRIGGER_TYPES;
6752905e 551 sr_spew("zp: %s: Returning triggertypes: %s.", __func__, info);
a1bb33af 552 break;
5a2326a7 553 case SR_DI_CUR_SAMPLERATE:
ea9cfed7 554 info = &ctx->cur_samplerate;
6752905e
UH
555 sr_spew("zp: %s: Returning samplerate: %" PRIu64 "Hz.",
556 __func__, ctx->cur_samplerate);
bf43ea23
UH
557 break;
558 default:
559 /* Unknown device info ID, return NULL. */
560 sr_err("zp: %s: Unknown device info ID", __func__);
561 info = NULL;
a1bb33af
UH
562 break;
563 }
564
565 return info;
566}
567
e7eb703f 568static int hw_dev_status_get(int dev_index)
a1bb33af 569{
d68e2d1a 570 struct sr_dev_inst *sdi;
a1bb33af 571
32756547 572 sdi = sr_dev_inst_get(zdi->instances, dev_index);
fed16f06 573 if (sdi)
a1bb33af
UH
574 return sdi->status;
575 else
5a2326a7 576 return SR_ST_NOT_FOUND;
a1bb33af
UH
577}
578
915f7cc8 579static const int *hw_hwcap_get_all(void)
a1bb33af 580{
ffedd0bf 581 return hwcaps;
a1bb33af
UH
582}
583
a9a245b4 584static int set_samplerate(struct sr_dev_inst *sdi, uint64_t samplerate)
a1bb33af 585{
ea9cfed7 586 struct context *ctx;
bf43ea23
UH
587
588 if (!sdi) {
589 sr_err("zp: %s: sdi was NULL", __func__);
590 return SR_ERR_ARG;
591 }
592
ea9cfed7 593 if (!(ctx = sdi->priv)) {
bf43ea23
UH
594 sr_err("zp: %s: sdi->priv was NULL", __func__);
595 return SR_ERR_ARG;
596 }
597
73017cf9
UH
598 sr_info("zp: Setting samplerate to %" PRIu64 "Hz.", samplerate);
599
59df0c77
UH
600 if (samplerate > SR_MHZ(1))
601 analyzer_set_freq(samplerate / SR_MHZ(1), FREQ_SCALE_MHZ);
602 else if (samplerate > SR_KHZ(1))
603 analyzer_set_freq(samplerate / SR_KHZ(1), FREQ_SCALE_KHZ);
a1bb33af 604 else
fed16f06 605 analyzer_set_freq(samplerate, FREQ_SCALE_HZ);
a1bb33af 606
ea9cfed7 607 ctx->cur_samplerate = samplerate;
a1bb33af 608
e46b8fb1 609 return SR_OK;
a1bb33af
UH
610}
611
1b79df2f 612static int hw_dev_config_set(int dev_index, int hwcap, const void *value)
a1bb33af 613{
d68e2d1a 614 struct sr_dev_inst *sdi;
ea9cfed7 615 struct context *ctx;
a1bb33af 616
32756547 617 if (!(sdi = sr_dev_inst_get(zdi->instances, dev_index))) {
bf43ea23 618 sr_err("zp: %s: sdi was NULL", __func__);
e46b8fb1 619 return SR_ERR;
bf43ea23
UH
620 }
621
ea9cfed7 622 if (!(ctx = sdi->priv)) {
bf43ea23
UH
623 sr_err("zp: %s: sdi->priv was NULL", __func__);
624 return SR_ERR_ARG;
625 }
a1bb33af 626
ffedd0bf 627 switch (hwcap) {
5a2326a7 628 case SR_HWCAP_SAMPLERATE:
1b79df2f 629 return set_samplerate(sdi, *(const uint64_t *)value);
5a2326a7 630 case SR_HWCAP_PROBECONFIG:
1b79df2f 631 return configure_probes(sdi, (const GSList *)value);
5a2326a7 632 case SR_HWCAP_LIMIT_SAMPLES:
1b79df2f 633 ctx->limit_samples = *(const uint64_t *)value;
e46b8fb1 634 return SR_OK;
fed16f06 635 default:
e46b8fb1 636 return SR_ERR;
a1bb33af
UH
637 }
638}
639
3cd3a20b 640static int hw_dev_acquisition_start(int dev_index, void *cb_data)
a1bb33af 641{
d68e2d1a 642 struct sr_dev_inst *sdi;
b9c735a2 643 struct sr_datafeed_packet packet;
9c939c51 644 struct sr_datafeed_logic logic;
b9c735a2 645 struct sr_datafeed_header header;
f366e86c 646 struct sr_datafeed_meta_logic meta;
9c939c51 647 uint64_t samples_read;
a1bb33af 648 int res;
afc8e4de 649 unsigned int packet_num;
a1bb33af 650 unsigned char *buf;
ea9cfed7 651 struct context *ctx;
a1bb33af 652
32756547 653 if (!(sdi = sr_dev_inst_get(zdi->instances, dev_index))) {
bf43ea23 654 sr_err("zp: %s: sdi was NULL", __func__);
e46b8fb1 655 return SR_ERR;
bf43ea23
UH
656 }
657
ea9cfed7 658 if (!(ctx = sdi->priv)) {
bf43ea23
UH
659 sr_err("zp: %s: sdi->priv was NULL", __func__);
660 return SR_ERR_ARG;
661 }
a1bb33af 662
a143e4e5 663 /* push configured settings to device */
ea9cfed7 664 analyzer_configure(ctx->usb->devhdl);
a143e4e5 665
ea9cfed7 666 analyzer_start(ctx->usb->devhdl);
7b48d6e1 667 sr_info("zp: Waiting for data");
ea9cfed7 668 analyzer_wait_data(ctx->usb->devhdl);
a1bb33af 669
7b48d6e1 670 sr_info("zp: Stop address = 0x%x",
ea9cfed7 671 analyzer_get_stop_address(ctx->usb->devhdl));
7b48d6e1 672 sr_info("zp: Now address = 0x%x",
ea9cfed7 673 analyzer_get_now_address(ctx->usb->devhdl));
7b48d6e1 674 sr_info("zp: Trigger address = 0x%x",
ea9cfed7 675 analyzer_get_trigger_address(ctx->usb->devhdl));
a1bb33af 676
5a2326a7 677 packet.type = SR_DF_HEADER;
9c939c51 678 packet.payload = &header;
a1bb33af
UH
679 header.feed_version = 1;
680 gettimeofday(&header.starttime, NULL);
f366e86c
BV
681 sr_session_send(cb_data, &packet);
682
683 /* Send metadata about the SR_DF_LOGIC packets to come. */
684 packet.type = SR_DF_META_LOGIC;
685 packet.payload = &meta;
686 meta.samplerate = ctx->cur_samplerate;
687 meta.num_probes = ctx->num_channels;
3cd3a20b 688 sr_session_send(cb_data, &packet);
a1bb33af 689
b53738ba 690 if (!(buf = g_try_malloc(PACKET_SIZE))) {
bf43ea23 691 sr_err("zp: %s: buf malloc failed", __func__);
b53738ba
UH
692 return SR_ERR_MALLOC;
693 }
694
9c939c51 695 samples_read = 0;
ea9cfed7 696 analyzer_read_start(ctx->usb->devhdl);
fed16f06 697 /* Send the incoming transfer to the session bus. */
ea9cfed7 698 for (packet_num = 0; packet_num < (ctx->memory_size * 4 / PACKET_SIZE);
fed16f06 699 packet_num++) {
ea9cfed7 700 res = analyzer_read_data(ctx->usb->devhdl, buf, PACKET_SIZE);
7b48d6e1 701 sr_info("zp: Tried to read %llx bytes, actually read %x bytes",
b08024a8 702 PACKET_SIZE, res);
a1bb33af 703
5a2326a7 704 packet.type = SR_DF_LOGIC;
9c939c51
BV
705 packet.payload = &logic;
706 logic.length = PACKET_SIZE;
707 logic.unitsize = 4;
708 logic.data = buf;
3cd3a20b 709 sr_session_send(cb_data, &packet);
9c939c51 710 samples_read += res / 4;
a1bb33af 711 }
ea9cfed7 712 analyzer_read_stop(ctx->usb->devhdl);
a1bb33af
UH
713 g_free(buf);
714
5a2326a7 715 packet.type = SR_DF_END;
3cd3a20b 716 sr_session_send(cb_data, &packet);
a1bb33af 717
e46b8fb1 718 return SR_OK;
a1bb33af
UH
719}
720
3cd3a20b
UH
721/* TODO: This stops acquisition on ALL devices, ignoring dev_index. */
722static int hw_dev_acquisition_stop(int dev_index, void *cb_data)
a1bb33af 723{
b9c735a2 724 struct sr_datafeed_packet packet;
d68e2d1a 725 struct sr_dev_inst *sdi;
ea9cfed7 726 struct context *ctx;
a1bb33af 727
5a2326a7 728 packet.type = SR_DF_END;
3cd3a20b 729 sr_session_send(cb_data, &packet);
a1bb33af 730
32756547 731 if (!(sdi = sr_dev_inst_get(zdi->instances, dev_index))) {
69890f73 732 sr_err("zp: %s: sdi was NULL", __func__);
3010f21c 733 return SR_ERR_BUG;
69890f73
UH
734 }
735
ea9cfed7 736 if (!(ctx = sdi->priv)) {
69890f73 737 sr_err("zp: %s: sdi->priv was NULL", __func__);
3010f21c 738 return SR_ERR_BUG;
69890f73 739 }
a1bb33af 740
ea9cfed7 741 analyzer_reset(ctx->usb->devhdl);
fed16f06 742 /* TODO: Need to cancel and free any queued up transfers. */
3010f21c
UH
743
744 return SR_OK;
a1bb33af
UH
745}
746
c09f0b57 747SR_PRIV struct sr_dev_driver zeroplus_logic_cube_driver_info = {
e519ba86 748 .name = "zeroplus-logic-cube",
8fdecced 749 .longname = "ZEROPLUS Logic Cube LAP-C series",
e519ba86
UH
750 .api_version = 1,
751 .init = hw_init,
752 .cleanup = hw_cleanup,
61136ea6 753 .scan = hw_scan,
e7eb703f
UH
754 .dev_open = hw_dev_open,
755 .dev_close = hw_dev_close,
5097b0d0 756 .dev_info_get = hw_dev_info_get,
e7eb703f 757 .dev_status_get = hw_dev_status_get,
ffedd0bf 758 .hwcap_get_all = hw_hwcap_get_all,
a9a245b4 759 .dev_config_set = hw_dev_config_set,
69040b7c
UH
760 .dev_acquisition_start = hw_dev_acquisition_start,
761 .dev_acquisition_stop = hw_dev_acquisition_stop,
32756547 762 .instances = NULL,
a1bb33af 763};