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