]> sigrok.org Git - libsigrok.git/blame - hardware/openbench-logic-sniffer/api.c
Always interleave analog data with all enabled probes.
[libsigrok.git] / hardware / openbench-logic-sniffer / api.c
CommitLineData
0aba65da
UH
1/*
2 * This file is part of the sigrok project.
3 *
4 * Copyright (C) 2010-2012 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 "protocol.h"
21
22#define SERIALCOMM "115200/8n1"
23
aeabd308 24static const int hwopts[] = {
1953564a
BV
25 SR_CONF_CONN,
26 SR_CONF_SERIALCOMM,
aeabd308
UH
27 0,
28};
29
0aba65da 30static const int hwcaps[] = {
1953564a
BV
31 SR_CONF_LOGIC_ANALYZER,
32 SR_CONF_SAMPLERATE,
33 SR_CONF_CAPTURE_RATIO,
34 SR_CONF_LIMIT_SAMPLES,
35 SR_CONF_RLE,
0aba65da
UH
36 0,
37};
38
39/* Probes are numbered 0-31 (on the PCB silkscreen). */
40SR_PRIV const char *ols_probe_names[NUM_PROBES + 1] = {
78693401
UH
41 "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12",
42 "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23",
43 "24", "25", "26", "27", "28", "29", "30", "31",
0aba65da
UH
44 NULL,
45};
46
47/* default supported samplerates, can be overridden by device metadata */
48static const struct sr_samplerates samplerates = {
49 SR_HZ(10),
50 SR_MHZ(200),
51 SR_HZ(1),
52 NULL,
53};
54
55SR_PRIV struct sr_dev_driver ols_driver_info;
56static struct sr_dev_driver *di = &ols_driver_info;
57
58static int hw_init(struct sr_context *sr_ctx)
59{
60 struct drv_context *drvc;
61
62 if (!(drvc = g_try_malloc0(sizeof(struct drv_context)))) {
63 sr_err("Driver context malloc failed.");
64 return SR_ERR_MALLOC;
65 }
66 drvc->sr_ctx = sr_ctx;
67 di->priv = drvc;
68
69 return SR_OK;
70}
71
72static GSList *hw_scan(GSList *options)
73{
1987b8d6 74 struct sr_config *src;
0aba65da
UH
75 struct sr_dev_inst *sdi;
76 struct drv_context *drvc;
77 struct dev_context *devc;
78 struct sr_probe *probe;
79 struct sr_serial_dev_inst *serial;
80 GPollFD probefd;
81 GSList *l, *devices;
82 int ret, i;
83 const char *conn, *serialcomm;
84 char buf[8];
85
86 (void)options;
87 drvc = di->priv;
88 devices = NULL;
89
90 conn = serialcomm = NULL;
91 for (l = options; l; l = l->next) {
1987b8d6
BV
92 src = l->data;
93 switch (src->key) {
1953564a 94 case SR_CONF_CONN:
1987b8d6 95 conn = src->value;
0aba65da 96 break;
1953564a 97 case SR_CONF_SERIALCOMM:
1987b8d6 98 serialcomm = src->value;
0aba65da
UH
99 break;
100 }
101 }
102 if (!conn)
103 return NULL;
104
105 if (serialcomm == NULL)
106 serialcomm = SERIALCOMM;
107
108 if (!(serial = sr_serial_dev_inst_new(conn, serialcomm)))
109 return NULL;
110
111 /* The discovery procedure is like this: first send the Reset
112 * command (0x00) 5 times, since the device could be anywhere
113 * in a 5-byte command. Then send the ID command (0x02).
114 * If the device responds with 4 bytes ("OLS1" or "SLA1"), we
115 * have a match.
116 */
117 sr_info("Probing %s.", conn);
118 if (serial_open(serial, SERIAL_RDWR | SERIAL_NONBLOCK) != SR_OK)
119 return NULL;
120
121 ret = SR_OK;
122 for (i = 0; i < 5; i++) {
123 if ((ret = send_shortcommand(serial, CMD_RESET)) != SR_OK) {
124 sr_err("Port %s is not writable.", conn);
125 break;
126 }
127 }
128 if (ret != SR_OK) {
129 serial_close(serial);
130 sr_err("Could not use port %s. Quitting.", conn);
131 return NULL;
132 }
133 send_shortcommand(serial, CMD_ID);
134
135 /* Wait 10ms for a response. */
136 g_usleep(10000);
137
138 probefd.fd = serial->fd;
139 probefd.events = G_IO_IN;
140 g_poll(&probefd, 1, 1);
141
142 if (probefd.revents != G_IO_IN)
143 return NULL;
144 if (serial_read(serial, buf, 4) != 4)
145 return NULL;
146 if (strncmp(buf, "1SLO", 4) && strncmp(buf, "1ALS", 4))
147 return NULL;
148
149 /* Definitely using the OLS protocol, check if it supports
150 * the metadata command.
151 */
152 send_shortcommand(serial, CMD_METADATA);
153 if (g_poll(&probefd, 1, 10) > 0) {
154 /* Got metadata. */
155 sdi = get_metadata(serial);
156 sdi->index = 0;
157 devc = sdi->priv;
158 } else {
159 /* Not an OLS -- some other board that uses the sump protocol. */
160 sdi = sr_dev_inst_new(0, SR_ST_INACTIVE,
161 "Sump", "Logic Analyzer", "v1.0");
162 sdi->driver = di;
163 devc = ols_dev_new();
164 for (i = 0; i < 32; i++) {
165 if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE,
166 ols_probe_names[i])))
167 return 0;
168 sdi->probes = g_slist_append(sdi->probes, probe);
169 }
170 sdi->priv = devc;
171 }
172 devc->serial = serial;
173 drvc->instances = g_slist_append(drvc->instances, sdi);
174 devices = g_slist_append(devices, sdi);
175
176 serial_close(serial);
177
178 return devices;
179}
180
181static GSList *hw_dev_list(void)
182{
183 struct drv_context *drvc;
184
185 drvc = di->priv;
186
187 return drvc->instances;
188}
189
190static int hw_dev_open(struct sr_dev_inst *sdi)
191{
192 struct dev_context *devc;
193
194 devc = sdi->priv;
195
196 if (serial_open(devc->serial, SERIAL_RDWR) != SR_OK)
197 return SR_ERR;
198
199 sdi->status = SR_ST_ACTIVE;
200
201 return SR_OK;
202}
203
204static int hw_dev_close(struct sr_dev_inst *sdi)
205{
206 struct dev_context *devc;
207
208 devc = sdi->priv;
209
210 if (devc->serial && devc->serial->fd != -1) {
211 serial_close(devc->serial);
212 sdi->status = SR_ST_INACTIVE;
213 }
214
215 return SR_OK;
216}
217
218static int hw_cleanup(void)
219{
220 GSList *l;
221 struct sr_dev_inst *sdi;
222 struct drv_context *drvc;
223 struct dev_context *devc;
224 int ret = SR_OK;
225
226 if (!(drvc = di->priv))
227 return SR_OK;
228
229 /* Properly close and free all devices. */
230 for (l = drvc->instances; l; l = l->next) {
231 if (!(sdi = l->data)) {
232 /* Log error, but continue cleaning up the rest. */
233 sr_err("%s: sdi was NULL, continuing", __func__);
234 ret = SR_ERR_BUG;
235 continue;
236 }
237 if (!(devc = sdi->priv)) {
238 /* Log error, but continue cleaning up the rest. */
239 sr_err("%s: sdi->priv was NULL, continuing", __func__);
240 ret = SR_ERR_BUG;
241 continue;
242 }
243 hw_dev_close(sdi);
244 sr_serial_dev_inst_free(devc->serial);
245 sr_dev_inst_free(sdi);
246 }
247 g_slist_free(drvc->instances);
248 drvc->instances = NULL;
249
250 return ret;
251}
252
253static int hw_info_get(int info_id, const void **data,
254 const struct sr_dev_inst *sdi)
255{
256 struct dev_context *devc;
257
258 switch (info_id) {
aeabd308
UH
259 case SR_DI_HWOPTS:
260 *data = hwopts;
261 break;
0aba65da
UH
262 case SR_DI_HWCAPS:
263 *data = hwcaps;
264 break;
0aba65da
UH
265 case SR_DI_SAMPLERATES:
266 *data = &samplerates;
267 break;
268 case SR_DI_TRIGGER_TYPES:
269 *data = (char *)TRIGGER_TYPES;
270 break;
271 case SR_DI_CUR_SAMPLERATE:
272 if (sdi) {
273 devc = sdi->priv;
274 *data = &devc->cur_samplerate;
275 } else
276 return SR_ERR;
277 break;
278 default:
279 return SR_ERR_ARG;
280 }
281
282 return SR_OK;
283}
284
285static int hw_dev_config_set(const struct sr_dev_inst *sdi, int hwcap,
286 const void *value)
287{
288 struct dev_context *devc;
289 int ret;
290 const uint64_t *tmp_u64;
291
292 devc = sdi->priv;
293
294 if (sdi->status != SR_ST_ACTIVE)
295 return SR_ERR;
296
297 switch (hwcap) {
1953564a 298 case SR_CONF_SAMPLERATE:
0aba65da
UH
299 ret = ols_set_samplerate(sdi, *(const uint64_t *)value,
300 &samplerates);
301 break;
1953564a 302 case SR_CONF_LIMIT_SAMPLES:
0aba65da
UH
303 tmp_u64 = value;
304 if (*tmp_u64 < MIN_NUM_SAMPLES)
305 return SR_ERR;
306 if (*tmp_u64 > devc->max_samples)
307 sr_err("Sample limit exceeds hardware maximum.");
308 devc->limit_samples = *tmp_u64;
309 sr_info("Sample limit is %" PRIu64 ".", devc->limit_samples);
310 ret = SR_OK;
311 break;
1953564a 312 case SR_CONF_CAPTURE_RATIO:
0aba65da
UH
313 devc->capture_ratio = *(const uint64_t *)value;
314 if (devc->capture_ratio < 0 || devc->capture_ratio > 100) {
315 devc->capture_ratio = 0;
316 ret = SR_ERR;
317 } else
318 ret = SR_OK;
319 break;
1953564a 320 case SR_CONF_RLE:
0aba65da
UH
321 if (GPOINTER_TO_INT(value)) {
322 sr_info("Enabling RLE.");
323 devc->flag_reg |= FLAG_RLE;
324 }
325 ret = SR_OK;
326 break;
327 default:
328 ret = SR_ERR;
329 }
330
331 return ret;
332}
333
334static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi,
335 void *cb_data)
336{
337 struct sr_datafeed_packet *packet;
338 struct sr_datafeed_header *header;
0aba65da
UH
339 struct dev_context *devc;
340 uint32_t trigger_config[4];
341 uint32_t data;
342 uint16_t readcount, delaycount;
343 uint8_t changrp_mask;
344 int num_channels;
345 int i;
346
347 devc = sdi->priv;
348
349 if (sdi->status != SR_ST_ACTIVE)
350 return SR_ERR;
351
352 if (ols_configure_probes(sdi) != SR_OK) {
353 sr_err("Failed to configure probes.");
354 return SR_ERR;
355 }
356
357 /*
358 * Enable/disable channel groups in the flag register according to the
359 * probe mask. Calculate this here, because num_channels is needed
360 * to limit readcount.
361 */
362 changrp_mask = 0;
363 num_channels = 0;
364 for (i = 0; i < 4; i++) {
365 if (devc->probe_mask & (0xff << (i * 8))) {
366 changrp_mask |= (1 << i);
367 num_channels++;
368 }
369 }
370
371 /*
372 * Limit readcount to prevent reading past the end of the hardware
373 * buffer.
374 */
375 readcount = MIN(devc->max_samples / num_channels, devc->limit_samples) / 4;
376
377 memset(trigger_config, 0, 16);
378 trigger_config[devc->num_stages - 1] |= 0x08;
379 if (devc->trigger_mask[0]) {
380 delaycount = readcount * (1 - devc->capture_ratio / 100.0);
381 devc->trigger_at = (readcount - delaycount) * 4 - devc->num_stages;
382
383 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_MASK_0,
384 reverse32(devc->trigger_mask[0])) != SR_OK)
385 return SR_ERR;
386 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_VALUE_0,
387 reverse32(devc->trigger_value[0])) != SR_OK)
388 return SR_ERR;
389 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_CONFIG_0,
390 trigger_config[0]) != SR_OK)
391 return SR_ERR;
392
393 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_MASK_1,
394 reverse32(devc->trigger_mask[1])) != SR_OK)
395 return SR_ERR;
396 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_VALUE_1,
397 reverse32(devc->trigger_value[1])) != SR_OK)
398 return SR_ERR;
399 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_CONFIG_1,
400 trigger_config[1]) != SR_OK)
401 return SR_ERR;
402
403 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_MASK_2,
404 reverse32(devc->trigger_mask[2])) != SR_OK)
405 return SR_ERR;
406 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_VALUE_2,
407 reverse32(devc->trigger_value[2])) != SR_OK)
408 return SR_ERR;
409 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_CONFIG_2,
410 trigger_config[2]) != SR_OK)
411 return SR_ERR;
412
413 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_MASK_3,
414 reverse32(devc->trigger_mask[3])) != SR_OK)
415 return SR_ERR;
416 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_VALUE_3,
417 reverse32(devc->trigger_value[3])) != SR_OK)
418 return SR_ERR;
419 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_CONFIG_3,
420 trigger_config[3]) != SR_OK)
421 return SR_ERR;
422 } else {
423 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_MASK_0,
424 devc->trigger_mask[0]) != SR_OK)
425 return SR_ERR;
426 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_VALUE_0,
427 devc->trigger_value[0]) != SR_OK)
428 return SR_ERR;
429 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_CONFIG_0,
430 0x00000008) != SR_OK)
431 return SR_ERR;
432 delaycount = readcount;
433 }
434
435 sr_info("Setting samplerate to %" PRIu64 "Hz (divider %u, "
436 "demux %s)", devc->cur_samplerate, devc->cur_samplerate_divider,
437 devc->flag_reg & FLAG_DEMUX ? "on" : "off");
438 if (send_longcommand(devc->serial, CMD_SET_DIVIDER,
439 reverse32(devc->cur_samplerate_divider)) != SR_OK)
440 return SR_ERR;
441
442 /* Send sample limit and pre/post-trigger capture ratio. */
443 data = ((readcount - 1) & 0xffff) << 16;
444 data |= (delaycount - 1) & 0xffff;
445 if (send_longcommand(devc->serial, CMD_CAPTURE_SIZE, reverse16(data)) != SR_OK)
446 return SR_ERR;
447
448 /* The flag register wants them here, and 1 means "disable channel". */
449 devc->flag_reg |= ~(changrp_mask << 2) & 0x3c;
450 devc->flag_reg |= FLAG_FILTER;
451 devc->rle_count = 0;
452 data = (devc->flag_reg << 24) | ((devc->flag_reg << 8) & 0xff0000);
453 if (send_longcommand(devc->serial, CMD_SET_FLAGS, data) != SR_OK)
454 return SR_ERR;
455
456 /* Start acquisition on the device. */
457 if (send_shortcommand(devc->serial, CMD_RUN) != SR_OK)
458 return SR_ERR;
459
460 sr_source_add(devc->serial->fd, G_IO_IN, -1, ols_receive_data,
461 cb_data);
462
463 if (!(packet = g_try_malloc(sizeof(struct sr_datafeed_packet)))) {
464 sr_err("Datafeed packet malloc failed.");
465 return SR_ERR_MALLOC;
466 }
467
468 if (!(header = g_try_malloc(sizeof(struct sr_datafeed_header)))) {
469 sr_err("Datafeed header malloc failed.");
470 g_free(packet);
471 return SR_ERR_MALLOC;
472 }
473
474 /* Send header packet to the session bus. */
475 packet->type = SR_DF_HEADER;
476 packet->payload = (unsigned char *)header;
477 header->feed_version = 1;
478 gettimeofday(&header->starttime, NULL);
479 sr_session_send(cb_data, packet);
480
0aba65da
UH
481 g_free(header);
482 g_free(packet);
483
484 return SR_OK;
485}
486
487/* TODO: This stops acquisition on ALL devices, ignoring dev_index. */
488static int hw_dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
489{
490 /* Avoid compiler warnings. */
491 (void)cb_data;
492
493 abort_acquisition(sdi);
494
495 return SR_OK;
496}
497
498SR_PRIV struct sr_dev_driver ols_driver_info = {
499 .name = "ols",
500 .longname = "Openbench Logic Sniffer",
501 .api_version = 1,
502 .init = hw_init,
503 .cleanup = hw_cleanup,
504 .scan = hw_scan,
505 .dev_list = hw_dev_list,
506 .dev_clear = hw_cleanup,
507 .dev_open = hw_dev_open,
508 .dev_close = hw_dev_close,
509 .info_get = hw_info_get,
510 .dev_config_set = hw_dev_config_set,
511 .dev_acquisition_start = hw_dev_acquisition_start,
512 .dev_acquisition_stop = hw_dev_acquisition_stop,
513 .priv = NULL,
514};