]> sigrok.org Git - libsigrok.git/blame - hardware/openbench-logic-sniffer/ols.c
sr: Fix/document probe names.
[libsigrok.git] / hardware / openbench-logic-sniffer / ols.c
CommitLineData
a1bb33af
UH
1/*
2 * This file is part of the sigrok project.
3 *
c73d2ea4 4 * Copyright (C) 2010-2012 Bert Vermeulen <bert@biot.com>
a1bb33af
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 <stdio.h>
21#include <stdint.h>
22#include <stdlib.h>
23#include <sys/types.h>
24#include <sys/stat.h>
25#include <fcntl.h>
26#include <unistd.h>
a9f54bcd
UH
27#ifdef _WIN32
28#include <windows.h>
29#else
a1bb33af 30#include <termios.h>
926b866c 31#endif
a1bb33af
UH
32#include <string.h>
33#include <sys/time.h>
34#include <inttypes.h>
926b866c
UH
35#ifdef _WIN32
36/* TODO */
37#else
6937bb75 38#include <arpa/inet.h>
926b866c 39#endif
a1bb33af 40#include <glib.h>
b7f09cf8
UH
41#include "sigrok.h"
42#include "sigrok-internal.h"
4fe9a6da 43#include "ols.h"
a1bb33af 44
1fdb75e1
UH
45#ifdef _WIN32
46#define O_NONBLOCK FIONBIO
47#endif
48
ffedd0bf 49static int hwcaps[] = {
5a2326a7
UH
50 SR_HWCAP_LOGIC_ANALYZER,
51 SR_HWCAP_SAMPLERATE,
52 SR_HWCAP_CAPTURE_RATIO,
53 SR_HWCAP_LIMIT_SAMPLES,
3a4d09c0 54 SR_HWCAP_RLE,
43fc7885 55 0,
a1bb33af
UH
56};
57
d261dbbf 58/* Probes are numbered 0-31 (on the PCB silkscreen). */
c37d2b1b 59static const char *probe_names[NUM_PROBES + 1] = {
464d12c7
KS
60 "0",
61 "1",
62 "2",
63 "3",
64 "4",
65 "5",
66 "6",
67 "7",
68 "8",
69 "9",
70 "10",
71 "11",
72 "12",
73 "13",
74 "14",
75 "15",
76 "16",
77 "17",
78 "18",
79 "19",
80 "20",
81 "21",
82 "22",
83 "23",
84 "24",
85 "25",
86 "26",
87 "27",
88 "28",
89 "29",
90 "30",
91 "31",
92 NULL,
93};
94
4fe9a6da 95/* default supported samplerates, can be overridden by device metadata */
60679b18 96static struct sr_samplerates samplerates = {
c9140419 97 SR_HZ(10),
59df0c77 98 SR_MHZ(200),
c9140419
UH
99 SR_HZ(1),
100 NULL,
a1bb33af
UH
101};
102
d68e2d1a
UH
103/* List of struct sr_serial_dev_inst */
104static GSList *dev_insts = NULL;
a1bb33af 105
6937bb75 106static int send_shortcommand(int fd, uint8_t command)
a1bb33af
UH
107{
108 char buf[1];
109
b08024a8 110 sr_dbg("ols: sending cmd 0x%.2x", command);
a1bb33af 111 buf[0] = command;
2119ab03 112 if (serial_write(fd, buf, 1) != 1)
e46b8fb1 113 return SR_ERR;
a1bb33af 114
e46b8fb1 115 return SR_OK;
a1bb33af
UH
116}
117
6937bb75 118static int send_longcommand(int fd, uint8_t command, uint32_t data)
a1bb33af
UH
119{
120 char buf[5];
121
b08024a8 122 sr_dbg("ols: sending cmd 0x%.2x data 0x%.8x", command, data);
a1bb33af 123 buf[0] = command;
6937bb75
BV
124 buf[1] = (data & 0xff000000) >> 24;
125 buf[2] = (data & 0xff0000) >> 16;
126 buf[3] = (data & 0xff00) >> 8;
127 buf[4] = data & 0xff;
2119ab03 128 if (serial_write(fd, buf, 5) != 5)
e46b8fb1 129 return SR_ERR;
a1bb33af 130
e46b8fb1 131 return SR_OK;
a1bb33af
UH
132}
133
ea9cfed7 134static int configure_probes(struct context *ctx, GSList *probes)
a1bb33af 135{
1afe8989 136 struct sr_probe *probe;
a1bb33af 137 GSList *l;
6937bb75 138 int probe_bit, stage, i;
a1bb33af
UH
139 char *tc;
140
ea9cfed7 141 ctx->probe_mask = 0;
43fc7885 142 for (i = 0; i < NUM_TRIGGER_STAGES; i++) {
ea9cfed7
UH
143 ctx->trigger_mask[i] = 0;
144 ctx->trigger_value[i] = 0;
a1bb33af
UH
145 }
146
ea9cfed7 147 ctx->num_stages = 0;
43fc7885 148 for (l = probes; l; l = l->next) {
1afe8989 149 probe = (struct sr_probe *)l->data;
43fc7885 150 if (!probe->enabled)
6937bb75
BV
151 continue;
152
43fc7885
UH
153 /*
154 * Set up the probe mask for later configuration into the
155 * flag register.
156 */
a1bb33af 157 probe_bit = 1 << (probe->index - 1);
ea9cfed7 158 ctx->probe_mask |= probe_bit;
6937bb75 159
a803c0db 160 if (!probe->trigger)
6937bb75
BV
161 continue;
162
43fc7885 163 /* Configure trigger mask and value. */
6937bb75 164 stage = 0;
43fc7885 165 for (tc = probe->trigger; tc && *tc; tc++) {
ea9cfed7 166 ctx->trigger_mask[stage] |= probe_bit;
43fc7885 167 if (*tc == '1')
ea9cfed7 168 ctx->trigger_value[stage] |= probe_bit;
6937bb75 169 stage++;
43fc7885
UH
170 if (stage > 3)
171 /*
172 * TODO: Only supporting parallel mode, with
173 * up to 4 stages.
174 */
e46b8fb1 175 return SR_ERR;
a1bb33af 176 }
ea9cfed7
UH
177 if (stage > ctx->num_stages)
178 ctx->num_stages = stage;
a1bb33af
UH
179 }
180
e46b8fb1 181 return SR_OK;
a1bb33af
UH
182}
183
a803c0db 184static uint32_t reverse16(uint32_t in)
6937bb75
BV
185{
186 uint32_t out;
187
a803c0db
BV
188 out = (in & 0xff) << 8;
189 out |= (in & 0xff00) >> 8;
190 out |= (in & 0xff0000) << 8;
191 out |= (in & 0xff000000) >> 8;
192
193 return out;
194}
195
196static uint32_t reverse32(uint32_t in)
197{
198 uint32_t out;
199
200 out = (in & 0xff) << 24;
201 out |= (in & 0xff00) << 8;
202 out |= (in & 0xff0000) >> 8;
203 out |= (in & 0xff000000) >> 24;
204
205 return out;
6937bb75
BV
206}
207
ea9cfed7 208static struct context *ols_dev_new(void)
4fe9a6da 209{
ea9cfed7 210 struct context *ctx;
4fe9a6da 211
ea9cfed7
UH
212 /* TODO: Is 'ctx' ever g_free()'d? */
213 if (!(ctx = g_try_malloc0(sizeof(struct context)))) {
214 sr_err("ols: %s: ctx malloc failed", __func__);
b53738ba
UH
215 return NULL;
216 }
217
ea9cfed7
UH
218 ctx->trigger_at = -1;
219 ctx->probe_mask = 0xffffffff;
220 ctx->cur_samplerate = SR_KHZ(200);
221 ctx->serial = NULL;
4fe9a6da 222
ea9cfed7 223 return ctx;
4fe9a6da
BV
224}
225
d68e2d1a 226static struct sr_dev_inst *get_metadata(int fd)
4fe9a6da 227{
d68e2d1a 228 struct sr_dev_inst *sdi;
ea9cfed7 229 struct context *ctx;
4fe9a6da
BV
230 uint32_t tmp_int;
231 uint8_t key, type, token;
bb7ef793 232 GString *tmp_str, *devname, *version;
4fe9a6da
BV
233 gchar tmp_c;
234
d3683c42 235 sdi = sr_dev_inst_new(0, SR_ST_INACTIVE, NULL, NULL, NULL);
ea9cfed7
UH
236 ctx = ols_dev_new();
237 sdi->priv = ctx;
4fe9a6da 238
bb7ef793 239 devname = g_string_new("");
4fe9a6da
BV
240 version = g_string_new("");
241
242 key = 0xff;
243 while (key) {
244 if (serial_read(fd, &key, 1) != 1 || key == 0x00)
245 break;
246 type = key >> 5;
247 token = key & 0x1f;
248 switch (type) {
249 case 0:
250 /* NULL-terminated string */
251 tmp_str = g_string_new("");
252 while (serial_read(fd, &tmp_c, 1) == 1 && tmp_c != '\0')
253 g_string_append_c(tmp_str, tmp_c);
b08024a8
UH
254 sr_dbg("ols: got metadata key 0x%.2x value '%s'",
255 key, tmp_str->str);
4fe9a6da
BV
256 switch (token) {
257 case 0x01:
258 /* Device name */
bb7ef793 259 devname = g_string_append(devname, tmp_str->str);
4fe9a6da
BV
260 break;
261 case 0x02:
262 /* FPGA firmware version */
263 if (version->len)
264 g_string_append(version, ", ");
265 g_string_append(version, "FPGA version ");
266 g_string_append(version, tmp_str->str);
267 break;
268 case 0x03:
269 /* Ancillary version */
270 if (version->len)
271 g_string_append(version, ", ");
272 g_string_append(version, "Ancillary version ");
273 g_string_append(version, tmp_str->str);
274 break;
275 default:
b08024a8
UH
276 sr_info("ols: unknown token 0x%.2x: '%s'",
277 token, tmp_str->str);
4fe9a6da
BV
278 break;
279 }
280 g_string_free(tmp_str, TRUE);
281 break;
282 case 1:
283 /* 32-bit unsigned integer */
284 if (serial_read(fd, &tmp_int, 4) != 4)
285 break;
286 tmp_int = reverse32(tmp_int);
b08024a8
UH
287 sr_dbg("ols: got metadata key 0x%.2x value 0x%.8x",
288 key, tmp_int);
4fe9a6da
BV
289 switch (token) {
290 case 0x00:
291 /* Number of usable probes */
ea9cfed7 292 ctx->num_probes = tmp_int;
4fe9a6da
BV
293 break;
294 case 0x01:
295 /* Amount of sample memory available (bytes) */
ea9cfed7 296 ctx->max_samples = tmp_int;
4fe9a6da
BV
297 break;
298 case 0x02:
299 /* Amount of dynamic memory available (bytes) */
300 /* what is this for? */
301 break;
302 case 0x03:
303 /* Maximum sample rate (hz) */
ea9cfed7 304 ctx->max_samplerate = tmp_int;
4fe9a6da
BV
305 break;
306 case 0x04:
307 /* protocol version */
ea9cfed7 308 ctx->protocol_version = tmp_int;
4fe9a6da
BV
309 break;
310 default:
b08024a8
UH
311 sr_info("ols: unknown token 0x%.2x: 0x%.8x",
312 token, tmp_int);
4fe9a6da
BV
313 break;
314 }
315 break;
316 case 2:
317 /* 8-bit unsigned integer */
318 if (serial_read(fd, &tmp_c, 1) != 1)
319 break;
b08024a8
UH
320 sr_dbg("ols: got metadata key 0x%.2x value 0x%.2x",
321 key, tmp_c);
4fe9a6da
BV
322 switch (token) {
323 case 0x00:
324 /* Number of usable probes */
ea9cfed7 325 ctx->num_probes = tmp_c;
4fe9a6da
BV
326 break;
327 case 0x01:
328 /* protocol version */
ea9cfed7 329 ctx->protocol_version = tmp_c;
4fe9a6da
BV
330 break;
331 default:
b08024a8
UH
332 sr_info("ols: unknown token 0x%.2x: 0x%.2x",
333 token, tmp_c);
4fe9a6da
BV
334 break;
335 }
336 break;
337 default:
338 /* unknown type */
339 break;
340 }
341 }
342
bb7ef793 343 sdi->model = devname->str;
4fe9a6da 344 sdi->version = version->str;
bb7ef793 345 g_string_free(devname, FALSE);
4fe9a6da
BV
346 g_string_free(version, FALSE);
347
348 return sdi;
349}
350
bb7ef793 351static int hw_init(const char *devinfo)
a1bb33af 352{
d68e2d1a 353 struct sr_dev_inst *sdi;
ea9cfed7 354 struct context *ctx;
a1bb33af 355 GSList *ports, *l;
4fe9a6da 356 GPollFD *fds, probefd;
6937bb75 357 int devcnt, final_devcnt, num_ports, fd, ret, i;
bb7ef793 358 char buf[8], **dev_names, **serial_params;
a1bb33af 359
c0a4b971
UH
360 final_devcnt = 0;
361
bb7ef793
UH
362 if (devinfo)
363 ports = g_slist_append(NULL, g_strdup(devinfo));
a1bb33af 364 else
43fc7885 365 /* No specific device given, so scan all serial ports. */
a1bb33af
UH
366 ports = list_serial_ports();
367
368 num_ports = g_slist_length(ports);
c0a4b971
UH
369
370 if (!(fds = g_try_malloc0(num_ports * sizeof(GPollFD)))) {
371 sr_err("ols: %s: fds malloc failed", __func__);
372 goto hw_init_free_ports; /* TODO: SR_ERR_MALLOC. */
373 }
374
bb7ef793
UH
375 if (!(dev_names = g_try_malloc(num_ports * sizeof(char *)))) {
376 sr_err("ols: %s: dev_names malloc failed", __func__);
c0a4b971
UH
377 goto hw_init_free_fds; /* TODO: SR_ERR_MALLOC. */
378 }
379
380 if (!(serial_params = g_try_malloc(num_ports * sizeof(char *)))) {
381 sr_err("ols: %s: serial_params malloc failed", __func__);
bb7ef793 382 goto hw_init_free_dev_names; /* TODO: SR_ERR_MALLOC. */
c0a4b971
UH
383 }
384
a1bb33af 385 devcnt = 0;
43fc7885
UH
386 for (l = ports; l; l = l->next) {
387 /* The discovery procedure is like this: first send the Reset
388 * command (0x00) 5 times, since the device could be anywhere
389 * in a 5-byte command. Then send the ID command (0x02).
390 * If the device responds with 4 bytes ("OLS1" or "SLA1"), we
391 * have a match.
392 *
393 * Since it may take the device a while to respond at 115Kb/s,
394 * we do all the sending first, then wait for all of them to
395 * respond with g_poll().
a1bb33af 396 */
b08024a8 397 sr_info("ols: probing %s...", (char *)l->data);
d02a535e 398 fd = serial_open(l->data, O_RDWR | O_NONBLOCK);
43fc7885 399 if (fd != -1) {
d02a535e
BV
400 serial_params[devcnt] = serial_backup_params(fd);
401 serial_set_params(fd, 115200, 8, 0, 1, 2);
e46b8fb1 402 ret = SR_OK;
43fc7885
UH
403 for (i = 0; i < 5; i++) {
404 if ((ret = send_shortcommand(fd,
e46b8fb1 405 CMD_RESET)) != SR_OK) {
43fc7885 406 /* Serial port is not writable. */
6937bb75
BV
407 break;
408 }
a1bb33af 409 }
e46b8fb1 410 if (ret != SR_OK) {
43fc7885
UH
411 serial_restore_params(fd,
412 serial_params[devcnt]);
d02a535e 413 serial_close(fd);
6937bb75 414 continue;
d02a535e 415 }
6937bb75
BV
416 send_shortcommand(fd, CMD_ID);
417 fds[devcnt].fd = fd;
418 fds[devcnt].events = G_IO_IN;
bb7ef793 419 dev_names[devcnt] = g_strdup(l->data);
6937bb75 420 devcnt++;
a1bb33af 421 }
133a37bf 422 g_free(l->data);
a1bb33af
UH
423 }
424
5b15b41e
PS
425 /* 2ms isn't enough for reliable transfer with pl2303, let's try 10 */
426 usleep(10000);
a1bb33af 427
a1bb33af 428 g_poll(fds, devcnt, 1);
4fe9a6da 429
43fc7885 430 for (i = 0; i < devcnt; i++) {
4fe9a6da
BV
431 if (fds[i].revents != G_IO_IN)
432 continue;
433 if (serial_read(fds[i].fd, buf, 4) != 4)
434 continue;
435 if (strncmp(buf, "1SLO", 4) && strncmp(buf, "1ALS", 4))
436 continue;
437
438 /* definitely using the OLS protocol, check if it supports
439 * the metadata command
440 */
441 send_shortcommand(fds[i].fd, CMD_METADATA);
442 probefd.fd = fds[i].fd;
443 probefd.events = G_IO_IN;
444 if (g_poll(&probefd, 1, 10) > 0) {
445 /* got metadata */
446 sdi = get_metadata(fds[i].fd);
447 sdi->index = final_devcnt;
448 } else {
449 /* not an OLS -- some other board that uses the sump protocol */
d3683c42 450 sdi = sr_dev_inst_new(final_devcnt, SR_ST_INACTIVE,
4fe9a6da 451 "Sump", "Logic Analyzer", "v1.0");
ea9cfed7
UH
452 ctx = ols_dev_new();
453 ctx->num_probes = 32;
454 sdi->priv = ctx;
a1bb33af 455 }
ea9cfed7 456 ctx->serial = sr_serial_dev_inst_new(dev_names[i], -1);
d68e2d1a 457 dev_insts = g_slist_append(dev_insts, sdi);
4fe9a6da
BV
458 final_devcnt++;
459 serial_close(fds[i].fd);
460 fds[i].fd = 0;
4fe9a6da
BV
461 }
462
463 /* clean up after all the probing */
464 for (i = 0; i < devcnt; i++) {
43fc7885 465 if (fds[i].fd != 0) {
d02a535e
BV
466 serial_restore_params(fds[i].fd, serial_params[i]);
467 serial_close(fds[i].fd);
6937bb75 468 }
133a37bf 469 g_free(serial_params[i]);
bb7ef793 470 g_free(dev_names[i]);
a1bb33af
UH
471 }
472
c0a4b971 473 g_free(serial_params);
bb7ef793
UH
474hw_init_free_dev_names:
475 g_free(dev_names);
c0a4b971
UH
476hw_init_free_fds:
477 g_free(fds);
478hw_init_free_ports:
a1bb33af
UH
479 g_slist_free(ports);
480
481 return final_devcnt;
482}
483
e7eb703f 484static int hw_dev_open(int dev_index)
a1bb33af 485{
d68e2d1a 486 struct sr_dev_inst *sdi;
ea9cfed7 487 struct context *ctx;
a1bb33af 488
bb7ef793 489 if (!(sdi = sr_dev_inst_get(dev_insts, dev_index)))
e46b8fb1 490 return SR_ERR;
a1bb33af 491
ea9cfed7 492 ctx = sdi->priv;
69890f73 493
ea9cfed7
UH
494 ctx->serial->fd = serial_open(ctx->serial->port, O_RDWR);
495 if (ctx->serial->fd == -1)
e46b8fb1 496 return SR_ERR;
a1bb33af 497
5a2326a7 498 sdi->status = SR_ST_ACTIVE;
a1bb33af 499
e46b8fb1 500 return SR_OK;
a1bb33af
UH
501}
502
e7eb703f 503static int hw_dev_close(int dev_index)
a1bb33af 504{
d68e2d1a 505 struct sr_dev_inst *sdi;
ea9cfed7 506 struct context *ctx;
a1bb33af 507
bb7ef793 508 if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) {
697785d1
UH
509 sr_err("ols: %s: sdi was NULL", __func__);
510 return SR_ERR; /* TODO: SR_ERR_ARG? */
511 }
a1bb33af 512
ea9cfed7 513 ctx = sdi->priv;
69890f73 514
697785d1 515 /* TODO */
ea9cfed7
UH
516 if (ctx->serial->fd != -1) {
517 serial_close(ctx->serial->fd);
518 ctx->serial->fd = -1;
5a2326a7 519 sdi->status = SR_ST_INACTIVE;
a1bb33af 520 }
697785d1
UH
521
522 return SR_OK;
a1bb33af
UH
523}
524
57ab7d9f 525static int hw_cleanup(void)
a1bb33af
UH
526{
527 GSList *l;
d68e2d1a 528 struct sr_dev_inst *sdi;
ea9cfed7 529 struct context *ctx;
57ab7d9f 530 int ret = SR_OK;
a1bb33af 531
8722c31e 532 /* Properly close and free all devices. */
d68e2d1a 533 for (l = dev_insts; l; l = l->next) {
57ab7d9f
UH
534 if (!(sdi = l->data)) {
535 /* Log error, but continue cleaning up the rest. */
536 sr_err("ols: %s: sdi was NULL, continuing", __func__);
537 ret = SR_ERR_BUG;
538 continue;
539 }
ea9cfed7 540 if (!(ctx = sdi->priv)) {
57ab7d9f
UH
541 /* Log error, but continue cleaning up the rest. */
542 sr_err("ols: %s: sdi->priv was NULL, continuing",
543 __func__);
544 ret = SR_ERR_BUG;
545 continue;
546 }
547 /* TODO: Check for serial != NULL. */
ea9cfed7
UH
548 if (ctx->serial->fd != -1)
549 serial_close(ctx->serial->fd);
550 sr_serial_dev_inst_free(ctx->serial);
d3683c42 551 sr_dev_inst_free(sdi);
a1bb33af 552 }
d68e2d1a
UH
553 g_slist_free(dev_insts);
554 dev_insts = NULL;
57ab7d9f
UH
555
556 return ret;
a1bb33af
UH
557}
558
5097b0d0 559static void *hw_dev_info_get(int dev_index, int dev_info_id)
a1bb33af 560{
d68e2d1a 561 struct sr_dev_inst *sdi;
ea9cfed7 562 struct context *ctx;
a1bb33af
UH
563 void *info;
564
bb7ef793 565 if (!(sdi = sr_dev_inst_get(dev_insts, dev_index)))
a1bb33af 566 return NULL;
ea9cfed7 567 ctx = sdi->priv;
a1bb33af
UH
568
569 info = NULL;
bb7ef793 570 switch (dev_info_id) {
1d9a8a5f 571 case SR_DI_INST:
a1bb33af
UH
572 info = sdi;
573 break;
5a2326a7 574 case SR_DI_NUM_PROBES:
a1bb33af
UH
575 info = GINT_TO_POINTER(NUM_PROBES);
576 break;
464d12c7
KS
577 case SR_DI_PROBE_NAMES:
578 info = probe_names;
579 break;
5a2326a7 580 case SR_DI_SAMPLERATES:
a1bb33af
UH
581 info = &samplerates;
582 break;
5a2326a7 583 case SR_DI_TRIGGER_TYPES:
43fc7885 584 info = (char *)TRIGGER_TYPES;
a1bb33af 585 break;
5a2326a7 586 case SR_DI_CUR_SAMPLERATE:
ea9cfed7 587 info = &ctx->cur_samplerate;
a1bb33af
UH
588 break;
589 }
590
591 return info;
592}
593
e7eb703f 594static int hw_dev_status_get(int dev_index)
a1bb33af 595{
d68e2d1a 596 struct sr_dev_inst *sdi;
a1bb33af 597
bb7ef793 598 if (!(sdi = sr_dev_inst_get(dev_insts, dev_index)))
5a2326a7 599 return SR_ST_NOT_FOUND;
a1bb33af
UH
600
601 return sdi->status;
602}
603
ffedd0bf 604static int *hw_hwcap_get_all(void)
a1bb33af 605{
ffedd0bf 606 return hwcaps;
a1bb33af
UH
607}
608
a9a245b4 609static int set_samplerate(struct sr_dev_inst *sdi, uint64_t samplerate)
a1bb33af 610{
ea9cfed7 611 struct context *ctx;
a1bb33af 612
ea9cfed7
UH
613 ctx = sdi->priv;
614 if (ctx->max_samplerate) {
615 if (samplerate > ctx->max_samplerate)
4fe9a6da
BV
616 return SR_ERR_SAMPLERATE;
617 } else if (samplerate < samplerates.low || samplerate > samplerates.high)
e46b8fb1 618 return SR_ERR_SAMPLERATE;
a1bb33af 619
43fc7885 620 if (samplerate > CLOCK_RATE) {
ea9cfed7
UH
621 ctx->flag_reg |= FLAG_DEMUX;
622 ctx->cur_samplerate_divider = (CLOCK_RATE * 2 / samplerate) - 1;
43fc7885 623 } else {
ea9cfed7
UH
624 ctx->flag_reg &= ~FLAG_DEMUX;
625 ctx->cur_samplerate_divider = (CLOCK_RATE / samplerate) - 1;
a1bb33af 626 }
a1bb33af 627
7583b99d
GM
628 /* Calculate actual samplerate used and complain if it is different
629 * from the requested.
630 */
ea9cfed7
UH
631 ctx->cur_samplerate = CLOCK_RATE / (ctx->cur_samplerate_divider + 1);
632 if (ctx->flag_reg & FLAG_DEMUX)
633 ctx->cur_samplerate *= 2;
634 if (ctx->cur_samplerate != samplerate)
133a37bf 635 sr_err("ols: can't match samplerate %" PRIu64 ", using %"
ea9cfed7 636 PRIu64, samplerate, ctx->cur_samplerate);
7583b99d 637
e46b8fb1 638 return SR_OK;
a1bb33af
UH
639}
640
a9a245b4 641static int hw_dev_config_set(int dev_index, int hwcap, void *value)
a1bb33af 642{
d68e2d1a 643 struct sr_dev_inst *sdi;
ea9cfed7 644 struct context *ctx;
a1bb33af
UH
645 int ret;
646 uint64_t *tmp_u64;
647
bb7ef793 648 if (!(sdi = sr_dev_inst_get(dev_insts, dev_index)))
e46b8fb1 649 return SR_ERR;
ea9cfed7 650 ctx = sdi->priv;
a1bb33af 651
5a2326a7 652 if (sdi->status != SR_ST_ACTIVE)
e46b8fb1 653 return SR_ERR;
a1bb33af 654
ffedd0bf 655 switch (hwcap) {
5a2326a7 656 case SR_HWCAP_SAMPLERATE:
ee61b340 657 ret = set_samplerate(sdi, *(uint64_t *)value);
a803c0db 658 break;
5a2326a7 659 case SR_HWCAP_PROBECONFIG:
ea9cfed7 660 ret = configure_probes(ctx, (GSList *)value);
a803c0db 661 break;
5a2326a7 662 case SR_HWCAP_LIMIT_SAMPLES:
2458ea65 663 tmp_u64 = value;
574ce498 664 if (*tmp_u64 < MIN_NUM_SAMPLES)
e46b8fb1 665 return SR_ERR;
ea9cfed7 666 if (*tmp_u64 > ctx->max_samples)
133a37bf 667 sr_err("ols: sample limit exceeds hw max");
ea9cfed7
UH
668 ctx->limit_samples = *tmp_u64;
669 sr_info("ols: sample limit %" PRIu64, ctx->limit_samples);
e46b8fb1 670 ret = SR_OK;
a803c0db 671 break;
5a2326a7 672 case SR_HWCAP_CAPTURE_RATIO:
ea9cfed7
UH
673 ctx->capture_ratio = *(uint64_t *)value;
674 if (ctx->capture_ratio < 0 || ctx->capture_ratio > 100) {
675 ctx->capture_ratio = 0;
e46b8fb1 676 ret = SR_ERR;
43fc7885 677 } else
e46b8fb1 678 ret = SR_OK;
a803c0db 679 break;
3a4d09c0 680 case SR_HWCAP_RLE:
4d436e71 681 if (GPOINTER_TO_INT(value)) {
3a4d09c0 682 sr_info("ols: enabling RLE");
ea9cfed7 683 ctx->flag_reg |= FLAG_RLE;
3a4d09c0
GM
684 }
685 ret = SR_OK;
686 break;
a803c0db 687 default:
e46b8fb1 688 ret = SR_ERR;
43fc7885 689 }
a1bb33af
UH
690
691 return ret;
692}
693
9c939c51 694static int receive_data(int fd, int revents, void *session_data)
a1bb33af 695{
b9c735a2 696 struct sr_datafeed_packet packet;
9c939c51 697 struct sr_datafeed_logic logic;
d68e2d1a 698 struct sr_dev_inst *sdi;
ea9cfed7 699 struct context *ctx;
4fe9a6da 700 GSList *l;
3a4d09c0
GM
701 int num_channels, offset, i, j;
702 unsigned char byte;
a1bb33af 703
ea9cfed7
UH
704 /* Find this device's ctx struct by its fd. */
705 ctx = NULL;
d68e2d1a 706 for (l = dev_insts; l; l = l->next) {
4fe9a6da 707 sdi = l->data;
ea9cfed7
UH
708 if (ctx->serial->fd == fd) {
709 ctx = sdi->priv;
4fe9a6da
BV
710 break;
711 }
712 }
ea9cfed7
UH
713 if (!ctx)
714 /* Shouldn't happen. */
4fe9a6da
BV
715 return TRUE;
716
ea9cfed7 717 if (ctx->num_transfers++ == 0) {
43fc7885
UH
718 /*
719 * First time round, means the device started sending data,
720 * and will not stop until done. If it stops sending for
721 * longer than it takes to send a byte, that means it's
722 * finished. We'll double that to 30ms to be sure...
a1bb33af 723 */
6f1be0a2 724 sr_source_remove(fd);
9c939c51 725 sr_source_add(fd, G_IO_IN, 30, receive_data, session_data);
ea9cfed7
UH
726 ctx->raw_sample_buf = g_try_malloc(ctx->limit_samples * 4);
727 if (!ctx->raw_sample_buf) {
728 sr_err("ols: %s: ctx->raw_sample_buf malloc failed",
c0a4b971
UH
729 __func__);
730 return FALSE;
731 }
a803c0db 732 /* fill with 1010... for debugging */
ea9cfed7 733 memset(ctx->raw_sample_buf, 0x82, ctx->limit_samples * 4);
a1bb33af
UH
734 }
735
6937bb75 736 num_channels = 0;
43fc7885 737 for (i = 0x20; i > 0x02; i /= 2) {
ea9cfed7 738 if ((ctx->flag_reg & i) == 0)
6937bb75 739 num_channels++;
43fc7885 740 }
6937bb75 741
3a4d09c0 742 if (revents == G_IO_IN) {
2119ab03 743 if (serial_read(fd, &byte, 1) != 1)
a1bb33af
UH
744 return FALSE;
745
baf1d714 746 /* Ignore it if we've read enough. */
ea9cfed7 747 if (ctx->num_samples >= ctx->limit_samples)
baf1d714 748 return TRUE;
3a4d09c0 749
ea9cfed7 750 ctx->sample[ctx->num_bytes++] = byte;
b08024a8 751 sr_dbg("ols: received byte 0x%.2x", byte);
ea9cfed7 752 if (ctx->num_bytes == num_channels) {
43fc7885 753 /* Got a full sample. */
b08024a8 754 sr_dbg("ols: received sample 0x%.*x",
ea9cfed7
UH
755 ctx->num_bytes * 2, *(int *)ctx->sample);
756 if (ctx->flag_reg & FLAG_RLE) {
43fc7885
UH
757 /*
758 * In RLE mode -1 should never come in as a
759 * sample, because bit 31 is the "count" flag.
43fc7885 760 */
ea9cfed7
UH
761 if (ctx->sample[ctx->num_bytes - 1] & 0x80) {
762 ctx->sample[ctx->num_bytes - 1] &= 0x7f;
baf1d714
UH
763 /*
764 * FIXME: This will only work on
765 * little-endian systems.
a1bb33af 766 */
ea9cfed7
UH
767 ctx->rle_count = *(int *)(ctx->sample);
768 sr_dbg("ols: RLE count = %d", ctx->rle_count);
769 ctx->num_bytes = 0;
3a4d09c0 770 return TRUE;
baf1d714 771 }
3a4d09c0 772 }
ea9cfed7
UH
773 ctx->num_samples += ctx->rle_count + 1;
774 if (ctx->num_samples > ctx->limit_samples) {
baf1d714 775 /* Save us from overrunning the buffer. */
ea9cfed7
UH
776 ctx->rle_count -= ctx->num_samples - ctx->limit_samples;
777 ctx->num_samples = ctx->limit_samples;
a1bb33af
UH
778 }
779
43fc7885
UH
780 if (num_channels < 4) {
781 /*
782 * Some channel groups may have been turned
783 * off, to speed up transfer between the
784 * hardware and the PC. Expand that here before
785 * submitting it over the session bus --
786 * whatever is listening on the bus will be
787 * expecting a full 32-bit sample, based on
788 * the number of probes.
6937bb75
BV
789 */
790 j = 0;
ea9cfed7 791 memset(ctx->tmp_sample, 0, 4);
43fc7885 792 for (i = 0; i < 4; i++) {
ea9cfed7 793 if (((ctx->flag_reg >> 2) & (1 << i)) == 0) {
43fc7885
UH
794 /*
795 * This channel group was
796 * enabled, copy from received
797 * sample.
798 */
ea9cfed7 799 ctx->tmp_sample[i] = ctx->sample[j++];
6937bb75
BV
800 }
801 }
ea9cfed7
UH
802 memcpy(ctx->sample, ctx->tmp_sample, 4);
803 sr_dbg("ols: full sample 0x%.8x", *(int *)ctx->sample);
6937bb75
BV
804 }
805
a803c0db
BV
806 /* the OLS sends its sample buffer backwards.
807 * store it in reverse order here, so we can dump
808 * this on the session bus later.
809 */
ea9cfed7
UH
810 offset = (ctx->limit_samples - ctx->num_samples) * 4;
811 for (i = 0; i <= ctx->rle_count; i++) {
812 memcpy(ctx->raw_sample_buf + offset + (i * 4),
813 ctx->sample, 4);
baf1d714 814 }
ea9cfed7
UH
815 memset(ctx->sample, 0, 4);
816 ctx->num_bytes = 0;
817 ctx->rle_count = 0;
a1bb33af 818 }
43fc7885
UH
819 } else {
820 /*
821 * This is the main loop telling us a timeout was reached, or
822 * we've acquired all the samples we asked for -- we're done.
a803c0db 823 * Send the (properly-ordered) buffer to the frontend.
43fc7885 824 */
ea9cfed7 825 if (ctx->trigger_at != -1) {
a803c0db
BV
826 /* a trigger was set up, so we need to tell the frontend
827 * about it.
828 */
ea9cfed7 829 if (ctx->trigger_at > 0) {
a803c0db 830 /* there are pre-trigger samples, send those first */
5a2326a7 831 packet.type = SR_DF_LOGIC;
9c939c51 832 packet.payload = &logic;
ea9cfed7 833 logic.length = ctx->trigger_at * 4;
9c939c51 834 logic.unitsize = 4;
ea9cfed7
UH
835 logic.data = ctx->raw_sample_buf +
836 (ctx->limit_samples - ctx->num_samples) * 4;
9c939c51 837 sr_session_bus(session_data, &packet);
a803c0db
BV
838 }
839
9c939c51 840 /* send the trigger */
5a2326a7 841 packet.type = SR_DF_TRIGGER;
9c939c51 842 sr_session_bus(session_data, &packet);
a803c0db 843
9c939c51 844 /* send post-trigger samples */
5a2326a7 845 packet.type = SR_DF_LOGIC;
9c939c51 846 packet.payload = &logic;
ea9cfed7 847 logic.length = (ctx->num_samples * 4) - (ctx->trigger_at * 4);
9c939c51 848 logic.unitsize = 4;
ea9cfed7
UH
849 logic.data = ctx->raw_sample_buf + ctx->trigger_at * 4 +
850 (ctx->limit_samples - ctx->num_samples) * 4;
9c939c51 851 sr_session_bus(session_data, &packet);
a803c0db 852 } else {
9c939c51 853 /* no trigger was used */
5a2326a7 854 packet.type = SR_DF_LOGIC;
9c939c51 855 packet.payload = &logic;
ea9cfed7 856 logic.length = ctx->num_samples * 4;
9c939c51 857 logic.unitsize = 4;
ea9cfed7
UH
858 logic.data = ctx->raw_sample_buf +
859 (ctx->limit_samples - ctx->num_samples) * 4;
9c939c51 860 sr_session_bus(session_data, &packet);
a803c0db 861 }
ea9cfed7 862 g_free(ctx->raw_sample_buf);
a803c0db 863
06d64eb8 864 serial_flush(fd);
d02a535e 865 serial_close(fd);
5a2326a7 866 packet.type = SR_DF_END;
9c939c51 867 sr_session_bus(session_data, &packet);
a1bb33af
UH
868 }
869
870 return TRUE;
871}
872
69040b7c 873static int hw_dev_acquisition_start(int dev_index, gpointer session_data)
a1bb33af 874{
b9c735a2
UH
875 struct sr_datafeed_packet *packet;
876 struct sr_datafeed_header *header;
d68e2d1a 877 struct sr_dev_inst *sdi;
ea9cfed7 878 struct context *ctx;
a803c0db 879 uint32_t trigger_config[4];
a1bb33af 880 uint32_t data;
6937bb75
BV
881 uint16_t readcount, delaycount;
882 uint8_t changrp_mask;
22130421 883 int num_channels;
4fe9a6da 884 int i;
a1bb33af 885
bb7ef793 886 if (!(sdi = sr_dev_inst_get(dev_insts, dev_index)))
e46b8fb1 887 return SR_ERR;
c0a4b971 888
ea9cfed7 889 ctx = sdi->priv;
a1bb33af 890
5a2326a7 891 if (sdi->status != SR_ST_ACTIVE)
e46b8fb1 892 return SR_ERR;
a1bb33af 893
22130421
GM
894 /*
895 * Enable/disable channel groups in the flag register according to the
baf1d714 896 * probe mask. Calculate this here, because num_channels is needed
22130421
GM
897 * to limit readcount.
898 */
899 changrp_mask = 0;
900 num_channels = 0;
901 for (i = 0; i < 4; i++) {
ea9cfed7 902 if (ctx->probe_mask & (0xff << (i * 8))) {
22130421
GM
903 changrp_mask |= (1 << i);
904 num_channels++;
905 }
906 }
907
baf1d714
UH
908 /*
909 * Limit readcount to prevent reading past the end of the hardware
22130421
GM
910 * buffer.
911 */
ea9cfed7 912 readcount = MIN(ctx->max_samples / num_channels, ctx->limit_samples) / 4;
a803c0db
BV
913
914 memset(trigger_config, 0, 16);
ea9cfed7
UH
915 trigger_config[ctx->num_stages - 1] |= 0x08;
916 if (ctx->trigger_mask[0]) {
917 delaycount = readcount * (1 - ctx->capture_ratio / 100.0);
918 ctx->trigger_at = (readcount - delaycount) * 4 - ctx->num_stages;
a803c0db 919
ea9cfed7
UH
920 if (send_longcommand(ctx->serial->fd, CMD_SET_TRIGGER_MASK_0,
921 reverse32(ctx->trigger_mask[0])) != SR_OK)
e46b8fb1 922 return SR_ERR;
ea9cfed7
UH
923 if (send_longcommand(ctx->serial->fd, CMD_SET_TRIGGER_VALUE_0,
924 reverse32(ctx->trigger_value[0])) != SR_OK)
e46b8fb1 925 return SR_ERR;
ea9cfed7 926 if (send_longcommand(ctx->serial->fd, CMD_SET_TRIGGER_CONFIG_0,
e46b8fb1
UH
927 trigger_config[0]) != SR_OK)
928 return SR_ERR;
6937bb75 929
ea9cfed7
UH
930 if (send_longcommand(ctx->serial->fd, CMD_SET_TRIGGER_MASK_1,
931 reverse32(ctx->trigger_mask[1])) != SR_OK)
e46b8fb1 932 return SR_ERR;
ea9cfed7
UH
933 if (send_longcommand(ctx->serial->fd, CMD_SET_TRIGGER_VALUE_1,
934 reverse32(ctx->trigger_value[1])) != SR_OK)
e46b8fb1 935 return SR_ERR;
ea9cfed7 936 if (send_longcommand(ctx->serial->fd, CMD_SET_TRIGGER_CONFIG_1,
e46b8fb1
UH
937 trigger_config[1]) != SR_OK)
938 return SR_ERR;
6937bb75 939
ea9cfed7
UH
940 if (send_longcommand(ctx->serial->fd, CMD_SET_TRIGGER_MASK_2,
941 reverse32(ctx->trigger_mask[2])) != SR_OK)
e46b8fb1 942 return SR_ERR;
ea9cfed7
UH
943 if (send_longcommand(ctx->serial->fd, CMD_SET_TRIGGER_VALUE_2,
944 reverse32(ctx->trigger_value[2])) != SR_OK)
e46b8fb1 945 return SR_ERR;
ea9cfed7 946 if (send_longcommand(ctx->serial->fd, CMD_SET_TRIGGER_CONFIG_2,
e46b8fb1
UH
947 trigger_config[2]) != SR_OK)
948 return SR_ERR;
a803c0db 949
ea9cfed7
UH
950 if (send_longcommand(ctx->serial->fd, CMD_SET_TRIGGER_MASK_3,
951 reverse32(ctx->trigger_mask[3])) != SR_OK)
e46b8fb1 952 return SR_ERR;
ea9cfed7
UH
953 if (send_longcommand(ctx->serial->fd, CMD_SET_TRIGGER_VALUE_3,
954 reverse32(ctx->trigger_value[3])) != SR_OK)
e46b8fb1 955 return SR_ERR;
ea9cfed7 956 if (send_longcommand(ctx->serial->fd, CMD_SET_TRIGGER_CONFIG_3,
e46b8fb1
UH
957 trigger_config[3]) != SR_OK)
958 return SR_ERR;
6937bb75 959 } else {
ea9cfed7
UH
960 if (send_longcommand(ctx->serial->fd, CMD_SET_TRIGGER_MASK_0,
961 ctx->trigger_mask[0]) != SR_OK)
e46b8fb1 962 return SR_ERR;
ea9cfed7
UH
963 if (send_longcommand(ctx->serial->fd, CMD_SET_TRIGGER_VALUE_0,
964 ctx->trigger_value[0]) != SR_OK)
e46b8fb1 965 return SR_ERR;
ea9cfed7 966 if (send_longcommand(ctx->serial->fd, CMD_SET_TRIGGER_CONFIG_0,
e46b8fb1
UH
967 0x00000008) != SR_OK)
968 return SR_ERR;
a803c0db 969 delaycount = readcount;
6937bb75 970 }
a1bb33af 971
b08024a8 972 sr_info("ols: setting samplerate to %" PRIu64 " Hz (divider %u, "
ea9cfed7
UH
973 "demux %s)", ctx->cur_samplerate, ctx->cur_samplerate_divider,
974 ctx->flag_reg & FLAG_DEMUX ? "on" : "off");
975 if (send_longcommand(ctx->serial->fd, CMD_SET_DIVIDER,
976 reverse32(ctx->cur_samplerate_divider)) != SR_OK)
4fe9a6da 977 return SR_ERR;
a1bb33af 978
43fc7885 979 /* Send sample limit and pre/post-trigger capture ratio. */
a803c0db
BV
980 data = ((readcount - 1) & 0xffff) << 16;
981 data |= (delaycount - 1) & 0xffff;
ea9cfed7 982 if (send_longcommand(ctx->serial->fd, CMD_CAPTURE_SIZE, reverse16(data)) != SR_OK)
e46b8fb1 983 return SR_ERR;
a1bb33af 984
43fc7885 985 /* The flag register wants them here, and 1 means "disable channel". */
ea9cfed7
UH
986 ctx->flag_reg |= ~(changrp_mask << 2) & 0x3c;
987 ctx->flag_reg |= FLAG_FILTER;
988 ctx->rle_count = 0;
989 data = (ctx->flag_reg << 24) | ((ctx->flag_reg << 8) & 0xff0000);
990 if (send_longcommand(ctx->serial->fd, CMD_SET_FLAGS, data) != SR_OK)
e46b8fb1 991 return SR_ERR;
a1bb33af 992
43fc7885 993 /* Start acquisition on the device. */
ea9cfed7 994 if (send_shortcommand(ctx->serial->fd, CMD_RUN) != SR_OK)
e46b8fb1 995 return SR_ERR;
a1bb33af 996
ea9cfed7 997 sr_source_add(ctx->serial->fd, G_IO_IN, -1, receive_data,
9c939c51 998 session_data);
a1bb33af 999
b53738ba
UH
1000 if (!(packet = g_try_malloc(sizeof(struct sr_datafeed_packet)))) {
1001 sr_err("ols: %s: packet malloc failed", __func__);
1002 return SR_ERR_MALLOC;
1003 }
1004
1005 if (!(header = g_try_malloc(sizeof(struct sr_datafeed_header)))) {
1006 sr_err("ols: %s: header malloc failed", __func__);
c0a4b971 1007 g_free(packet);
b53738ba
UH
1008 return SR_ERR_MALLOC;
1009 }
1010
43fc7885 1011 /* Send header packet to the session bus. */
5a2326a7 1012 packet->type = SR_DF_HEADER;
43fc7885 1013 packet->payload = (unsigned char *)header;
a1bb33af
UH
1014 header->feed_version = 1;
1015 gettimeofday(&header->starttime, NULL);
ea9cfed7 1016 header->samplerate = ctx->cur_samplerate;
c2616fb9 1017 header->num_logic_probes = NUM_PROBES;
9c939c51 1018 sr_session_bus(session_data, packet);
c0a4b971 1019
a1bb33af
UH
1020 g_free(header);
1021 g_free(packet);
1022
e46b8fb1 1023 return SR_OK;
a1bb33af
UH
1024}
1025
69040b7c 1026static int hw_dev_acquisition_stop(int dev_index, gpointer session_dev_id)
a1bb33af 1027{
b9c735a2 1028 struct sr_datafeed_packet packet;
a1bb33af 1029
17e1afcb 1030 /* Avoid compiler warnings. */
bb7ef793 1031 (void)dev_index;
afc8e4de 1032
5a2326a7 1033 packet.type = SR_DF_END;
bb7ef793 1034 sr_session_bus(session_dev_id, &packet);
3010f21c
UH
1035
1036 return SR_OK;
a1bb33af
UH
1037}
1038
bb7ef793 1039SR_PRIV struct sr_dev_plugin ols_plugin_info = {
e519ba86
UH
1040 .name = "ols",
1041 .longname = "Openbench Logic Sniffer",
1042 .api_version = 1,
1043 .init = hw_init,
1044 .cleanup = hw_cleanup,
e7eb703f
UH
1045 .dev_open = hw_dev_open,
1046 .dev_close = hw_dev_close,
5097b0d0 1047 .dev_info_get = hw_dev_info_get,
e7eb703f 1048 .dev_status_get = hw_dev_status_get,
ffedd0bf 1049 .hwcap_get_all = hw_hwcap_get_all,
a9a245b4 1050 .dev_config_set = hw_dev_config_set,
69040b7c
UH
1051 .dev_acquisition_start = hw_dev_acquisition_start,
1052 .dev_acquisition_stop = hw_dev_acquisition_stop,
a1bb33af 1053};