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