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