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