]> sigrok.org Git - libsigrok.git/blame - hardware/openbench-logic-sniffer/ols.c
sr: Eliminate usb/serial instances from API.
[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;
69890f73 221 ols->serial = NULL;
4fe9a6da
BV
222
223 return ols;
224}
225
226static struct sr_device_instance *get_metadata(int fd)
227{
228 struct sr_device_instance *sdi;
229 struct ols_device *ols;
230 uint32_t tmp_int;
231 uint8_t key, type, token;
232 GString *tmp_str, *devicename, *version;
233 gchar tmp_c;
234
235 sdi = sr_device_instance_new(0, SR_ST_INACTIVE, NULL, NULL, NULL);
236 ols = ols_device_new();
237 sdi->priv = ols;
238
239 devicename = g_string_new("");
240 version = g_string_new("");
241
242 key = 0xff;
243 while (key) {
244 if (serial_read(fd, &key, 1) != 1 || key == 0x00)
245 break;
246 type = key >> 5;
247 token = key & 0x1f;
248 switch (type) {
249 case 0:
250 /* NULL-terminated string */
251 tmp_str = g_string_new("");
252 while (serial_read(fd, &tmp_c, 1) == 1 && tmp_c != '\0')
253 g_string_append_c(tmp_str, tmp_c);
b08024a8
UH
254 sr_dbg("ols: got metadata key 0x%.2x value '%s'",
255 key, tmp_str->str);
4fe9a6da
BV
256 switch (token) {
257 case 0x01:
258 /* Device name */
259 devicename = g_string_append(devicename, tmp_str->str);
260 break;
261 case 0x02:
262 /* FPGA firmware version */
263 if (version->len)
264 g_string_append(version, ", ");
265 g_string_append(version, "FPGA version ");
266 g_string_append(version, tmp_str->str);
267 break;
268 case 0x03:
269 /* Ancillary version */
270 if (version->len)
271 g_string_append(version, ", ");
272 g_string_append(version, "Ancillary version ");
273 g_string_append(version, tmp_str->str);
274 break;
275 default:
b08024a8
UH
276 sr_info("ols: unknown token 0x%.2x: '%s'",
277 token, tmp_str->str);
4fe9a6da
BV
278 break;
279 }
280 g_string_free(tmp_str, TRUE);
281 break;
282 case 1:
283 /* 32-bit unsigned integer */
284 if (serial_read(fd, &tmp_int, 4) != 4)
285 break;
286 tmp_int = reverse32(tmp_int);
b08024a8
UH
287 sr_dbg("ols: got metadata key 0x%.2x value 0x%.8x",
288 key, tmp_int);
4fe9a6da
BV
289 switch (token) {
290 case 0x00:
291 /* Number of usable probes */
292 ols->num_probes = tmp_int;
293 break;
294 case 0x01:
295 /* Amount of sample memory available (bytes) */
296 ols->max_samples = tmp_int;
297 break;
298 case 0x02:
299 /* Amount of dynamic memory available (bytes) */
300 /* what is this for? */
301 break;
302 case 0x03:
303 /* Maximum sample rate (hz) */
304 ols->max_samplerate = tmp_int;
305 break;
306 case 0x04:
307 /* protocol version */
308 ols->protocol_version = tmp_int;
309 break;
310 default:
b08024a8
UH
311 sr_info("ols: unknown token 0x%.2x: 0x%.8x",
312 token, tmp_int);
4fe9a6da
BV
313 break;
314 }
315 break;
316 case 2:
317 /* 8-bit unsigned integer */
318 if (serial_read(fd, &tmp_c, 1) != 1)
319 break;
b08024a8
UH
320 sr_dbg("ols: got metadata key 0x%.2x value 0x%.2x",
321 key, tmp_c);
4fe9a6da
BV
322 switch (token) {
323 case 0x00:
324 /* Number of usable probes */
325 ols->num_probes = tmp_c;
326 break;
327 case 0x01:
328 /* protocol version */
329 ols->protocol_version = tmp_c;
330 break;
331 default:
b08024a8
UH
332 sr_info("ols: unknown token 0x%.2x: 0x%.2x",
333 token, tmp_c);
4fe9a6da
BV
334 break;
335 }
336 break;
337 default:
338 /* unknown type */
339 break;
340 }
341 }
342
343 sdi->model = devicename->str;
344 sdi->version = version->str;
345 g_string_free(devicename, FALSE);
346 g_string_free(version, FALSE);
347
348 return sdi;
349}
350
54ac5277 351static int hw_init(const char *deviceinfo)
a1bb33af 352{
a00ba012 353 struct sr_device_instance *sdi;
4fe9a6da 354 struct ols_device *ols;
a1bb33af 355 GSList *ports, *l;
4fe9a6da 356 GPollFD *fds, probefd;
6937bb75 357 int devcnt, final_devcnt, num_ports, fd, ret, i;
d02a535e 358 char buf[8], **device_names, **serial_params;
a1bb33af 359
c0a4b971
UH
360 final_devcnt = 0;
361
43fc7885 362 if (deviceinfo)
6937bb75 363 ports = g_slist_append(NULL, strdup(deviceinfo));
a1bb33af 364 else
43fc7885 365 /* No specific device given, so scan all serial ports. */
a1bb33af
UH
366 ports = list_serial_ports();
367
368 num_ports = g_slist_length(ports);
c0a4b971
UH
369
370 if (!(fds = g_try_malloc0(num_ports * sizeof(GPollFD)))) {
371 sr_err("ols: %s: fds malloc failed", __func__);
372 goto hw_init_free_ports; /* TODO: SR_ERR_MALLOC. */
373 }
374
375 if (!(device_names = g_try_malloc(num_ports * sizeof(char *)))) {
376 sr_err("ols: %s: device_names malloc failed", __func__);
377 goto hw_init_free_fds; /* TODO: SR_ERR_MALLOC. */
378 }
379
380 if (!(serial_params = g_try_malloc(num_ports * sizeof(char *)))) {
381 sr_err("ols: %s: serial_params malloc failed", __func__);
382 goto hw_init_free_device_names; /* TODO: SR_ERR_MALLOC. */
383 }
384
a1bb33af 385 devcnt = 0;
43fc7885
UH
386 for (l = ports; l; l = l->next) {
387 /* The discovery procedure is like this: first send the Reset
388 * command (0x00) 5 times, since the device could be anywhere
389 * in a 5-byte command. Then send the ID command (0x02).
390 * If the device responds with 4 bytes ("OLS1" or "SLA1"), we
391 * have a match.
392 *
393 * Since it may take the device a while to respond at 115Kb/s,
394 * we do all the sending first, then wait for all of them to
395 * respond with g_poll().
a1bb33af 396 */
b08024a8 397 sr_info("ols: probing %s...", (char *)l->data);
d02a535e 398 fd = serial_open(l->data, O_RDWR | O_NONBLOCK);
43fc7885 399 if (fd != -1) {
d02a535e
BV
400 serial_params[devcnt] = serial_backup_params(fd);
401 serial_set_params(fd, 115200, 8, 0, 1, 2);
e46b8fb1 402 ret = SR_OK;
43fc7885
UH
403 for (i = 0; i < 5; i++) {
404 if ((ret = send_shortcommand(fd,
e46b8fb1 405 CMD_RESET)) != SR_OK) {
43fc7885 406 /* Serial port is not writable. */
6937bb75
BV
407 break;
408 }
a1bb33af 409 }
e46b8fb1 410 if (ret != SR_OK) {
43fc7885
UH
411 serial_restore_params(fd,
412 serial_params[devcnt]);
d02a535e 413 serial_close(fd);
6937bb75 414 continue;
d02a535e 415 }
6937bb75
BV
416 send_shortcommand(fd, CMD_ID);
417 fds[devcnt].fd = fd;
418 fds[devcnt].events = G_IO_IN;
419 device_names[devcnt] = strdup(l->data);
420 devcnt++;
a1bb33af 421 }
6937bb75 422 free(l->data);
a1bb33af
UH
423 }
424
5b15b41e
PS
425 /* 2ms isn't enough for reliable transfer with pl2303, let's try 10 */
426 usleep(10000);
a1bb33af 427
a1bb33af 428 g_poll(fds, devcnt, 1);
4fe9a6da 429
43fc7885 430 for (i = 0; i < devcnt; i++) {
4fe9a6da
BV
431 if (fds[i].revents != G_IO_IN)
432 continue;
433 if (serial_read(fds[i].fd, buf, 4) != 4)
434 continue;
435 if (strncmp(buf, "1SLO", 4) && strncmp(buf, "1ALS", 4))
436 continue;
437
438 /* definitely using the OLS protocol, check if it supports
439 * the metadata command
440 */
441 send_shortcommand(fds[i].fd, CMD_METADATA);
442 probefd.fd = fds[i].fd;
443 probefd.events = G_IO_IN;
444 if (g_poll(&probefd, 1, 10) > 0) {
445 /* got metadata */
446 sdi = get_metadata(fds[i].fd);
447 sdi->index = final_devcnt;
448 } else {
449 /* not an OLS -- some other board that uses the sump protocol */
450 sdi = sr_device_instance_new(final_devcnt, SR_ST_INACTIVE,
451 "Sump", "Logic Analyzer", "v1.0");
452 ols = ols_device_new();
453 ols->num_probes = 32;
454 sdi->priv = ols;
a1bb33af 455 }
69890f73 456 ols->serial = sr_serial_device_instance_new(device_names[i], -1);
4fe9a6da
BV
457 device_instances = g_slist_append(device_instances, sdi);
458 final_devcnt++;
459 serial_close(fds[i].fd);
460 fds[i].fd = 0;
4fe9a6da
BV
461 }
462
463 /* clean up after all the probing */
464 for (i = 0; i < devcnt; i++) {
43fc7885 465 if (fds[i].fd != 0) {
d02a535e
BV
466 serial_restore_params(fds[i].fd, serial_params[i]);
467 serial_close(fds[i].fd);
6937bb75 468 }
d02a535e 469 free(serial_params[i]);
4fe9a6da 470 free(device_names[i]);
a1bb33af
UH
471 }
472
c0a4b971
UH
473 g_free(serial_params);
474hw_init_free_device_names:
475 g_free(device_names);
476hw_init_free_fds:
477 g_free(fds);
478hw_init_free_ports:
a1bb33af
UH
479 g_slist_free(ports);
480
481 return final_devcnt;
482}
483
a1bb33af
UH
484static int hw_opendev(int device_index)
485{
a00ba012 486 struct sr_device_instance *sdi;
69890f73 487 struct ols_device *ols;
a1bb33af 488
d32d961d 489 if (!(sdi = sr_get_device_instance(device_instances, device_index)))
e46b8fb1 490 return SR_ERR;
a1bb33af 491
69890f73
UH
492 ols = sdi->priv;
493
494 ols->serial->fd = serial_open(ols->serial->port, O_RDWR);
495 if (ols->serial->fd == -1)
e46b8fb1 496 return SR_ERR;
a1bb33af 497
5a2326a7 498 sdi->status = SR_ST_ACTIVE;
a1bb33af 499
e46b8fb1 500 return SR_OK;
a1bb33af
UH
501}
502
697785d1 503static int hw_closedev(int device_index)
a1bb33af 504{
a00ba012 505 struct sr_device_instance *sdi;
69890f73 506 struct ols_device *ols;
a1bb33af 507
697785d1
UH
508 if (!(sdi = sr_get_device_instance(device_instances, device_index))) {
509 sr_err("ols: %s: sdi was NULL", __func__);
510 return SR_ERR; /* TODO: SR_ERR_ARG? */
511 }
a1bb33af 512
69890f73
UH
513 ols = sdi->priv;
514
697785d1 515 /* TODO */
69890f73
UH
516 if (ols->serial->fd != -1) {
517 serial_close(ols->serial->fd);
518 ols->serial->fd = -1;
5a2326a7 519 sdi->status = SR_ST_INACTIVE;
a1bb33af 520 }
697785d1
UH
521
522 return SR_OK;
a1bb33af
UH
523}
524
a1bb33af
UH
525static void hw_cleanup(void)
526{
527 GSList *l;
a00ba012 528 struct sr_device_instance *sdi;
69890f73 529 struct ols_device *ols;
a1bb33af 530
8722c31e 531 /* Properly close and free all devices. */
43fc7885 532 for (l = device_instances; l; l = l->next) {
a1bb33af 533 sdi = l->data;
69890f73
UH
534 ols = sdi->priv;
535 if (ols->serial->fd != -1)
536 serial_close(ols->serial->fd);
537 sr_serial_device_instance_free(ols->serial);
a00ba012 538 sr_device_instance_free(sdi);
a1bb33af
UH
539 }
540 g_slist_free(device_instances);
541 device_instances = NULL;
a1bb33af
UH
542}
543
a1bb33af
UH
544static void *hw_get_device_info(int device_index, int device_info_id)
545{
a00ba012 546 struct sr_device_instance *sdi;
4fe9a6da 547 struct ols_device *ols;
a1bb33af
UH
548 void *info;
549
d32d961d 550 if (!(sdi = sr_get_device_instance(device_instances, device_index)))
a1bb33af 551 return NULL;
4fe9a6da 552 ols = sdi->priv;
a1bb33af
UH
553
554 info = NULL;
43fc7885 555 switch (device_info_id) {
5a2326a7 556 case SR_DI_INSTANCE:
a1bb33af
UH
557 info = sdi;
558 break;
5a2326a7 559 case SR_DI_NUM_PROBES:
a1bb33af
UH
560 info = GINT_TO_POINTER(NUM_PROBES);
561 break;
464d12c7
KS
562 case SR_DI_PROBE_NAMES:
563 info = probe_names;
564 break;
5a2326a7 565 case SR_DI_SAMPLERATES:
a1bb33af
UH
566 info = &samplerates;
567 break;
5a2326a7 568 case SR_DI_TRIGGER_TYPES:
43fc7885 569 info = (char *)TRIGGER_TYPES;
a1bb33af 570 break;
5a2326a7 571 case SR_DI_CUR_SAMPLERATE:
4fe9a6da 572 info = &ols->cur_samplerate;
a1bb33af
UH
573 break;
574 }
575
576 return info;
577}
578
a1bb33af
UH
579static int hw_get_status(int device_index)
580{
a00ba012 581 struct sr_device_instance *sdi;
a1bb33af 582
d32d961d 583 if (!(sdi = sr_get_device_instance(device_instances, device_index)))
5a2326a7 584 return SR_ST_NOT_FOUND;
a1bb33af
UH
585
586 return sdi->status;
587}
588
a1bb33af
UH
589static int *hw_get_capabilities(void)
590{
a1bb33af
UH
591 return capabilities;
592}
593
a00ba012 594static int set_configuration_samplerate(struct sr_device_instance *sdi,
43fc7885 595 uint64_t samplerate)
a1bb33af 596{
4fe9a6da 597 struct ols_device *ols;
a1bb33af 598
4fe9a6da
BV
599 ols = sdi->priv;
600 if (ols->max_samplerate) {
601 if (samplerate > ols->max_samplerate)
602 return SR_ERR_SAMPLERATE;
603 } else if (samplerate < samplerates.low || samplerate > samplerates.high)
e46b8fb1 604 return SR_ERR_SAMPLERATE;
a1bb33af 605
43fc7885 606 if (samplerate > CLOCK_RATE) {
4fe9a6da
BV
607 ols->flag_reg |= FLAG_DEMUX;
608 ols->cur_samplerate_divider = (CLOCK_RATE * 2 / samplerate) - 1;
43fc7885 609 } else {
4fe9a6da
BV
610 ols->flag_reg &= ~FLAG_DEMUX;
611 ols->cur_samplerate_divider = (CLOCK_RATE / samplerate) - 1;
a1bb33af 612 }
a1bb33af 613
7583b99d
GM
614 /* Calculate actual samplerate used and complain if it is different
615 * from the requested.
616 */
617 ols->cur_samplerate = CLOCK_RATE / (ols->cur_samplerate_divider + 1);
618 if(ols->flag_reg & FLAG_DEMUX)
619 ols->cur_samplerate *= 2;
620 ols->period_ps = 1000000000000 / ols->cur_samplerate;
621 if(ols->cur_samplerate != samplerate)
622 sr_warn("ols: can't match samplerate %" PRIu64 ", using %" PRIu64,
623 samplerate, ols->cur_samplerate);
624
e46b8fb1 625 return SR_OK;
a1bb33af
UH
626}
627
a1bb33af
UH
628static int hw_set_configuration(int device_index, int capability, void *value)
629{
a00ba012 630 struct sr_device_instance *sdi;
4fe9a6da 631 struct ols_device *ols;
a1bb33af
UH
632 int ret;
633 uint64_t *tmp_u64;
634
d32d961d 635 if (!(sdi = sr_get_device_instance(device_instances, device_index)))
e46b8fb1 636 return SR_ERR;
4fe9a6da 637 ols = sdi->priv;
a1bb33af 638
5a2326a7 639 if (sdi->status != SR_ST_ACTIVE)
e46b8fb1 640 return SR_ERR;
a1bb33af 641
a803c0db 642 switch (capability) {
5a2326a7 643 case SR_HWCAP_SAMPLERATE:
a1bb33af
UH
644 tmp_u64 = value;
645 ret = set_configuration_samplerate(sdi, *tmp_u64);
a803c0db 646 break;
5a2326a7 647 case SR_HWCAP_PROBECONFIG:
4fe9a6da 648 ret = configure_probes(ols, (GSList *) value);
a803c0db 649 break;
5a2326a7 650 case SR_HWCAP_LIMIT_SAMPLES:
2458ea65 651 tmp_u64 = value;
574ce498 652 if (*tmp_u64 < MIN_NUM_SAMPLES)
e46b8fb1 653 return SR_ERR;
baf1d714 654 if (*tmp_u64 > ols->max_samples)
22130421 655 sr_warn("ols: sample limit exceeds hw max");
4fe9a6da 656 ols->limit_samples = *tmp_u64;
b08024a8 657 sr_info("ols: sample limit %" PRIu64, ols->limit_samples);
e46b8fb1 658 ret = SR_OK;
a803c0db 659 break;
5a2326a7 660 case SR_HWCAP_CAPTURE_RATIO:
a803c0db 661 tmp_u64 = value;
4fe9a6da
BV
662 ols->capture_ratio = *tmp_u64;
663 if (ols->capture_ratio < 0 || ols->capture_ratio > 100) {
664 ols->capture_ratio = 0;
e46b8fb1 665 ret = SR_ERR;
43fc7885 666 } else
e46b8fb1 667 ret = SR_OK;
a803c0db 668 break;
3a4d09c0 669 case SR_HWCAP_RLE:
4d436e71 670 if (GPOINTER_TO_INT(value)) {
3a4d09c0
GM
671 sr_info("ols: enabling RLE");
672 ols->flag_reg |= FLAG_RLE;
673 }
674 ret = SR_OK;
675 break;
a803c0db 676 default:
e46b8fb1 677 ret = SR_ERR;
43fc7885 678 }
a1bb33af
UH
679
680 return ret;
681}
682
9c939c51 683static int receive_data(int fd, int revents, void *session_data)
a1bb33af 684{
b9c735a2 685 struct sr_datafeed_packet packet;
9c939c51 686 struct sr_datafeed_logic logic;
4fe9a6da
BV
687 struct sr_device_instance *sdi;
688 struct ols_device *ols;
689 GSList *l;
3a4d09c0
GM
690 int num_channels, offset, i, j;
691 unsigned char byte;
a1bb33af 692
4fe9a6da
BV
693 /* find this device's ols_device struct by its fd */
694 ols = NULL;
695 for (l = device_instances; l; l = l->next) {
696 sdi = l->data;
69890f73 697 if (ols->serial->fd == fd) {
4fe9a6da
BV
698 ols = sdi->priv;
699 break;
700 }
701 }
702 if (!ols)
703 /* shouldn't happen */
704 return TRUE;
705
706 if (ols->num_transfers++ == 0) {
43fc7885
UH
707 /*
708 * First time round, means the device started sending data,
709 * and will not stop until done. If it stops sending for
710 * longer than it takes to send a byte, that means it's
711 * finished. We'll double that to 30ms to be sure...
a1bb33af 712 */
6f1be0a2 713 sr_source_remove(fd);
9c939c51 714 sr_source_add(fd, G_IO_IN, 30, receive_data, session_data);
c0a4b971
UH
715 ols->raw_sample_buf = g_try_malloc(ols->limit_samples * 4);
716 if (!ols->raw_sample_buf) {
717 sr_err("ols: %s: ols->raw_sample_buf malloc failed",
718 __func__);
719 return FALSE;
720 }
a803c0db 721 /* fill with 1010... for debugging */
4fe9a6da 722 memset(ols->raw_sample_buf, 0x82, ols->limit_samples * 4);
a1bb33af
UH
723 }
724
6937bb75 725 num_channels = 0;
43fc7885 726 for (i = 0x20; i > 0x02; i /= 2) {
4fe9a6da 727 if ((ols->flag_reg & i) == 0)
6937bb75 728 num_channels++;
43fc7885 729 }
6937bb75 730
3a4d09c0 731 if (revents == G_IO_IN) {
2119ab03 732 if (serial_read(fd, &byte, 1) != 1)
a1bb33af
UH
733 return FALSE;
734
baf1d714
UH
735 /* Ignore it if we've read enough. */
736 if (ols->num_samples >= ols->limit_samples)
737 return TRUE;
3a4d09c0 738
4fe9a6da 739 ols->sample[ols->num_bytes++] = byte;
b08024a8 740 sr_dbg("ols: received byte 0x%.2x", byte);
4fe9a6da 741 if (ols->num_bytes == num_channels) {
43fc7885 742 /* Got a full sample. */
b08024a8 743 sr_dbg("ols: received sample 0x%.*x",
baf1d714 744 ols->num_bytes * 2, *(int *)ols->sample);
4fe9a6da 745 if (ols->flag_reg & FLAG_RLE) {
43fc7885
UH
746 /*
747 * In RLE mode -1 should never come in as a
748 * sample, because bit 31 is the "count" flag.
43fc7885 749 */
3a4d09c0 750 if (ols->sample[ols->num_bytes - 1] & 0x80) {
baf1d714
UH
751 ols->sample[ols->num_bytes - 1] &= 0x7f;
752 /*
753 * FIXME: This will only work on
754 * little-endian systems.
a1bb33af 755 */
baf1d714 756 ols->rle_count = *(int *)(ols->sample);
3a4d09c0
GM
757 sr_dbg("ols: RLE count = %d", ols->rle_count);
758 ols->num_bytes = 0;
759 return TRUE;
baf1d714 760 }
3a4d09c0
GM
761 }
762 ols->num_samples += ols->rle_count + 1;
baf1d714
UH
763 if (ols->num_samples > ols->limit_samples) {
764 /* Save us from overrunning the buffer. */
3a4d09c0
GM
765 ols->rle_count -= ols->num_samples - ols->limit_samples;
766 ols->num_samples = ols->limit_samples;
a1bb33af
UH
767 }
768
43fc7885
UH
769 if (num_channels < 4) {
770 /*
771 * Some channel groups may have been turned
772 * off, to speed up transfer between the
773 * hardware and the PC. Expand that here before
774 * submitting it over the session bus --
775 * whatever is listening on the bus will be
776 * expecting a full 32-bit sample, based on
777 * the number of probes.
6937bb75
BV
778 */
779 j = 0;
4fe9a6da 780 memset(ols->tmp_sample, 0, 4);
43fc7885 781 for (i = 0; i < 4; i++) {
4fe9a6da 782 if (((ols->flag_reg >> 2) & (1 << i)) == 0) {
43fc7885
UH
783 /*
784 * This channel group was
785 * enabled, copy from received
786 * sample.
787 */
4fe9a6da 788 ols->tmp_sample[i] = ols->sample[j++];
6937bb75
BV
789 }
790 }
4fe9a6da 791 memcpy(ols->sample, ols->tmp_sample, 4);
baf1d714 792 sr_dbg("ols: full sample 0x%.8x", *(int *)ols->sample);
6937bb75
BV
793 }
794
a803c0db
BV
795 /* the OLS sends its sample buffer backwards.
796 * store it in reverse order here, so we can dump
797 * this on the session bus later.
798 */
3a4d09c0 799 offset = (ols->limit_samples - ols->num_samples) * 4;
baf1d714
UH
800 for (i = 0; i <= ols->rle_count; i++) {
801 memcpy(ols->raw_sample_buf + offset + (i * 4),
802 ols->sample, 4);
803 }
4fe9a6da
BV
804 memset(ols->sample, 0, 4);
805 ols->num_bytes = 0;
3a4d09c0 806 ols->rle_count = 0;
a1bb33af 807 }
43fc7885
UH
808 } else {
809 /*
810 * This is the main loop telling us a timeout was reached, or
811 * we've acquired all the samples we asked for -- we're done.
a803c0db 812 * Send the (properly-ordered) buffer to the frontend.
43fc7885 813 */
4fe9a6da 814 if (ols->trigger_at != -1) {
a803c0db
BV
815 /* a trigger was set up, so we need to tell the frontend
816 * about it.
817 */
4fe9a6da 818 if (ols->trigger_at > 0) {
a803c0db 819 /* there are pre-trigger samples, send those first */
5a2326a7 820 packet.type = SR_DF_LOGIC;
9c939c51
BV
821 packet.timeoffset = 0;
822 packet.duration = ols->trigger_at * ols->period_ps;
823 packet.payload = &logic;
824 logic.length = ols->trigger_at * 4;
825 logic.unitsize = 4;
baf1d714 826 logic.data = ols->raw_sample_buf +
22130421 827 (ols->limit_samples - ols->num_samples) * 4;
9c939c51 828 sr_session_bus(session_data, &packet);
a803c0db
BV
829 }
830
9c939c51 831 /* send the trigger */
5a2326a7 832 packet.type = SR_DF_TRIGGER;
9c939c51
BV
833 packet.timeoffset = ols->trigger_at * ols->period_ps;
834 packet.duration = 0;
835 sr_session_bus(session_data, &packet);
a803c0db 836
9c939c51 837 /* send post-trigger samples */
5a2326a7 838 packet.type = SR_DF_LOGIC;
9c939c51 839 packet.timeoffset = ols->trigger_at * ols->period_ps;
22130421 840 packet.duration = (ols->num_samples - ols->trigger_at) * ols->period_ps;
9c939c51 841 packet.payload = &logic;
22130421 842 logic.length = (ols->num_samples * 4) - (ols->trigger_at * 4);
9c939c51 843 logic.unitsize = 4;
22130421
GM
844 logic.data = ols->raw_sample_buf + ols->trigger_at * 4 +
845 (ols->limit_samples - ols->num_samples) * 4;
9c939c51 846 sr_session_bus(session_data, &packet);
a803c0db 847 } else {
9c939c51 848 /* no trigger was used */
5a2326a7 849 packet.type = SR_DF_LOGIC;
9c939c51 850 packet.timeoffset = 0;
22130421 851 packet.duration = ols->num_samples * ols->period_ps;
9c939c51 852 packet.payload = &logic;
22130421 853 logic.length = ols->num_samples * 4;
9c939c51 854 logic.unitsize = 4;
22130421
GM
855 logic.data = ols->raw_sample_buf +
856 (ols->limit_samples - ols->num_samples) * 4;
9c939c51 857 sr_session_bus(session_data, &packet);
a803c0db 858 }
c0a4b971 859 g_free(ols->raw_sample_buf);
a803c0db 860
06d64eb8 861 serial_flush(fd);
d02a535e 862 serial_close(fd);
5a2326a7 863 packet.type = SR_DF_END;
22130421 864 packet.timeoffset = ols->num_samples * ols->period_ps;
9c939c51
BV
865 packet.duration = 0;
866 sr_session_bus(session_data, &packet);
a1bb33af
UH
867 }
868
869 return TRUE;
870}
871
9c939c51 872static int hw_start_acquisition(int device_index, gpointer session_data)
a1bb33af 873{
b9c735a2
UH
874 struct sr_datafeed_packet *packet;
875 struct sr_datafeed_header *header;
a00ba012 876 struct sr_device_instance *sdi;
4fe9a6da 877 struct ols_device *ols;
a803c0db 878 uint32_t trigger_config[4];
a1bb33af 879 uint32_t data;
6937bb75
BV
880 uint16_t readcount, delaycount;
881 uint8_t changrp_mask;
22130421 882 int num_channels;
4fe9a6da 883 int i;
a1bb33af 884
d32d961d 885 if (!(sdi = sr_get_device_instance(device_instances, device_index)))
e46b8fb1 886 return SR_ERR;
c0a4b971 887
4fe9a6da 888 ols = sdi->priv;
a1bb33af 889
5a2326a7 890 if (sdi->status != SR_ST_ACTIVE)
e46b8fb1 891 return SR_ERR;
a1bb33af 892
22130421
GM
893 /*
894 * Enable/disable channel groups in the flag register according to the
baf1d714 895 * probe mask. Calculate this here, because num_channels is needed
22130421
GM
896 * to limit readcount.
897 */
898 changrp_mask = 0;
899 num_channels = 0;
900 for (i = 0; i < 4; i++) {
901 if (ols->probe_mask & (0xff << (i * 8))) {
902 changrp_mask |= (1 << i);
903 num_channels++;
904 }
905 }
906
baf1d714
UH
907 /*
908 * Limit readcount to prevent reading past the end of the hardware
22130421
GM
909 * buffer.
910 */
911 readcount = MIN(ols->max_samples / num_channels, ols->limit_samples) / 4;
a803c0db
BV
912
913 memset(trigger_config, 0, 16);
4fe9a6da
BV
914 trigger_config[ols->num_stages - 1] |= 0x08;
915 if (ols->trigger_mask[0]) {
916 delaycount = readcount * (1 - ols->capture_ratio / 100.0);
917 ols->trigger_at = (readcount - delaycount) * 4 - ols->num_stages;
a803c0db 918
69890f73 919 if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_MASK_0,
4fe9a6da 920 reverse32(ols->trigger_mask[0])) != SR_OK)
e46b8fb1 921 return SR_ERR;
69890f73 922 if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_VALUE_0,
4fe9a6da 923 reverse32(ols->trigger_value[0])) != SR_OK)
e46b8fb1 924 return SR_ERR;
69890f73 925 if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_CONFIG_0,
e46b8fb1
UH
926 trigger_config[0]) != SR_OK)
927 return SR_ERR;
6937bb75 928
69890f73 929 if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_MASK_1,
4fe9a6da 930 reverse32(ols->trigger_mask[1])) != SR_OK)
e46b8fb1 931 return SR_ERR;
69890f73 932 if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_VALUE_1,
4fe9a6da 933 reverse32(ols->trigger_value[1])) != SR_OK)
e46b8fb1 934 return SR_ERR;
69890f73 935 if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_CONFIG_1,
e46b8fb1
UH
936 trigger_config[1]) != SR_OK)
937 return SR_ERR;
6937bb75 938
69890f73 939 if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_MASK_2,
4fe9a6da 940 reverse32(ols->trigger_mask[2])) != SR_OK)
e46b8fb1 941 return SR_ERR;
69890f73 942 if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_VALUE_2,
4fe9a6da 943 reverse32(ols->trigger_value[2])) != SR_OK)
e46b8fb1 944 return SR_ERR;
69890f73 945 if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_CONFIG_2,
e46b8fb1
UH
946 trigger_config[2]) != SR_OK)
947 return SR_ERR;
a803c0db 948
69890f73 949 if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_MASK_3,
4fe9a6da 950 reverse32(ols->trigger_mask[3])) != SR_OK)
e46b8fb1 951 return SR_ERR;
69890f73 952 if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_VALUE_3,
4fe9a6da 953 reverse32(ols->trigger_value[3])) != SR_OK)
e46b8fb1 954 return SR_ERR;
69890f73 955 if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_CONFIG_3,
e46b8fb1
UH
956 trigger_config[3]) != SR_OK)
957 return SR_ERR;
6937bb75 958 } else {
69890f73 959 if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_MASK_0,
4fe9a6da 960 ols->trigger_mask[0]) != SR_OK)
e46b8fb1 961 return SR_ERR;
69890f73 962 if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_VALUE_0,
4fe9a6da 963 ols->trigger_value[0]) != SR_OK)
e46b8fb1 964 return SR_ERR;
69890f73 965 if (send_longcommand(ols->serial->fd, CMD_SET_TRIGGER_CONFIG_0,
e46b8fb1
UH
966 0x00000008) != SR_OK)
967 return SR_ERR;
a803c0db 968 delaycount = readcount;
6937bb75 969 }
a1bb33af 970
b08024a8
UH
971 sr_info("ols: setting samplerate to %" PRIu64 " Hz (divider %u, "
972 "demux %s)", ols->cur_samplerate, ols->cur_samplerate_divider,
973 ols->flag_reg & FLAG_DEMUX ? "on" : "off");
69890f73 974 if (send_longcommand(ols->serial->fd, CMD_SET_DIVIDER,
4fe9a6da
BV
975 reverse32(ols->cur_samplerate_divider)) != SR_OK)
976 return SR_ERR;
a1bb33af 977
43fc7885 978 /* Send sample limit and pre/post-trigger capture ratio. */
a803c0db
BV
979 data = ((readcount - 1) & 0xffff) << 16;
980 data |= (delaycount - 1) & 0xffff;
69890f73 981 if (send_longcommand(ols->serial->fd, CMD_CAPTURE_SIZE, reverse16(data)) != SR_OK)
e46b8fb1 982 return SR_ERR;
a1bb33af 983
43fc7885 984 /* The flag register wants them here, and 1 means "disable channel". */
4fe9a6da
BV
985 ols->flag_reg |= ~(changrp_mask << 2) & 0x3c;
986 ols->flag_reg |= FLAG_FILTER;
3a4d09c0
GM
987 ols->rle_count = 0;
988 data = (ols->flag_reg << 24) | ((ols->flag_reg << 8) & 0xff0000);
69890f73 989 if (send_longcommand(ols->serial->fd, CMD_SET_FLAGS, data) != SR_OK)
e46b8fb1 990 return SR_ERR;
a1bb33af 991
43fc7885 992 /* Start acquisition on the device. */
69890f73 993 if (send_shortcommand(ols->serial->fd, CMD_RUN) != SR_OK)
e46b8fb1 994 return SR_ERR;
a1bb33af 995
69890f73 996 sr_source_add(ols->serial->fd, G_IO_IN, -1, receive_data,
9c939c51 997 session_data);
a1bb33af 998
b53738ba
UH
999 if (!(packet = g_try_malloc(sizeof(struct sr_datafeed_packet)))) {
1000 sr_err("ols: %s: packet malloc failed", __func__);
1001 return SR_ERR_MALLOC;
1002 }
1003
1004 if (!(header = g_try_malloc(sizeof(struct sr_datafeed_header)))) {
1005 sr_err("ols: %s: header malloc failed", __func__);
c0a4b971 1006 g_free(packet);
b53738ba
UH
1007 return SR_ERR_MALLOC;
1008 }
1009
43fc7885 1010 /* Send header packet to the session bus. */
5a2326a7 1011 packet->type = SR_DF_HEADER;
43fc7885 1012 packet->payload = (unsigned char *)header;
a1bb33af
UH
1013 header->feed_version = 1;
1014 gettimeofday(&header->starttime, NULL);
4fe9a6da 1015 header->samplerate = ols->cur_samplerate;
c2616fb9
DR
1016 header->num_logic_probes = NUM_PROBES;
1017 header->num_analog_probes = 0;
9c939c51 1018 sr_session_bus(session_data, packet);
c0a4b971 1019
a1bb33af
UH
1020 g_free(header);
1021 g_free(packet);
1022
e46b8fb1 1023 return SR_OK;
a1bb33af
UH
1024}
1025
a1bb33af
UH
1026static void hw_stop_acquisition(int device_index, gpointer session_device_id)
1027{
b9c735a2 1028 struct sr_datafeed_packet packet;
a1bb33af 1029
17e1afcb 1030 /* Avoid compiler warnings. */
cb93f8a9 1031 (void)device_index;
afc8e4de 1032
5a2326a7 1033 packet.type = SR_DF_END;
8a2efef2 1034 sr_session_bus(session_device_id, &packet);
a1bb33af
UH
1035}
1036
5c2d46d1 1037struct sr_device_plugin ols_plugin_info = {
e519ba86
UH
1038 .name = "ols",
1039 .longname = "Openbench Logic Sniffer",
1040 .api_version = 1,
1041 .init = hw_init,
1042 .cleanup = hw_cleanup,
86f5e3d8
UH
1043 .opendev = hw_opendev,
1044 .closedev = hw_closedev,
e519ba86
UH
1045 .get_device_info = hw_get_device_info,
1046 .get_status = hw_get_status,
1047 .get_capabilities = hw_get_capabilities,
1048 .set_configuration = hw_set_configuration,
1049 .start_acquisition = hw_start_acquisition,
1050 .stop_acquisition = hw_stop_acquisition,
a1bb33af 1051};