]> sigrok.org Git - libsigrok.git/blame - hardware/zeroplus-logic-cube/zeroplus.c
sr: Mark API functions with SR_API/SR_PRIV.
[libsigrok.git] / hardware / zeroplus-logic-cube / zeroplus.c
CommitLineData
a1bb33af
UH
1/*
2 * This file is part of the sigrok project.
3 *
01469707 4 * Copyright (C) 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
66static int capabilities[] = {
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
c37d2b1b 77static const char *probe_names[] = {
464d12c7
KS
78 "0",
79 "1",
80 "2",
81 "3",
82 "4",
83 "5",
84 "6",
85 "7",
86 "8",
87 "9",
88 "10",
89 "11",
90 "12",
91 "13",
92 "14",
93 "15",
94 "16",
95 "17",
96 "18",
97 "19",
98 "20",
99 "21",
100 "22",
101 "23",
102 "24",
103 "25",
104 "26",
105 "27",
106 "28",
107 "29",
108 "30",
109 "31",
110 NULL,
111};
112
a00ba012 113/* List of struct sr_device_instance, maintained by opendev()/closedev(). */
a1bb33af
UH
114static GSList *device_instances = NULL;
115
116static libusb_context *usb_context = NULL;
117
fed16f06
UH
118/*
119 * The hardware supports more samplerates than these, but these are the
120 * options hardcoded into the vendor's Windows GUI.
121 */
a1bb33af 122
fed16f06
UH
123/*
124 * TODO: We shouldn't support 150MHz and 200MHz on devices that don't go up
125 * that high.
126 */
a1bb33af 127static uint64_t supported_samplerates[] = {
c9140419
UH
128 SR_HZ(100),
129 SR_HZ(500),
59df0c77
UH
130 SR_KHZ(1),
131 SR_KHZ(5),
132 SR_KHZ(25),
133 SR_KHZ(50),
134 SR_KHZ(100),
135 SR_KHZ(200),
136 SR_KHZ(400),
137 SR_KHZ(800),
138 SR_MHZ(1),
139 SR_MHZ(10),
140 SR_MHZ(25),
141 SR_MHZ(50),
142 SR_MHZ(80),
143 SR_MHZ(100),
144 SR_MHZ(150),
145 SR_MHZ(200),
fed16f06 146 0,
a1bb33af
UH
147};
148
60679b18 149static struct sr_samplerates samplerates = {
c9140419
UH
150 SR_HZ(0),
151 SR_HZ(0),
152 SR_HZ(0),
fed16f06 153 supported_samplerates,
a1bb33af
UH
154};
155
bf43ea23
UH
156struct zp {
157 uint64_t cur_samplerate;
bf43ea23
UH
158 uint64_t limit_samples;
159 int num_channels; /* TODO: This isn't initialized before it's needed :( */
160 uint64_t memory_size;
161 uint8_t probe_mask;
162 uint8_t trigger_mask[NUM_TRIGGER_STAGES];
163 uint8_t trigger_value[NUM_TRIGGER_STAGES];
164 // uint8_t trigger_buffer[NUM_TRIGGER_STAGES];
69890f73
UH
165
166 struct sr_usb_device_instance *usb;
bf43ea23 167};
a1bb33af
UH
168
169static int hw_set_configuration(int device_index, int capability, void *value);
170
171static unsigned int get_memory_size(int type)
172{
fed16f06
UH
173 if (type == MEMORY_SIZE_8K)
174 return 8 * 1024;
175 else if (type == MEMORY_SIZE_64K)
176 return 64 * 1024;
177 else if (type == MEMORY_SIZE_128K)
178 return 128 * 1024;
179 else if (type == MEMORY_SIZE_512K)
180 return 512 * 1024;
181 else
182 return 0;
a1bb33af
UH
183}
184
a00ba012 185static int opendev4(struct sr_device_instance **sdi, libusb_device *dev,
408e7199
UH
186 struct libusb_device_descriptor *des)
187{
bf43ea23 188 struct zp *zp;
9a498834
UH
189 unsigned int i;
190 int err;
408e7199 191
bf43ea23
UH
192 /* Note: sdi is non-NULL, the caller already checked this. */
193
194 if (!(zp = (*sdi)->priv)) {
195 sr_err("zp: %s: (*sdi)->priv was NULL", __func__);
196 return -1;
197 }
198
408e7199 199 if ((err = libusb_get_device_descriptor(dev, des))) {
b08024a8 200 sr_warn("failed to get device descriptor: %d", err);
408e7199
UH
201 return -1;
202 }
203
9a498834 204 if (des->idVendor != USB_VENDOR)
408e7199
UH
205 return 0;
206
69890f73
UH
207 if (libusb_get_bus_number(dev) == zp->usb->bus
208 && libusb_get_device_address(dev) == zp->usb->address) {
408e7199 209
9a498834
UH
210 for (i = 0; i < ARRAY_SIZE(zeroplus_models); i++) {
211 if (!(des->idProduct == zeroplus_models[i].pid))
408e7199
UH
212 continue;
213
b08024a8
UH
214 sr_info("Found PID=%04X (%s)", des->idProduct,
215 zeroplus_models[i].model_name);
bf43ea23
UH
216 zp->num_channels = zeroplus_models[i].channels;
217 zp->memory_size = zeroplus_models[i].sample_depth * 1024;
408e7199
UH
218 break;
219 }
220
bf43ea23 221 if (zp->num_channels == 0) {
b08024a8 222 sr_warn("Unknown ZeroPlus device %04X", des->idProduct);
408e7199
UH
223 return -2;
224 }
225
226 /* Found it. */
69890f73 227 if (!(err = libusb_open(dev, &(zp->usb->devhdl)))) {
5a2326a7 228 (*sdi)->status = SR_ST_ACTIVE;
b08024a8 229 sr_info("opened device %d on %d.%d interface %d",
69890f73
UH
230 (*sdi)->index, zp->usb->bus,
231 zp->usb->address, USB_INTERFACE);
408e7199 232 } else {
b08024a8 233 sr_warn("failed to open device: %d", err);
408e7199
UH
234 *sdi = NULL;
235 }
236 }
237
238 return 0;
239}
240
29cbfeaf 241static struct sr_device_instance *zp_open_device(int device_index)
a1bb33af 242{
a00ba012 243 struct sr_device_instance *sdi;
a1bb33af
UH
244 libusb_device **devlist;
245 struct libusb_device_descriptor des;
afc8e4de 246 int err, i;
a1bb33af 247
d32d961d 248 if (!(sdi = sr_get_device_instance(device_instances, device_index)))
a1bb33af
UH
249 return NULL;
250
251 libusb_get_device_list(usb_context, &devlist);
5a2326a7 252 if (sdi->status == SR_ST_INACTIVE) {
fed16f06 253 /* Find the device by vendor, product, bus and address. */
a1bb33af 254 libusb_get_device_list(usb_context, &devlist);
fed16f06 255 for (i = 0; devlist[i]; i++) {
408e7199 256 /* TODO: Error handling. */
9a5c6dcf 257 err = opendev4(&sdi, devlist[i], &des);
a1bb33af 258 }
fed16f06 259 } else {
5a2326a7 260 /* Status must be SR_ST_ACTIVE, i.e. already in use... */
a1bb33af
UH
261 sdi = NULL;
262 }
263 libusb_free_device_list(devlist, 1);
264
5a2326a7 265 if (sdi && sdi->status != SR_ST_ACTIVE)
a1bb33af
UH
266 sdi = NULL;
267
268 return sdi;
269}
270
a00ba012 271static void close_device(struct sr_device_instance *sdi)
a1bb33af 272{
69890f73
UH
273 struct zp *zp;
274
275 if (!(zp = sdi->priv)) {
276 sr_err("zp: %s: sdi->priv was NULL", __func__);
277 return; /* FIXME */
278 }
279
280 if (!zp->usb->devhdl)
408e7199
UH
281 return;
282
b08024a8 283 sr_info("closing device %d on %d.%d interface %d", sdi->index,
69890f73
UH
284 zp->usb->bus, zp->usb->address, USB_INTERFACE);
285 libusb_release_interface(zp->usb->devhdl, USB_INTERFACE);
286 libusb_close(zp->usb->devhdl);
287 zp->usb->devhdl = NULL;
5a2326a7 288 sdi->status = SR_ST_INACTIVE;
a1bb33af
UH
289}
290
bf43ea23 291static int configure_probes(struct sr_device_instance *sdi, GSList *probes)
a1bb33af 292{
bf43ea23 293 struct zp *zp;
1afe8989 294 struct sr_probe *probe;
a1bb33af
UH
295 GSList *l;
296 int probe_bit, stage, i;
297 char *tc;
298
bf43ea23
UH
299 /* Note: sdi and sdi->priv are non-NULL, the caller checked this. */
300 zp = sdi->priv;
301
302 zp->probe_mask = 0;
fed16f06 303 for (i = 0; i < NUM_TRIGGER_STAGES; i++) {
bf43ea23
UH
304 zp->trigger_mask[i] = 0;
305 zp->trigger_value[i] = 0;
a1bb33af
UH
306 }
307
308 stage = -1;
fed16f06 309 for (l = probes; l; l = l->next) {
1afe8989 310 probe = (struct sr_probe *)l->data;
fed16f06 311 if (probe->enabled == FALSE)
a1bb33af
UH
312 continue;
313 probe_bit = 1 << (probe->index - 1);
bf43ea23 314 zp->probe_mask |= probe_bit;
fed16f06
UH
315
316 if (probe->trigger) {
a1bb33af 317 stage = 0;
fed16f06 318 for (tc = probe->trigger; *tc; tc++) {
bf43ea23 319 zp->trigger_mask[stage] |= probe_bit;
fed16f06 320 if (*tc == '1')
bf43ea23 321 zp->trigger_value[stage] |= probe_bit;
a1bb33af 322 stage++;
fed16f06 323 if (stage > NUM_TRIGGER_STAGES)
e46b8fb1 324 return SR_ERR;
a1bb33af
UH
325 }
326 }
327 }
328
e46b8fb1 329 return SR_OK;
a1bb33af
UH
330}
331
a1bb33af
UH
332/*
333 * API callbacks
334 */
335
54ac5277 336static int hw_init(const char *deviceinfo)
a1bb33af 337{
a00ba012 338 struct sr_device_instance *sdi;
a1bb33af
UH
339 struct libusb_device_descriptor des;
340 libusb_device **devlist;
341 int err, devcnt, i;
bf43ea23 342 struct zp *zp;
a1bb33af 343
17e1afcb 344 /* Avoid compiler warnings. */
cb93f8a9 345 (void)deviceinfo;
afc8e4de 346
bf43ea23
UH
347 /* Allocate memory for our private driver context. */
348 if (!(zp = g_try_malloc(sizeof(struct zp)))) {
349 sr_err("zp: %s: struct zp malloc failed", __func__);
350 return 0;
351 }
352
353 /* Set some sane defaults. */
354 zp->cur_samplerate = 0;
bf43ea23
UH
355 zp->limit_samples = 0;
356 zp->num_channels = 32; /* TODO: This isn't initialized before it's needed :( */
357 zp->memory_size = 0;
358 zp->probe_mask = 0;
359 memset(zp->trigger_mask, 0, NUM_TRIGGER_STAGES);
360 memset(zp->trigger_value, 0, NUM_TRIGGER_STAGES);
361 // memset(zp->trigger_buffer, 0, NUM_TRIGGER_STAGES);
362
fed16f06 363 if (libusb_init(&usb_context) != 0) {
b08024a8 364 sr_warn("Failed to initialize USB.");
a1bb33af
UH
365 return 0;
366 }
367
fed16f06 368 /* Find all ZeroPlus analyzers and add them to device list. */
a1bb33af
UH
369 devcnt = 0;
370 libusb_get_device_list(usb_context, &devlist);
fed16f06
UH
371
372 for (i = 0; devlist[i]; i++) {
a1bb33af 373 err = libusb_get_device_descriptor(devlist[i], &des);
fed16f06 374 if (err != 0) {
b08024a8 375 sr_warn("failed to get device descriptor: %d", err);
a1bb33af
UH
376 continue;
377 }
378
fed16f06
UH
379 if (des.idVendor == USB_VENDOR) {
380 /*
381 * Definitely a Zeroplus.
382 * TODO: Any way to detect specific model/version in
383 * the zeroplus range?
384 */
bf43ea23 385 /* Register the device with libsigrok. */
a00ba012 386 sdi = sr_device_instance_new(devcnt,
5a2326a7 387 SR_ST_INACTIVE, USB_VENDOR_NAME,
fed16f06 388 USB_MODEL_NAME, USB_MODEL_VERSION);
bf43ea23
UH
389 if (!sdi) {
390 sr_err("zp: %s: sr_device_instance_new failed",
391 __func__);
a1bb33af 392 return 0;
bf43ea23
UH
393 }
394
395 sdi->priv = zp;
396
fed16f06
UH
397 device_instances =
398 g_slist_append(device_instances, sdi);
69890f73 399 zp->usb = sr_usb_device_instance_new(
fed16f06
UH
400 libusb_get_bus_number(devlist[i]),
401 libusb_get_device_address(devlist[i]), NULL);
a1bb33af
UH
402 devcnt++;
403 }
404 }
405 libusb_free_device_list(devlist, 1);
406
407 return devcnt;
408}
409
a1bb33af
UH
410static int hw_opendev(int device_index)
411{
a00ba012 412 struct sr_device_instance *sdi;
bf43ea23 413 struct zp *zp;
a1bb33af
UH
414 int err;
415
fed16f06 416 if (!(sdi = zp_open_device(device_index))) {
b08024a8 417 sr_warn("unable to open device");
e46b8fb1 418 return SR_ERR;
a1bb33af
UH
419 }
420
bf43ea23
UH
421 /* TODO: Note: sdi is retrieved in zp_open_device(). */
422
423 if (!(zp = sdi->priv)) {
424 sr_err("zp: %s: sdi->priv was NULL", __func__);
425 return SR_ERR_ARG;
426 }
427
69890f73 428 err = libusb_claim_interface(zp->usb->devhdl, USB_INTERFACE);
fed16f06 429 if (err != 0) {
b08024a8 430 sr_warn("Unable to claim interface: %d", err);
e46b8fb1 431 return SR_ERR;
a1bb33af 432 }
69890f73
UH
433 analyzer_reset(zp->usb->devhdl);
434 analyzer_initialize(zp->usb->devhdl);
a1bb33af
UH
435
436 analyzer_set_memory_size(MEMORY_SIZE_512K);
fed16f06 437 // analyzer_set_freq(g_freq, g_freq_scale);
a1bb33af 438 analyzer_set_trigger_count(1);
408e7199
UH
439 // analyzer_set_ramsize_trigger_address((((100 - g_pre_trigger)
440 // * get_memory_size(g_memory_size)) / 100) >> 2);
fed16f06
UH
441 analyzer_set_ramsize_trigger_address(
442 (100 * get_memory_size(MEMORY_SIZE_512K) / 100) >> 2);
a1bb33af 443
fed16f06
UH
444#if 0
445 if (g_double_mode == 1)
a1bb33af
UH
446 analyzer_set_compression(COMPRESSION_DOUBLE);
447 else if (g_compression == 1)
448 analyzer_set_compression(COMPRESSION_ENABLE);
fed16f06
UH
449 else
450#endif
451 analyzer_set_compression(COMPRESSION_NONE);
a1bb33af 452
bf43ea23 453 if (zp->cur_samplerate == 0) {
408e7199 454 /* Samplerate hasn't been set. Default to the slowest one. */
5a2326a7 455 if (hw_set_configuration(device_index, SR_HWCAP_SAMPLERATE,
73017cf9 456 &samplerates.list[0]) == SR_ERR)
e46b8fb1 457 return SR_ERR;
a1bb33af
UH
458 }
459
e46b8fb1 460 return SR_OK;
a1bb33af
UH
461}
462
697785d1 463static int hw_closedev(int device_index)
a1bb33af 464{
a00ba012 465 struct sr_device_instance *sdi;
a1bb33af 466
697785d1 467 if (!(sdi = sr_get_device_instance(device_instances, device_index))) {
bf43ea23 468 sr_err("zp: %s: sdi was NULL", __func__);
697785d1
UH
469 return SR_ERR; /* TODO: SR_ERR_ARG? */
470 }
471
472 /* TODO */
473 close_device(sdi);
474
475 return SR_OK;
a1bb33af
UH
476}
477
a1bb33af
UH
478static void hw_cleanup(void)
479{
480 GSList *l;
481
408e7199 482 /* Properly close all devices... */
fed16f06 483 for (l = device_instances; l; l = l->next)
a00ba012 484 close_device((struct sr_device_instance *)l->data);
a1bb33af 485
408e7199 486 /* ...and free all their memory. */
fed16f06 487 for (l = device_instances; l; l = l->next)
a1bb33af
UH
488 g_free(l->data);
489 g_slist_free(device_instances);
490 device_instances = NULL;
491
fed16f06 492 if (usb_context)
a1bb33af
UH
493 libusb_exit(usb_context);
494 usb_context = NULL;
a1bb33af
UH
495}
496
a1bb33af
UH
497static void *hw_get_device_info(int device_index, int device_info_id)
498{
a00ba012 499 struct sr_device_instance *sdi;
bf43ea23
UH
500 struct zp *zp;
501 void *info;
a1bb33af 502
bf43ea23
UH
503 if (!(sdi = sr_get_device_instance(device_instances, device_index))) {
504 sr_err("zp: %s: sdi was NULL", __func__);
a1bb33af 505 return NULL;
bf43ea23
UH
506 }
507
508 if (!(zp = sdi->priv)) {
509 sr_err("zp: %s: sdi->priv was NULL", __func__);
510 return NULL;
511 }
a1bb33af 512
fed16f06 513 switch (device_info_id) {
5a2326a7 514 case SR_DI_INSTANCE:
a1bb33af
UH
515 info = sdi;
516 break;
5a2326a7 517 case SR_DI_NUM_PROBES:
bf43ea23 518 info = GINT_TO_POINTER(zp->num_channels);
a1bb33af 519 break;
464d12c7
KS
520 case SR_DI_PROBE_NAMES:
521 info = probe_names;
522 break;
5a2326a7 523 case SR_DI_SAMPLERATES:
a1bb33af
UH
524 info = &samplerates;
525 break;
5a2326a7 526 case SR_DI_TRIGGER_TYPES:
a1bb33af
UH
527 info = TRIGGER_TYPES;
528 break;
5a2326a7 529 case SR_DI_CUR_SAMPLERATE:
bf43ea23
UH
530 info = &zp->cur_samplerate;
531 break;
532 default:
533 /* Unknown device info ID, return NULL. */
534 sr_err("zp: %s: Unknown device info ID", __func__);
535 info = NULL;
a1bb33af
UH
536 break;
537 }
538
539 return info;
540}
541
a1bb33af
UH
542static int hw_get_status(int device_index)
543{
a00ba012 544 struct sr_device_instance *sdi;
a1bb33af 545
d32d961d 546 sdi = sr_get_device_instance(device_instances, device_index);
fed16f06 547 if (sdi)
a1bb33af
UH
548 return sdi->status;
549 else
5a2326a7 550 return SR_ST_NOT_FOUND;
a1bb33af
UH
551}
552
a1bb33af
UH
553static int *hw_get_capabilities(void)
554{
a1bb33af
UH
555 return capabilities;
556}
557
bf43ea23
UH
558static int set_configuration_samplerate(struct sr_device_instance *sdi,
559 uint64_t samplerate)
a1bb33af 560{
bf43ea23
UH
561 struct zp *zp;
562
563 if (!sdi) {
564 sr_err("zp: %s: sdi was NULL", __func__);
565 return SR_ERR_ARG;
566 }
567
568 if (!(zp = sdi->priv)) {
569 sr_err("zp: %s: sdi->priv was NULL", __func__);
570 return SR_ERR_ARG;
571 }
572
73017cf9
UH
573 sr_info("zp: Setting samplerate to %" PRIu64 "Hz.", samplerate);
574
59df0c77
UH
575 if (samplerate > SR_MHZ(1))
576 analyzer_set_freq(samplerate / SR_MHZ(1), FREQ_SCALE_MHZ);
577 else if (samplerate > SR_KHZ(1))
578 analyzer_set_freq(samplerate / SR_KHZ(1), FREQ_SCALE_KHZ);
a1bb33af 579 else
fed16f06 580 analyzer_set_freq(samplerate, FREQ_SCALE_HZ);
a1bb33af 581
bf43ea23 582 zp->cur_samplerate = samplerate;
a1bb33af 583
e46b8fb1 584 return SR_OK;
a1bb33af
UH
585}
586
587static int hw_set_configuration(int device_index, int capability, void *value)
588{
a00ba012 589 struct sr_device_instance *sdi;
a1bb33af 590 uint64_t *tmp_u64;
bf43ea23 591 struct zp *zp;
a1bb33af 592
bf43ea23
UH
593 if (!(sdi = sr_get_device_instance(device_instances, device_index))) {
594 sr_err("zp: %s: sdi was NULL", __func__);
e46b8fb1 595 return SR_ERR;
bf43ea23
UH
596 }
597
598 if (!(zp = sdi->priv)) {
599 sr_err("zp: %s: sdi->priv was NULL", __func__);
600 return SR_ERR_ARG;
601 }
a1bb33af
UH
602
603 switch (capability) {
5a2326a7 604 case SR_HWCAP_SAMPLERATE:
fed16f06 605 tmp_u64 = value;
bf43ea23 606 return set_configuration_samplerate(sdi, *tmp_u64);
5a2326a7 607 case SR_HWCAP_PROBECONFIG:
bf43ea23 608 return configure_probes(sdi, (GSList *)value);
5a2326a7 609 case SR_HWCAP_LIMIT_SAMPLES:
2458ea65 610 tmp_u64 = value;
bf43ea23 611 zp->limit_samples = *tmp_u64;
e46b8fb1 612 return SR_OK;
fed16f06 613 default:
e46b8fb1 614 return SR_ERR;
a1bb33af
UH
615 }
616}
617
9c939c51 618static int hw_start_acquisition(int device_index, gpointer session_data)
a1bb33af 619{
a00ba012 620 struct sr_device_instance *sdi;
b9c735a2 621 struct sr_datafeed_packet packet;
9c939c51 622 struct sr_datafeed_logic logic;
b9c735a2 623 struct sr_datafeed_header header;
9c939c51 624 uint64_t samples_read;
a1bb33af 625 int res;
afc8e4de 626 unsigned int packet_num;
a1bb33af 627 unsigned char *buf;
bf43ea23 628 struct zp *zp;
a1bb33af 629
bf43ea23
UH
630 if (!(sdi = sr_get_device_instance(device_instances, device_index))) {
631 sr_err("zp: %s: sdi was NULL", __func__);
e46b8fb1 632 return SR_ERR;
bf43ea23
UH
633 }
634
635 if (!(zp = sdi->priv)) {
636 sr_err("zp: %s: sdi->priv was NULL", __func__);
637 return SR_ERR_ARG;
638 }
a1bb33af 639
a143e4e5 640 /* push configured settings to device */
69890f73 641 analyzer_configure(zp->usb->devhdl);
a143e4e5 642
69890f73 643 analyzer_start(zp->usb->devhdl);
b08024a8 644 sr_info("Waiting for data");
69890f73 645 analyzer_wait_data(zp->usb->devhdl);
a1bb33af 646
69890f73
UH
647 sr_info("Stop address = 0x%x", analyzer_get_stop_address(zp->usb->devhdl));
648 sr_info("Now address = 0x%x", analyzer_get_now_address(zp->usb->devhdl));
649 sr_info("Trigger address = 0x%x", analyzer_get_trigger_address(zp->usb->devhdl));
a1bb33af 650
5a2326a7 651 packet.type = SR_DF_HEADER;
9c939c51 652 packet.payload = &header;
a1bb33af
UH
653 header.feed_version = 1;
654 gettimeofday(&header.starttime, NULL);
bf43ea23
UH
655 header.samplerate = zp->cur_samplerate;
656 header.num_logic_probes = zp->num_channels;
c2616fb9 657 header.num_analog_probes = 0;
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;
69890f73 666 analyzer_read_start(zp->usb->devhdl);
fed16f06 667 /* Send the incoming transfer to the session bus. */
bf43ea23 668 for (packet_num = 0; packet_num < (zp->memory_size * 4 / PACKET_SIZE);
fed16f06 669 packet_num++) {
69890f73 670 res = analyzer_read_data(zp->usb->devhdl, buf, PACKET_SIZE);
b08024a8
UH
671 sr_info("Tried to read %llx bytes, actually read %x bytes",
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 }
69890f73 682 analyzer_read_stop(zp->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
fed16f06 691/* This stops acquisition on ALL devices, ignoring device_index. */
a1bb33af
UH
692static void hw_stop_acquisition(int device_index, gpointer session_device_id)
693{
b9c735a2 694 struct sr_datafeed_packet packet;
a00ba012 695 struct sr_device_instance *sdi;
69890f73 696 struct zp *zp;
a1bb33af 697
5a2326a7 698 packet.type = SR_DF_END;
8a2efef2 699 sr_session_bus(session_device_id, &packet);
a1bb33af 700
69890f73
UH
701 if (!(sdi = sr_get_device_instance(device_instances, device_index))) {
702 sr_err("zp: %s: sdi was NULL", __func__);
703 return; /* FIXME */
704 }
705
706 if (!(zp = sdi->priv)) {
707 sr_err("zp: %s: sdi->priv was NULL", __func__);
708 return; /* FIXME */
709 }
a1bb33af 710
69890f73 711 analyzer_reset(zp->usb->devhdl);
fed16f06 712 /* TODO: Need to cancel and free any queued up transfers. */
a1bb33af
UH
713}
714
5c2d46d1 715struct sr_device_plugin zeroplus_logic_cube_plugin_info = {
e519ba86
UH
716 .name = "zeroplus-logic-cube",
717 .longname = "Zeroplus Logic Cube LAP-C series",
718 .api_version = 1,
719 .init = hw_init,
720 .cleanup = hw_cleanup,
86f5e3d8
UH
721 .opendev = hw_opendev,
722 .closedev = hw_closedev,
e519ba86
UH
723 .get_device_info = hw_get_device_info,
724 .get_status = hw_get_status,
725 .get_capabilities = hw_get_capabilities,
726 .set_configuration = hw_set_configuration,
727 .start_acquisition = hw_start_acquisition,
728 .stop_acquisition = hw_stop_acquisition,
a1bb33af 729};