]> sigrok.org Git - libsigrok.git/blame - src/hardware/zeroplus-logic-cube/api.c
Pass driver struct pointer to driver callbacks.
[libsigrok.git] / src / hardware / zeroplus-logic-cube / api.c
CommitLineData
a1bb33af 1/*
50985c20 2 * This file is part of the libsigrok project.
a1bb33af 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
6d116114 20#include "protocol.h"
a1bb33af 21
8fdecced 22#define VENDOR_NAME "ZEROPLUS"
a1bb33af
UH
23#define USB_INTERFACE 0
24#define USB_CONFIGURATION 1
25#define NUM_TRIGGER_STAGES 4
fed16f06 26#define PACKET_SIZE 2048 /* ?? */
a1bb33af 27
0ab0cb94
TY
28//#define ZP_EXPERIMENTAL
29
e495a676
UH
30struct zp_model {
31 uint16_t vid;
32 uint16_t pid;
428edbe1 33 char *model_name;
a1bb33af 34 unsigned int channels;
fed16f06 35 unsigned int sample_depth; /* In Ksamples/channel */
a1bb33af 36 unsigned int max_sampling_freq;
e495a676 37};
a1bb33af 38
fed16f06
UH
39/*
40 * Note -- 16032, 16064 and 16128 *usually* -- but not always -- have the
41 * same 128K sample depth.
42 */
e495a676 43static const struct zp_model zeroplus_models[] = {
9e5670d0 44 {0x0c12, 0x7002, "LAP-16128U", 16, 128, 200},
428edbe1 45 {0x0c12, 0x7009, "LAP-C(16064)", 16, 64, 100},
e495a676 46 {0x0c12, 0x700a, "LAP-C(16128)", 16, 128, 200},
5db0c668
RD
47 {0x0c12, 0x700b, "LAP-C(32128)", 32, 128, 200},
48 {0x0c12, 0x700c, "LAP-C(321000)", 32, 1024, 200},
49 {0x0c12, 0x700d, "LAP-C(322000)", 32, 2048, 200},
e495a676 50 {0x0c12, 0x700e, "LAP-C(16032)", 16, 32, 100},
428edbe1 51 {0x0c12, 0x7016, "LAP-C(162000)", 16, 2048, 200},
e3594306 52 {0x0c12, 0x7100, "AKIP-9101", 16, 256, 200},
428edbe1 53 { 0, 0, 0, 0, 0, 0 }
a1bb33af
UH
54};
55
f254bc4b 56static const uint32_t devopts[] = {
1953564a 57 SR_CONF_LOGIC_ANALYZER,
5827f61b
BV
58 SR_CONF_LIMIT_SAMPLES | SR_CONF_SET | SR_CONF_LIST,
59 SR_CONF_SAMPLERATE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
60 SR_CONF_TRIGGER_MATCH | SR_CONF_LIST,
61 SR_CONF_CAPTURE_RATIO | SR_CONF_GET | SR_CONF_SET,
62 SR_CONF_VOLTAGE_THRESHOLD | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
a1bb33af
UH
63};
64
28731bab
BV
65static const int32_t trigger_matches[] = {
66 SR_TRIGGER_ZERO,
67 SR_TRIGGER_ONE,
68};
69
d261dbbf 70/*
ba7dd8bb 71 * ZEROPLUS LAP-C (16032) numbers the 16 channels A0-A7 and B0-B7.
d261dbbf
UH
72 * We currently ignore other untested/unsupported devices here.
73 */
ba7dd8bb 74static const char *channel_names[] = {
78693401
UH
75 "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7",
76 "B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7",
5db0c668
RD
77 "C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7",
78 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
464d12c7
KS
79 NULL,
80};
81
32756547 82SR_PRIV struct sr_dev_driver zeroplus_logic_cube_driver_info;
a1bb33af 83
fed16f06
UH
84/*
85 * The hardware supports more samplerates than these, but these are the
86 * options hardcoded into the vendor's Windows GUI.
87 */
a1bb33af 88
8386096f 89static const uint64_t samplerates_100[] = {
17548571
UH
90 SR_HZ(100),
91 SR_HZ(500),
92 SR_KHZ(1),
93 SR_KHZ(5),
94 SR_KHZ(25),
95 SR_KHZ(50),
96 SR_KHZ(100),
97 SR_KHZ(200),
98 SR_KHZ(400),
99 SR_KHZ(800),
100 SR_MHZ(1),
101 SR_MHZ(10),
102 SR_MHZ(25),
103 SR_MHZ(50),
104 SR_MHZ(80),
105 SR_MHZ(100),
17548571
UH
106};
107
8386096f 108const uint64_t samplerates_200[] = {
c9140419
UH
109 SR_HZ(100),
110 SR_HZ(500),
59df0c77
UH
111 SR_KHZ(1),
112 SR_KHZ(5),
113 SR_KHZ(25),
114 SR_KHZ(50),
115 SR_KHZ(100),
116 SR_KHZ(200),
117 SR_KHZ(400),
118 SR_KHZ(800),
119 SR_MHZ(1),
120 SR_MHZ(10),
121 SR_MHZ(25),
122 SR_MHZ(50),
123 SR_MHZ(80),
124 SR_MHZ(100),
125 SR_MHZ(150),
126 SR_MHZ(200),
bf43ea23 127};
a1bb33af 128
6078d2c9 129static int dev_close(struct sr_dev_inst *sdi);
a1bb33af 130
3316e149
BV
131SR_PRIV int zp_set_samplerate(struct dev_context *devc, uint64_t samplerate)
132{
133 int i;
134
135 for (i = 0; ARRAY_SIZE(samplerates_200); i++)
136 if (samplerate == samplerates_200[i])
137 break;
138
139 if (i == ARRAY_SIZE(samplerates_200) || samplerate > devc->max_samplerate) {
140 sr_err("Unsupported samplerate: %" PRIu64 "Hz.", samplerate);
141 return SR_ERR_ARG;
142 }
143
144 sr_info("Setting samplerate to %" PRIu64 "Hz.", samplerate);
145
146 if (samplerate >= SR_MHZ(1))
147 analyzer_set_freq(samplerate / SR_MHZ(1), FREQ_SCALE_MHZ);
148 else if (samplerate >= SR_KHZ(1))
149 analyzer_set_freq(samplerate / SR_KHZ(1), FREQ_SCALE_KHZ);
150 else
151 analyzer_set_freq(samplerate, FREQ_SCALE_HZ);
152
153 devc->cur_samplerate = samplerate;
154
155 return SR_OK;
156}
157
4f840ce9 158static int init(struct sr_dev_driver *di, struct sr_context *sr_ctx)
61136ea6 159{
f6beaac5 160 return std_init(sr_ctx, di, LOG_PREFIX);
61136ea6
BV
161}
162
4f840ce9 163static GSList *scan(struct sr_dev_driver *di, GSList *options)
a1bb33af 164{
d68e2d1a 165 struct sr_dev_inst *sdi;
310e9e9b
BV
166 struct drv_context *drvc;
167 struct dev_context *devc;
e495a676 168 const struct zp_model *prof;
a1bb33af 169 struct libusb_device_descriptor des;
ee4f9bb1 170 struct libusb_device_handle *hdl;
a1bb33af 171 libusb_device **devlist;
428edbe1 172 GSList *devices;
ee4f9bb1
SA
173 int ret, i, j;
174 char serial_num[64], connection_id[64];
a1bb33af 175
4ca38984 176 (void)options;
64d33dc2 177
a873c594 178 drvc = di->priv;
4b97c74e 179
4ca38984
BV
180 devices = NULL;
181
8fdecced 182 /* Find all ZEROPLUS analyzers and add them to device list. */
d4abb463 183 libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist); /* TODO: Errors. */
fed16f06
UH
184
185 for (i = 0; devlist[i]; i++) {
ebc34738
UH
186 ret = libusb_get_device_descriptor(devlist[i], &des);
187 if (ret != 0) {
6d116114 188 sr_err("Failed to get device descriptor: %s.",
d4928d71 189 libusb_error_name(ret));
a1bb33af
UH
190 continue;
191 }
192
ee4f9bb1
SA
193 if ((ret = libusb_open(devlist[i], &hdl)) < 0)
194 continue;
195
196 if (des.iSerialNumber == 0) {
197 serial_num[0] = '\0';
198 } else if ((ret = libusb_get_string_descriptor_ascii(hdl,
199 des.iSerialNumber, (unsigned char *) serial_num,
200 sizeof(serial_num))) < 0) {
201 sr_warn("Failed to get serial number string descriptor: %s.",
202 libusb_error_name(ret));
203 continue;
204 }
205
206 libusb_close(hdl);
207
208 usb_get_port_path(devlist[i], connection_id, sizeof(connection_id));
209
428edbe1
BV
210 prof = NULL;
211 for (j = 0; j < zeroplus_models[j].vid; j++) {
212 if (des.idVendor == zeroplus_models[j].vid &&
213 des.idProduct == zeroplus_models[j].pid) {
214 prof = &zeroplus_models[j];
bf43ea23 215 }
a1bb33af 216 }
e495a676 217 /* Skip if the device was not found. */
428edbe1
BV
218 if (!prof)
219 continue;
e495a676 220 sr_info("Found ZEROPLUS %s.", prof->model_name);
428edbe1
BV
221
222 /* Register the device with libsigrok. */
aac29cc1 223 sdi = g_malloc0(sizeof(struct sr_dev_inst));
0af636be
UH
224 sdi->status = SR_ST_INACTIVE;
225 sdi->vendor = g_strdup(VENDOR_NAME);
226 sdi->model = g_strdup(prof->model_name);
a873c594 227 sdi->driver = di;
ee4f9bb1
SA
228 sdi->serial_num = g_strdup(serial_num);
229 sdi->connection_id = g_strdup(connection_id);
428edbe1
BV
230
231 /* Allocate memory for our private driver context. */
f57d8ffe 232 devc = g_malloc0(sizeof(struct dev_context));
310e9e9b 233 sdi->priv = devc;
17548571 234 devc->prof = prof;
310e9e9b 235 devc->num_channels = prof->channels;
0ab0cb94 236#ifdef ZP_EXPERIMENTAL
e93fb98b 237 devc->max_sample_depth = 128 * 1024;
0ab0cb94
TY
238 devc->max_samplerate = 200;
239#else
e93fb98b 240 devc->max_sample_depth = prof->sample_depth * 1024;
0ab0cb94
TY
241 devc->max_samplerate = prof->max_sampling_freq;
242#endif
243 devc->max_samplerate *= SR_MHZ(1);
244 devc->memory_size = MEMORY_SIZE_8K;
310e9e9b 245 // memset(devc->trigger_buffer, 0, NUM_TRIGGER_STAGES);
428edbe1 246
ba7dd8bb 247 /* Fill in channellist according to this device's profile. */
5e23fcab
ML
248 for (j = 0; j < devc->num_channels; j++)
249 sr_channel_new(sdi, j, SR_CHANNEL_LOGIC, TRUE,
c368e6f3 250 channel_names[j]);
428edbe1
BV
251
252 devices = g_slist_append(devices, sdi);
310e9e9b 253 drvc->instances = g_slist_append(drvc->instances, sdi);
8111446a 254 sdi->inst_type = SR_INST_USB;
609bfd75 255 sdi->conn = sr_usb_dev_inst_new(
428edbe1
BV
256 libusb_get_bus_number(devlist[i]),
257 libusb_get_device_address(devlist[i]), NULL);
a1bb33af
UH
258 }
259 libusb_free_device_list(devlist, 1);
260
4ca38984 261 return devices;
a1bb33af
UH
262}
263
4f840ce9 264static GSList *dev_list(const struct sr_dev_driver *di)
811deee4 265{
0e94d524 266 return ((struct drv_context *)(di->priv))->instances;
811deee4
BV
267}
268
6078d2c9 269static int dev_open(struct sr_dev_inst *sdi)
a1bb33af 270{
4f840ce9 271 struct sr_dev_driver *di = sdi->driver;
310e9e9b 272 struct dev_context *devc;
e495a676 273 struct drv_context *drvc;
609bfd75 274 struct sr_usb_dev_inst *usb;
428edbe1 275 libusb_device **devlist, *dev;
428edbe1 276 int device_count, ret, i;
ee4f9bb1 277 char connection_id[64];
a1bb33af 278
e495a676 279 drvc = di->priv;
609bfd75 280 usb = sdi->conn;
e495a676 281
310e9e9b 282 if (!(devc = sdi->priv)) {
6d116114 283 sr_err("%s: sdi->priv was NULL", __func__);
bf43ea23
UH
284 return SR_ERR_ARG;
285 }
286
d4abb463
PS
287 device_count = libusb_get_device_list(drvc->sr_ctx->libusb_ctx,
288 &devlist);
428edbe1 289 if (device_count < 0) {
6d116114 290 sr_err("Failed to retrieve device list.");
428edbe1
BV
291 return SR_ERR;
292 }
293
294 dev = NULL;
295 for (i = 0; i < device_count; i++) {
ee4f9bb1
SA
296 usb_get_port_path(devlist[i], connection_id, sizeof(connection_id));
297 if (!strcmp(sdi->connection_id, connection_id)) {
428edbe1
BV
298 dev = devlist[i];
299 break;
300 }
301 }
302 if (!dev) {
ee4f9bb1
SA
303 sr_err("Device on %d.%d (logical) / %s (physical) disappeared!",
304 usb->bus, usb->address, sdi->connection_id);
428edbe1
BV
305 return SR_ERR;
306 }
307
609bfd75 308 if (!(ret = libusb_open(dev, &(usb->devhdl)))) {
428edbe1 309 sdi->status = SR_ST_ACTIVE;
ee4f9bb1
SA
310 sr_info("Opened device on %d.%d (logical) / %s (physical) interface %d.",
311 usb->bus, usb->address, sdi->connection_id, USB_INTERFACE);
428edbe1 312 } else {
6d116114 313 sr_err("Failed to open device: %s.", libusb_error_name(ret));
428edbe1
BV
314 return SR_ERR;
315 }
316
609bfd75 317 ret = libusb_set_configuration(usb->devhdl, USB_CONFIGURATION);
ebc34738 318 if (ret < 0) {
6d116114 319 sr_err("Unable to set USB configuration %d: %s.",
d4928d71 320 USB_CONFIGURATION, libusb_error_name(ret));
185ae2c5
UH
321 return SR_ERR;
322 }
323
609bfd75 324 ret = libusb_claim_interface(usb->devhdl, USB_INTERFACE);
ebc34738 325 if (ret != 0) {
6d116114 326 sr_err("Unable to claim interface: %s.",
d4928d71 327 libusb_error_name(ret));
e46b8fb1 328 return SR_ERR;
a1bb33af 329 }
185ae2c5 330
e495a676 331 /* Set default configuration after power on. */
609bfd75
BV
332 if (analyzer_read_status(usb->devhdl) == 0)
333 analyzer_configure(usb->devhdl);
0ab0cb94 334
609bfd75
BV
335 analyzer_reset(usb->devhdl);
336 analyzer_initialize(usb->devhdl);
a1bb33af 337
0ab0cb94 338 //analyzer_set_memory_size(MEMORY_SIZE_512K);
fed16f06 339 // analyzer_set_freq(g_freq, g_freq_scale);
a1bb33af 340 analyzer_set_trigger_count(1);
408e7199
UH
341 // analyzer_set_ramsize_trigger_address((((100 - g_pre_trigger)
342 // * get_memory_size(g_memory_size)) / 100) >> 2);
a1bb33af 343
fed16f06
UH
344#if 0
345 if (g_double_mode == 1)
a1bb33af
UH
346 analyzer_set_compression(COMPRESSION_DOUBLE);
347 else if (g_compression == 1)
348 analyzer_set_compression(COMPRESSION_ENABLE);
fed16f06
UH
349 else
350#endif
351 analyzer_set_compression(COMPRESSION_NONE);
a1bb33af 352
310e9e9b 353 if (devc->cur_samplerate == 0) {
0ab0cb94
TY
354 /* Samplerate hasn't been set. Default to 1MHz. */
355 analyzer_set_freq(1, FREQ_SCALE_MHZ);
356 devc->cur_samplerate = SR_MHZ(1);
a1bb33af
UH
357 }
358
7142d6b9
RD
359 if (devc->cur_threshold == 0)
360 set_voltage_threshold(devc, 1.5);
361
e46b8fb1 362 return SR_OK;
a1bb33af
UH
363}
364
6078d2c9 365static int dev_close(struct sr_dev_inst *sdi)
a1bb33af 366{
609bfd75 367 struct sr_usb_dev_inst *usb;
a1bb33af 368
609bfd75 369 usb = sdi->conn;
697785d1 370
609bfd75 371 if (!usb->devhdl)
25a0f108
BV
372 return SR_ERR;
373
ee4f9bb1
SA
374 sr_info("Closing device on %d.%d (logical) / %s (physical) interface %d.",
375 usb->bus, usb->address, sdi->connection_id, USB_INTERFACE);
609bfd75
BV
376 libusb_release_interface(usb->devhdl, USB_INTERFACE);
377 libusb_reset_device(usb->devhdl);
378 libusb_close(usb->devhdl);
379 usb->devhdl = NULL;
25a0f108 380 sdi->status = SR_ST_INACTIVE;
697785d1
UH
381
382 return SR_OK;
a1bb33af
UH
383}
384
4f840ce9 385static int cleanup(const struct sr_dev_driver *di)
a1bb33af 386{
a6630742 387 return std_dev_clear(di, NULL);
a1bb33af
UH
388}
389
584560f1 390static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
53b4680f 391 const struct sr_channel_group *cg)
a1bb33af 392{
310e9e9b 393 struct dev_context *devc;
a1bb33af 394
53b4680f 395 (void)cg;
8f996b89 396
584560f1 397 switch (key) {
123e1313 398 case SR_CONF_SAMPLERATE:
626409ab 399 if (sdi) {
310e9e9b 400 devc = sdi->priv;
8386096f 401 *data = g_variant_new_uint64(devc->cur_samplerate);
6d116114
UH
402 sr_spew("Returning samplerate: %" PRIu64 "Hz.",
403 devc->cur_samplerate);
626409ab 404 } else
67055d4c 405 return SR_ERR_ARG;
bf43ea23 406 break;
05f853b5
RD
407 case SR_CONF_CAPTURE_RATIO:
408 if (sdi) {
409 devc = sdi->priv;
410 *data = g_variant_new_uint64(devc->capture_ratio);
411 } else
67055d4c 412 return SR_ERR_ARG;
05f853b5 413 break;
7142d6b9
RD
414 case SR_CONF_VOLTAGE_THRESHOLD:
415 if (sdi) {
416 GVariant *range[2];
417 devc = sdi->priv;
418 range[0] = g_variant_new_double(devc->cur_threshold);
419 range[1] = g_variant_new_double(devc->cur_threshold);
420 *data = g_variant_new_tuple(range, 2);
67055d4c
BV
421 } else
422 return SR_ERR_ARG;
423 break;
bf43ea23 424 default:
bd6fbf62 425 return SR_ERR_NA;
a1bb33af
UH
426 }
427
626409ab 428 return SR_OK;
a1bb33af
UH
429}
430
584560f1 431static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sdi,
53b4680f 432 const struct sr_channel_group *cg)
a1bb33af 433{
310e9e9b 434 struct dev_context *devc;
7142d6b9 435 gdouble low, high;
a1bb33af 436
53b4680f 437 (void)cg;
8f996b89 438
e73ffd42
BV
439 if (sdi->status != SR_ST_ACTIVE)
440 return SR_ERR_DEV_CLOSED;
0ab0cb94 441
310e9e9b 442 if (!(devc = sdi->priv)) {
6d116114 443 sr_err("%s: sdi->priv was NULL", __func__);
bf43ea23
UH
444 return SR_ERR_ARG;
445 }
a1bb33af 446
584560f1 447 switch (key) {
1953564a 448 case SR_CONF_SAMPLERATE:
8386096f 449 return zp_set_samplerate(devc, g_variant_get_uint64(data));
1953564a 450 case SR_CONF_LIMIT_SAMPLES:
8386096f 451 return set_limit_samples(devc, g_variant_get_uint64(data));
1953564a 452 case SR_CONF_CAPTURE_RATIO:
8386096f 453 return set_capture_ratio(devc, g_variant_get_uint64(data));
7142d6b9
RD
454 case SR_CONF_VOLTAGE_THRESHOLD:
455 g_variant_get(data, "(dd)", &low, &high);
456 return set_voltage_threshold(devc, (low + high) / 2.0);
fed16f06 457 default:
bd6fbf62 458 return SR_ERR_NA;
a1bb33af 459 }
e495a676
UH
460
461 return SR_OK;
a1bb33af
UH
462}
463
584560f1 464static int config_list(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
53b4680f 465 const struct sr_channel_group *cg)
a1c743fc 466{
17548571 467 struct dev_context *devc;
f0de2dd0 468 GVariant *gvar, *grange[2];
8386096f 469 GVariantBuilder gvb;
7142d6b9
RD
470 double v;
471 GVariant *range[2];
a1c743fc 472
53b4680f 473 (void)cg;
8f996b89 474
a1c743fc 475 switch (key) {
9a6517d1 476 case SR_CONF_DEVICE_OPTIONS:
584560f1 477 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
f254bc4b 478 devopts, ARRAY_SIZE(devopts), sizeof(uint32_t));
9a6517d1 479 break;
a1c743fc 480 case SR_CONF_SAMPLERATE:
17548571 481 devc = sdi->priv;
8386096f 482 g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}"));
17548571 483 if (devc->prof->max_sampling_freq == 100) {
8386096f
BV
484 gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"),
485 samplerates_100, ARRAY_SIZE(samplerates_100),
486 sizeof(uint64_t));
17548571 487 } else if (devc->prof->max_sampling_freq == 200) {
8386096f
BV
488 gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"),
489 samplerates_200, ARRAY_SIZE(samplerates_200),
490 sizeof(uint64_t));
17548571
UH
491 } else {
492 sr_err("Internal error: Unknown max. samplerate: %d.",
493 devc->prof->max_sampling_freq);
494 return SR_ERR_ARG;
495 }
8386096f
BV
496 g_variant_builder_add(&gvb, "{sv}", "samplerates", gvar);
497 *data = g_variant_builder_end(&gvb);
a1c743fc 498 break;
28731bab
BV
499 case SR_CONF_TRIGGER_MATCH:
500 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
501 trigger_matches, ARRAY_SIZE(trigger_matches),
502 sizeof(int32_t));
c50277a6 503 break;
7142d6b9
RD
504 case SR_CONF_VOLTAGE_THRESHOLD:
505 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
506 for (v = -6.0; v <= 6.0; v += 0.1) {
507 range[0] = g_variant_new_double(v);
508 range[1] = g_variant_new_double(v);
509 gvar = g_variant_new_tuple(range, 2);
510 g_variant_builder_add_value(&gvb, gvar);
511 }
512 *data = g_variant_builder_end(&gvb);
513 break;
f0de2dd0
BV
514 case SR_CONF_LIMIT_SAMPLES:
515 if (!sdi)
516 return SR_ERR_ARG;
517 devc = sdi->priv;
518 grange[0] = g_variant_new_uint64(0);
519 grange[1] = g_variant_new_uint64(devc->max_sample_depth);
520 *data = g_variant_new_tuple(grange, 2);
521 break;
a1c743fc 522 default:
bd6fbf62 523 return SR_ERR_NA;
a1c743fc
BV
524 }
525
526 return SR_OK;
527}
528
6078d2c9 529static int dev_acquisition_start(const struct sr_dev_inst *sdi,
3ffb6964 530 void *cb_data)
a1bb33af 531{
609bfd75
BV
532 struct dev_context *devc;
533 struct sr_usb_dev_inst *usb;
b9c735a2 534 struct sr_datafeed_packet packet;
9c939c51 535 struct sr_datafeed_logic logic;
42ceb777 536 unsigned int samples_read;
a1bb33af 537 int res;
e495a676 538 unsigned int packet_num, n;
a1bb33af 539 unsigned char *buf;
42ceb777
RD
540 unsigned int status;
541 unsigned int stop_address;
542 unsigned int now_address;
543 unsigned int trigger_address;
544 unsigned int trigger_offset;
545 unsigned int triggerbar;
546 unsigned int ramsize_trigger;
547 unsigned int memory_size;
548 unsigned int valid_samples;
549 unsigned int discard;
550 int trigger_now;
a1bb33af 551
e73ffd42
BV
552 if (sdi->status != SR_ST_ACTIVE)
553 return SR_ERR_DEV_CLOSED;
554
310e9e9b 555 if (!(devc = sdi->priv)) {
6d116114 556 sr_err("%s: sdi->priv was NULL", __func__);
bf43ea23
UH
557 return SR_ERR_ARG;
558 }
a1bb33af 559
28731bab
BV
560 if (analyzer_add_triggers(sdi) != SR_OK) {
561 sr_err("Failed to configure triggers.");
014359e3
BV
562 return SR_ERR;
563 }
564
609bfd75
BV
565 usb = sdi->conn;
566
0ab0cb94
TY
567 set_triggerbar(devc);
568
e495a676 569 /* Push configured settings to device. */
609bfd75 570 analyzer_configure(usb->devhdl);
a143e4e5 571
609bfd75 572 analyzer_start(usb->devhdl);
6d116114 573 sr_info("Waiting for data.");
609bfd75 574 analyzer_wait_data(usb->devhdl);
a1bb33af 575
42ceb777
RD
576 status = analyzer_read_status(usb->devhdl);
577 stop_address = analyzer_get_stop_address(usb->devhdl);
578 now_address = analyzer_get_now_address(usb->devhdl);
579 trigger_address = analyzer_get_trigger_address(usb->devhdl);
580
581 triggerbar = analyzer_get_triggerbar_address();
582 ramsize_trigger = analyzer_get_ramsize_trigger_address();
583
584 n = get_memory_size(devc->memory_size);
585 memory_size = n / 4;
586
587 sr_info("Status = 0x%x.", status);
588 sr_info("Stop address = 0x%x.", stop_address);
589 sr_info("Now address = 0x%x.", now_address);
590 sr_info("Trigger address = 0x%x.", trigger_address);
591 sr_info("Triggerbar address = 0x%x.", triggerbar);
592 sr_info("Ramsize trigger = 0x%x.", ramsize_trigger);
593 sr_info("Memory size = 0x%x.", memory_size);
a1bb33af 594
4afdfd46 595 /* Send header packet to the session bus. */
29a27196 596 std_session_send_df_header(cb_data, LOG_PREFIX);
f366e86c 597
42ceb777
RD
598 /* Check for empty capture */
599 if ((status & STATUS_READY) && !stop_address) {
600 packet.type = SR_DF_END;
601 sr_session_send(cb_data, &packet);
602 return SR_OK;
603 }
604
b53738ba 605 if (!(buf = g_try_malloc(PACKET_SIZE))) {
6d116114 606 sr_err("Packet buffer malloc failed.");
b53738ba
UH
607 return SR_ERR_MALLOC;
608 }
609
42ceb777
RD
610 /* Check if the trigger is in the samples we are throwing away */
611 trigger_now = now_address == trigger_address ||
612 ((now_address + 1) % memory_size) == trigger_address;
613
614 /*
615 * STATUS_READY doesn't clear until now_address advances past
616 * addr 0, but for our logic, clear it in that case
617 */
618 if (!now_address)
619 status &= ~STATUS_READY;
620
609bfd75 621 analyzer_read_start(usb->devhdl);
42ceb777
RD
622
623 /* Calculate how much data to discard */
624 discard = 0;
625 if (status & STATUS_READY) {
626 /*
627 * We haven't wrapped around, we need to throw away data from
628 * our current position to the end of the buffer.
629 * Additionally, the first two samples captured are always
630 * bogus.
631 */
632 discard += memory_size - now_address + 2;
633 now_address = 2;
634 }
635
636 /* If we have more samples than we need, discard them */
637 valid_samples = (stop_address - now_address) % memory_size;
638 if (valid_samples > ramsize_trigger + triggerbar) {
639 discard += valid_samples - (ramsize_trigger + triggerbar);
640 now_address += valid_samples - (ramsize_trigger + triggerbar);
641 }
642
643 sr_info("Need to discard %d samples.", discard);
644
645 /* Calculate how far in the trigger is */
646 if (trigger_now)
647 trigger_offset = 0;
648 else
649 trigger_offset = (trigger_address - now_address) % memory_size;
650
651 /* Recalculate the number of samples available */
652 valid_samples = (stop_address - now_address) % memory_size;
653
fed16f06 654 /* Send the incoming transfer to the session bus. */
42ceb777 655 samples_read = 0;
0ab0cb94 656 for (packet_num = 0; packet_num < n / PACKET_SIZE; packet_num++) {
42ceb777
RD
657 unsigned int len;
658 unsigned int buf_offset;
659
609bfd75 660 res = analyzer_read_data(usb->devhdl, buf, PACKET_SIZE);
6d116114 661 sr_info("Tried to read %d bytes, actually read %d bytes.",
b08024a8 662 PACKET_SIZE, res);
a1bb33af 663
42ceb777
RD
664 if (discard >= PACKET_SIZE / 4) {
665 discard -= PACKET_SIZE / 4;
666 continue;
667 }
668
669 len = PACKET_SIZE - discard * 4;
670 buf_offset = discard * 4;
671 discard = 0;
672
673 /* Check if we've read all the samples */
674 if (samples_read + len / 4 >= valid_samples)
675 len = (valid_samples - samples_read) * 4;
676 if (!len)
677 break;
678
679 if (samples_read < trigger_offset &&
680 samples_read + len / 4 > trigger_offset) {
681 /* Send out samples remaining before trigger */
682 packet.type = SR_DF_LOGIC;
683 packet.payload = &logic;
684 logic.length = (trigger_offset - samples_read) * 4;
685 logic.unitsize = 4;
686 logic.data = buf + buf_offset;
687 sr_session_send(cb_data, &packet);
688 len -= logic.length;
689 samples_read += logic.length / 4;
690 buf_offset += logic.length;
691 }
692
693 if (samples_read == trigger_offset) {
694 /* Send out trigger */
695 packet.type = SR_DF_TRIGGER;
696 packet.payload = NULL;
697 sr_session_send(cb_data, &packet);
698 }
699
700 /* Send out data (or data after trigger) */
5a2326a7 701 packet.type = SR_DF_LOGIC;
9c939c51 702 packet.payload = &logic;
42ceb777 703 logic.length = len;
9c939c51 704 logic.unitsize = 4;
42ceb777 705 logic.data = buf + buf_offset;
3cd3a20b 706 sr_session_send(cb_data, &packet);
42ceb777 707 samples_read += len / 4;
a1bb33af 708 }
609bfd75 709 analyzer_read_stop(usb->devhdl);
a1bb33af
UH
710 g_free(buf);
711
5a2326a7 712 packet.type = SR_DF_END;
3cd3a20b 713 sr_session_send(cb_data, &packet);
a1bb33af 714
e46b8fb1 715 return SR_OK;
a1bb33af
UH
716}
717
3cd3a20b 718/* TODO: This stops acquisition on ALL devices, ignoring dev_index. */
6078d2c9 719static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
a1bb33af 720{
310e9e9b 721 struct dev_context *devc;
609bfd75
BV
722 struct sr_usb_dev_inst *usb;
723 struct sr_datafeed_packet packet;
a1bb33af 724
5a2326a7 725 packet.type = SR_DF_END;
3cd3a20b 726 sr_session_send(cb_data, &packet);
a1bb33af 727
310e9e9b 728 if (!(devc = sdi->priv)) {
6d116114 729 sr_err("%s: sdi->priv was NULL", __func__);
3010f21c 730 return SR_ERR_BUG;
69890f73 731 }
a1bb33af 732
609bfd75
BV
733 usb = sdi->conn;
734 analyzer_reset(usb->devhdl);
fed16f06 735 /* TODO: Need to cancel and free any queued up transfers. */
3010f21c
UH
736
737 return SR_OK;
a1bb33af
UH
738}
739
c09f0b57 740SR_PRIV struct sr_dev_driver zeroplus_logic_cube_driver_info = {
e519ba86 741 .name = "zeroplus-logic-cube",
8fdecced 742 .longname = "ZEROPLUS Logic Cube LAP-C series",
e519ba86 743 .api_version = 1,
6078d2c9
UH
744 .init = init,
745 .cleanup = cleanup,
746 .scan = scan,
747 .dev_list = dev_list,
a6630742 748 .dev_clear = NULL,
035a1078
BV
749 .config_get = config_get,
750 .config_set = config_set,
a1c743fc 751 .config_list = config_list,
6078d2c9
UH
752 .dev_open = dev_open,
753 .dev_close = dev_close,
754 .dev_acquisition_start = dev_acquisition_start,
755 .dev_acquisition_stop = dev_acquisition_stop,
310e9e9b 756 .priv = NULL,
a1bb33af 757};