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