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