]> sigrok.org Git - libsigrok.git/blame - hardware/openbench-logic-sniffer/ols.c
sr: adjust copyright year
[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
a1bb33af 49static int capabilities[] = {
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
6c290072 102/* List of struct sr_serial_device_instance */
a1bb33af
UH
103static GSList *device_instances = NULL;
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
4fe9a6da 133static int configure_probes(struct ols_device *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
4fe9a6da
BV
207static struct ols_device *ols_device_new(void)
208{
209 struct ols_device *ols;
210
c0a4b971 211 /* TODO: Is 'ols' ever g_free()'d? */
b53738ba
UH
212 if (!(ols = g_try_malloc0(sizeof(struct ols_device)))) {
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
225static struct sr_device_instance *get_metadata(int fd)
226{
227 struct sr_device_instance *sdi;
228 struct ols_device *ols;
229 uint32_t tmp_int;
230 uint8_t key, type, token;
231 GString *tmp_str, *devicename, *version;
232 gchar tmp_c;
233
234 sdi = sr_device_instance_new(0, SR_ST_INACTIVE, NULL, NULL, NULL);
235 ols = ols_device_new();
236 sdi->priv = ols;
237
238 devicename = g_string_new("");
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 */
258 devicename = g_string_append(devicename, tmp_str->str);
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
342 sdi->model = devicename->str;
343 sdi->version = version->str;
344 g_string_free(devicename, FALSE);
345 g_string_free(version, FALSE);
346
347 return sdi;
348}
349
54ac5277 350static int hw_init(const char *deviceinfo)
a1bb33af 351{
a00ba012 352 struct sr_device_instance *sdi;
4fe9a6da 353 struct ols_device *ols;
a1bb33af 354 GSList *ports, *l;
4fe9a6da 355 GPollFD *fds, probefd;
6937bb75 356 int devcnt, final_devcnt, num_ports, fd, ret, i;
d02a535e 357 char buf[8], **device_names, **serial_params;
a1bb33af 358
c0a4b971
UH
359 final_devcnt = 0;
360
43fc7885 361 if (deviceinfo)
133a37bf 362 ports = g_slist_append(NULL, g_strdup(deviceinfo));
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
374 if (!(device_names = g_try_malloc(num_ports * sizeof(char *)))) {
375 sr_err("ols: %s: device_names malloc failed", __func__);
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__);
381 goto hw_init_free_device_names; /* TODO: SR_ERR_MALLOC. */
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;
133a37bf 418 device_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 */
449 sdi = sr_device_instance_new(final_devcnt, SR_ST_INACTIVE,
450 "Sump", "Logic Analyzer", "v1.0");
451 ols = ols_device_new();
452 ols->num_probes = 32;
453 sdi->priv = ols;
a1bb33af 454 }
69890f73 455 ols->serial = sr_serial_device_instance_new(device_names[i], -1);
4fe9a6da
BV
456 device_instances = g_slist_append(device_instances, sdi);
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
UH
468 g_free(serial_params[i]);
469 g_free(device_names[i]);
a1bb33af
UH
470 }
471
c0a4b971
UH
472 g_free(serial_params);
473hw_init_free_device_names:
474 g_free(device_names);
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
a1bb33af
UH
483static int hw_opendev(int device_index)
484{
a00ba012 485 struct sr_device_instance *sdi;
69890f73 486 struct ols_device *ols;
a1bb33af 487
d32d961d 488 if (!(sdi = sr_get_device_instance(device_instances, device_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
697785d1 502static int hw_closedev(int device_index)
a1bb33af 503{
a00ba012 504 struct sr_device_instance *sdi;
69890f73 505 struct ols_device *ols;
a1bb33af 506
697785d1
UH
507 if (!(sdi = sr_get_device_instance(device_instances, device_index))) {
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
a1bb33af
UH
524static void hw_cleanup(void)
525{
526 GSList *l;
a00ba012 527 struct sr_device_instance *sdi;
69890f73 528 struct ols_device *ols;
a1bb33af 529
8722c31e 530 /* Properly close and free all devices. */
43fc7885 531 for (l = device_instances; l; l = l->next) {
a1bb33af 532 sdi = l->data;
69890f73
UH
533 ols = sdi->priv;
534 if (ols->serial->fd != -1)
535 serial_close(ols->serial->fd);
536 sr_serial_device_instance_free(ols->serial);
a00ba012 537 sr_device_instance_free(sdi);
a1bb33af
UH
538 }
539 g_slist_free(device_instances);
540 device_instances = NULL;
a1bb33af
UH
541}
542
a1bb33af
UH
543static void *hw_get_device_info(int device_index, int device_info_id)
544{
a00ba012 545 struct sr_device_instance *sdi;
4fe9a6da 546 struct ols_device *ols;
a1bb33af
UH
547 void *info;
548
d32d961d 549 if (!(sdi = sr_get_device_instance(device_instances, device_index)))
a1bb33af 550 return NULL;
4fe9a6da 551 ols = sdi->priv;
a1bb33af
UH
552
553 info = NULL;
43fc7885 554 switch (device_info_id) {
5a2326a7 555 case SR_DI_INSTANCE:
a1bb33af
UH
556 info = sdi;
557 break;
5a2326a7 558 case SR_DI_NUM_PROBES:
a1bb33af
UH
559 info = GINT_TO_POINTER(NUM_PROBES);
560 break;
464d12c7
KS
561 case SR_DI_PROBE_NAMES:
562 info = probe_names;
563 break;
5a2326a7 564 case SR_DI_SAMPLERATES:
a1bb33af
UH
565 info = &samplerates;
566 break;
5a2326a7 567 case SR_DI_TRIGGER_TYPES:
43fc7885 568 info = (char *)TRIGGER_TYPES;
a1bb33af 569 break;
5a2326a7 570 case SR_DI_CUR_SAMPLERATE:
4fe9a6da 571 info = &ols->cur_samplerate;
a1bb33af
UH
572 break;
573 }
574
575 return info;
576}
577
a1bb33af
UH
578static int hw_get_status(int device_index)
579{
a00ba012 580 struct sr_device_instance *sdi;
a1bb33af 581
d32d961d 582 if (!(sdi = sr_get_device_instance(device_instances, device_index)))
5a2326a7 583 return SR_ST_NOT_FOUND;
a1bb33af
UH
584
585 return sdi->status;
586}
587
a1bb33af
UH
588static int *hw_get_capabilities(void)
589{
a1bb33af
UH
590 return capabilities;
591}
592
a00ba012 593static int set_configuration_samplerate(struct sr_device_instance *sdi,
43fc7885 594 uint64_t samplerate)
a1bb33af 595{
4fe9a6da 596 struct ols_device *ols;
a1bb33af 597
4fe9a6da
BV
598 ols = sdi->priv;
599 if (ols->max_samplerate) {
600 if (samplerate > ols->max_samplerate)
601 return SR_ERR_SAMPLERATE;
602 } else if (samplerate < samplerates.low || samplerate > samplerates.high)
e46b8fb1 603 return SR_ERR_SAMPLERATE;
a1bb33af 604
43fc7885 605 if (samplerate > CLOCK_RATE) {
4fe9a6da
BV
606 ols->flag_reg |= FLAG_DEMUX;
607 ols->cur_samplerate_divider = (CLOCK_RATE * 2 / samplerate) - 1;
43fc7885 608 } else {
4fe9a6da
BV
609 ols->flag_reg &= ~FLAG_DEMUX;
610 ols->cur_samplerate_divider = (CLOCK_RATE / samplerate) - 1;
a1bb33af 611 }
a1bb33af 612
7583b99d
GM
613 /* Calculate actual samplerate used and complain if it is different
614 * from the requested.
615 */
616 ols->cur_samplerate = CLOCK_RATE / (ols->cur_samplerate_divider + 1);
133a37bf 617 if (ols->flag_reg & FLAG_DEMUX)
7583b99d 618 ols->cur_samplerate *= 2;
133a37bf
UH
619 if (ols->cur_samplerate != samplerate)
620 sr_err("ols: can't match samplerate %" PRIu64 ", using %"
621 PRIu64, samplerate, ols->cur_samplerate);
7583b99d 622
e46b8fb1 623 return SR_OK;
a1bb33af
UH
624}
625
a1bb33af
UH
626static int hw_set_configuration(int device_index, int capability, void *value)
627{
a00ba012 628 struct sr_device_instance *sdi;
4fe9a6da 629 struct ols_device *ols;
a1bb33af
UH
630 int ret;
631 uint64_t *tmp_u64;
632
d32d961d 633 if (!(sdi = sr_get_device_instance(device_instances, device_index)))
e46b8fb1 634 return SR_ERR;
4fe9a6da 635 ols = sdi->priv;
a1bb33af 636
5a2326a7 637 if (sdi->status != SR_ST_ACTIVE)
e46b8fb1 638 return SR_ERR;
a1bb33af 639
a803c0db 640 switch (capability) {
5a2326a7 641 case SR_HWCAP_SAMPLERATE:
a1bb33af
UH
642 tmp_u64 = value;
643 ret = set_configuration_samplerate(sdi, *tmp_u64);
a803c0db 644 break;
5a2326a7 645 case SR_HWCAP_PROBECONFIG:
4fe9a6da 646 ret = configure_probes(ols, (GSList *) value);
a803c0db 647 break;
5a2326a7 648 case SR_HWCAP_LIMIT_SAMPLES:
2458ea65 649 tmp_u64 = value;
574ce498 650 if (*tmp_u64 < MIN_NUM_SAMPLES)
e46b8fb1 651 return SR_ERR;
baf1d714 652 if (*tmp_u64 > ols->max_samples)
133a37bf 653 sr_err("ols: sample limit exceeds hw max");
4fe9a6da 654 ols->limit_samples = *tmp_u64;
b08024a8 655 sr_info("ols: sample limit %" PRIu64, ols->limit_samples);
e46b8fb1 656 ret = SR_OK;
a803c0db 657 break;
5a2326a7 658 case SR_HWCAP_CAPTURE_RATIO:
a803c0db 659 tmp_u64 = value;
4fe9a6da
BV
660 ols->capture_ratio = *tmp_u64;
661 if (ols->capture_ratio < 0 || ols->capture_ratio > 100) {
662 ols->capture_ratio = 0;
e46b8fb1 663 ret = SR_ERR;
43fc7885 664 } else
e46b8fb1 665 ret = SR_OK;
a803c0db 666 break;
3a4d09c0 667 case SR_HWCAP_RLE:
4d436e71 668 if (GPOINTER_TO_INT(value)) {
3a4d09c0
GM
669 sr_info("ols: enabling RLE");
670 ols->flag_reg |= FLAG_RLE;
671 }
672 ret = SR_OK;
673 break;
a803c0db 674 default:
e46b8fb1 675 ret = SR_ERR;
43fc7885 676 }
a1bb33af
UH
677
678 return ret;
679}
680
9c939c51 681static int receive_data(int fd, int revents, void *session_data)
a1bb33af 682{
b9c735a2 683 struct sr_datafeed_packet packet;
9c939c51 684 struct sr_datafeed_logic logic;
4fe9a6da
BV
685 struct sr_device_instance *sdi;
686 struct ols_device *ols;
687 GSList *l;
3a4d09c0
GM
688 int num_channels, offset, i, j;
689 unsigned char byte;
a1bb33af 690
4fe9a6da
BV
691 /* find this device's ols_device struct by its fd */
692 ols = NULL;
693 for (l = device_instances; l; l = l->next) {
694 sdi = l->data;
69890f73 695 if (ols->serial->fd == fd) {
4fe9a6da
BV
696 ols = sdi->priv;
697 break;
698 }
699 }
700 if (!ols)
701 /* shouldn't happen */
702 return TRUE;
703
704 if (ols->num_transfers++ == 0) {
43fc7885
UH
705 /*
706 * First time round, means the device started sending data,
707 * and will not stop until done. If it stops sending for
708 * longer than it takes to send a byte, that means it's
709 * finished. We'll double that to 30ms to be sure...
a1bb33af 710 */
6f1be0a2 711 sr_source_remove(fd);
9c939c51 712 sr_source_add(fd, G_IO_IN, 30, receive_data, session_data);
c0a4b971
UH
713 ols->raw_sample_buf = g_try_malloc(ols->limit_samples * 4);
714 if (!ols->raw_sample_buf) {
715 sr_err("ols: %s: ols->raw_sample_buf malloc failed",
716 __func__);
717 return FALSE;
718 }
a803c0db 719 /* fill with 1010... for debugging */
4fe9a6da 720 memset(ols->raw_sample_buf, 0x82, ols->limit_samples * 4);
a1bb33af
UH
721 }
722
6937bb75 723 num_channels = 0;
43fc7885 724 for (i = 0x20; i > 0x02; i /= 2) {
4fe9a6da 725 if ((ols->flag_reg & i) == 0)
6937bb75 726 num_channels++;
43fc7885 727 }
6937bb75 728
3a4d09c0 729 if (revents == G_IO_IN) {
2119ab03 730 if (serial_read(fd, &byte, 1) != 1)
a1bb33af
UH
731 return FALSE;
732
baf1d714
UH
733 /* Ignore it if we've read enough. */
734 if (ols->num_samples >= ols->limit_samples)
735 return TRUE;
3a4d09c0 736
4fe9a6da 737 ols->sample[ols->num_bytes++] = byte;
b08024a8 738 sr_dbg("ols: received byte 0x%.2x", byte);
4fe9a6da 739 if (ols->num_bytes == num_channels) {
43fc7885 740 /* Got a full sample. */
b08024a8 741 sr_dbg("ols: received sample 0x%.*x",
baf1d714 742 ols->num_bytes * 2, *(int *)ols->sample);
4fe9a6da 743 if (ols->flag_reg & FLAG_RLE) {
43fc7885
UH
744 /*
745 * In RLE mode -1 should never come in as a
746 * sample, because bit 31 is the "count" flag.
43fc7885 747 */
3a4d09c0 748 if (ols->sample[ols->num_bytes - 1] & 0x80) {
baf1d714
UH
749 ols->sample[ols->num_bytes - 1] &= 0x7f;
750 /*
751 * FIXME: This will only work on
752 * little-endian systems.
a1bb33af 753 */
baf1d714 754 ols->rle_count = *(int *)(ols->sample);
3a4d09c0
GM
755 sr_dbg("ols: RLE count = %d", ols->rle_count);
756 ols->num_bytes = 0;
757 return TRUE;
baf1d714 758 }
3a4d09c0
GM
759 }
760 ols->num_samples += ols->rle_count + 1;
baf1d714
UH
761 if (ols->num_samples > ols->limit_samples) {
762 /* Save us from overrunning the buffer. */
3a4d09c0
GM
763 ols->rle_count -= ols->num_samples - ols->limit_samples;
764 ols->num_samples = ols->limit_samples;
a1bb33af
UH
765 }
766
43fc7885
UH
767 if (num_channels < 4) {
768 /*
769 * Some channel groups may have been turned
770 * off, to speed up transfer between the
771 * hardware and the PC. Expand that here before
772 * submitting it over the session bus --
773 * whatever is listening on the bus will be
774 * expecting a full 32-bit sample, based on
775 * the number of probes.
6937bb75
BV
776 */
777 j = 0;
4fe9a6da 778 memset(ols->tmp_sample, 0, 4);
43fc7885 779 for (i = 0; i < 4; i++) {
4fe9a6da 780 if (((ols->flag_reg >> 2) & (1 << i)) == 0) {
43fc7885
UH
781 /*
782 * This channel group was
783 * enabled, copy from received
784 * sample.
785 */
4fe9a6da 786 ols->tmp_sample[i] = ols->sample[j++];
6937bb75
BV
787 }
788 }
4fe9a6da 789 memcpy(ols->sample, ols->tmp_sample, 4);
baf1d714 790 sr_dbg("ols: full sample 0x%.8x", *(int *)ols->sample);
6937bb75
BV
791 }
792
a803c0db
BV
793 /* the OLS sends its sample buffer backwards.
794 * store it in reverse order here, so we can dump
795 * this on the session bus later.
796 */
3a4d09c0 797 offset = (ols->limit_samples - ols->num_samples) * 4;
baf1d714
UH
798 for (i = 0; i <= ols->rle_count; i++) {
799 memcpy(ols->raw_sample_buf + offset + (i * 4),
800 ols->sample, 4);
801 }
4fe9a6da
BV
802 memset(ols->sample, 0, 4);
803 ols->num_bytes = 0;
3a4d09c0 804 ols->rle_count = 0;
a1bb33af 805 }
43fc7885
UH
806 } else {
807 /*
808 * This is the main loop telling us a timeout was reached, or
809 * we've acquired all the samples we asked for -- we're done.
a803c0db 810 * Send the (properly-ordered) buffer to the frontend.
43fc7885 811 */
4fe9a6da 812 if (ols->trigger_at != -1) {
a803c0db
BV
813 /* a trigger was set up, so we need to tell the frontend
814 * about it.
815 */
4fe9a6da 816 if (ols->trigger_at > 0) {
a803c0db 817 /* there are pre-trigger samples, send those first */
5a2326a7 818 packet.type = SR_DF_LOGIC;
9c939c51
BV
819 packet.payload = &logic;
820 logic.length = ols->trigger_at * 4;
821 logic.unitsize = 4;
baf1d714 822 logic.data = ols->raw_sample_buf +
22130421 823 (ols->limit_samples - ols->num_samples) * 4;
9c939c51 824 sr_session_bus(session_data, &packet);
a803c0db
BV
825 }
826
9c939c51 827 /* send the trigger */
5a2326a7 828 packet.type = SR_DF_TRIGGER;
9c939c51 829 sr_session_bus(session_data, &packet);
a803c0db 830
9c939c51 831 /* send post-trigger samples */
5a2326a7 832 packet.type = SR_DF_LOGIC;
9c939c51 833 packet.payload = &logic;
22130421 834 logic.length = (ols->num_samples * 4) - (ols->trigger_at * 4);
9c939c51 835 logic.unitsize = 4;
22130421
GM
836 logic.data = ols->raw_sample_buf + ols->trigger_at * 4 +
837 (ols->limit_samples - ols->num_samples) * 4;
9c939c51 838 sr_session_bus(session_data, &packet);
a803c0db 839 } else {
9c939c51 840 /* no trigger was used */
5a2326a7 841 packet.type = SR_DF_LOGIC;
9c939c51 842 packet.payload = &logic;
22130421 843 logic.length = ols->num_samples * 4;
9c939c51 844 logic.unitsize = 4;
22130421
GM
845 logic.data = ols->raw_sample_buf +
846 (ols->limit_samples - ols->num_samples) * 4;
9c939c51 847 sr_session_bus(session_data, &packet);
a803c0db 848 }
c0a4b971 849 g_free(ols->raw_sample_buf);
a803c0db 850
06d64eb8 851 serial_flush(fd);
d02a535e 852 serial_close(fd);
5a2326a7 853 packet.type = SR_DF_END;
9c939c51 854 sr_session_bus(session_data, &packet);
a1bb33af
UH
855 }
856
857 return TRUE;
858}
859
9c939c51 860static int hw_start_acquisition(int device_index, gpointer session_data)
a1bb33af 861{
b9c735a2
UH
862 struct sr_datafeed_packet *packet;
863 struct sr_datafeed_header *header;
a00ba012 864 struct sr_device_instance *sdi;
4fe9a6da 865 struct ols_device *ols;
a803c0db 866 uint32_t trigger_config[4];
a1bb33af 867 uint32_t data;
6937bb75
BV
868 uint16_t readcount, delaycount;
869 uint8_t changrp_mask;
22130421 870 int num_channels;
4fe9a6da 871 int i;
a1bb33af 872
d32d961d 873 if (!(sdi = sr_get_device_instance(device_instances, device_index)))
e46b8fb1 874 return SR_ERR;
c0a4b971 875
4fe9a6da 876 ols = sdi->priv;
a1bb33af 877
5a2326a7 878 if (sdi->status != SR_ST_ACTIVE)
e46b8fb1 879 return SR_ERR;
a1bb33af 880
22130421
GM
881 /*
882 * Enable/disable channel groups in the flag register according to the
baf1d714 883 * probe mask. Calculate this here, because num_channels is needed
22130421
GM
884 * to limit readcount.
885 */
886 changrp_mask = 0;
887 num_channels = 0;
888 for (i = 0; i < 4; i++) {
889 if (ols->probe_mask & (0xff << (i * 8))) {
890 changrp_mask |= (1 << i);
891 num_channels++;
892 }
893 }
894
baf1d714
UH
895 /*
896 * Limit readcount to prevent reading past the end of the hardware
22130421
GM
897 * buffer.
898 */
899 readcount = MIN(ols->max_samples / num_channels, ols->limit_samples) / 4;
a803c0db
BV
900
901 memset(trigger_config, 0, 16);
4fe9a6da
BV
902 trigger_config[ols->num_stages - 1] |= 0x08;
903 if (ols->trigger_mask[0]) {
904 delaycount = readcount * (1 - ols->capture_ratio / 100.0);
905 ols->trigger_at = (readcount - delaycount) * 4 - ols->num_stages;
a803c0db 906
69890f73 907 if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_MASK_0,
4fe9a6da 908 reverse32(ols->trigger_mask[0])) != SR_OK)
e46b8fb1 909 return SR_ERR;
69890f73 910 if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_VALUE_0,
4fe9a6da 911 reverse32(ols->trigger_value[0])) != SR_OK)
e46b8fb1 912 return SR_ERR;
69890f73 913 if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_CONFIG_0,
e46b8fb1
UH
914 trigger_config[0]) != SR_OK)
915 return SR_ERR;
6937bb75 916
69890f73 917 if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_MASK_1,
4fe9a6da 918 reverse32(ols->trigger_mask[1])) != SR_OK)
e46b8fb1 919 return SR_ERR;
69890f73 920 if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_VALUE_1,
4fe9a6da 921 reverse32(ols->trigger_value[1])) != SR_OK)
e46b8fb1 922 return SR_ERR;
69890f73 923 if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_CONFIG_1,
e46b8fb1
UH
924 trigger_config[1]) != SR_OK)
925 return SR_ERR;
6937bb75 926
69890f73 927 if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_MASK_2,
4fe9a6da 928 reverse32(ols->trigger_mask[2])) != SR_OK)
e46b8fb1 929 return SR_ERR;
69890f73 930 if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_VALUE_2,
4fe9a6da 931 reverse32(ols->trigger_value[2])) != SR_OK)
e46b8fb1 932 return SR_ERR;
69890f73 933 if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_CONFIG_2,
e46b8fb1
UH
934 trigger_config[2]) != SR_OK)
935 return SR_ERR;
a803c0db 936
69890f73 937 if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_MASK_3,
4fe9a6da 938 reverse32(ols->trigger_mask[3])) != SR_OK)
e46b8fb1 939 return SR_ERR;
69890f73 940 if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_VALUE_3,
4fe9a6da 941 reverse32(ols->trigger_value[3])) != SR_OK)
e46b8fb1 942 return SR_ERR;
69890f73 943 if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_CONFIG_3,
e46b8fb1
UH
944 trigger_config[3]) != SR_OK)
945 return SR_ERR;
6937bb75 946 } else {
69890f73 947 if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_MASK_0,
4fe9a6da 948 ols->trigger_mask[0]) != SR_OK)
e46b8fb1 949 return SR_ERR;
69890f73 950 if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_VALUE_0,
4fe9a6da 951 ols->trigger_value[0]) != SR_OK)
e46b8fb1 952 return SR_ERR;
69890f73 953 if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_CONFIG_0,
e46b8fb1
UH
954 0x00000008) != SR_OK)
955 return SR_ERR;
a803c0db 956 delaycount = readcount;
6937bb75 957 }
a1bb33af 958
b08024a8
UH
959 sr_info("ols: setting samplerate to %" PRIu64 " Hz (divider %u, "
960 "demux %s)", ols->cur_samplerate, ols->cur_samplerate_divider,
961 ols->flag_reg & FLAG_DEMUX ? "on" : "off");
69890f73 962 if (send_longcommand(ols->serial->fd, CMD_SET_DIVIDER,
4fe9a6da
BV
963 reverse32(ols->cur_samplerate_divider)) != SR_OK)
964 return SR_ERR;
a1bb33af 965
43fc7885 966 /* Send sample limit and pre/post-trigger capture ratio. */
a803c0db
BV
967 data = ((readcount - 1) & 0xffff) << 16;
968 data |= (delaycount - 1) & 0xffff;
69890f73 969 if (send_longcommand(ols->serial->fd, CMD_CAPTURE_SIZE, reverse16(data)) != SR_OK)
e46b8fb1 970 return SR_ERR;
a1bb33af 971
43fc7885 972 /* The flag register wants them here, and 1 means "disable channel". */
4fe9a6da
BV
973 ols->flag_reg |= ~(changrp_mask << 2) & 0x3c;
974 ols->flag_reg |= FLAG_FILTER;
3a4d09c0
GM
975 ols->rle_count = 0;
976 data = (ols->flag_reg << 24) | ((ols->flag_reg << 8) & 0xff0000);
69890f73 977 if (send_longcommand(ols->serial->fd, CMD_SET_FLAGS, data) != SR_OK)
e46b8fb1 978 return SR_ERR;
a1bb33af 979
43fc7885 980 /* Start acquisition on the device. */
69890f73 981 if (send_shortcommand(ols->serial->fd, CMD_RUN) != SR_OK)
e46b8fb1 982 return SR_ERR;
a1bb33af 983
69890f73 984 sr_source_add(ols->serial->fd, G_IO_IN, -1, receive_data,
9c939c51 985 session_data);
a1bb33af 986
b53738ba
UH
987 if (!(packet = g_try_malloc(sizeof(struct sr_datafeed_packet)))) {
988 sr_err("ols: %s: packet malloc failed", __func__);
989 return SR_ERR_MALLOC;
990 }
991
992 if (!(header = g_try_malloc(sizeof(struct sr_datafeed_header)))) {
993 sr_err("ols: %s: header malloc failed", __func__);
c0a4b971 994 g_free(packet);
b53738ba
UH
995 return SR_ERR_MALLOC;
996 }
997
43fc7885 998 /* Send header packet to the session bus. */
5a2326a7 999 packet->type = SR_DF_HEADER;
43fc7885 1000 packet->payload = (unsigned char *)header;
a1bb33af
UH
1001 header->feed_version = 1;
1002 gettimeofday(&header->starttime, NULL);
4fe9a6da 1003 header->samplerate = ols->cur_samplerate;
c2616fb9 1004 header->num_logic_probes = NUM_PROBES;
9c939c51 1005 sr_session_bus(session_data, packet);
c0a4b971 1006
a1bb33af
UH
1007 g_free(header);
1008 g_free(packet);
1009
e46b8fb1 1010 return SR_OK;
a1bb33af
UH
1011}
1012
a1bb33af
UH
1013static void hw_stop_acquisition(int device_index, gpointer session_device_id)
1014{
b9c735a2 1015 struct sr_datafeed_packet packet;
a1bb33af 1016
17e1afcb 1017 /* Avoid compiler warnings. */
cb93f8a9 1018 (void)device_index;
afc8e4de 1019
5a2326a7 1020 packet.type = SR_DF_END;
8a2efef2 1021 sr_session_bus(session_device_id, &packet);
a1bb33af
UH
1022}
1023
ca070ed9 1024SR_PRIV struct sr_device_plugin ols_plugin_info = {
e519ba86
UH
1025 .name = "ols",
1026 .longname = "Openbench Logic Sniffer",
1027 .api_version = 1,
1028 .init = hw_init,
1029 .cleanup = hw_cleanup,
86f5e3d8
UH
1030 .opendev = hw_opendev,
1031 .closedev = hw_closedev,
e519ba86
UH
1032 .get_device_info = hw_get_device_info,
1033 .get_status = hw_get_status,
1034 .get_capabilities = hw_get_capabilities,
1035 .set_configuration = hw_set_configuration,
1036 .start_acquisition = hw_start_acquisition,
1037 .stop_acquisition = hw_stop_acquisition,
a1bb33af 1038};