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