]> sigrok.org Git - libsigrok.git/blame - hardware/openbench-logic-sniffer/api.c
Add SR_CONF_MAX_UNCOMPRESSED_SAMPLES.
[libsigrok.git] / 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
e46aa4f6 25static const int32_t hwopts[] = {
1953564a
BV
26 SR_CONF_CONN,
27 SR_CONF_SERIALCOMM,
aeabd308
UH
28};
29
e46aa4f6 30static const int32_t hwcaps[] = {
1953564a
BV
31 SR_CONF_LOGIC_ANALYZER,
32 SR_CONF_SAMPLERATE,
0c05591a 33 SR_CONF_TRIGGER_TYPE,
1953564a
BV
34 SR_CONF_CAPTURE_RATIO,
35 SR_CONF_LIMIT_SAMPLES,
eb1b610b 36 SR_CONF_EXTERNAL_CLOCK,
967760a8 37 SR_CONF_PATTERN_MODE,
7b0a57fd 38 SR_CONF_SWAP,
1953564a 39 SR_CONF_RLE,
0aba65da
UH
40};
41
967760a8
MR
42#define STR_PATTERN_EXTERNAL "external"
43#define STR_PATTERN_INTERNAL "internal"
44
45/* Supported methods of test pattern outputs */
46enum {
47 /**
48 * Capture pins 31:16 (unbuffered wing) output a test pattern
49 * that can captured on pins 0:15.
50 */
51 PATTERN_EXTERNAL,
52
53 /** Route test pattern internally to capture buffer. */
54 PATTERN_INTERNAL,
55};
56
7c07a178
UH
57static const char *patterns[] = {
58 STR_PATTERN_EXTERNAL,
59 STR_PATTERN_INTERNAL,
60};
61
0aba65da
UH
62/* Probes are numbered 0-31 (on the PCB silkscreen). */
63SR_PRIV const char *ols_probe_names[NUM_PROBES + 1] = {
78693401
UH
64 "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12",
65 "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23",
66 "24", "25", "26", "27", "28", "29", "30", "31",
0aba65da
UH
67 NULL,
68};
69
d3b38ad3 70/* Default supported samplerates, can be overridden by device metadata. */
e46aa4f6
BV
71static const uint64_t samplerates[] = {
72 SR_HZ(10),
73 SR_MHZ(200),
74 SR_HZ(1),
0aba65da
UH
75};
76
77SR_PRIV struct sr_dev_driver ols_driver_info;
78static struct sr_dev_driver *di = &ols_driver_info;
79
eea49cf1
UH
80static int dev_clear(void)
81{
82 return std_dev_clear(di, NULL);
83}
84
03f4de8c 85static int init(struct sr_context *sr_ctx)
0aba65da 86{
f6beaac5 87 return std_init(sr_ctx, di, LOG_PREFIX);
0aba65da
UH
88}
89
03f4de8c 90static GSList *scan(GSList *options)
0aba65da 91{
1987b8d6 92 struct sr_config *src;
0aba65da
UH
93 struct sr_dev_inst *sdi;
94 struct drv_context *drvc;
95 struct dev_context *devc;
96 struct sr_probe *probe;
97 struct sr_serial_dev_inst *serial;
98 GPollFD probefd;
99 GSList *l, *devices;
100 int ret, i;
101 const char *conn, *serialcomm;
102 char buf[8];
103
0aba65da 104 drvc = di->priv;
4b97c74e 105
0aba65da
UH
106 devices = NULL;
107
108 conn = serialcomm = NULL;
109 for (l = options; l; l = l->next) {
1987b8d6
BV
110 src = l->data;
111 switch (src->key) {
1953564a 112 case SR_CONF_CONN:
e46aa4f6 113 conn = g_variant_get_string(src->data, NULL);
0aba65da 114 break;
1953564a 115 case SR_CONF_SERIALCOMM:
e46aa4f6 116 serialcomm = g_variant_get_string(src->data, NULL);
0aba65da
UH
117 break;
118 }
119 }
120 if (!conn)
121 return NULL;
122
123 if (serialcomm == NULL)
124 serialcomm = SERIALCOMM;
125
126 if (!(serial = sr_serial_dev_inst_new(conn, serialcomm)))
127 return NULL;
128
129 /* The discovery procedure is like this: first send the Reset
130 * command (0x00) 5 times, since the device could be anywhere
131 * in a 5-byte command. Then send the ID command (0x02).
132 * If the device responds with 4 bytes ("OLS1" or "SLA1"), we
133 * have a match.
134 */
135 sr_info("Probing %s.", conn);
136 if (serial_open(serial, SERIAL_RDWR | SERIAL_NONBLOCK) != SR_OK)
137 return NULL;
138
139 ret = SR_OK;
140 for (i = 0; i < 5; i++) {
141 if ((ret = send_shortcommand(serial, CMD_RESET)) != SR_OK) {
142 sr_err("Port %s is not writable.", conn);
143 break;
144 }
145 }
146 if (ret != SR_OK) {
147 serial_close(serial);
148 sr_err("Could not use port %s. Quitting.", conn);
149 return NULL;
150 }
151 send_shortcommand(serial, CMD_ID);
152
153 /* Wait 10ms for a response. */
154 g_usleep(10000);
155
bf72f649 156 sp_get_port_handle(serial->data, &probefd.fd);
0aba65da
UH
157 probefd.events = G_IO_IN;
158 g_poll(&probefd, 1, 1);
159
160 if (probefd.revents != G_IO_IN)
161 return NULL;
9f5d4c3c 162 if (serial_read_blocking(serial, buf, 4) != 4)
0aba65da
UH
163 return NULL;
164 if (strncmp(buf, "1SLO", 4) && strncmp(buf, "1ALS", 4))
165 return NULL;
166
167 /* Definitely using the OLS protocol, check if it supports
168 * the metadata command.
169 */
170 send_shortcommand(serial, CMD_METADATA);
171 if (g_poll(&probefd, 1, 10) > 0) {
172 /* Got metadata. */
173 sdi = get_metadata(serial);
174 sdi->index = 0;
175 devc = sdi->priv;
176 } else {
177 /* Not an OLS -- some other board that uses the sump protocol. */
72cd99b8 178 sr_info("Device does not support metadata.");
0aba65da
UH
179 sdi = sr_dev_inst_new(0, SR_ST_INACTIVE,
180 "Sump", "Logic Analyzer", "v1.0");
181 sdi->driver = di;
0aba65da
UH
182 for (i = 0; i < 32; i++) {
183 if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE,
184 ols_probe_names[i])))
185 return 0;
186 sdi->probes = g_slist_append(sdi->probes, probe);
187 }
bf256783 188 devc = ols_dev_new();
0aba65da
UH
189 sdi->priv = devc;
190 }
bf256783
BV
191 /* Configure samplerate and divider. */
192 if (ols_set_samplerate(sdi, DEFAULT_SAMPLERATE) != SR_OK)
193 sr_dbg("Failed to set default samplerate (%"PRIu64").",
194 DEFAULT_SAMPLERATE);
195 /* Clear trigger masks, values and stages. */
196 ols_configure_probes(sdi);
459a0f26
BV
197 sdi->inst_type = SR_INST_SERIAL;
198 sdi->conn = serial;
bf256783 199
0aba65da
UH
200 drvc->instances = g_slist_append(drvc->instances, sdi);
201 devices = g_slist_append(devices, sdi);
202
203 serial_close(serial);
204
205 return devices;
206}
207
03f4de8c 208static GSList *dev_list(void)
0aba65da 209{
0e94d524 210 return ((struct drv_context *)(di->priv))->instances;
0aba65da
UH
211}
212
eea49cf1 213static int cleanup(void)
0aba65da 214{
eea49cf1 215 return dev_clear();
0aba65da
UH
216}
217
8f996b89
ML
218static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
219 const struct sr_probe_group *probe_group)
0aba65da
UH
220{
221 struct dev_context *devc;
222
8f996b89
ML
223 (void)probe_group;
224
0c05591a
BV
225 if (!sdi)
226 return SR_ERR_ARG;
227
228 devc = sdi->priv;
035a1078 229 switch (id) {
123e1313 230 case SR_CONF_SAMPLERATE:
0c05591a
BV
231 *data = g_variant_new_uint64(devc->cur_samplerate);
232 break;
233 case SR_CONF_CAPTURE_RATIO:
234 *data = g_variant_new_uint64(devc->capture_ratio);
235 break;
236 case SR_CONF_LIMIT_SAMPLES:
237 *data = g_variant_new_uint64(devc->limit_samples);
238 break;
967760a8
MR
239 case SR_CONF_PATTERN_MODE:
240 if (devc->flag_reg & FLAG_EXTERNAL_TEST_MODE)
241 *data = g_variant_new_string(STR_PATTERN_EXTERNAL);
242 else if (devc->flag_reg & FLAG_INTERNAL_TEST_MODE)
243 *data = g_variant_new_string(STR_PATTERN_INTERNAL);
244 break;
0c05591a
BV
245 case SR_CONF_RLE:
246 *data = g_variant_new_boolean(devc->flag_reg & FLAG_RLE ? TRUE : FALSE);
0aba65da
UH
247 break;
248 default:
bd6fbf62 249 return SR_ERR_NA;
0aba65da
UH
250 }
251
252 return SR_OK;
253}
254
8f996b89
ML
255static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi,
256 const struct sr_probe_group *probe_group)
0aba65da
UH
257{
258 struct dev_context *devc;
259 int ret;
e46aa4f6 260 uint64_t tmp_u64;
967760a8 261 const char *stropt;
0aba65da 262
8f996b89
ML
263 (void)probe_group;
264
e73ffd42
BV
265 if (sdi->status != SR_ST_ACTIVE)
266 return SR_ERR_DEV_CLOSED;
267
0aba65da
UH
268 devc = sdi->priv;
269
035a1078 270 switch (id) {
1953564a 271 case SR_CONF_SAMPLERATE:
e46aa4f6
BV
272 tmp_u64 = g_variant_get_uint64(data);
273 if (tmp_u64 < samplerates[0] || tmp_u64 > samplerates[1])
274 return SR_ERR_SAMPLERATE;
275 ret = ols_set_samplerate(sdi, g_variant_get_uint64(data));
0aba65da 276 break;
1953564a 277 case SR_CONF_LIMIT_SAMPLES:
e46aa4f6
BV
278 tmp_u64 = g_variant_get_uint64(data);
279 if (tmp_u64 < MIN_NUM_SAMPLES)
0aba65da 280 return SR_ERR;
e46aa4f6 281 devc->limit_samples = tmp_u64;
0aba65da
UH
282 ret = SR_OK;
283 break;
1953564a 284 case SR_CONF_CAPTURE_RATIO:
e46aa4f6 285 devc->capture_ratio = g_variant_get_uint64(data);
0aba65da
UH
286 if (devc->capture_ratio < 0 || devc->capture_ratio > 100) {
287 devc->capture_ratio = 0;
288 ret = SR_ERR;
289 } else
290 ret = SR_OK;
291 break;
eb1b610b
MR
292 case SR_CONF_EXTERNAL_CLOCK:
293 if (g_variant_get_boolean(data)) {
294 sr_info("Enabling external clock.");
295 devc->flag_reg |= FLAG_CLOCK_EXTERNAL;
296 } else {
297 sr_info("Disabled external clock.");
298 devc->flag_reg &= ~FLAG_CLOCK_EXTERNAL;
299 }
300 ret = SR_OK;
301 break;
967760a8
MR
302 case SR_CONF_PATTERN_MODE:
303 stropt = g_variant_get_string(data, NULL);
304 ret = SR_OK;
305 if (!strcmp(stropt, STR_PATTERN_INTERNAL)) {
306 sr_info("Enabling internal test mode.");
307 devc->flag_reg |= FLAG_INTERNAL_TEST_MODE;
308 } else if (!strcmp(stropt, STR_PATTERN_EXTERNAL)) {
309 sr_info("Enabling external test mode.");
310 devc->flag_reg |= FLAG_EXTERNAL_TEST_MODE;
311 } else {
312 ret = SR_ERR;
313 }
314 break;
7b0a57fd
MR
315 case SR_CONF_SWAP:
316 if (g_variant_get_boolean(data)) {
317 sr_info("Enabling channel swapping.");
318 devc->flag_reg |= FLAG_SWAP_PROBES;
319 } else {
320 sr_info("Disabling channel swapping.");
321 devc->flag_reg &= ~FLAG_SWAP_PROBES;
322 }
323 ret = SR_OK;
324 break;
325
1953564a 326 case SR_CONF_RLE:
e46aa4f6 327 if (g_variant_get_boolean(data)) {
0aba65da
UH
328 sr_info("Enabling RLE.");
329 devc->flag_reg |= FLAG_RLE;
aeea0572
BV
330 } else {
331 sr_info("Disabling RLE.");
332 devc->flag_reg &= ~FLAG_RLE;
0aba65da
UH
333 }
334 ret = SR_OK;
335 break;
336 default:
bd6fbf62 337 ret = SR_ERR_NA;
0aba65da
UH
338 }
339
340 return ret;
341}
342
8f996b89
ML
343static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
344 const struct sr_probe_group *probe_group)
a1c743fc 345{
e46aa4f6
BV
346 GVariant *gvar;
347 GVariantBuilder gvb;
a1c743fc
BV
348
349 (void)sdi;
8f996b89 350 (void)probe_group;
a1c743fc
BV
351
352 switch (key) {
0d485e30 353 case SR_CONF_SCAN_OPTIONS:
e46aa4f6
BV
354 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
355 hwopts, ARRAY_SIZE(hwopts), sizeof(int32_t));
0d485e30 356 break;
9a6517d1 357 case SR_CONF_DEVICE_OPTIONS:
e46aa4f6
BV
358 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
359 hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
9a6517d1 360 break;
a1c743fc 361 case SR_CONF_SAMPLERATE:
e46aa4f6
BV
362 g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}"));
363 gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), samplerates,
364 ARRAY_SIZE(samplerates), sizeof(uint64_t));
365 g_variant_builder_add(&gvb, "{sv}", "samplerate-steps", gvar);
366 *data = g_variant_builder_end(&gvb);
a1c743fc 367 break;
c50277a6 368 case SR_CONF_TRIGGER_TYPE:
e46aa4f6 369 *data = g_variant_new_string(TRIGGER_TYPE);
c50277a6 370 break;
7c07a178
UH
371 case SR_CONF_PATTERN_MODE:
372 *data = g_variant_new_strv(patterns, ARRAY_SIZE(patterns));
373 break;
a1c743fc 374 default:
bd6fbf62 375 return SR_ERR_NA;
a1c743fc
BV
376 }
377
378 return SR_OK;
379}
380
03f4de8c 381static int dev_acquisition_start(const struct sr_dev_inst *sdi,
0aba65da
UH
382 void *cb_data)
383{
0aba65da 384 struct dev_context *devc;
459a0f26 385 struct sr_serial_dev_inst *serial;
0aba65da
UH
386 uint32_t trigger_config[4];
387 uint32_t data;
388 uint16_t readcount, delaycount;
389 uint8_t changrp_mask;
390 int num_channels;
391 int i;
392
e73ffd42
BV
393 if (sdi->status != SR_ST_ACTIVE)
394 return SR_ERR_DEV_CLOSED;
395
0aba65da 396 devc = sdi->priv;
459a0f26 397 serial = sdi->conn;
0aba65da 398
0aba65da
UH
399 if (ols_configure_probes(sdi) != SR_OK) {
400 sr_err("Failed to configure probes.");
401 return SR_ERR;
402 }
403
404 /*
405 * Enable/disable channel groups in the flag register according to the
406 * probe mask. Calculate this here, because num_channels is needed
407 * to limit readcount.
408 */
409 changrp_mask = 0;
410 num_channels = 0;
411 for (i = 0; i < 4; i++) {
412 if (devc->probe_mask & (0xff << (i * 8))) {
413 changrp_mask |= (1 << i);
414 num_channels++;
415 }
416 }
417
418 /*
419 * Limit readcount to prevent reading past the end of the hardware
420 * buffer.
421 */
422 readcount = MIN(devc->max_samples / num_channels, devc->limit_samples) / 4;
423
424 memset(trigger_config, 0, 16);
2e5b73c0 425 trigger_config[devc->num_stages] |= 0x08;
0aba65da
UH
426 if (devc->trigger_mask[0]) {
427 delaycount = readcount * (1 - devc->capture_ratio / 100.0);
428 devc->trigger_at = (readcount - delaycount) * 4 - devc->num_stages;
429
459a0f26 430 if (send_longcommand(serial, CMD_SET_TRIGGER_MASK_0,
0aba65da
UH
431 reverse32(devc->trigger_mask[0])) != SR_OK)
432 return SR_ERR;
459a0f26 433 if (send_longcommand(serial, CMD_SET_TRIGGER_VALUE_0,
0aba65da
UH
434 reverse32(devc->trigger_value[0])) != SR_OK)
435 return SR_ERR;
459a0f26 436 if (send_longcommand(serial, CMD_SET_TRIGGER_CONFIG_0,
0aba65da
UH
437 trigger_config[0]) != SR_OK)
438 return SR_ERR;
439
459a0f26 440 if (send_longcommand(serial, CMD_SET_TRIGGER_MASK_1,
0aba65da
UH
441 reverse32(devc->trigger_mask[1])) != SR_OK)
442 return SR_ERR;
459a0f26 443 if (send_longcommand(serial, CMD_SET_TRIGGER_VALUE_1,
0aba65da
UH
444 reverse32(devc->trigger_value[1])) != SR_OK)
445 return SR_ERR;
459a0f26 446 if (send_longcommand(serial, CMD_SET_TRIGGER_CONFIG_1,
0aba65da
UH
447 trigger_config[1]) != SR_OK)
448 return SR_ERR;
449
459a0f26 450 if (send_longcommand(serial, CMD_SET_TRIGGER_MASK_2,
0aba65da
UH
451 reverse32(devc->trigger_mask[2])) != SR_OK)
452 return SR_ERR;
459a0f26 453 if (send_longcommand(serial, CMD_SET_TRIGGER_VALUE_2,
0aba65da
UH
454 reverse32(devc->trigger_value[2])) != SR_OK)
455 return SR_ERR;
459a0f26 456 if (send_longcommand(serial, CMD_SET_TRIGGER_CONFIG_2,
0aba65da
UH
457 trigger_config[2]) != SR_OK)
458 return SR_ERR;
459
459a0f26 460 if (send_longcommand(serial, CMD_SET_TRIGGER_MASK_3,
0aba65da
UH
461 reverse32(devc->trigger_mask[3])) != SR_OK)
462 return SR_ERR;
459a0f26 463 if (send_longcommand(serial, CMD_SET_TRIGGER_VALUE_3,
0aba65da
UH
464 reverse32(devc->trigger_value[3])) != SR_OK)
465 return SR_ERR;
459a0f26 466 if (send_longcommand(serial, CMD_SET_TRIGGER_CONFIG_3,
0aba65da
UH
467 trigger_config[3]) != SR_OK)
468 return SR_ERR;
469 } else {
459a0f26 470 if (send_longcommand(serial, CMD_SET_TRIGGER_MASK_0,
0aba65da
UH
471 devc->trigger_mask[0]) != SR_OK)
472 return SR_ERR;
459a0f26 473 if (send_longcommand(serial, CMD_SET_TRIGGER_VALUE_0,
0aba65da
UH
474 devc->trigger_value[0]) != SR_OK)
475 return SR_ERR;
459a0f26 476 if (send_longcommand(serial, CMD_SET_TRIGGER_CONFIG_0,
0aba65da
UH
477 0x00000008) != SR_OK)
478 return SR_ERR;
479 delaycount = readcount;
480 }
481
482 sr_info("Setting samplerate to %" PRIu64 "Hz (divider %u, "
de524099
MR
483 "demux %s, noise_filter %s)", devc->cur_samplerate,
484 devc->cur_samplerate_divider,
485 devc->flag_reg & FLAG_DEMUX ? "on" : "off",
486 devc->flag_reg & FLAG_FILTER ? "on": "off");
459a0f26 487 if (send_longcommand(serial, CMD_SET_DIVIDER,
0aba65da
UH
488 reverse32(devc->cur_samplerate_divider)) != SR_OK)
489 return SR_ERR;
490
491 /* Send sample limit and pre/post-trigger capture ratio. */
492 data = ((readcount - 1) & 0xffff) << 16;
493 data |= (delaycount - 1) & 0xffff;
459a0f26 494 if (send_longcommand(serial, CMD_CAPTURE_SIZE, reverse16(data)) != SR_OK)
0aba65da
UH
495 return SR_ERR;
496
497 /* The flag register wants them here, and 1 means "disable channel". */
498 devc->flag_reg |= ~(changrp_mask << 2) & 0x3c;
0aba65da
UH
499 devc->rle_count = 0;
500 data = (devc->flag_reg << 24) | ((devc->flag_reg << 8) & 0xff0000);
459a0f26 501 if (send_longcommand(serial, CMD_SET_FLAGS, data) != SR_OK)
0aba65da
UH
502 return SR_ERR;
503
504 /* Start acquisition on the device. */
459a0f26 505 if (send_shortcommand(serial, CMD_RUN) != SR_OK)
0aba65da
UH
506 return SR_ERR;
507
bf256783
BV
508 /* Reset all operational states. */
509 devc->num_transfers = devc->num_samples = devc->num_bytes = 0;
abb39e6b 510 memset(devc->sample, 0, 4);
bf256783 511
4afdfd46 512 /* Send header packet to the session bus. */
29a27196 513 std_session_send_df_header(cb_data, LOG_PREFIX);
4afdfd46 514
abc4b335 515 serial_source_add(serial, G_IO_IN, -1, ols_receive_data, cb_data);
0aba65da 516
0aba65da
UH
517 return SR_OK;
518}
519
03f4de8c 520static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
0aba65da 521{
0aba65da
UH
522 (void)cb_data;
523
524 abort_acquisition(sdi);
525
526 return SR_OK;
527}
528
529SR_PRIV struct sr_dev_driver ols_driver_info = {
530 .name = "ols",
531 .longname = "Openbench Logic Sniffer",
532 .api_version = 1,
03f4de8c 533 .init = init,
eea49cf1 534 .cleanup = cleanup,
03f4de8c
BV
535 .scan = scan,
536 .dev_list = dev_list,
537 .dev_clear = dev_clear,
035a1078
BV
538 .config_get = config_get,
539 .config_set = config_set,
a1c743fc 540 .config_list = config_list,
854434de 541 .dev_open = std_serial_dev_open,
bf2c987f 542 .dev_close = std_serial_dev_close,
03f4de8c
BV
543 .dev_acquisition_start = dev_acquisition_start,
544 .dev_acquisition_stop = dev_acquisition_stop,
0aba65da
UH
545 .priv = NULL,
546};