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