]> sigrok.org Git - libsigrok.git/blame - hardware/zeroplus-logic-cube/zeroplus.c
sr: fx2lafw: Consistent #include guard naming.
[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
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
e7eb703f 113/* List of struct sr_dev_inst, maintained by dev_open()/dev_close(). */
d68e2d1a 114static GSList *dev_insts = NULL;
a1bb33af
UH
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
ea9cfed7
UH
156/* Private, per-device-instance driver context. */
157struct context {
bf43ea23 158 uint64_t cur_samplerate;
bf43ea23
UH
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 166
d68e2d1a 167 struct sr_usb_dev_inst *usb;
bf43ea23 168};
a1bb33af 169
a9a245b4 170static int hw_dev_config_set(int dev_index, int hwcap, void *value);
a1bb33af
UH
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
d68e2d1a 186static int opendev4(struct sr_dev_inst **sdi, libusb_device *dev,
408e7199
UH
187 struct libusb_device_descriptor *des)
188{
ea9cfed7 189 struct context *ctx;
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
ea9cfed7 195 if (!(ctx = (*sdi)->priv)) {
bf43ea23
UH
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))) {
7b48d6e1 201 sr_err("zp: 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
ea9cfed7
UH
208 if (libusb_get_bus_number(dev) == ctx->usb->bus
209 && libusb_get_device_address(dev) == ctx->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
7b48d6e1
UH
215 sr_info("zp: Found ZeroPlus device 0x%04x (%s)",
216 des->idProduct, zeroplus_models[i].model_name);
ea9cfed7
UH
217 ctx->num_channels = zeroplus_models[i].channels;
218 ctx->memory_size = zeroplus_models[i].sample_depth * 1024;
408e7199
UH
219 break;
220 }
221
ea9cfed7 222 if (ctx->num_channels == 0) {
7b48d6e1
UH
223 sr_err("zp: Unknown ZeroPlus device 0x%04x",
224 des->idProduct);
408e7199
UH
225 return -2;
226 }
227
228 /* Found it. */
ea9cfed7 229 if (!(err = libusb_open(dev, &(ctx->usb->devhdl)))) {
5a2326a7 230 (*sdi)->status = SR_ST_ACTIVE;
7b48d6e1 231 sr_info("zp: opened device %d on %d.%d interface %d",
ea9cfed7
UH
232 (*sdi)->index, ctx->usb->bus,
233 ctx->usb->address, USB_INTERFACE);
408e7199 234 } else {
7b48d6e1 235 sr_err("zp: failed to open device: %d", err);
408e7199
UH
236 *sdi = NULL;
237 }
238 }
239
240 return 0;
241}
242
bb7ef793 243static struct sr_dev_inst *zp_open_dev(int dev_index)
a1bb33af 244{
d68e2d1a 245 struct sr_dev_inst *sdi;
a1bb33af
UH
246 libusb_device **devlist;
247 struct libusb_device_descriptor des;
afc8e4de 248 int err, i;
a1bb33af 249
bb7ef793 250 if (!(sdi = sr_dev_inst_get(dev_insts, dev_index)))
a1bb33af
UH
251 return NULL;
252
253 libusb_get_device_list(usb_context, &devlist);
5a2326a7 254 if (sdi->status == SR_ST_INACTIVE) {
fed16f06 255 /* Find the device by vendor, product, bus and address. */
a1bb33af 256 libusb_get_device_list(usb_context, &devlist);
fed16f06 257 for (i = 0; devlist[i]; i++) {
408e7199 258 /* TODO: Error handling. */
9a5c6dcf 259 err = opendev4(&sdi, devlist[i], &des);
a1bb33af 260 }
fed16f06 261 } else {
5a2326a7 262 /* Status must be SR_ST_ACTIVE, i.e. already in use... */
a1bb33af
UH
263 sdi = NULL;
264 }
265 libusb_free_device_list(devlist, 1);
266
5a2326a7 267 if (sdi && sdi->status != SR_ST_ACTIVE)
a1bb33af
UH
268 sdi = NULL;
269
270 return sdi;
271}
272
bb7ef793 273static void close_dev(struct sr_dev_inst *sdi)
a1bb33af 274{
ea9cfed7 275 struct context *ctx;
69890f73 276
ea9cfed7 277 if (!(ctx = sdi->priv)) {
69890f73
UH
278 sr_err("zp: %s: sdi->priv was NULL", __func__);
279 return; /* FIXME */
280 }
281
ea9cfed7 282 if (!ctx->usb->devhdl)
408e7199
UH
283 return;
284
7b48d6e1 285 sr_info("zp: closing device %d on %d.%d interface %d", sdi->index,
ea9cfed7
UH
286 ctx->usb->bus, ctx->usb->address, USB_INTERFACE);
287 libusb_release_interface(ctx->usb->devhdl, USB_INTERFACE);
288 libusb_reset_device(ctx->usb->devhdl);
289 libusb_close(ctx->usb->devhdl);
290 ctx->usb->devhdl = NULL;
185ae2c5 291 /* TODO: Call libusb_exit() here or only in hw_cleanup()? */
5a2326a7 292 sdi->status = SR_ST_INACTIVE;
a1bb33af
UH
293}
294
d68e2d1a 295static int configure_probes(struct sr_dev_inst *sdi, GSList *probes)
a1bb33af 296{
ea9cfed7 297 struct context *ctx;
1afe8989 298 struct sr_probe *probe;
a1bb33af
UH
299 GSList *l;
300 int probe_bit, stage, i;
301 char *tc;
302
bf43ea23 303 /* Note: sdi and sdi->priv are non-NULL, the caller checked this. */
ea9cfed7 304 ctx = sdi->priv;
bf43ea23 305
ea9cfed7 306 ctx->probe_mask = 0;
fed16f06 307 for (i = 0; i < NUM_TRIGGER_STAGES; i++) {
ea9cfed7
UH
308 ctx->trigger_mask[i] = 0;
309 ctx->trigger_value[i] = 0;
a1bb33af
UH
310 }
311
312 stage = -1;
fed16f06 313 for (l = probes; l; l = l->next) {
1afe8989 314 probe = (struct sr_probe *)l->data;
fed16f06 315 if (probe->enabled == FALSE)
a1bb33af
UH
316 continue;
317 probe_bit = 1 << (probe->index - 1);
ea9cfed7 318 ctx->probe_mask |= probe_bit;
fed16f06
UH
319
320 if (probe->trigger) {
a1bb33af 321 stage = 0;
fed16f06 322 for (tc = probe->trigger; *tc; tc++) {
ea9cfed7 323 ctx->trigger_mask[stage] |= probe_bit;
fed16f06 324 if (*tc == '1')
ea9cfed7 325 ctx->trigger_value[stage] |= probe_bit;
a1bb33af 326 stage++;
fed16f06 327 if (stage > NUM_TRIGGER_STAGES)
e46b8fb1 328 return SR_ERR;
a1bb33af
UH
329 }
330 }
331 }
332
e46b8fb1 333 return SR_OK;
a1bb33af
UH
334}
335
a1bb33af
UH
336/*
337 * API callbacks
338 */
339
bb7ef793 340static int hw_init(const char *devinfo)
a1bb33af 341{
d68e2d1a 342 struct sr_dev_inst *sdi;
a1bb33af
UH
343 struct libusb_device_descriptor des;
344 libusb_device **devlist;
345 int err, devcnt, i;
ea9cfed7 346 struct context *ctx;
a1bb33af 347
17e1afcb 348 /* Avoid compiler warnings. */
bb7ef793 349 (void)devinfo;
afc8e4de 350
bf43ea23 351 /* Allocate memory for our private driver context. */
ea9cfed7
UH
352 if (!(ctx = g_try_malloc(sizeof(struct context)))) {
353 sr_err("zp: %s: ctx malloc failed", __func__);
bf43ea23
UH
354 return 0;
355 }
356
357 /* Set some sane defaults. */
ea9cfed7
UH
358 ctx->cur_samplerate = 0;
359 ctx->limit_samples = 0;
360 ctx->num_channels = 32; /* TODO: This isn't initialized before it's needed :( */
361 ctx->memory_size = 0;
362 ctx->probe_mask = 0;
363 memset(ctx->trigger_mask, 0, NUM_TRIGGER_STAGES);
364 memset(ctx->trigger_value, 0, NUM_TRIGGER_STAGES);
365 // memset(ctx->trigger_buffer, 0, NUM_TRIGGER_STAGES);
bf43ea23 366
fed16f06 367 if (libusb_init(&usb_context) != 0) {
7b48d6e1 368 sr_err("zp: Failed to initialize USB.");
a1bb33af
UH
369 return 0;
370 }
371
fed16f06 372 /* Find all ZeroPlus analyzers and add them to device list. */
a1bb33af 373 devcnt = 0;
185ae2c5 374 libusb_get_device_list(usb_context, &devlist); /* TODO: Errors. */
fed16f06
UH
375
376 for (i = 0; devlist[i]; i++) {
a1bb33af 377 err = libusb_get_device_descriptor(devlist[i], &des);
fed16f06 378 if (err != 0) {
7b48d6e1 379 sr_err("zp: failed to get device descriptor: %d", err);
a1bb33af
UH
380 continue;
381 }
382
fed16f06
UH
383 if (des.idVendor == USB_VENDOR) {
384 /*
385 * Definitely a Zeroplus.
386 * TODO: Any way to detect specific model/version in
387 * the zeroplus range?
388 */
bf43ea23 389 /* Register the device with libsigrok. */
d68e2d1a 390 if (!(sdi = sr_dev_inst_new(devcnt,
5a2326a7 391 SR_ST_INACTIVE, USB_VENDOR_NAME,
d68e2d1a
UH
392 USB_MODEL_NAME, USB_MODEL_VERSION))) {
393 sr_err("zp: %s: sr_dev_inst_new failed",
bf43ea23 394 __func__);
a1bb33af 395 return 0;
bf43ea23
UH
396 }
397
ea9cfed7 398 sdi->priv = ctx;
bf43ea23 399
d68e2d1a
UH
400 dev_insts =
401 g_slist_append(dev_insts, sdi);
ea9cfed7 402 ctx->usb = sr_usb_dev_inst_new(
fed16f06
UH
403 libusb_get_bus_number(devlist[i]),
404 libusb_get_device_address(devlist[i]), NULL);
a1bb33af
UH
405 devcnt++;
406 }
407 }
408 libusb_free_device_list(devlist, 1);
409
410 return devcnt;
411}
412
e7eb703f 413static int hw_dev_open(int dev_index)
a1bb33af 414{
d68e2d1a 415 struct sr_dev_inst *sdi;
ea9cfed7 416 struct context *ctx;
a1bb33af
UH
417 int err;
418
bb7ef793 419 if (!(sdi = zp_open_dev(dev_index))) {
7b48d6e1 420 sr_err("zp: unable to open device");
e46b8fb1 421 return SR_ERR;
a1bb33af
UH
422 }
423
bb7ef793 424 /* TODO: Note: sdi is retrieved in zp_open_dev(). */
bf43ea23 425
ea9cfed7 426 if (!(ctx = sdi->priv)) {
bf43ea23
UH
427 sr_err("zp: %s: sdi->priv was NULL", __func__);
428 return SR_ERR_ARG;
429 }
430
ea9cfed7 431 err = libusb_set_configuration(ctx->usb->devhdl, USB_CONFIGURATION);
185ae2c5 432 if (err < 0) {
133a37bf
UH
433 sr_err("zp: Unable to set USB configuration %d: %d",
434 USB_CONFIGURATION, err);
185ae2c5
UH
435 return SR_ERR;
436 }
437
ea9cfed7 438 err = libusb_claim_interface(ctx->usb->devhdl, USB_INTERFACE);
fed16f06 439 if (err != 0) {
7b48d6e1 440 sr_err("zp: Unable to claim interface: %d", err);
e46b8fb1 441 return SR_ERR;
a1bb33af 442 }
185ae2c5 443
ea9cfed7
UH
444 analyzer_reset(ctx->usb->devhdl);
445 analyzer_initialize(ctx->usb->devhdl);
a1bb33af
UH
446
447 analyzer_set_memory_size(MEMORY_SIZE_512K);
fed16f06 448 // analyzer_set_freq(g_freq, g_freq_scale);
a1bb33af 449 analyzer_set_trigger_count(1);
408e7199
UH
450 // analyzer_set_ramsize_trigger_address((((100 - g_pre_trigger)
451 // * get_memory_size(g_memory_size)) / 100) >> 2);
fed16f06
UH
452 analyzer_set_ramsize_trigger_address(
453 (100 * get_memory_size(MEMORY_SIZE_512K) / 100) >> 2);
a1bb33af 454
fed16f06
UH
455#if 0
456 if (g_double_mode == 1)
a1bb33af
UH
457 analyzer_set_compression(COMPRESSION_DOUBLE);
458 else if (g_compression == 1)
459 analyzer_set_compression(COMPRESSION_ENABLE);
fed16f06
UH
460 else
461#endif
462 analyzer_set_compression(COMPRESSION_NONE);
a1bb33af 463
ea9cfed7 464 if (ctx->cur_samplerate == 0) {
408e7199 465 /* Samplerate hasn't been set. Default to the slowest one. */
a9a245b4 466 if (hw_dev_config_set(dev_index, SR_HWCAP_SAMPLERATE,
73017cf9 467 &samplerates.list[0]) == SR_ERR)
e46b8fb1 468 return SR_ERR;
a1bb33af
UH
469 }
470
e46b8fb1 471 return SR_OK;
a1bb33af
UH
472}
473
e7eb703f 474static int hw_dev_close(int dev_index)
a1bb33af 475{
d68e2d1a 476 struct sr_dev_inst *sdi;
a1bb33af 477
bb7ef793 478 if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) {
bf43ea23 479 sr_err("zp: %s: sdi was NULL", __func__);
697785d1
UH
480 return SR_ERR; /* TODO: SR_ERR_ARG? */
481 }
482
483 /* TODO */
bb7ef793 484 close_dev(sdi);
697785d1
UH
485
486 return SR_OK;
a1bb33af
UH
487}
488
57ab7d9f 489static int hw_cleanup(void)
a1bb33af
UH
490{
491 GSList *l;
d68e2d1a 492 struct sr_dev_inst *sdi;
a1bb33af 493
d68e2d1a 494 for (l = dev_insts; l; l = l->next) {
341ce415
BV
495 sdi = l->data;
496 /* Properly close all devices... */
bb7ef793 497 close_dev(sdi);
341ce415
BV
498 /* ...and free all their memory. */
499 sr_dev_inst_free(sdi);
500 }
d68e2d1a
UH
501 g_slist_free(dev_insts);
502 dev_insts = NULL;
a1bb33af 503
fed16f06 504 if (usb_context)
a1bb33af
UH
505 libusb_exit(usb_context);
506 usb_context = NULL;
57ab7d9f
UH
507
508 return SR_OK;
a1bb33af
UH
509}
510
5097b0d0 511static void *hw_dev_info_get(int dev_index, int dev_info_id)
a1bb33af 512{
d68e2d1a 513 struct sr_dev_inst *sdi;
ea9cfed7 514 struct context *ctx;
bf43ea23 515 void *info;
a1bb33af 516
bb7ef793 517 if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) {
bf43ea23 518 sr_err("zp: %s: sdi was NULL", __func__);
a1bb33af 519 return NULL;
bf43ea23
UH
520 }
521
ea9cfed7 522 if (!(ctx = sdi->priv)) {
bf43ea23
UH
523 sr_err("zp: %s: sdi->priv was NULL", __func__);
524 return NULL;
525 }
a1bb33af 526
bb7ef793 527 switch (dev_info_id) {
1d9a8a5f 528 case SR_DI_INST:
a1bb33af
UH
529 info = sdi;
530 break;
5a2326a7 531 case SR_DI_NUM_PROBES:
ea9cfed7 532 info = GINT_TO_POINTER(ctx->num_channels);
a1bb33af 533 break;
464d12c7
KS
534 case SR_DI_PROBE_NAMES:
535 info = probe_names;
536 break;
5a2326a7 537 case SR_DI_SAMPLERATES:
a1bb33af
UH
538 info = &samplerates;
539 break;
5a2326a7 540 case SR_DI_TRIGGER_TYPES:
a1bb33af
UH
541 info = TRIGGER_TYPES;
542 break;
5a2326a7 543 case SR_DI_CUR_SAMPLERATE:
ea9cfed7 544 info = &ctx->cur_samplerate;
bf43ea23
UH
545 break;
546 default:
547 /* Unknown device info ID, return NULL. */
548 sr_err("zp: %s: Unknown device info ID", __func__);
549 info = NULL;
a1bb33af
UH
550 break;
551 }
552
553 return info;
554}
555
e7eb703f 556static int hw_dev_status_get(int dev_index)
a1bb33af 557{
d68e2d1a 558 struct sr_dev_inst *sdi;
a1bb33af 559
bb7ef793 560 sdi = sr_dev_inst_get(dev_insts, dev_index);
fed16f06 561 if (sdi)
a1bb33af
UH
562 return sdi->status;
563 else
5a2326a7 564 return SR_ST_NOT_FOUND;
a1bb33af
UH
565}
566
ffedd0bf 567static int *hw_hwcap_get_all(void)
a1bb33af 568{
ffedd0bf 569 return hwcaps;
a1bb33af
UH
570}
571
a9a245b4 572static int set_samplerate(struct sr_dev_inst *sdi, uint64_t samplerate)
a1bb33af 573{
ea9cfed7 574 struct context *ctx;
bf43ea23
UH
575
576 if (!sdi) {
577 sr_err("zp: %s: sdi was NULL", __func__);
578 return SR_ERR_ARG;
579 }
580
ea9cfed7 581 if (!(ctx = sdi->priv)) {
bf43ea23
UH
582 sr_err("zp: %s: sdi->priv was NULL", __func__);
583 return SR_ERR_ARG;
584 }
585
73017cf9
UH
586 sr_info("zp: Setting samplerate to %" PRIu64 "Hz.", samplerate);
587
59df0c77
UH
588 if (samplerate > SR_MHZ(1))
589 analyzer_set_freq(samplerate / SR_MHZ(1), FREQ_SCALE_MHZ);
590 else if (samplerate > SR_KHZ(1))
591 analyzer_set_freq(samplerate / SR_KHZ(1), FREQ_SCALE_KHZ);
a1bb33af 592 else
fed16f06 593 analyzer_set_freq(samplerate, FREQ_SCALE_HZ);
a1bb33af 594
ea9cfed7 595 ctx->cur_samplerate = samplerate;
a1bb33af 596
e46b8fb1 597 return SR_OK;
a1bb33af
UH
598}
599
a9a245b4 600static int hw_dev_config_set(int dev_index, int hwcap, void *value)
a1bb33af 601{
d68e2d1a 602 struct sr_dev_inst *sdi;
ea9cfed7 603 struct context *ctx;
a1bb33af 604
bb7ef793 605 if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) {
bf43ea23 606 sr_err("zp: %s: sdi was NULL", __func__);
e46b8fb1 607 return SR_ERR;
bf43ea23
UH
608 }
609
ea9cfed7 610 if (!(ctx = sdi->priv)) {
bf43ea23
UH
611 sr_err("zp: %s: sdi->priv was NULL", __func__);
612 return SR_ERR_ARG;
613 }
a1bb33af 614
ffedd0bf 615 switch (hwcap) {
5a2326a7 616 case SR_HWCAP_SAMPLERATE:
ee61b340 617 return set_samplerate(sdi, *(uint64_t *)value);
5a2326a7 618 case SR_HWCAP_PROBECONFIG:
bf43ea23 619 return configure_probes(sdi, (GSList *)value);
5a2326a7 620 case SR_HWCAP_LIMIT_SAMPLES:
ea9cfed7 621 ctx->limit_samples = *(uint64_t *)value;
e46b8fb1 622 return SR_OK;
fed16f06 623 default:
e46b8fb1 624 return SR_ERR;
a1bb33af
UH
625 }
626}
627
69040b7c 628static int hw_dev_acquisition_start(int dev_index, gpointer session_data)
a1bb33af 629{
d68e2d1a 630 struct sr_dev_inst *sdi;
b9c735a2 631 struct sr_datafeed_packet packet;
9c939c51 632 struct sr_datafeed_logic logic;
b9c735a2 633 struct sr_datafeed_header header;
9c939c51 634 uint64_t samples_read;
a1bb33af 635 int res;
afc8e4de 636 unsigned int packet_num;
a1bb33af 637 unsigned char *buf;
ea9cfed7 638 struct context *ctx;
a1bb33af 639
bb7ef793 640 if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) {
bf43ea23 641 sr_err("zp: %s: sdi was NULL", __func__);
e46b8fb1 642 return SR_ERR;
bf43ea23
UH
643 }
644
ea9cfed7 645 if (!(ctx = sdi->priv)) {
bf43ea23
UH
646 sr_err("zp: %s: sdi->priv was NULL", __func__);
647 return SR_ERR_ARG;
648 }
a1bb33af 649
a143e4e5 650 /* push configured settings to device */
ea9cfed7 651 analyzer_configure(ctx->usb->devhdl);
a143e4e5 652
ea9cfed7 653 analyzer_start(ctx->usb->devhdl);
7b48d6e1 654 sr_info("zp: Waiting for data");
ea9cfed7 655 analyzer_wait_data(ctx->usb->devhdl);
a1bb33af 656
7b48d6e1 657 sr_info("zp: Stop address = 0x%x",
ea9cfed7 658 analyzer_get_stop_address(ctx->usb->devhdl));
7b48d6e1 659 sr_info("zp: Now address = 0x%x",
ea9cfed7 660 analyzer_get_now_address(ctx->usb->devhdl));
7b48d6e1 661 sr_info("zp: Trigger address = 0x%x",
ea9cfed7 662 analyzer_get_trigger_address(ctx->usb->devhdl));
a1bb33af 663
5a2326a7 664 packet.type = SR_DF_HEADER;
9c939c51 665 packet.payload = &header;
a1bb33af
UH
666 header.feed_version = 1;
667 gettimeofday(&header.starttime, NULL);
ea9cfed7
UH
668 header.samplerate = ctx->cur_samplerate;
669 header.num_logic_probes = ctx->num_channels;
9c939c51 670 sr_session_bus(session_data, &packet);
a1bb33af 671
b53738ba 672 if (!(buf = g_try_malloc(PACKET_SIZE))) {
bf43ea23 673 sr_err("zp: %s: buf malloc failed", __func__);
b53738ba
UH
674 return SR_ERR_MALLOC;
675 }
676
9c939c51 677 samples_read = 0;
ea9cfed7 678 analyzer_read_start(ctx->usb->devhdl);
fed16f06 679 /* Send the incoming transfer to the session bus. */
ea9cfed7 680 for (packet_num = 0; packet_num < (ctx->memory_size * 4 / PACKET_SIZE);
fed16f06 681 packet_num++) {
ea9cfed7 682 res = analyzer_read_data(ctx->usb->devhdl, buf, PACKET_SIZE);
7b48d6e1 683 sr_info("zp: Tried to read %llx bytes, actually read %x bytes",
b08024a8 684 PACKET_SIZE, res);
a1bb33af 685
5a2326a7 686 packet.type = SR_DF_LOGIC;
9c939c51
BV
687 packet.payload = &logic;
688 logic.length = PACKET_SIZE;
689 logic.unitsize = 4;
690 logic.data = buf;
691 sr_session_bus(session_data, &packet);
692 samples_read += res / 4;
a1bb33af 693 }
ea9cfed7 694 analyzer_read_stop(ctx->usb->devhdl);
a1bb33af
UH
695 g_free(buf);
696
5a2326a7 697 packet.type = SR_DF_END;
9c939c51 698 sr_session_bus(session_data, &packet);
a1bb33af 699
e46b8fb1 700 return SR_OK;
a1bb33af
UH
701}
702
bb7ef793 703/* This stops acquisition on ALL devices, ignoring dev_index. */
69040b7c 704static int hw_dev_acquisition_stop(int dev_index, gpointer session_dev_id)
a1bb33af 705{
b9c735a2 706 struct sr_datafeed_packet packet;
d68e2d1a 707 struct sr_dev_inst *sdi;
ea9cfed7 708 struct context *ctx;
a1bb33af 709
5a2326a7 710 packet.type = SR_DF_END;
bb7ef793 711 sr_session_bus(session_dev_id, &packet);
a1bb33af 712
bb7ef793 713 if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) {
69890f73 714 sr_err("zp: %s: sdi was NULL", __func__);
3010f21c 715 return SR_ERR_BUG;
69890f73
UH
716 }
717
ea9cfed7 718 if (!(ctx = sdi->priv)) {
69890f73 719 sr_err("zp: %s: sdi->priv was NULL", __func__);
3010f21c 720 return SR_ERR_BUG;
69890f73 721 }
a1bb33af 722
ea9cfed7 723 analyzer_reset(ctx->usb->devhdl);
fed16f06 724 /* TODO: Need to cancel and free any queued up transfers. */
3010f21c
UH
725
726 return SR_OK;
a1bb33af
UH
727}
728
bb7ef793 729SR_PRIV struct sr_dev_plugin zeroplus_logic_cube_plugin_info = {
e519ba86
UH
730 .name = "zeroplus-logic-cube",
731 .longname = "Zeroplus Logic Cube LAP-C series",
732 .api_version = 1,
733 .init = hw_init,
734 .cleanup = hw_cleanup,
e7eb703f
UH
735 .dev_open = hw_dev_open,
736 .dev_close = hw_dev_close,
5097b0d0 737 .dev_info_get = hw_dev_info_get,
e7eb703f 738 .dev_status_get = hw_dev_status_get,
ffedd0bf 739 .hwcap_get_all = hw_hwcap_get_all,
a9a245b4 740 .dev_config_set = hw_dev_config_set,
69040b7c
UH
741 .dev_acquisition_start = hw_dev_acquisition_start,
742 .dev_acquisition_stop = hw_dev_acquisition_stop,
a1bb33af 743};