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