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