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