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