]> sigrok.org Git - libsigrok.git/blame - hardware/zeroplus-logic-cube/zeroplus.c
sr: add new driver API call: scan()
[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(). */
d68e2d1a 104static GSList *dev_insts = NULL;
a1bb33af
UH
105
106static libusb_context *usb_context = NULL;
107
fed16f06
UH
108/*
109 * The hardware supports more samplerates than these, but these are the
110 * options hardcoded into the vendor's Windows GUI.
111 */
a1bb33af 112
fed16f06
UH
113/*
114 * TODO: We shouldn't support 150MHz and 200MHz on devices that don't go up
115 * that high.
116 */
a533743d 117static const uint64_t supported_samplerates[] = {
c9140419
UH
118 SR_HZ(100),
119 SR_HZ(500),
59df0c77
UH
120 SR_KHZ(1),
121 SR_KHZ(5),
122 SR_KHZ(25),
123 SR_KHZ(50),
124 SR_KHZ(100),
125 SR_KHZ(200),
126 SR_KHZ(400),
127 SR_KHZ(800),
128 SR_MHZ(1),
129 SR_MHZ(10),
130 SR_MHZ(25),
131 SR_MHZ(50),
132 SR_MHZ(80),
133 SR_MHZ(100),
134 SR_MHZ(150),
135 SR_MHZ(200),
fed16f06 136 0,
a1bb33af
UH
137};
138
a533743d 139static const struct sr_samplerates samplerates = {
590b9f9a
UH
140 0,
141 0,
142 0,
fed16f06 143 supported_samplerates,
a1bb33af
UH
144};
145
ea9cfed7
UH
146/* Private, per-device-instance driver context. */
147struct context {
bf43ea23 148 uint64_t cur_samplerate;
bf43ea23
UH
149 uint64_t limit_samples;
150 int num_channels; /* TODO: This isn't initialized before it's needed :( */
151 uint64_t memory_size;
152 uint8_t probe_mask;
153 uint8_t trigger_mask[NUM_TRIGGER_STAGES];
154 uint8_t trigger_value[NUM_TRIGGER_STAGES];
155 // uint8_t trigger_buffer[NUM_TRIGGER_STAGES];
69890f73 156
d68e2d1a 157 struct sr_usb_dev_inst *usb;
bf43ea23 158};
a1bb33af 159
1b79df2f 160static int hw_dev_config_set(int dev_index, int hwcap, const void *value);
a1bb33af
UH
161
162static unsigned int get_memory_size(int type)
163{
fed16f06
UH
164 if (type == MEMORY_SIZE_8K)
165 return 8 * 1024;
166 else if (type == MEMORY_SIZE_64K)
167 return 64 * 1024;
168 else if (type == MEMORY_SIZE_128K)
169 return 128 * 1024;
170 else if (type == MEMORY_SIZE_512K)
171 return 512 * 1024;
172 else
173 return 0;
a1bb33af
UH
174}
175
d68e2d1a 176static int opendev4(struct sr_dev_inst **sdi, libusb_device *dev,
408e7199
UH
177 struct libusb_device_descriptor *des)
178{
ea9cfed7 179 struct context *ctx;
9a498834 180 unsigned int i;
ebc34738 181 int ret;
408e7199 182
bf43ea23
UH
183 /* Note: sdi is non-NULL, the caller already checked this. */
184
ea9cfed7 185 if (!(ctx = (*sdi)->priv)) {
bf43ea23
UH
186 sr_err("zp: %s: (*sdi)->priv was NULL", __func__);
187 return -1;
188 }
189
ebc34738
UH
190 if ((ret = libusb_get_device_descriptor(dev, des))) {
191 sr_err("zp: failed to get device descriptor: %d", ret);
408e7199
UH
192 return -1;
193 }
194
9a498834 195 if (des->idVendor != USB_VENDOR)
408e7199
UH
196 return 0;
197
ea9cfed7
UH
198 if (libusb_get_bus_number(dev) == ctx->usb->bus
199 && libusb_get_device_address(dev) == ctx->usb->address) {
408e7199 200
9a498834
UH
201 for (i = 0; i < ARRAY_SIZE(zeroplus_models); i++) {
202 if (!(des->idProduct == zeroplus_models[i].pid))
408e7199
UH
203 continue;
204
8fdecced 205 sr_info("zp: Found ZEROPLUS device 0x%04x (%s)",
7b48d6e1 206 des->idProduct, zeroplus_models[i].model_name);
ea9cfed7
UH
207 ctx->num_channels = zeroplus_models[i].channels;
208 ctx->memory_size = zeroplus_models[i].sample_depth * 1024;
408e7199
UH
209 break;
210 }
211
ea9cfed7 212 if (ctx->num_channels == 0) {
8fdecced 213 sr_err("zp: Unknown ZEROPLUS device 0x%04x",
7b48d6e1 214 des->idProduct);
408e7199
UH
215 return -2;
216 }
217
218 /* Found it. */
ebc34738 219 if (!(ret = libusb_open(dev, &(ctx->usb->devhdl)))) {
5a2326a7 220 (*sdi)->status = SR_ST_ACTIVE;
7b48d6e1 221 sr_info("zp: opened device %d on %d.%d interface %d",
ea9cfed7
UH
222 (*sdi)->index, ctx->usb->bus,
223 ctx->usb->address, USB_INTERFACE);
408e7199 224 } else {
ebc34738 225 sr_err("zp: failed to open device: %d", ret);
408e7199
UH
226 *sdi = NULL;
227 }
228 }
229
230 return 0;
231}
232
bb7ef793 233static struct sr_dev_inst *zp_open_dev(int dev_index)
a1bb33af 234{
d68e2d1a 235 struct sr_dev_inst *sdi;
a1bb33af
UH
236 libusb_device **devlist;
237 struct libusb_device_descriptor des;
2285cf9b 238 int i;
a1bb33af 239
bb7ef793 240 if (!(sdi = sr_dev_inst_get(dev_insts, dev_index)))
a1bb33af
UH
241 return NULL;
242
243 libusb_get_device_list(usb_context, &devlist);
5a2326a7 244 if (sdi->status == SR_ST_INACTIVE) {
fed16f06 245 /* Find the device by vendor, product, bus and address. */
a1bb33af 246 libusb_get_device_list(usb_context, &devlist);
fed16f06 247 for (i = 0; devlist[i]; i++) {
408e7199 248 /* TODO: Error handling. */
2285cf9b 249 opendev4(&sdi, devlist[i], &des);
a1bb33af 250 }
fed16f06 251 } else {
5a2326a7 252 /* Status must be SR_ST_ACTIVE, i.e. already in use... */
a1bb33af
UH
253 sdi = NULL;
254 }
255 libusb_free_device_list(devlist, 1);
256
5a2326a7 257 if (sdi && sdi->status != SR_ST_ACTIVE)
a1bb33af
UH
258 sdi = NULL;
259
260 return sdi;
261}
262
bb7ef793 263static void close_dev(struct sr_dev_inst *sdi)
a1bb33af 264{
ea9cfed7 265 struct context *ctx;
69890f73 266
ea9cfed7 267 if (!(ctx = sdi->priv)) {
69890f73
UH
268 sr_err("zp: %s: sdi->priv was NULL", __func__);
269 return; /* FIXME */
270 }
271
ea9cfed7 272 if (!ctx->usb->devhdl)
408e7199
UH
273 return;
274
7b48d6e1 275 sr_info("zp: closing device %d on %d.%d interface %d", sdi->index,
ea9cfed7
UH
276 ctx->usb->bus, ctx->usb->address, USB_INTERFACE);
277 libusb_release_interface(ctx->usb->devhdl, USB_INTERFACE);
278 libusb_reset_device(ctx->usb->devhdl);
279 libusb_close(ctx->usb->devhdl);
280 ctx->usb->devhdl = NULL;
185ae2c5 281 /* TODO: Call libusb_exit() here or only in hw_cleanup()? */
5a2326a7 282 sdi->status = SR_ST_INACTIVE;
a1bb33af
UH
283}
284
1b79df2f 285static int configure_probes(struct sr_dev_inst *sdi, const GSList *probes)
a1bb33af 286{
ea9cfed7 287 struct context *ctx;
1b79df2f
JH
288 const struct sr_probe *probe;
289 const GSList *l;
a1bb33af
UH
290 int probe_bit, stage, i;
291 char *tc;
292
bf43ea23 293 /* Note: sdi and sdi->priv are non-NULL, the caller checked this. */
ea9cfed7 294 ctx = sdi->priv;
bf43ea23 295
ea9cfed7 296 ctx->probe_mask = 0;
fed16f06 297 for (i = 0; i < NUM_TRIGGER_STAGES; i++) {
ea9cfed7
UH
298 ctx->trigger_mask[i] = 0;
299 ctx->trigger_value[i] = 0;
a1bb33af
UH
300 }
301
302 stage = -1;
fed16f06 303 for (l = probes; l; l = l->next) {
1afe8989 304 probe = (struct sr_probe *)l->data;
fed16f06 305 if (probe->enabled == FALSE)
a1bb33af
UH
306 continue;
307 probe_bit = 1 << (probe->index - 1);
ea9cfed7 308 ctx->probe_mask |= probe_bit;
fed16f06
UH
309
310 if (probe->trigger) {
a1bb33af 311 stage = 0;
fed16f06 312 for (tc = probe->trigger; *tc; tc++) {
ea9cfed7 313 ctx->trigger_mask[stage] |= probe_bit;
fed16f06 314 if (*tc == '1')
ea9cfed7 315 ctx->trigger_value[stage] |= probe_bit;
a1bb33af 316 stage++;
fed16f06 317 if (stage > NUM_TRIGGER_STAGES)
e46b8fb1 318 return SR_ERR;
a1bb33af
UH
319 }
320 }
321 }
322
e46b8fb1 323 return SR_OK;
a1bb33af
UH
324}
325
a1bb33af
UH
326/*
327 * API callbacks
328 */
329
40dda2c3 330static int hw_init(void)
61136ea6
BV
331{
332
333 /* Nothing to do. */
334
335 return SR_OK;
336}
337
338static int hw_scan(void)
a1bb33af 339{
d68e2d1a 340 struct sr_dev_inst *sdi;
a1bb33af
UH
341 struct libusb_device_descriptor des;
342 libusb_device **devlist;
ebc34738 343 int ret, devcnt, i;
ea9cfed7 344 struct context *ctx;
a1bb33af 345
bf43ea23 346 /* Allocate memory for our private driver context. */
ea9cfed7
UH
347 if (!(ctx = g_try_malloc(sizeof(struct context)))) {
348 sr_err("zp: %s: ctx malloc failed", __func__);
bf43ea23
UH
349 return 0;
350 }
351
352 /* Set some sane defaults. */
ea9cfed7
UH
353 ctx->cur_samplerate = 0;
354 ctx->limit_samples = 0;
6752905e
UH
355 /* TODO: num_channels isn't initialized before it's needed :( */
356 ctx->num_channels = NUM_PROBES;
ea9cfed7
UH
357 ctx->memory_size = 0;
358 ctx->probe_mask = 0;
359 memset(ctx->trigger_mask, 0, NUM_TRIGGER_STAGES);
360 memset(ctx->trigger_value, 0, NUM_TRIGGER_STAGES);
361 // memset(ctx->trigger_buffer, 0, NUM_TRIGGER_STAGES);
bf43ea23 362
fed16f06 363 if (libusb_init(&usb_context) != 0) {
7b48d6e1 364 sr_err("zp: Failed to initialize USB.");
a1bb33af
UH
365 return 0;
366 }
367
8fdecced 368 /* Find all ZEROPLUS analyzers and add them to device list. */
a1bb33af 369 devcnt = 0;
185ae2c5 370 libusb_get_device_list(usb_context, &devlist); /* TODO: Errors. */
fed16f06
UH
371
372 for (i = 0; devlist[i]; i++) {
ebc34738
UH
373 ret = libusb_get_device_descriptor(devlist[i], &des);
374 if (ret != 0) {
375 sr_err("zp: failed to get device descriptor: %d", ret);
a1bb33af
UH
376 continue;
377 }
378
fed16f06
UH
379 if (des.idVendor == USB_VENDOR) {
380 /*
8fdecced 381 * Definitely a ZEROPLUS.
fed16f06 382 * TODO: Any way to detect specific model/version in
8fdecced 383 * the ZEROPLUS range?
fed16f06 384 */
bf43ea23 385 /* Register the device with libsigrok. */
d68e2d1a 386 if (!(sdi = sr_dev_inst_new(devcnt,
8fdecced
UH
387 SR_ST_INACTIVE, VENDOR_NAME,
388 MODEL_NAME, MODEL_VERSION))) {
d68e2d1a 389 sr_err("zp: %s: sr_dev_inst_new failed",
bf43ea23 390 __func__);
a1bb33af 391 return 0;
bf43ea23
UH
392 }
393
ea9cfed7 394 sdi->priv = ctx;
bf43ea23 395
d68e2d1a
UH
396 dev_insts =
397 g_slist_append(dev_insts, 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
bb7ef793 474 if (!(sdi = sr_dev_inst_get(dev_insts, 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
d68e2d1a 490 for (l = dev_insts; 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 }
d68e2d1a
UH
497 g_slist_free(dev_insts);
498 dev_insts = 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
bb7ef793 513 if (!(sdi = sr_dev_inst_get(dev_insts, 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
bb7ef793 567 sdi = sr_dev_inst_get(dev_insts, 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
bb7ef793 612 if (!(sdi = sr_dev_inst_get(dev_insts, 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
bb7ef793 648 if (!(sdi = sr_dev_inst_get(dev_insts, 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
bb7ef793 726 if (!(sdi = sr_dev_inst_get(dev_insts, 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,
a1bb33af 757};