]> sigrok.org Git - libsigrok.git/blame - src/hardware/openbench-logic-sniffer/api.c
Introduce standard cleanup helper
[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
0aba65da 88SR_PRIV struct sr_dev_driver ols_driver_info;
0aba65da 89
4f840ce9 90static int init(struct sr_dev_driver *di, struct sr_context *sr_ctx)
0aba65da 91{
f6beaac5 92 return std_init(sr_ctx, di, LOG_PREFIX);
0aba65da
UH
93}
94
4f840ce9 95static GSList *scan(struct sr_dev_driver *di, GSList *options)
0aba65da 96{
1987b8d6 97 struct sr_config *src;
0aba65da
UH
98 struct sr_dev_inst *sdi;
99 struct drv_context *drvc;
0aba65da 100 struct sr_serial_dev_inst *serial;
0aba65da 101 GSList *l, *devices;
07ffa5b3
UH
102 int ret;
103 unsigned int i;
0aba65da
UH
104 const char *conn, *serialcomm;
105 char buf[8];
106
41812aca 107 drvc = di->context;
4b97c74e 108
0aba65da
UH
109 devices = NULL;
110
111 conn = serialcomm = NULL;
112 for (l = options; l; l = l->next) {
1987b8d6
BV
113 src = l->data;
114 switch (src->key) {
1953564a 115 case SR_CONF_CONN:
e46aa4f6 116 conn = g_variant_get_string(src->data, NULL);
0aba65da 117 break;
1953564a 118 case SR_CONF_SERIALCOMM:
e46aa4f6 119 serialcomm = g_variant_get_string(src->data, NULL);
0aba65da
UH
120 break;
121 }
122 }
123 if (!conn)
124 return NULL;
125
98fec29e 126 if (!serialcomm)
0aba65da
UH
127 serialcomm = SERIALCOMM;
128
91219afc 129 serial = sr_serial_dev_inst_new(conn, serialcomm);
0aba65da
UH
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
1a46cc62 155 g_usleep(RESPONSE_DELAY_US);
0aba65da 156
ed936ccc
UH
157 if (sp_input_waiting(serial->data) == 0) {
158 sr_dbg("Didn't get any reply.");
0aba65da 159 return NULL;
ed936ccc
UH
160 }
161
162 ret = serial_read_blocking(serial, buf, 4, serial_timeout(serial, 4));
163 if (ret != 4) {
164 sr_err("Invalid reply (expected 4 bytes, got %d).", ret);
0aba65da 165 return NULL;
ed936ccc
UH
166 }
167
168 if (strncmp(buf, "1SLO", 4) && strncmp(buf, "1ALS", 4)) {
169 sr_err("Invalid reply (expected '1SLO' or '1ALS', got "
170 "'%c%c%c%c').", buf[0], buf[1], buf[2], buf[3]);
0aba65da 171 return NULL;
ed936ccc 172 }
0aba65da
UH
173
174 /* Definitely using the OLS protocol, check if it supports
175 * the metadata command.
176 */
177 send_shortcommand(serial, CMD_METADATA);
ed936ccc 178
1a46cc62 179 g_usleep(RESPONSE_DELAY_US);
ed936ccc
UH
180
181 if (sp_input_waiting(serial->data) != 0) {
0aba65da
UH
182 /* Got metadata. */
183 sdi = get_metadata(serial);
0aba65da
UH
184 } else {
185 /* Not an OLS -- some other board that uses the sump protocol. */
72cd99b8 186 sr_info("Device does not support metadata.");
aac29cc1 187 sdi = g_malloc0(sizeof(struct sr_dev_inst));
0af636be
UH
188 sdi->status = SR_ST_INACTIVE;
189 sdi->vendor = g_strdup("Sump");
190 sdi->model = g_strdup("Logic Analyzer");
191 sdi->version = g_strdup("v1.0");
0aba65da 192 sdi->driver = di;
07ffa5b3 193 for (i = 0; i < ARRAY_SIZE(ols_channel_names); i++)
5e23fcab 194 sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE,
c368e6f3 195 ols_channel_names[i]);
e57057ae 196 sdi->priv = ols_dev_new();
0aba65da 197 }
bf256783
BV
198 /* Configure samplerate and divider. */
199 if (ols_set_samplerate(sdi, DEFAULT_SAMPLERATE) != SR_OK)
200 sr_dbg("Failed to set default samplerate (%"PRIu64").",
201 DEFAULT_SAMPLERATE);
459a0f26
BV
202 sdi->inst_type = SR_INST_SERIAL;
203 sdi->conn = serial;
bf256783 204
0aba65da
UH
205 drvc->instances = g_slist_append(drvc->instances, sdi);
206 devices = g_slist_append(devices, sdi);
207
208 serial_close(serial);
209
210 return devices;
211}
212
4f840ce9 213static GSList *dev_list(const struct sr_dev_driver *di)
0aba65da 214{
41812aca 215 return ((struct drv_context *)(di->context))->instances;
0aba65da
UH
216}
217
584560f1 218static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
53b4680f 219 const struct sr_channel_group *cg)
0aba65da
UH
220{
221 struct dev_context *devc;
222
53b4680f 223 (void)cg;
8f996b89 224
0c05591a
BV
225 if (!sdi)
226 return SR_ERR_ARG;
227
228 devc = sdi->priv;
584560f1 229 switch (key) {
123e1313 230 case SR_CONF_SAMPLERATE:
0c05591a
BV
231 *data = g_variant_new_uint64(devc->cur_samplerate);
232 break;
233 case SR_CONF_CAPTURE_RATIO:
234 *data = g_variant_new_uint64(devc->capture_ratio);
235 break;
236 case SR_CONF_LIMIT_SAMPLES:
237 *data = g_variant_new_uint64(devc->limit_samples);
238 break;
967760a8
MR
239 case SR_CONF_PATTERN_MODE:
240 if (devc->flag_reg & FLAG_EXTERNAL_TEST_MODE)
241 *data = g_variant_new_string(STR_PATTERN_EXTERNAL);
242 else if (devc->flag_reg & FLAG_INTERNAL_TEST_MODE)
243 *data = g_variant_new_string(STR_PATTERN_INTERNAL);
6d16fdfb
BV
244 else
245 *data = g_variant_new_string(STR_PATTERN_NONE);
967760a8 246 break;
0c05591a
BV
247 case SR_CONF_RLE:
248 *data = g_variant_new_boolean(devc->flag_reg & FLAG_RLE ? TRUE : FALSE);
7730e4f0 249 break;
0aba65da 250 default:
bd6fbf62 251 return SR_ERR_NA;
0aba65da
UH
252 }
253
254 return SR_OK;
255}
256
584560f1 257static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sdi,
53b4680f 258 const struct sr_channel_group *cg)
0aba65da
UH
259{
260 struct dev_context *devc;
6d16fdfb 261 uint16_t flag;
e46aa4f6 262 uint64_t tmp_u64;
6d16fdfb 263 int ret;
967760a8 264 const char *stropt;
0aba65da 265
53b4680f 266 (void)cg;
8f996b89 267
e73ffd42
BV
268 if (sdi->status != SR_ST_ACTIVE)
269 return SR_ERR_DEV_CLOSED;
270
0aba65da
UH
271 devc = sdi->priv;
272
584560f1 273 switch (key) {
1953564a 274 case SR_CONF_SAMPLERATE:
e46aa4f6
BV
275 tmp_u64 = g_variant_get_uint64(data);
276 if (tmp_u64 < samplerates[0] || tmp_u64 > samplerates[1])
277 return SR_ERR_SAMPLERATE;
278 ret = ols_set_samplerate(sdi, g_variant_get_uint64(data));
0aba65da 279 break;
1953564a 280 case SR_CONF_LIMIT_SAMPLES:
e46aa4f6
BV
281 tmp_u64 = g_variant_get_uint64(data);
282 if (tmp_u64 < MIN_NUM_SAMPLES)
0aba65da 283 return SR_ERR;
e46aa4f6 284 devc->limit_samples = tmp_u64;
0aba65da
UH
285 ret = SR_OK;
286 break;
1953564a 287 case SR_CONF_CAPTURE_RATIO:
e46aa4f6 288 devc->capture_ratio = g_variant_get_uint64(data);
a5c38703 289 if (devc->capture_ratio < 0 || devc->capture_ratio > 100)
0aba65da 290 ret = SR_ERR;
a5c38703 291 else
0aba65da
UH
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:
63ea6141
BV
369 if (!sdi)
370 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
371 drvopts, ARRAY_SIZE(drvopts), sizeof(uint32_t));
372 else
373 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
374 devopts, ARRAY_SIZE(devopts), sizeof(uint32_t));
9a6517d1 375 break;
a1c743fc 376 case SR_CONF_SAMPLERATE:
e46aa4f6
BV
377 g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}"));
378 gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), samplerates,
379 ARRAY_SIZE(samplerates), sizeof(uint64_t));
380 g_variant_builder_add(&gvb, "{sv}", "samplerate-steps", gvar);
381 *data = g_variant_builder_end(&gvb);
a1c743fc 382 break;
91fd0f72
BV
383 case SR_CONF_TRIGGER_MATCH:
384 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
385 trigger_matches, ARRAY_SIZE(trigger_matches),
386 sizeof(int32_t));
c50277a6 387 break;
7c07a178
UH
388 case SR_CONF_PATTERN_MODE:
389 *data = g_variant_new_strv(patterns, ARRAY_SIZE(patterns));
390 break;
f0de2dd0
BV
391 case SR_CONF_LIMIT_SAMPLES:
392 if (!sdi)
393 return SR_ERR_ARG;
394 devc = sdi->priv;
395 if (devc->flag_reg & FLAG_RLE)
396 return SR_ERR_NA;
397 if (devc->max_samples == 0)
398 /* Device didn't specify sample memory size in metadata. */
399 return SR_ERR_NA;
400 /*
ba7dd8bb 401 * Channel groups are turned off if no channels in that group are
f0de2dd0
BV
402 * enabled, making more room for samples for the enabled group.
403 */
91fd0f72
BV
404 ols_channel_mask(sdi);
405 num_ols_changrp = 0;
f0de2dd0 406 for (i = 0; i < 4; i++) {
ba7dd8bb 407 if (devc->channel_mask & (0xff << (i * 8)))
91fd0f72 408 num_ols_changrp++;
1e1dac0c 409 }
f0de2dd0 410 grange[0] = g_variant_new_uint64(MIN_NUM_SAMPLES);
91fd0f72
BV
411 if (num_ols_changrp)
412 grange[1] = g_variant_new_uint64(devc->max_samples / num_ols_changrp);
413 else
414 grange[1] = g_variant_new_uint64(MIN_NUM_SAMPLES);
f0de2dd0
BV
415 *data = g_variant_new_tuple(grange, 2);
416 break;
a1c743fc 417 default:
bd6fbf62 418 return SR_ERR_NA;
a1c743fc
BV
419 }
420
421 return SR_OK;
422}
423
016e72f3
BV
424static int set_trigger(const struct sr_dev_inst *sdi, int stage)
425{
426 struct dev_context *devc;
427 struct sr_serial_dev_inst *serial;
428 uint8_t cmd, arg[4];
429
430 devc = sdi->priv;
431 serial = sdi->conn;
432
433 cmd = CMD_SET_TRIGGER_MASK + stage * 4;
434 arg[0] = devc->trigger_mask[stage] & 0xff;
435 arg[1] = (devc->trigger_mask[stage] >> 8) & 0xff;
436 arg[2] = (devc->trigger_mask[stage] >> 16) & 0xff;
437 arg[3] = (devc->trigger_mask[stage] >> 24) & 0xff;
438 if (send_longcommand(serial, cmd, arg) != SR_OK)
439 return SR_ERR;
440
441 cmd = CMD_SET_TRIGGER_VALUE + stage * 4;
442 arg[0] = devc->trigger_value[stage] & 0xff;
443 arg[1] = (devc->trigger_value[stage] >> 8) & 0xff;
444 arg[2] = (devc->trigger_value[stage] >> 16) & 0xff;
445 arg[3] = (devc->trigger_value[stage] >> 24) & 0xff;
446 if (send_longcommand(serial, cmd, arg) != SR_OK)
447 return SR_ERR;
448
449 cmd = CMD_SET_TRIGGER_CONFIG + stage * 4;
450 arg[0] = arg[1] = arg[3] = 0x00;
451 arg[2] = stage;
452 if (stage == devc->num_stages)
453 /* Last stage, fire when this one matches. */
454 arg[3] |= TRIGGER_START;
455 if (send_longcommand(serial, cmd, arg) != SR_OK)
456 return SR_ERR;
457
458 return SR_OK;
459}
460
695dc859 461static int dev_acquisition_start(const struct sr_dev_inst *sdi)
0aba65da 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
695dc859 567 std_session_send_df_header(sdi, LOG_PREFIX);
4afdfd46 568
8105e829
DE
569 /* If the device stops sending for longer than it takes to send a byte,
570 * that means it's finished. But wait at least 100 ms to be safe.
571 */
572 serial_source_add(sdi->session, serial, G_IO_IN, 100,
695dc859 573 ols_receive_data, (struct sr_dev_inst *)sdi);
0aba65da 574
0aba65da
UH
575 return SR_OK;
576}
577
695dc859 578static int dev_acquisition_stop(struct sr_dev_inst *sdi)
0aba65da 579{
0aba65da
UH
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,
700d6b64 590 .cleanup = std_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,
41812aca 601 .context = NULL,
0aba65da 602};