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