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