]> sigrok.org Git - libsigrok.git/blame - src/hardware/openbench-logic-sniffer/api.c
Removal of sdi->index, step 4: fix trivial sr_dev_inst_new() calls
[libsigrok.git] / src / hardware / openbench-logic-sniffer / api.c
CommitLineData
0aba65da 1/*
50985c20 2 * This file is part of the libsigrok project.
0aba65da 3 *
13d8e03c 4 * Copyright (C) 2013 Bert Vermeulen <bert@biot.com>
0aba65da
UH
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "protocol.h"
bf72f649 21#include <libserialport.h>
0aba65da
UH
22
23#define SERIALCOMM "115200/8n1"
24
a0e0bb41 25static const uint32_t scanopts[] = {
1953564a
BV
26 SR_CONF_CONN,
27 SR_CONF_SERIALCOMM,
aeabd308
UH
28};
29
f254bc4b 30static const uint32_t devopts[] = {
1953564a 31 SR_CONF_LOGIC_ANALYZER,
5827f61b
BV
32 SR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
33 SR_CONF_SAMPLERATE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
34 SR_CONF_TRIGGER_MATCH | SR_CONF_LIST,
35 SR_CONF_CAPTURE_RATIO | SR_CONF_GET | SR_CONF_SET,
36 SR_CONF_EXTERNAL_CLOCK | SR_CONF_SET,
37 SR_CONF_PATTERN_MODE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
38 SR_CONF_SWAP | SR_CONF_SET,
39 SR_CONF_RLE | SR_CONF_GET | SR_CONF_SET,
0aba65da
UH
40};
41
91fd0f72
BV
42static const int32_t trigger_matches[] = {
43 SR_TRIGGER_ZERO,
44 SR_TRIGGER_ONE,
45};
46
6d16fdfb
BV
47#define STR_PATTERN_NONE "None"
48#define STR_PATTERN_EXTERNAL "External"
49#define STR_PATTERN_INTERNAL "Internal"
967760a8
MR
50
51/* Supported methods of test pattern outputs */
52enum {
53 /**
54 * Capture pins 31:16 (unbuffered wing) output a test pattern
55 * that can captured on pins 0:15.
56 */
57 PATTERN_EXTERNAL,
58
59 /** Route test pattern internally to capture buffer. */
60 PATTERN_INTERNAL,
61};
62
7c07a178 63static const char *patterns[] = {
6d16fdfb 64 STR_PATTERN_NONE,
7c07a178
UH
65 STR_PATTERN_EXTERNAL,
66 STR_PATTERN_INTERNAL,
67};
68
ba7dd8bb 69/* Channels are numbered 0-31 (on the PCB silkscreen). */
3f239f08 70SR_PRIV const char *ols_channel_names[NUM_CHANNELS + 1] = {
78693401
UH
71 "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12",
72 "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23",
73 "24", "25", "26", "27", "28", "29", "30", "31",
0aba65da
UH
74 NULL,
75};
76
d3b38ad3 77/* Default supported samplerates, can be overridden by device metadata. */
e46aa4f6
BV
78static const uint64_t samplerates[] = {
79 SR_HZ(10),
80 SR_MHZ(200),
81 SR_HZ(1),
0aba65da
UH
82};
83
84SR_PRIV struct sr_dev_driver ols_driver_info;
85static struct sr_dev_driver *di = &ols_driver_info;
86
03f4de8c 87static int init(struct sr_context *sr_ctx)
0aba65da 88{
f6beaac5 89 return std_init(sr_ctx, di, LOG_PREFIX);
0aba65da
UH
90}
91
03f4de8c 92static GSList *scan(GSList *options)
0aba65da 93{
1987b8d6 94 struct sr_config *src;
0aba65da
UH
95 struct sr_dev_inst *sdi;
96 struct drv_context *drvc;
97 struct dev_context *devc;
ba7dd8bb 98 struct sr_channel *ch;
0aba65da
UH
99 struct sr_serial_dev_inst *serial;
100 GPollFD probefd;
101 GSList *l, *devices;
102 int ret, i;
103 const char *conn, *serialcomm;
104 char buf[8];
105
0aba65da 106 drvc = di->priv;
4b97c74e 107
0aba65da
UH
108 devices = NULL;
109
110 conn = serialcomm = NULL;
111 for (l = options; l; l = l->next) {
1987b8d6
BV
112 src = l->data;
113 switch (src->key) {
1953564a 114 case SR_CONF_CONN:
e46aa4f6 115 conn = g_variant_get_string(src->data, NULL);
0aba65da 116 break;
1953564a 117 case SR_CONF_SERIALCOMM:
e46aa4f6 118 serialcomm = g_variant_get_string(src->data, NULL);
0aba65da
UH
119 break;
120 }
121 }
122 if (!conn)
123 return NULL;
124
125 if (serialcomm == NULL)
126 serialcomm = SERIALCOMM;
127
128 if (!(serial = sr_serial_dev_inst_new(conn, serialcomm)))
129 return NULL;
130
131 /* The discovery procedure is like this: first send the Reset
132 * command (0x00) 5 times, since the device could be anywhere
133 * in a 5-byte command. Then send the ID command (0x02).
134 * If the device responds with 4 bytes ("OLS1" or "SLA1"), we
135 * have a match.
136 */
137 sr_info("Probing %s.", conn);
4ded59ee 138 if (serial_open(serial, SERIAL_RDWR) != SR_OK)
0aba65da
UH
139 return NULL;
140
141 ret = SR_OK;
142 for (i = 0; i < 5; i++) {
143 if ((ret = send_shortcommand(serial, CMD_RESET)) != SR_OK) {
144 sr_err("Port %s is not writable.", conn);
145 break;
146 }
147 }
148 if (ret != SR_OK) {
149 serial_close(serial);
150 sr_err("Could not use port %s. Quitting.", conn);
151 return NULL;
152 }
153 send_shortcommand(serial, CMD_ID);
154
155 /* Wait 10ms for a response. */
156 g_usleep(10000);
157
bf72f649 158 sp_get_port_handle(serial->data, &probefd.fd);
0aba65da
UH
159 probefd.events = G_IO_IN;
160 g_poll(&probefd, 1, 1);
161
162 if (probefd.revents != G_IO_IN)
163 return NULL;
9f5d4c3c 164 if (serial_read_blocking(serial, buf, 4) != 4)
0aba65da
UH
165 return NULL;
166 if (strncmp(buf, "1SLO", 4) && strncmp(buf, "1ALS", 4))
167 return NULL;
168
169 /* Definitely using the OLS protocol, check if it supports
170 * the metadata command.
171 */
172 send_shortcommand(serial, CMD_METADATA);
173 if (g_poll(&probefd, 1, 10) > 0) {
174 /* Got metadata. */
175 sdi = get_metadata(serial);
0aba65da
UH
176 devc = sdi->priv;
177 } else {
178 /* Not an OLS -- some other board that uses the sump protocol. */
72cd99b8 179 sr_info("Device does not support metadata.");
aed4ad0b 180 sdi = sr_dev_inst_new(SR_ST_INACTIVE,
0aba65da
UH
181 "Sump", "Logic Analyzer", "v1.0");
182 sdi->driver = di;
0aba65da 183 for (i = 0; i < 32; i++) {
3f239f08 184 if (!(ch = sr_channel_new(i, SR_CHANNEL_LOGIC, TRUE,
ba7dd8bb 185 ols_channel_names[i])))
0aba65da 186 return 0;
ba7dd8bb 187 sdi->channels = g_slist_append(sdi->channels, ch);
0aba65da 188 }
bf256783 189 devc = ols_dev_new();
0aba65da
UH
190 sdi->priv = devc;
191 }
bf256783
BV
192 /* Configure samplerate and divider. */
193 if (ols_set_samplerate(sdi, DEFAULT_SAMPLERATE) != SR_OK)
194 sr_dbg("Failed to set default samplerate (%"PRIu64").",
195 DEFAULT_SAMPLERATE);
459a0f26
BV
196 sdi->inst_type = SR_INST_SERIAL;
197 sdi->conn = serial;
bf256783 198
0aba65da
UH
199 drvc->instances = g_slist_append(drvc->instances, sdi);
200 devices = g_slist_append(devices, sdi);
201
202 serial_close(serial);
203
204 return devices;
205}
206
03f4de8c 207static GSList *dev_list(void)
0aba65da 208{
0e94d524 209 return ((struct drv_context *)(di->priv))->instances;
0aba65da
UH
210}
211
eea49cf1 212static int cleanup(void)
0aba65da 213{
a6630742 214 return std_dev_clear(di, NULL);
0aba65da
UH
215}
216
584560f1 217static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
53b4680f 218 const struct sr_channel_group *cg)
0aba65da
UH
219{
220 struct dev_context *devc;
221
53b4680f 222 (void)cg;
8f996b89 223
0c05591a
BV
224 if (!sdi)
225 return SR_ERR_ARG;
226
227 devc = sdi->priv;
584560f1 228 switch (key) {
123e1313 229 case SR_CONF_SAMPLERATE:
0c05591a
BV
230 *data = g_variant_new_uint64(devc->cur_samplerate);
231 break;
232 case SR_CONF_CAPTURE_RATIO:
233 *data = g_variant_new_uint64(devc->capture_ratio);
234 break;
235 case SR_CONF_LIMIT_SAMPLES:
236 *data = g_variant_new_uint64(devc->limit_samples);
237 break;
967760a8
MR
238 case SR_CONF_PATTERN_MODE:
239 if (devc->flag_reg & FLAG_EXTERNAL_TEST_MODE)
240 *data = g_variant_new_string(STR_PATTERN_EXTERNAL);
241 else if (devc->flag_reg & FLAG_INTERNAL_TEST_MODE)
242 *data = g_variant_new_string(STR_PATTERN_INTERNAL);
6d16fdfb
BV
243 else
244 *data = g_variant_new_string(STR_PATTERN_NONE);
967760a8 245 break;
0c05591a
BV
246 case SR_CONF_RLE:
247 *data = g_variant_new_boolean(devc->flag_reg & FLAG_RLE ? TRUE : FALSE);
7730e4f0 248 break;
0aba65da 249 default:
bd6fbf62 250 return SR_ERR_NA;
0aba65da
UH
251 }
252
253 return SR_OK;
254}
255
584560f1 256static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sdi,
53b4680f 257 const struct sr_channel_group *cg)
0aba65da
UH
258{
259 struct dev_context *devc;
6d16fdfb 260 uint16_t flag;
e46aa4f6 261 uint64_t tmp_u64;
6d16fdfb 262 int ret;
967760a8 263 const char *stropt;
0aba65da 264
53b4680f 265 (void)cg;
8f996b89 266
e73ffd42
BV
267 if (sdi->status != SR_ST_ACTIVE)
268 return SR_ERR_DEV_CLOSED;
269
0aba65da
UH
270 devc = sdi->priv;
271
584560f1 272 switch (key) {
1953564a 273 case SR_CONF_SAMPLERATE:
e46aa4f6
BV
274 tmp_u64 = g_variant_get_uint64(data);
275 if (tmp_u64 < samplerates[0] || tmp_u64 > samplerates[1])
276 return SR_ERR_SAMPLERATE;
277 ret = ols_set_samplerate(sdi, g_variant_get_uint64(data));
0aba65da 278 break;
1953564a 279 case SR_CONF_LIMIT_SAMPLES:
e46aa4f6
BV
280 tmp_u64 = g_variant_get_uint64(data);
281 if (tmp_u64 < MIN_NUM_SAMPLES)
0aba65da 282 return SR_ERR;
e46aa4f6 283 devc->limit_samples = tmp_u64;
0aba65da
UH
284 ret = SR_OK;
285 break;
1953564a 286 case SR_CONF_CAPTURE_RATIO:
e46aa4f6 287 devc->capture_ratio = g_variant_get_uint64(data);
0aba65da
UH
288 if (devc->capture_ratio < 0 || devc->capture_ratio > 100) {
289 devc->capture_ratio = 0;
290 ret = SR_ERR;
291 } else
292 ret = SR_OK;
293 break;
eb1b610b
MR
294 case SR_CONF_EXTERNAL_CLOCK:
295 if (g_variant_get_boolean(data)) {
296 sr_info("Enabling external clock.");
297 devc->flag_reg |= FLAG_CLOCK_EXTERNAL;
298 } else {
299 sr_info("Disabled external clock.");
300 devc->flag_reg &= ~FLAG_CLOCK_EXTERNAL;
301 }
302 ret = SR_OK;
303 break;
967760a8
MR
304 case SR_CONF_PATTERN_MODE:
305 stropt = g_variant_get_string(data, NULL);
306 ret = SR_OK;
6d16fdfb
BV
307 flag = 0xffff;
308 if (!strcmp(stropt, STR_PATTERN_NONE)) {
309 sr_info("Disabling test modes.");
310 flag = 0x0000;
311 }else if (!strcmp(stropt, STR_PATTERN_INTERNAL)) {
967760a8 312 sr_info("Enabling internal test mode.");
6d16fdfb 313 flag = FLAG_INTERNAL_TEST_MODE;
967760a8
MR
314 } else if (!strcmp(stropt, STR_PATTERN_EXTERNAL)) {
315 sr_info("Enabling external test mode.");
6d16fdfb 316 flag = FLAG_EXTERNAL_TEST_MODE;
967760a8
MR
317 } else {
318 ret = SR_ERR;
319 }
6d16fdfb
BV
320 if (flag != 0xffff) {
321 devc->flag_reg &= ~(FLAG_INTERNAL_TEST_MODE | FLAG_EXTERNAL_TEST_MODE);
322 devc->flag_reg |= flag;
323 }
967760a8 324 break;
7b0a57fd
MR
325 case SR_CONF_SWAP:
326 if (g_variant_get_boolean(data)) {
327 sr_info("Enabling channel swapping.");
3f239f08 328 devc->flag_reg |= FLAG_SWAP_CHANNELS;
7b0a57fd
MR
329 } else {
330 sr_info("Disabling channel swapping.");
3f239f08 331 devc->flag_reg &= ~FLAG_SWAP_CHANNELS;
7b0a57fd
MR
332 }
333 ret = SR_OK;
334 break;
335
1953564a 336 case SR_CONF_RLE:
e46aa4f6 337 if (g_variant_get_boolean(data)) {
0aba65da
UH
338 sr_info("Enabling RLE.");
339 devc->flag_reg |= FLAG_RLE;
aeea0572
BV
340 } else {
341 sr_info("Disabling RLE.");
342 devc->flag_reg &= ~FLAG_RLE;
0aba65da
UH
343 }
344 ret = SR_OK;
345 break;
346 default:
bd6fbf62 347 ret = SR_ERR_NA;
0aba65da
UH
348 }
349
350 return ret;
351}
352
584560f1 353static int config_list(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
53b4680f 354 const struct sr_channel_group *cg)
a1c743fc 355{
f0de2dd0
BV
356 struct dev_context *devc;
357 GVariant *gvar, *grange[2];
e46aa4f6 358 GVariantBuilder gvb;
91fd0f72 359 int num_ols_changrp, i;
a1c743fc 360
53b4680f 361 (void)cg;
a1c743fc
BV
362
363 switch (key) {
0d485e30 364 case SR_CONF_SCAN_OPTIONS:
584560f1 365 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
a0e0bb41 366 scanopts, ARRAY_SIZE(scanopts), sizeof(uint32_t));
0d485e30 367 break;
9a6517d1 368 case SR_CONF_DEVICE_OPTIONS:
584560f1 369 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
f254bc4b 370 devopts, ARRAY_SIZE(devopts), sizeof(uint32_t));
9a6517d1 371 break;
a1c743fc 372 case SR_CONF_SAMPLERATE:
e46aa4f6
BV
373 g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}"));
374 gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), samplerates,
375 ARRAY_SIZE(samplerates), sizeof(uint64_t));
376 g_variant_builder_add(&gvb, "{sv}", "samplerate-steps", gvar);
377 *data = g_variant_builder_end(&gvb);
a1c743fc 378 break;
91fd0f72
BV
379 case SR_CONF_TRIGGER_MATCH:
380 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
381 trigger_matches, ARRAY_SIZE(trigger_matches),
382 sizeof(int32_t));
c50277a6 383 break;
7c07a178
UH
384 case SR_CONF_PATTERN_MODE:
385 *data = g_variant_new_strv(patterns, ARRAY_SIZE(patterns));
386 break;
f0de2dd0
BV
387 case SR_CONF_LIMIT_SAMPLES:
388 if (!sdi)
389 return SR_ERR_ARG;
390 devc = sdi->priv;
391 if (devc->flag_reg & FLAG_RLE)
392 return SR_ERR_NA;
393 if (devc->max_samples == 0)
394 /* Device didn't specify sample memory size in metadata. */
395 return SR_ERR_NA;
396 /*
ba7dd8bb 397 * Channel groups are turned off if no channels in that group are
f0de2dd0
BV
398 * enabled, making more room for samples for the enabled group.
399 */
91fd0f72
BV
400 ols_channel_mask(sdi);
401 num_ols_changrp = 0;
f0de2dd0 402 for (i = 0; i < 4; i++) {
ba7dd8bb 403 if (devc->channel_mask & (0xff << (i * 8)))
91fd0f72 404 num_ols_changrp++;
1e1dac0c 405 }
f0de2dd0 406 grange[0] = g_variant_new_uint64(MIN_NUM_SAMPLES);
91fd0f72
BV
407 if (num_ols_changrp)
408 grange[1] = g_variant_new_uint64(devc->max_samples / num_ols_changrp);
409 else
410 grange[1] = g_variant_new_uint64(MIN_NUM_SAMPLES);
f0de2dd0
BV
411 *data = g_variant_new_tuple(grange, 2);
412 break;
a1c743fc 413 default:
bd6fbf62 414 return SR_ERR_NA;
a1c743fc
BV
415 }
416
417 return SR_OK;
418}
419
016e72f3
BV
420static int set_trigger(const struct sr_dev_inst *sdi, int stage)
421{
422 struct dev_context *devc;
423 struct sr_serial_dev_inst *serial;
424 uint8_t cmd, arg[4];
425
426 devc = sdi->priv;
427 serial = sdi->conn;
428
429 cmd = CMD_SET_TRIGGER_MASK + stage * 4;
430 arg[0] = devc->trigger_mask[stage] & 0xff;
431 arg[1] = (devc->trigger_mask[stage] >> 8) & 0xff;
432 arg[2] = (devc->trigger_mask[stage] >> 16) & 0xff;
433 arg[3] = (devc->trigger_mask[stage] >> 24) & 0xff;
434 if (send_longcommand(serial, cmd, arg) != SR_OK)
435 return SR_ERR;
436
437 cmd = CMD_SET_TRIGGER_VALUE + stage * 4;
438 arg[0] = devc->trigger_value[stage] & 0xff;
439 arg[1] = (devc->trigger_value[stage] >> 8) & 0xff;
440 arg[2] = (devc->trigger_value[stage] >> 16) & 0xff;
441 arg[3] = (devc->trigger_value[stage] >> 24) & 0xff;
442 if (send_longcommand(serial, cmd, arg) != SR_OK)
443 return SR_ERR;
444
445 cmd = CMD_SET_TRIGGER_CONFIG + stage * 4;
446 arg[0] = arg[1] = arg[3] = 0x00;
447 arg[2] = stage;
448 if (stage == devc->num_stages)
449 /* Last stage, fire when this one matches. */
450 arg[3] |= TRIGGER_START;
451 if (send_longcommand(serial, cmd, arg) != SR_OK)
452 return SR_ERR;
453
454 return SR_OK;
455}
456
03f4de8c 457static int dev_acquisition_start(const struct sr_dev_inst *sdi,
0aba65da
UH
458 void *cb_data)
459{
0aba65da 460 struct dev_context *devc;
459a0f26 461 struct sr_serial_dev_inst *serial;
32f09bfd 462 uint16_t samplecount, readcount, delaycount;
91fd0f72
BV
463 uint8_t ols_changrp_mask, arg[4];
464 int num_ols_changrp;
016e72f3 465 int ret, i;
0aba65da 466
e73ffd42
BV
467 if (sdi->status != SR_ST_ACTIVE)
468 return SR_ERR_DEV_CLOSED;
469
0aba65da 470 devc = sdi->priv;
459a0f26 471 serial = sdi->conn;
0aba65da 472
91fd0f72 473 ols_channel_mask(sdi);
0aba65da 474
91fd0f72
BV
475 num_ols_changrp = 0;
476 ols_changrp_mask = 0;
0aba65da 477 for (i = 0; i < 4; i++) {
ba7dd8bb 478 if (devc->channel_mask & (0xff << (i * 8))) {
91fd0f72
BV
479 ols_changrp_mask |= (1 << i);
480 num_ols_changrp++;
0aba65da
UH
481 }
482 }
483
484 /*
485 * Limit readcount to prevent reading past the end of the hardware
486 * buffer.
487 */
91fd0f72 488 samplecount = MIN(devc->max_samples / num_ols_changrp, devc->limit_samples);
32f09bfd 489 readcount = samplecount / 4;
016e72f3
BV
490
491 /* Rather read too many samples than too few. */
492 if (samplecount % 4 != 0)
32f09bfd 493 readcount++;
0aba65da 494
016e72f3 495 /* Basic triggers. */
91fd0f72
BV
496 if (ols_convert_trigger(sdi) != SR_OK) {
497 sr_err("Failed to configure channels.");
498 return SR_ERR;
499 }
500 if (devc->num_stages > 0) {
0aba65da
UH
501 delaycount = readcount * (1 - devc->capture_ratio / 100.0);
502 devc->trigger_at = (readcount - delaycount) * 4 - devc->num_stages;
016e72f3 503 for (i = 0; i <= devc->num_stages; i++) {
91fd0f72 504 sr_dbg("Setting OLS stage %d trigger.", i);
016e72f3
BV
505 if ((ret = set_trigger(sdi, i)) != SR_OK)
506 return ret;
507 }
0aba65da 508 } else {
016e72f3
BV
509 /* No triggers configured, force trigger on first stage. */
510 sr_dbg("Forcing trigger at stage 0.");
511 if ((ret = set_trigger(sdi, 0)) != SR_OK)
512 return ret;
0aba65da
UH
513 delaycount = readcount;
514 }
515
6d16fdfb 516 /* Samplerate. */
016e72f3 517 sr_dbg("Setting samplerate to %" PRIu64 "Hz (divider %u)",
6d16fdfb 518 devc->cur_samplerate, devc->cur_samplerate_divider);
016e72f3
BV
519 arg[0] = devc->cur_samplerate_divider & 0xff;
520 arg[1] = (devc->cur_samplerate_divider & 0xff00) >> 8;
521 arg[2] = (devc->cur_samplerate_divider & 0xff0000) >> 16;
522 arg[3] = 0x00;
523 if (send_longcommand(serial, CMD_SET_DIVIDER, arg) != SR_OK)
0aba65da
UH
524 return SR_ERR;
525
526 /* Send sample limit and pre/post-trigger capture ratio. */
016e72f3 527 sr_dbg("Setting sample limit %d, trigger point at %d",
6d16fdfb 528 (readcount - 1) * 4, (delaycount - 1) * 4);
016e72f3
BV
529 arg[0] = ((readcount - 1) & 0xff);
530 arg[1] = ((readcount - 1) & 0xff00) >> 8;
531 arg[2] = ((delaycount - 1) & 0xff);
532 arg[3] = ((delaycount - 1) & 0xff00) >> 8;
533 if (send_longcommand(serial, CMD_CAPTURE_SIZE, arg) != SR_OK)
0aba65da
UH
534 return SR_ERR;
535
6d16fdfb 536 /* Flag register. */
625763e2
BV
537 sr_dbg("Setting intpat %s, extpat %s, RLE %s, noise_filter %s, demux %s",
538 devc->flag_reg & FLAG_INTERNAL_TEST_MODE ? "on": "off",
6d16fdfb 539 devc->flag_reg & FLAG_EXTERNAL_TEST_MODE ? "on": "off",
625763e2
BV
540 devc->flag_reg & FLAG_RLE ? "on" : "off",
541 devc->flag_reg & FLAG_FILTER ? "on": "off",
542 devc->flag_reg & FLAG_DEMUX ? "on" : "off");
91fd0f72
BV
543 /*
544 * Enable/disable OLS channel groups in the flag register according
545 * to the channel mask. 1 means "disable channel".
546 */
547 devc->flag_reg |= ~(ols_changrp_mask << 2) & 0x3c;
016e72f3
BV
548 arg[0] = devc->flag_reg & 0xff;
549 arg[1] = devc->flag_reg >> 8;
550 arg[2] = arg[3] = 0x00;
551 if (send_longcommand(serial, CMD_SET_FLAGS, arg) != SR_OK)
0aba65da
UH
552 return SR_ERR;
553
554 /* Start acquisition on the device. */
459a0f26 555 if (send_shortcommand(serial, CMD_RUN) != SR_OK)
0aba65da
UH
556 return SR_ERR;
557
bf256783 558 /* Reset all operational states. */
6d16fdfb
BV
559 devc->rle_count = devc->num_transfers = 0;
560 devc->num_samples = devc->num_bytes = 0;
625763e2 561 devc->cnt_bytes = devc->cnt_samples = devc->cnt_samples_rle = 0;
abb39e6b 562 memset(devc->sample, 0, 4);
bf256783 563
4afdfd46 564 /* Send header packet to the session bus. */
29a27196 565 std_session_send_df_header(cb_data, LOG_PREFIX);
4afdfd46 566
102f1239
BV
567 serial_source_add(sdi->session, serial, G_IO_IN, -1,
568 ols_receive_data, cb_data);
0aba65da 569
0aba65da
UH
570 return SR_OK;
571}
572
03f4de8c 573static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
0aba65da 574{
0aba65da
UH
575 (void)cb_data;
576
577 abort_acquisition(sdi);
578
579 return SR_OK;
580}
581
582SR_PRIV struct sr_dev_driver ols_driver_info = {
583 .name = "ols",
584 .longname = "Openbench Logic Sniffer",
585 .api_version = 1,
03f4de8c 586 .init = init,
eea49cf1 587 .cleanup = cleanup,
03f4de8c
BV
588 .scan = scan,
589 .dev_list = dev_list,
a6630742 590 .dev_clear = NULL,
035a1078
BV
591 .config_get = config_get,
592 .config_set = config_set,
a1c743fc 593 .config_list = config_list,
854434de 594 .dev_open = std_serial_dev_open,
bf2c987f 595 .dev_close = std_serial_dev_close,
03f4de8c
BV
596 .dev_acquisition_start = dev_acquisition_start,
597 .dev_acquisition_stop = dev_acquisition_stop,
0aba65da
UH
598 .priv = NULL,
599};