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