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