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