]> sigrok.org Git - libsigrok.git/blame - src/hardware/openbench-logic-sniffer/api.c
Change sr_dev_inst_new() to take no parameters.
[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;
f4d3a4fb 164 if (serial_read_blocking(serial, buf, 4, serial_timeout(serial, 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.");
0af636be
UH
180 sdi = sr_dev_inst_new();
181 sdi->status = SR_ST_INACTIVE;
182 sdi->vendor = g_strdup("Sump");
183 sdi->model = g_strdup("Logic Analyzer");
184 sdi->version = g_strdup("v1.0");
0aba65da 185 sdi->driver = di;
0aba65da 186 for (i = 0; i < 32; i++) {
3f239f08 187 if (!(ch = sr_channel_new(i, SR_CHANNEL_LOGIC, TRUE,
ba7dd8bb 188 ols_channel_names[i])))
0aba65da 189 return 0;
ba7dd8bb 190 sdi->channels = g_slist_append(sdi->channels, ch);
0aba65da 191 }
bf256783 192 devc = ols_dev_new();
0aba65da
UH
193 sdi->priv = devc;
194 }
bf256783
BV
195 /* Configure samplerate and divider. */
196 if (ols_set_samplerate(sdi, DEFAULT_SAMPLERATE) != SR_OK)
197 sr_dbg("Failed to set default samplerate (%"PRIu64").",
198 DEFAULT_SAMPLERATE);
459a0f26
BV
199 sdi->inst_type = SR_INST_SERIAL;
200 sdi->conn = serial;
bf256783 201
0aba65da
UH
202 drvc->instances = g_slist_append(drvc->instances, sdi);
203 devices = g_slist_append(devices, sdi);
204
205 serial_close(serial);
206
207 return devices;
208}
209
03f4de8c 210static GSList *dev_list(void)
0aba65da 211{
0e94d524 212 return ((struct drv_context *)(di->priv))->instances;
0aba65da
UH
213}
214
eea49cf1 215static int cleanup(void)
0aba65da 216{
a6630742 217 return std_dev_clear(di, NULL);
0aba65da
UH
218}
219
584560f1 220static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
53b4680f 221 const struct sr_channel_group *cg)
0aba65da
UH
222{
223 struct dev_context *devc;
224
53b4680f 225 (void)cg;
8f996b89 226
0c05591a
BV
227 if (!sdi)
228 return SR_ERR_ARG;
229
230 devc = sdi->priv;
584560f1 231 switch (key) {
123e1313 232 case SR_CONF_SAMPLERATE:
0c05591a
BV
233 *data = g_variant_new_uint64(devc->cur_samplerate);
234 break;
235 case SR_CONF_CAPTURE_RATIO:
236 *data = g_variant_new_uint64(devc->capture_ratio);
237 break;
238 case SR_CONF_LIMIT_SAMPLES:
239 *data = g_variant_new_uint64(devc->limit_samples);
240 break;
967760a8
MR
241 case SR_CONF_PATTERN_MODE:
242 if (devc->flag_reg & FLAG_EXTERNAL_TEST_MODE)
243 *data = g_variant_new_string(STR_PATTERN_EXTERNAL);
244 else if (devc->flag_reg & FLAG_INTERNAL_TEST_MODE)
245 *data = g_variant_new_string(STR_PATTERN_INTERNAL);
6d16fdfb
BV
246 else
247 *data = g_variant_new_string(STR_PATTERN_NONE);
967760a8 248 break;
0c05591a
BV
249 case SR_CONF_RLE:
250 *data = g_variant_new_boolean(devc->flag_reg & FLAG_RLE ? TRUE : FALSE);
7730e4f0 251 break;
0aba65da 252 default:
bd6fbf62 253 return SR_ERR_NA;
0aba65da
UH
254 }
255
256 return SR_OK;
257}
258
584560f1 259static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sdi,
53b4680f 260 const struct sr_channel_group *cg)
0aba65da
UH
261{
262 struct dev_context *devc;
6d16fdfb 263 uint16_t flag;
e46aa4f6 264 uint64_t tmp_u64;
6d16fdfb 265 int ret;
967760a8 266 const char *stropt;
0aba65da 267
53b4680f 268 (void)cg;
8f996b89 269
e73ffd42
BV
270 if (sdi->status != SR_ST_ACTIVE)
271 return SR_ERR_DEV_CLOSED;
272
0aba65da
UH
273 devc = sdi->priv;
274
584560f1 275 switch (key) {
1953564a 276 case SR_CONF_SAMPLERATE:
e46aa4f6
BV
277 tmp_u64 = g_variant_get_uint64(data);
278 if (tmp_u64 < samplerates[0] || tmp_u64 > samplerates[1])
279 return SR_ERR_SAMPLERATE;
280 ret = ols_set_samplerate(sdi, g_variant_get_uint64(data));
0aba65da 281 break;
1953564a 282 case SR_CONF_LIMIT_SAMPLES:
e46aa4f6
BV
283 tmp_u64 = g_variant_get_uint64(data);
284 if (tmp_u64 < MIN_NUM_SAMPLES)
0aba65da 285 return SR_ERR;
e46aa4f6 286 devc->limit_samples = tmp_u64;
0aba65da
UH
287 ret = SR_OK;
288 break;
1953564a 289 case SR_CONF_CAPTURE_RATIO:
e46aa4f6 290 devc->capture_ratio = g_variant_get_uint64(data);
0aba65da
UH
291 if (devc->capture_ratio < 0 || devc->capture_ratio > 100) {
292 devc->capture_ratio = 0;
293 ret = SR_ERR;
294 } else
295 ret = SR_OK;
296 break;
eb1b610b
MR
297 case SR_CONF_EXTERNAL_CLOCK:
298 if (g_variant_get_boolean(data)) {
299 sr_info("Enabling external clock.");
300 devc->flag_reg |= FLAG_CLOCK_EXTERNAL;
301 } else {
302 sr_info("Disabled external clock.");
303 devc->flag_reg &= ~FLAG_CLOCK_EXTERNAL;
304 }
305 ret = SR_OK;
306 break;
967760a8
MR
307 case SR_CONF_PATTERN_MODE:
308 stropt = g_variant_get_string(data, NULL);
309 ret = SR_OK;
6d16fdfb
BV
310 flag = 0xffff;
311 if (!strcmp(stropt, STR_PATTERN_NONE)) {
312 sr_info("Disabling test modes.");
313 flag = 0x0000;
314 }else if (!strcmp(stropt, STR_PATTERN_INTERNAL)) {
967760a8 315 sr_info("Enabling internal test mode.");
6d16fdfb 316 flag = FLAG_INTERNAL_TEST_MODE;
967760a8
MR
317 } else if (!strcmp(stropt, STR_PATTERN_EXTERNAL)) {
318 sr_info("Enabling external test mode.");
6d16fdfb 319 flag = FLAG_EXTERNAL_TEST_MODE;
967760a8
MR
320 } else {
321 ret = SR_ERR;
322 }
6d16fdfb
BV
323 if (flag != 0xffff) {
324 devc->flag_reg &= ~(FLAG_INTERNAL_TEST_MODE | FLAG_EXTERNAL_TEST_MODE);
325 devc->flag_reg |= flag;
326 }
967760a8 327 break;
7b0a57fd
MR
328 case SR_CONF_SWAP:
329 if (g_variant_get_boolean(data)) {
330 sr_info("Enabling channel swapping.");
3f239f08 331 devc->flag_reg |= FLAG_SWAP_CHANNELS;
7b0a57fd
MR
332 } else {
333 sr_info("Disabling channel swapping.");
3f239f08 334 devc->flag_reg &= ~FLAG_SWAP_CHANNELS;
7b0a57fd
MR
335 }
336 ret = SR_OK;
337 break;
338
1953564a 339 case SR_CONF_RLE:
e46aa4f6 340 if (g_variant_get_boolean(data)) {
0aba65da
UH
341 sr_info("Enabling RLE.");
342 devc->flag_reg |= FLAG_RLE;
aeea0572
BV
343 } else {
344 sr_info("Disabling RLE.");
345 devc->flag_reg &= ~FLAG_RLE;
0aba65da
UH
346 }
347 ret = SR_OK;
348 break;
349 default:
bd6fbf62 350 ret = SR_ERR_NA;
0aba65da
UH
351 }
352
353 return ret;
354}
355
584560f1 356static int config_list(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
53b4680f 357 const struct sr_channel_group *cg)
a1c743fc 358{
f0de2dd0
BV
359 struct dev_context *devc;
360 GVariant *gvar, *grange[2];
e46aa4f6 361 GVariantBuilder gvb;
91fd0f72 362 int num_ols_changrp, i;
a1c743fc 363
53b4680f 364 (void)cg;
a1c743fc
BV
365
366 switch (key) {
0d485e30 367 case SR_CONF_SCAN_OPTIONS:
584560f1 368 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
a0e0bb41 369 scanopts, ARRAY_SIZE(scanopts), sizeof(uint32_t));
0d485e30 370 break;
9a6517d1 371 case SR_CONF_DEVICE_OPTIONS:
584560f1 372 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
f254bc4b 373 devopts, ARRAY_SIZE(devopts), sizeof(uint32_t));
9a6517d1 374 break;
a1c743fc 375 case SR_CONF_SAMPLERATE:
e46aa4f6
BV
376 g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}"));
377 gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), samplerates,
378 ARRAY_SIZE(samplerates), sizeof(uint64_t));
379 g_variant_builder_add(&gvb, "{sv}", "samplerate-steps", gvar);
380 *data = g_variant_builder_end(&gvb);
a1c743fc 381 break;
91fd0f72
BV
382 case SR_CONF_TRIGGER_MATCH:
383 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
384 trigger_matches, ARRAY_SIZE(trigger_matches),
385 sizeof(int32_t));
c50277a6 386 break;
7c07a178
UH
387 case SR_CONF_PATTERN_MODE:
388 *data = g_variant_new_strv(patterns, ARRAY_SIZE(patterns));
389 break;
f0de2dd0
BV
390 case SR_CONF_LIMIT_SAMPLES:
391 if (!sdi)
392 return SR_ERR_ARG;
393 devc = sdi->priv;
394 if (devc->flag_reg & FLAG_RLE)
395 return SR_ERR_NA;
396 if (devc->max_samples == 0)
397 /* Device didn't specify sample memory size in metadata. */
398 return SR_ERR_NA;
399 /*
ba7dd8bb 400 * Channel groups are turned off if no channels in that group are
f0de2dd0
BV
401 * enabled, making more room for samples for the enabled group.
402 */
91fd0f72
BV
403 ols_channel_mask(sdi);
404 num_ols_changrp = 0;
f0de2dd0 405 for (i = 0; i < 4; i++) {
ba7dd8bb 406 if (devc->channel_mask & (0xff << (i * 8)))
91fd0f72 407 num_ols_changrp++;
1e1dac0c 408 }
f0de2dd0 409 grange[0] = g_variant_new_uint64(MIN_NUM_SAMPLES);
91fd0f72
BV
410 if (num_ols_changrp)
411 grange[1] = g_variant_new_uint64(devc->max_samples / num_ols_changrp);
412 else
413 grange[1] = g_variant_new_uint64(MIN_NUM_SAMPLES);
f0de2dd0
BV
414 *data = g_variant_new_tuple(grange, 2);
415 break;
a1c743fc 416 default:
bd6fbf62 417 return SR_ERR_NA;
a1c743fc
BV
418 }
419
420 return SR_OK;
421}
422
016e72f3
BV
423static int set_trigger(const struct sr_dev_inst *sdi, int stage)
424{
425 struct dev_context *devc;
426 struct sr_serial_dev_inst *serial;
427 uint8_t cmd, arg[4];
428
429 devc = sdi->priv;
430 serial = sdi->conn;
431
432 cmd = CMD_SET_TRIGGER_MASK + stage * 4;
433 arg[0] = devc->trigger_mask[stage] & 0xff;
434 arg[1] = (devc->trigger_mask[stage] >> 8) & 0xff;
435 arg[2] = (devc->trigger_mask[stage] >> 16) & 0xff;
436 arg[3] = (devc->trigger_mask[stage] >> 24) & 0xff;
437 if (send_longcommand(serial, cmd, arg) != SR_OK)
438 return SR_ERR;
439
440 cmd = CMD_SET_TRIGGER_VALUE + stage * 4;
441 arg[0] = devc->trigger_value[stage] & 0xff;
442 arg[1] = (devc->trigger_value[stage] >> 8) & 0xff;
443 arg[2] = (devc->trigger_value[stage] >> 16) & 0xff;
444 arg[3] = (devc->trigger_value[stage] >> 24) & 0xff;
445 if (send_longcommand(serial, cmd, arg) != SR_OK)
446 return SR_ERR;
447
448 cmd = CMD_SET_TRIGGER_CONFIG + stage * 4;
449 arg[0] = arg[1] = arg[3] = 0x00;
450 arg[2] = stage;
451 if (stage == devc->num_stages)
452 /* Last stage, fire when this one matches. */
453 arg[3] |= TRIGGER_START;
454 if (send_longcommand(serial, cmd, arg) != SR_OK)
455 return SR_ERR;
456
457 return SR_OK;
458}
459
03f4de8c 460static int dev_acquisition_start(const struct sr_dev_inst *sdi,
0aba65da
UH
461 void *cb_data)
462{
0aba65da 463 struct dev_context *devc;
459a0f26 464 struct sr_serial_dev_inst *serial;
32f09bfd 465 uint16_t samplecount, readcount, delaycount;
91fd0f72
BV
466 uint8_t ols_changrp_mask, arg[4];
467 int num_ols_changrp;
016e72f3 468 int ret, i;
0aba65da 469
e73ffd42
BV
470 if (sdi->status != SR_ST_ACTIVE)
471 return SR_ERR_DEV_CLOSED;
472
0aba65da 473 devc = sdi->priv;
459a0f26 474 serial = sdi->conn;
0aba65da 475
91fd0f72 476 ols_channel_mask(sdi);
0aba65da 477
91fd0f72
BV
478 num_ols_changrp = 0;
479 ols_changrp_mask = 0;
0aba65da 480 for (i = 0; i < 4; i++) {
ba7dd8bb 481 if (devc->channel_mask & (0xff << (i * 8))) {
91fd0f72
BV
482 ols_changrp_mask |= (1 << i);
483 num_ols_changrp++;
0aba65da
UH
484 }
485 }
486
487 /*
488 * Limit readcount to prevent reading past the end of the hardware
489 * buffer.
490 */
91fd0f72 491 samplecount = MIN(devc->max_samples / num_ols_changrp, devc->limit_samples);
32f09bfd 492 readcount = samplecount / 4;
016e72f3
BV
493
494 /* Rather read too many samples than too few. */
495 if (samplecount % 4 != 0)
32f09bfd 496 readcount++;
0aba65da 497
016e72f3 498 /* Basic triggers. */
91fd0f72
BV
499 if (ols_convert_trigger(sdi) != SR_OK) {
500 sr_err("Failed to configure channels.");
501 return SR_ERR;
502 }
503 if (devc->num_stages > 0) {
0aba65da
UH
504 delaycount = readcount * (1 - devc->capture_ratio / 100.0);
505 devc->trigger_at = (readcount - delaycount) * 4 - devc->num_stages;
016e72f3 506 for (i = 0; i <= devc->num_stages; i++) {
91fd0f72 507 sr_dbg("Setting OLS stage %d trigger.", i);
016e72f3
BV
508 if ((ret = set_trigger(sdi, i)) != SR_OK)
509 return ret;
510 }
0aba65da 511 } else {
016e72f3
BV
512 /* No triggers configured, force trigger on first stage. */
513 sr_dbg("Forcing trigger at stage 0.");
514 if ((ret = set_trigger(sdi, 0)) != SR_OK)
515 return ret;
0aba65da
UH
516 delaycount = readcount;
517 }
518
6d16fdfb 519 /* Samplerate. */
016e72f3 520 sr_dbg("Setting samplerate to %" PRIu64 "Hz (divider %u)",
6d16fdfb 521 devc->cur_samplerate, devc->cur_samplerate_divider);
016e72f3
BV
522 arg[0] = devc->cur_samplerate_divider & 0xff;
523 arg[1] = (devc->cur_samplerate_divider & 0xff00) >> 8;
524 arg[2] = (devc->cur_samplerate_divider & 0xff0000) >> 16;
525 arg[3] = 0x00;
526 if (send_longcommand(serial, CMD_SET_DIVIDER, arg) != SR_OK)
0aba65da
UH
527 return SR_ERR;
528
529 /* Send sample limit and pre/post-trigger capture ratio. */
016e72f3 530 sr_dbg("Setting sample limit %d, trigger point at %d",
6d16fdfb 531 (readcount - 1) * 4, (delaycount - 1) * 4);
016e72f3
BV
532 arg[0] = ((readcount - 1) & 0xff);
533 arg[1] = ((readcount - 1) & 0xff00) >> 8;
534 arg[2] = ((delaycount - 1) & 0xff);
535 arg[3] = ((delaycount - 1) & 0xff00) >> 8;
536 if (send_longcommand(serial, CMD_CAPTURE_SIZE, arg) != SR_OK)
0aba65da
UH
537 return SR_ERR;
538
6d16fdfb 539 /* Flag register. */
625763e2
BV
540 sr_dbg("Setting intpat %s, extpat %s, RLE %s, noise_filter %s, demux %s",
541 devc->flag_reg & FLAG_INTERNAL_TEST_MODE ? "on": "off",
6d16fdfb 542 devc->flag_reg & FLAG_EXTERNAL_TEST_MODE ? "on": "off",
625763e2
BV
543 devc->flag_reg & FLAG_RLE ? "on" : "off",
544 devc->flag_reg & FLAG_FILTER ? "on": "off",
545 devc->flag_reg & FLAG_DEMUX ? "on" : "off");
91fd0f72
BV
546 /*
547 * Enable/disable OLS channel groups in the flag register according
548 * to the channel mask. 1 means "disable channel".
549 */
550 devc->flag_reg |= ~(ols_changrp_mask << 2) & 0x3c;
016e72f3
BV
551 arg[0] = devc->flag_reg & 0xff;
552 arg[1] = devc->flag_reg >> 8;
553 arg[2] = arg[3] = 0x00;
554 if (send_longcommand(serial, CMD_SET_FLAGS, arg) != SR_OK)
0aba65da
UH
555 return SR_ERR;
556
557 /* Start acquisition on the device. */
459a0f26 558 if (send_shortcommand(serial, CMD_RUN) != SR_OK)
0aba65da
UH
559 return SR_ERR;
560
bf256783 561 /* Reset all operational states. */
6d16fdfb
BV
562 devc->rle_count = devc->num_transfers = 0;
563 devc->num_samples = devc->num_bytes = 0;
625763e2 564 devc->cnt_bytes = devc->cnt_samples = devc->cnt_samples_rle = 0;
abb39e6b 565 memset(devc->sample, 0, 4);
bf256783 566
4afdfd46 567 /* Send header packet to the session bus. */
29a27196 568 std_session_send_df_header(cb_data, LOG_PREFIX);
4afdfd46 569
102f1239
BV
570 serial_source_add(sdi->session, serial, G_IO_IN, -1,
571 ols_receive_data, cb_data);
0aba65da 572
0aba65da
UH
573 return SR_OK;
574}
575
03f4de8c 576static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
0aba65da 577{
0aba65da
UH
578 (void)cb_data;
579
580 abort_acquisition(sdi);
581
582 return SR_OK;
583}
584
585SR_PRIV struct sr_dev_driver ols_driver_info = {
586 .name = "ols",
587 .longname = "Openbench Logic Sniffer",
588 .api_version = 1,
03f4de8c 589 .init = init,
eea49cf1 590 .cleanup = cleanup,
03f4de8c
BV
591 .scan = scan,
592 .dev_list = dev_list,
a6630742 593 .dev_clear = NULL,
035a1078
BV
594 .config_get = config_get,
595 .config_set = config_set,
a1c743fc 596 .config_list = config_list,
854434de 597 .dev_open = std_serial_dev_open,
bf2c987f 598 .dev_close = std_serial_dev_close,
03f4de8c
BV
599 .dev_acquisition_start = dev_acquisition_start,
600 .dev_acquisition_stop = dev_acquisition_stop,
0aba65da
UH
601 .priv = NULL,
602};