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