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