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