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