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