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