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