]> sigrok.org Git - libsigrok.git/blame - src/hardware/openbench-logic-sniffer/api.c
ols: Make external clock setting queriable
[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
6ec6c43b 20#include <config.h>
515ab088 21#include "protocol.h"
0aba65da
UH
22
23#define SERIALCOMM "115200/8n1"
24
a0e0bb41 25static const uint32_t scanopts[] = {
1953564a
BV
26 SR_CONF_CONN,
27 SR_CONF_SERIALCOMM,
aeabd308
UH
28};
29
55fb76b3
UH
30static const uint32_t drvopts[] = {
31 SR_CONF_LOGIC_ANALYZER,
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,
50b15953 39 SR_CONF_EXTERNAL_CLOCK | SR_CONF_GET | SR_CONF_SET,
f20c39d9 40 SR_CONF_CLOCK_EDGE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
5827f61b
BV
41 SR_CONF_PATTERN_MODE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
42 SR_CONF_SWAP | SR_CONF_SET,
43 SR_CONF_RLE | SR_CONF_GET | SR_CONF_SET,
0aba65da
UH
44};
45
91fd0f72
BV
46static const int32_t trigger_matches[] = {
47 SR_TRIGGER_ZERO,
48 SR_TRIGGER_ONE,
49};
50
f20c39d9 51static const char* external_clock_edges[] = {
52 "rising", // positive edge
53 "falling" // negative edge
54};
55
6d16fdfb
BV
56#define STR_PATTERN_NONE "None"
57#define STR_PATTERN_EXTERNAL "External"
58#define STR_PATTERN_INTERNAL "Internal"
967760a8
MR
59
60/* Supported methods of test pattern outputs */
61enum {
62 /**
63 * Capture pins 31:16 (unbuffered wing) output a test pattern
64 * that can captured on pins 0:15.
65 */
66 PATTERN_EXTERNAL,
67
68 /** Route test pattern internally to capture buffer. */
69 PATTERN_INTERNAL,
70};
71
7c07a178 72static const char *patterns[] = {
6d16fdfb 73 STR_PATTERN_NONE,
7c07a178
UH
74 STR_PATTERN_EXTERNAL,
75 STR_PATTERN_INTERNAL,
76};
77
ba7dd8bb 78/* Channels are numbered 0-31 (on the PCB silkscreen). */
53cda65a 79SR_PRIV const char *ols_channel_names[] = {
78693401
UH
80 "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12",
81 "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23",
82 "24", "25", "26", "27", "28", "29", "30", "31",
0aba65da
UH
83};
84
d3b38ad3 85/* Default supported samplerates, can be overridden by device metadata. */
e46aa4f6
BV
86static const uint64_t samplerates[] = {
87 SR_HZ(10),
88 SR_MHZ(200),
89 SR_HZ(1),
0aba65da
UH
90};
91
ae4e6999 92#define RESPONSE_DELAY_US (20 * 1000)
1a46cc62 93
4f840ce9 94static GSList *scan(struct sr_dev_driver *di, GSList *options)
0aba65da 95{
1987b8d6 96 struct sr_config *src;
0aba65da 97 struct sr_dev_inst *sdi;
0aba65da 98 struct sr_serial_dev_inst *serial;
43376f33 99 GSList *l;
35be304b 100 int num_read;
07ffa5b3 101 unsigned int i;
0aba65da 102 const char *conn, *serialcomm;
35be304b 103 char buf[4] = { 0, 0, 0, 0 };
0aba65da 104
0aba65da
UH
105 conn = serialcomm = NULL;
106 for (l = options; l; l = l->next) {
1987b8d6
BV
107 src = l->data;
108 switch (src->key) {
1953564a 109 case SR_CONF_CONN:
e46aa4f6 110 conn = g_variant_get_string(src->data, NULL);
0aba65da 111 break;
1953564a 112 case SR_CONF_SERIALCOMM:
e46aa4f6 113 serialcomm = g_variant_get_string(src->data, NULL);
0aba65da
UH
114 break;
115 }
116 }
117 if (!conn)
118 return NULL;
119
98fec29e 120 if (!serialcomm)
0aba65da
UH
121 serialcomm = SERIALCOMM;
122
91219afc 123 serial = sr_serial_dev_inst_new(conn, serialcomm);
0aba65da
UH
124
125 /* The discovery procedure is like this: first send the Reset
126 * command (0x00) 5 times, since the device could be anywhere
127 * in a 5-byte command. Then send the ID command (0x02).
128 * If the device responds with 4 bytes ("OLS1" or "SLA1"), we
129 * have a match.
130 */
131 sr_info("Probing %s.", conn);
4ded59ee 132 if (serial_open(serial, SERIAL_RDWR) != SR_OK)
0aba65da
UH
133 return NULL;
134
244995a2 135 if (ols_send_reset(serial) != SR_OK) {
0aba65da
UH
136 serial_close(serial);
137 sr_err("Could not use port %s. Quitting.", conn);
138 return NULL;
139 }
140 send_shortcommand(serial, CMD_ID);
141
1a46cc62 142 g_usleep(RESPONSE_DELAY_US);
0aba65da 143
f9921513 144 if (serial_has_receive_data(serial) == 0) {
35be304b 145 sr_dbg("Didn't get any ID reply.");
0aba65da 146 return NULL;
ed936ccc
UH
147 }
148
35be304b
WS
149 num_read = serial_read_blocking(serial, buf, 4, serial_timeout(serial, 4));
150 if (num_read < 0) {
151 sr_err("Getting ID reply failed (%d).", num_read);
0aba65da 152 return NULL;
ed936ccc
UH
153 }
154
155 if (strncmp(buf, "1SLO", 4) && strncmp(buf, "1ALS", 4)) {
35be304b
WS
156 GString *id = sr_hexdump_new((uint8_t *)buf, num_read);
157
158 sr_err("Invalid ID reply (got %s).", id->str);
159
160 sr_hexdump_free(id);
0aba65da 161 return NULL;
ed936ccc 162 }
0aba65da
UH
163
164 /* Definitely using the OLS protocol, check if it supports
165 * the metadata command.
166 */
167 send_shortcommand(serial, CMD_METADATA);
ed936ccc 168
1a46cc62 169 g_usleep(RESPONSE_DELAY_US);
ed936ccc 170
f9921513 171 if (serial_has_receive_data(serial) != 0) {
0aba65da
UH
172 /* Got metadata. */
173 sdi = get_metadata(serial);
0aba65da
UH
174 } else {
175 /* Not an OLS -- some other board that uses the sump protocol. */
72cd99b8 176 sr_info("Device does not support metadata.");
aac29cc1 177 sdi = g_malloc0(sizeof(struct sr_dev_inst));
0af636be
UH
178 sdi->status = SR_ST_INACTIVE;
179 sdi->vendor = g_strdup("Sump");
180 sdi->model = g_strdup("Logic Analyzer");
181 sdi->version = g_strdup("v1.0");
07ffa5b3 182 for (i = 0; i < ARRAY_SIZE(ols_channel_names); i++)
5e23fcab 183 sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE,
c368e6f3 184 ols_channel_names[i]);
e57057ae 185 sdi->priv = ols_dev_new();
0aba65da 186 }
bf256783
BV
187 /* Configure samplerate and divider. */
188 if (ols_set_samplerate(sdi, DEFAULT_SAMPLERATE) != SR_OK)
189 sr_dbg("Failed to set default samplerate (%"PRIu64").",
190 DEFAULT_SAMPLERATE);
459a0f26
BV
191 sdi->inst_type = SR_INST_SERIAL;
192 sdi->conn = serial;
bf256783 193
0aba65da
UH
194 serial_close(serial);
195
43376f33 196 return std_scan_complete(di, g_slist_append(NULL, sdi));
0aba65da
UH
197}
198
dd7a72ea
UH
199static int config_get(uint32_t key, GVariant **data,
200 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
0aba65da
UH
201{
202 struct dev_context *devc;
203
53b4680f 204 (void)cg;
8f996b89 205
0c05591a
BV
206 if (!sdi)
207 return SR_ERR_ARG;
208
209 devc = sdi->priv;
758906aa 210
584560f1 211 switch (key) {
123e1313 212 case SR_CONF_SAMPLERATE:
0c05591a
BV
213 *data = g_variant_new_uint64(devc->cur_samplerate);
214 break;
215 case SR_CONF_CAPTURE_RATIO:
216 *data = g_variant_new_uint64(devc->capture_ratio);
217 break;
218 case SR_CONF_LIMIT_SAMPLES:
219 *data = g_variant_new_uint64(devc->limit_samples);
220 break;
967760a8 221 case SR_CONF_PATTERN_MODE:
a80bed76 222 if (devc->capture_flags & CAPTURE_FLAG_EXTERNAL_TEST_MODE)
967760a8 223 *data = g_variant_new_string(STR_PATTERN_EXTERNAL);
a80bed76 224 else if (devc->capture_flags & CAPTURE_FLAG_INTERNAL_TEST_MODE)
967760a8 225 *data = g_variant_new_string(STR_PATTERN_INTERNAL);
6d16fdfb
BV
226 else
227 *data = g_variant_new_string(STR_PATTERN_NONE);
967760a8 228 break;
0c05591a 229 case SR_CONF_RLE:
a80bed76 230 *data = g_variant_new_boolean(devc->capture_flags & CAPTURE_FLAG_RLE ? TRUE : FALSE);
7730e4f0 231 break;
50b15953 232 case SR_CONF_EXTERNAL_CLOCK:
233 *data = g_variant_new_boolean(
234 devc->capture_flags & CAPTURE_FLAG_CLOCK_EXTERNAL ? TRUE : FALSE);
235 break;
f20c39d9 236 case SR_CONF_CLOCK_EDGE:
237 *data = g_variant_new_string(external_clock_edges[
238 devc->capture_flags & CAPTURE_FLAG_INVERT_EXT_CLOCK ? 1 : 0]);
239 break;
0aba65da 240 default:
bd6fbf62 241 return SR_ERR_NA;
0aba65da
UH
242 }
243
244 return SR_OK;
245}
246
dd7a72ea
UH
247static int config_set(uint32_t key, GVariant *data,
248 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
0aba65da
UH
249{
250 struct dev_context *devc;
6d16fdfb 251 uint16_t flag;
e46aa4f6 252 uint64_t tmp_u64;
967760a8 253 const char *stropt;
0aba65da 254
53b4680f 255 (void)cg;
8f996b89 256
0aba65da
UH
257 devc = sdi->priv;
258
584560f1 259 switch (key) {
1953564a 260 case SR_CONF_SAMPLERATE:
e46aa4f6
BV
261 tmp_u64 = g_variant_get_uint64(data);
262 if (tmp_u64 < samplerates[0] || tmp_u64 > samplerates[1])
263 return SR_ERR_SAMPLERATE;
758906aa 264 return ols_set_samplerate(sdi, g_variant_get_uint64(data));
1953564a 265 case SR_CONF_LIMIT_SAMPLES:
e46aa4f6
BV
266 tmp_u64 = g_variant_get_uint64(data);
267 if (tmp_u64 < MIN_NUM_SAMPLES)
0aba65da 268 return SR_ERR;
e46aa4f6 269 devc->limit_samples = tmp_u64;
0aba65da 270 break;
1953564a 271 case SR_CONF_CAPTURE_RATIO:
e46aa4f6 272 devc->capture_ratio = g_variant_get_uint64(data);
0aba65da 273 break;
eb1b610b
MR
274 case SR_CONF_EXTERNAL_CLOCK:
275 if (g_variant_get_boolean(data)) {
276 sr_info("Enabling external clock.");
a80bed76 277 devc->capture_flags |= CAPTURE_FLAG_CLOCK_EXTERNAL;
eb1b610b
MR
278 } else {
279 sr_info("Disabled external clock.");
a80bed76 280 devc->capture_flags &= ~CAPTURE_FLAG_CLOCK_EXTERNAL;
eb1b610b 281 }
eb1b610b 282 break;
f20c39d9 283 case SR_CONF_CLOCK_EDGE:
284 stropt = g_variant_get_string(data, NULL);
285 if (!strcmp(stropt, external_clock_edges[1])) {
286 sr_info("Triggering on falling edge of external clock.");
287 devc->capture_flags |= CAPTURE_FLAG_INVERT_EXT_CLOCK;
288 } else {
289 sr_info("Triggering on rising edge of external clock.");
290 devc->capture_flags &= ~CAPTURE_FLAG_INVERT_EXT_CLOCK;
291 }
292 break;
967760a8
MR
293 case SR_CONF_PATTERN_MODE:
294 stropt = g_variant_get_string(data, NULL);
6d16fdfb
BV
295 if (!strcmp(stropt, STR_PATTERN_NONE)) {
296 sr_info("Disabling test modes.");
297 flag = 0x0000;
758906aa 298 } else if (!strcmp(stropt, STR_PATTERN_INTERNAL)) {
967760a8 299 sr_info("Enabling internal test mode.");
a80bed76 300 flag = CAPTURE_FLAG_INTERNAL_TEST_MODE;
967760a8
MR
301 } else if (!strcmp(stropt, STR_PATTERN_EXTERNAL)) {
302 sr_info("Enabling external test mode.");
a80bed76 303 flag = CAPTURE_FLAG_EXTERNAL_TEST_MODE;
967760a8 304 } else {
758906aa 305 return SR_ERR;
967760a8 306 }
a80bed76 307 devc->capture_flags &= ~CAPTURE_FLAG_INTERNAL_TEST_MODE;
308 devc->capture_flags &= ~CAPTURE_FLAG_EXTERNAL_TEST_MODE;
309 devc->capture_flags |= flag;
967760a8 310 break;
7b0a57fd
MR
311 case SR_CONF_SWAP:
312 if (g_variant_get_boolean(data)) {
313 sr_info("Enabling channel swapping.");
a80bed76 314 devc->capture_flags |= CAPTURE_FLAG_SWAP_CHANNELS;
7b0a57fd
MR
315 } else {
316 sr_info("Disabling channel swapping.");
a80bed76 317 devc->capture_flags &= ~CAPTURE_FLAG_SWAP_CHANNELS;
7b0a57fd 318 }
7b0a57fd 319 break;
1953564a 320 case SR_CONF_RLE:
e46aa4f6 321 if (g_variant_get_boolean(data)) {
0aba65da 322 sr_info("Enabling RLE.");
a80bed76 323 devc->capture_flags |= CAPTURE_FLAG_RLE;
aeea0572
BV
324 } else {
325 sr_info("Disabling RLE.");
a80bed76 326 devc->capture_flags &= ~CAPTURE_FLAG_RLE;
0aba65da 327 }
0aba65da
UH
328 break;
329 default:
758906aa 330 return SR_ERR_NA;
0aba65da
UH
331 }
332
758906aa 333 return SR_OK;
0aba65da
UH
334}
335
dd7a72ea
UH
336static int config_list(uint32_t key, GVariant **data,
337 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
a1c743fc 338{
f0de2dd0 339 struct dev_context *devc;
91fd0f72 340 int num_ols_changrp, i;
a1c743fc 341
a1c743fc 342 switch (key) {
0d485e30 343 case SR_CONF_SCAN_OPTIONS:
9a6517d1 344 case SR_CONF_DEVICE_OPTIONS:
e66d1892 345 return STD_CONFIG_LIST(key, data, sdi, cg, scanopts, drvopts, devopts);
a1c743fc 346 case SR_CONF_SAMPLERATE:
53012da6 347 *data = std_gvar_samplerates_steps(ARRAY_AND_SIZE(samplerates));
a1c743fc 348 break;
91fd0f72 349 case SR_CONF_TRIGGER_MATCH:
53012da6 350 *data = std_gvar_array_i32(ARRAY_AND_SIZE(trigger_matches));
c50277a6 351 break;
f20c39d9 352 case SR_CONF_CLOCK_EDGE:
353 *data = std_gvar_array_str(ARRAY_AND_SIZE(external_clock_edges));
354 break;
7c07a178 355 case SR_CONF_PATTERN_MODE:
53012da6 356 *data = g_variant_new_strv(ARRAY_AND_SIZE(patterns));
7c07a178 357 break;
f0de2dd0
BV
358 case SR_CONF_LIMIT_SAMPLES:
359 if (!sdi)
360 return SR_ERR_ARG;
361 devc = sdi->priv;
a80bed76 362 if (devc->capture_flags & CAPTURE_FLAG_RLE)
f0de2dd0
BV
363 return SR_ERR_NA;
364 if (devc->max_samples == 0)
365 /* Device didn't specify sample memory size in metadata. */
366 return SR_ERR_NA;
367 /*
ba7dd8bb 368 * Channel groups are turned off if no channels in that group are
f0de2dd0
BV
369 * enabled, making more room for samples for the enabled group.
370 */
91fd0f72
BV
371 ols_channel_mask(sdi);
372 num_ols_changrp = 0;
f0de2dd0 373 for (i = 0; i < 4; i++) {
ba7dd8bb 374 if (devc->channel_mask & (0xff << (i * 8)))
91fd0f72 375 num_ols_changrp++;
1e1dac0c 376 }
a162eeb2
UH
377
378 *data = std_gvar_tuple_u64(MIN_NUM_SAMPLES,
379 (num_ols_changrp) ? devc->max_samples / num_ols_changrp : MIN_NUM_SAMPLES);
f0de2dd0 380 break;
a1c743fc 381 default:
bd6fbf62 382 return SR_ERR_NA;
a1c743fc
BV
383 }
384
385 return SR_OK;
386}
387
6f9234e6 388static int set_basic_trigger(const struct sr_dev_inst *sdi, int stage)
016e72f3
BV
389{
390 struct dev_context *devc;
391 struct sr_serial_dev_inst *serial;
392 uint8_t cmd, arg[4];
393
394 devc = sdi->priv;
395 serial = sdi->conn;
396
6f9234e6 397 cmd = CMD_SET_BASIC_TRIGGER_MASK0 + stage * 4;
016e72f3
BV
398 arg[0] = devc->trigger_mask[stage] & 0xff;
399 arg[1] = (devc->trigger_mask[stage] >> 8) & 0xff;
400 arg[2] = (devc->trigger_mask[stage] >> 16) & 0xff;
401 arg[3] = (devc->trigger_mask[stage] >> 24) & 0xff;
402 if (send_longcommand(serial, cmd, arg) != SR_OK)
403 return SR_ERR;
404
6f9234e6 405 cmd = CMD_SET_BASIC_TRIGGER_VALUE0 + stage * 4;
016e72f3
BV
406 arg[0] = devc->trigger_value[stage] & 0xff;
407 arg[1] = (devc->trigger_value[stage] >> 8) & 0xff;
408 arg[2] = (devc->trigger_value[stage] >> 16) & 0xff;
409 arg[3] = (devc->trigger_value[stage] >> 24) & 0xff;
410 if (send_longcommand(serial, cmd, arg) != SR_OK)
411 return SR_ERR;
412
6f9234e6 413 cmd = CMD_SET_BASIC_TRIGGER_CONFIG0 + stage * 4;
016e72f3
BV
414 arg[0] = arg[1] = arg[3] = 0x00;
415 arg[2] = stage;
416 if (stage == devc->num_stages)
417 /* Last stage, fire when this one matches. */
418 arg[3] |= TRIGGER_START;
419 if (send_longcommand(serial, cmd, arg) != SR_OK)
420 return SR_ERR;
421
422 return SR_OK;
423}
424
695dc859 425static int dev_acquisition_start(const struct sr_dev_inst *sdi)
0aba65da 426{
0aba65da 427 struct dev_context *devc;
459a0f26 428 struct sr_serial_dev_inst *serial;
6e5a1a01 429 uint32_t samplecount, readcount, delaycount;
91fd0f72
BV
430 uint8_t ols_changrp_mask, arg[4];
431 int num_ols_changrp;
016e72f3 432 int ret, i;
0aba65da
UH
433
434 devc = sdi->priv;
459a0f26 435 serial = sdi->conn;
0aba65da 436
91fd0f72 437 ols_channel_mask(sdi);
0aba65da 438
91fd0f72
BV
439 num_ols_changrp = 0;
440 ols_changrp_mask = 0;
0aba65da 441 for (i = 0; i < 4; i++) {
ba7dd8bb 442 if (devc->channel_mask & (0xff << (i * 8))) {
91fd0f72
BV
443 ols_changrp_mask |= (1 << i);
444 num_ols_changrp++;
0aba65da
UH
445 }
446 }
447
448 /*
449 * Limit readcount to prevent reading past the end of the hardware
aad0c777 450 * buffer. Rather read too many samples than too few.
0aba65da 451 */
91fd0f72 452 samplecount = MIN(devc->max_samples / num_ols_changrp, devc->limit_samples);
aad0c777 453 readcount = (samplecount + 3) / 4;
0aba65da 454
016e72f3 455 /* Basic triggers. */
91fd0f72
BV
456 if (ols_convert_trigger(sdi) != SR_OK) {
457 sr_err("Failed to configure channels.");
458 return SR_ERR;
459 }
460 if (devc->num_stages > 0) {
b853eb76
GGM
461 /*
462 * According to http://mygizmos.org/ols/Logic-Sniffer-FPGA-Spec.pdf
463 * reset command must be send prior each arm command
464 */
465 sr_dbg("Send reset command before trigger configure");
466 if (ols_send_reset(serial) != SR_OK)
467 return SR_ERR;
468
0aba65da 469 delaycount = readcount * (1 - devc->capture_ratio / 100.0);
a2b1a53b 470 devc->trigger_at_smpl = (readcount - delaycount) * 4 - devc->num_stages;
016e72f3 471 for (i = 0; i <= devc->num_stages; i++) {
91fd0f72 472 sr_dbg("Setting OLS stage %d trigger.", i);
6f9234e6 473 if ((ret = set_basic_trigger(sdi, i)) != SR_OK)
016e72f3
BV
474 return ret;
475 }
0aba65da 476 } else {
016e72f3
BV
477 /* No triggers configured, force trigger on first stage. */
478 sr_dbg("Forcing trigger at stage 0.");
6f9234e6 479 if ((ret = set_basic_trigger(sdi, 0)) != SR_OK)
016e72f3 480 return ret;
0aba65da
UH
481 delaycount = readcount;
482 }
483
6d16fdfb 484 /* Samplerate. */
016e72f3 485 sr_dbg("Setting samplerate to %" PRIu64 "Hz (divider %u)",
6d16fdfb 486 devc->cur_samplerate, devc->cur_samplerate_divider);
016e72f3
BV
487 arg[0] = devc->cur_samplerate_divider & 0xff;
488 arg[1] = (devc->cur_samplerate_divider & 0xff00) >> 8;
489 arg[2] = (devc->cur_samplerate_divider & 0xff0000) >> 16;
490 arg[3] = 0x00;
491 if (send_longcommand(serial, CMD_SET_DIVIDER, arg) != SR_OK)
0aba65da
UH
492 return SR_ERR;
493
494 /* Send sample limit and pre/post-trigger capture ratio. */
016e72f3 495 sr_dbg("Setting sample limit %d, trigger point at %d",
6d16fdfb 496 (readcount - 1) * 4, (delaycount - 1) * 4);
f6ce25ec
WS
497
498 if (devc->max_samples > 256 * 1024) {
499 arg[0] = ((readcount - 1) & 0xff);
500 arg[1] = ((readcount - 1) & 0xff00) >> 8;
501 arg[2] = ((readcount - 1) & 0xff0000) >> 16;
502 arg[3] = ((readcount - 1) & 0xff000000) >> 24;
503 if (send_longcommand(serial, CMD_CAPTURE_READCOUNT, arg) != SR_OK)
504 return SR_ERR;
505 arg[0] = ((delaycount - 1) & 0xff);
506 arg[1] = ((delaycount - 1) & 0xff00) >> 8;
507 arg[2] = ((delaycount - 1) & 0xff0000) >> 16;
508 arg[3] = ((delaycount - 1) & 0xff000000) >> 24;
509 if (send_longcommand(serial, CMD_CAPTURE_DELAYCOUNT, arg) != SR_OK)
510 return SR_ERR;
511 } else {
512 arg[0] = ((readcount - 1) & 0xff);
513 arg[1] = ((readcount - 1) & 0xff00) >> 8;
514 arg[2] = ((delaycount - 1) & 0xff);
515 arg[3] = ((delaycount - 1) & 0xff00) >> 8;
516 if (send_longcommand(serial, CMD_CAPTURE_SIZE, arg) != SR_OK)
517 return SR_ERR;
518 }
0aba65da 519
6d16fdfb 520 /* Flag register. */
f20c39d9 521 sr_dbg("Setting intpat %s, extpat %s, RLE %s, noise_filter %s, demux %s, %s clock%s",
a80bed76 522 devc->capture_flags & CAPTURE_FLAG_INTERNAL_TEST_MODE ? "on": "off",
523 devc->capture_flags & CAPTURE_FLAG_EXTERNAL_TEST_MODE ? "on": "off",
524 devc->capture_flags & CAPTURE_FLAG_RLE ? "on" : "off",
525 devc->capture_flags & CAPTURE_FLAG_NOISE_FILTER ? "on": "off",
f20c39d9 526 devc->capture_flags & CAPTURE_FLAG_DEMUX ? "on" : "off",
527 devc->capture_flags & CAPTURE_FLAG_CLOCK_EXTERNAL ? "external" : "internal",
528 devc->capture_flags & CAPTURE_FLAG_CLOCK_EXTERNAL ? (devc->capture_flags & CAPTURE_FLAG_INVERT_EXT_CLOCK
529 ? " on falling edge" : "on rising edge") : "");
c36a7d84 530
91fd0f72
BV
531 /*
532 * Enable/disable OLS channel groups in the flag register according
533 * to the channel mask. 1 means "disable channel".
534 */
c36a7d84 535 devc->capture_flags &= ~0x3c;
a80bed76 536 devc->capture_flags |= ~(ols_changrp_mask << 2) & 0x3c;
58a75642 537
538 /* RLE mode is always zero, for now. */
539
a80bed76 540 arg[0] = devc->capture_flags & 0xff;
541 arg[1] = devc->capture_flags >> 8;
016e72f3
BV
542 arg[2] = arg[3] = 0x00;
543 if (send_longcommand(serial, CMD_SET_FLAGS, arg) != SR_OK)
0aba65da
UH
544 return SR_ERR;
545
546 /* Start acquisition on the device. */
6f9234e6 547 if (send_shortcommand(serial, CMD_ARM_BASIC_TRIGGER) != SR_OK)
0aba65da
UH
548 return SR_ERR;
549
bf256783 550 /* Reset all operational states. */
6d16fdfb
BV
551 devc->rle_count = devc->num_transfers = 0;
552 devc->num_samples = devc->num_bytes = 0;
625763e2 553 devc->cnt_bytes = devc->cnt_samples = devc->cnt_samples_rle = 0;
abb39e6b 554 memset(devc->sample, 0, 4);
bf256783 555
bee2b016 556 std_session_send_df_header(sdi);
4afdfd46 557
8105e829
DE
558 /* If the device stops sending for longer than it takes to send a byte,
559 * that means it's finished. But wait at least 100 ms to be safe.
560 */
561 serial_source_add(sdi->session, serial, G_IO_IN, 100,
695dc859 562 ols_receive_data, (struct sr_dev_inst *)sdi);
0aba65da 563
0aba65da
UH
564 return SR_OK;
565}
566
695dc859 567static int dev_acquisition_stop(struct sr_dev_inst *sdi)
0aba65da 568{
0aba65da
UH
569 abort_acquisition(sdi);
570
571 return SR_OK;
572}
573
15a5bfe4 574static struct sr_dev_driver ols_driver_info = {
0aba65da 575 .name = "ols",
60143473 576 .longname = "Openbench Logic Sniffer & SUMP compatibles",
0aba65da 577 .api_version = 1,
c2fdcc25 578 .init = std_init,
700d6b64 579 .cleanup = std_cleanup,
03f4de8c 580 .scan = scan,
c01bf34c 581 .dev_list = std_dev_list,
f778bf02 582 .dev_clear = std_dev_clear,
035a1078
BV
583 .config_get = config_get,
584 .config_set = config_set,
a1c743fc 585 .config_list = config_list,
854434de 586 .dev_open = std_serial_dev_open,
bf2c987f 587 .dev_close = std_serial_dev_close,
03f4de8c
BV
588 .dev_acquisition_start = dev_acquisition_start,
589 .dev_acquisition_stop = dev_acquisition_stop,
41812aca 590 .context = NULL,
0aba65da 591};
dd5c48a6 592SR_REGISTER_DEV_DRIVER(ols_driver_info);