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