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