]> sigrok.org Git - libsigrok.git/blame - hardware/openbench-logic-sniffer/api.c
drivers: return SR_ERR_NA on unsupported config key
[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. */
72cd99b8 151 sr_info("Device does not support metadata.");
0aba65da
UH
152 sdi = sr_dev_inst_new(0, SR_ST_INACTIVE,
153 "Sump", "Logic Analyzer", "v1.0");
154 sdi->driver = di;
0aba65da
UH
155 for (i = 0; i < 32; i++) {
156 if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE,
157 ols_probe_names[i])))
158 return 0;
159 sdi->probes = g_slist_append(sdi->probes, probe);
160 }
bf256783 161 devc = ols_dev_new();
0aba65da
UH
162 sdi->priv = devc;
163 }
bf256783
BV
164 /* Configure samplerate and divider. */
165 if (ols_set_samplerate(sdi, DEFAULT_SAMPLERATE) != SR_OK)
166 sr_dbg("Failed to set default samplerate (%"PRIu64").",
167 DEFAULT_SAMPLERATE);
168 /* Clear trigger masks, values and stages. */
169 ols_configure_probes(sdi);
0aba65da 170 devc->serial = serial;
bf256783 171
0aba65da
UH
172 drvc->instances = g_slist_append(drvc->instances, sdi);
173 devices = g_slist_append(devices, sdi);
174
175 serial_close(serial);
176
177 return devices;
178}
179
180static GSList *hw_dev_list(void)
181{
0e94d524 182 return ((struct drv_context *)(di->priv))->instances;
0aba65da
UH
183}
184
185static int hw_dev_open(struct sr_dev_inst *sdi)
186{
187 struct dev_context *devc;
188
189 devc = sdi->priv;
190
191 if (serial_open(devc->serial, SERIAL_RDWR) != SR_OK)
192 return SR_ERR;
193
194 sdi->status = SR_ST_ACTIVE;
195
196 return SR_OK;
197}
198
199static int hw_dev_close(struct sr_dev_inst *sdi)
200{
201 struct dev_context *devc;
202
203 devc = sdi->priv;
204
205 if (devc->serial && devc->serial->fd != -1) {
206 serial_close(devc->serial);
207 sdi->status = SR_ST_INACTIVE;
208 }
209
210 return SR_OK;
211}
212
213static int hw_cleanup(void)
214{
215 GSList *l;
216 struct sr_dev_inst *sdi;
217 struct drv_context *drvc;
218 struct dev_context *devc;
219 int ret = SR_OK;
220
221 if (!(drvc = di->priv))
222 return SR_OK;
223
224 /* Properly close and free all devices. */
225 for (l = drvc->instances; l; l = l->next) {
226 if (!(sdi = l->data)) {
227 /* Log error, but continue cleaning up the rest. */
228 sr_err("%s: sdi was NULL, continuing", __func__);
229 ret = SR_ERR_BUG;
230 continue;
231 }
232 if (!(devc = sdi->priv)) {
233 /* Log error, but continue cleaning up the rest. */
234 sr_err("%s: sdi->priv was NULL, continuing", __func__);
235 ret = SR_ERR_BUG;
236 continue;
237 }
238 hw_dev_close(sdi);
239 sr_serial_dev_inst_free(devc->serial);
240 sr_dev_inst_free(sdi);
241 }
242 g_slist_free(drvc->instances);
243 drvc->instances = NULL;
244
245 return ret;
246}
247
e46aa4f6 248static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi)
0aba65da
UH
249{
250 struct dev_context *devc;
251
0c05591a
BV
252 if (!sdi)
253 return SR_ERR_ARG;
254
255 devc = sdi->priv;
035a1078 256 switch (id) {
123e1313 257 case SR_CONF_SAMPLERATE:
0c05591a
BV
258 *data = g_variant_new_uint64(devc->cur_samplerate);
259 break;
260 case SR_CONF_CAPTURE_RATIO:
261 *data = g_variant_new_uint64(devc->capture_ratio);
262 break;
263 case SR_CONF_LIMIT_SAMPLES:
264 *data = g_variant_new_uint64(devc->limit_samples);
265 break;
266 case SR_CONF_RLE:
267 *data = g_variant_new_boolean(devc->flag_reg & FLAG_RLE ? TRUE : FALSE);
0aba65da
UH
268 break;
269 default:
bd6fbf62 270 return SR_ERR_NA;
0aba65da
UH
271 }
272
273 return SR_OK;
274}
275
e46aa4f6 276static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi)
0aba65da
UH
277{
278 struct dev_context *devc;
279 int ret;
e46aa4f6 280 uint64_t tmp_u64;
0aba65da
UH
281
282 devc = sdi->priv;
283
035a1078 284 switch (id) {
1953564a 285 case SR_CONF_SAMPLERATE:
e46aa4f6
BV
286 tmp_u64 = g_variant_get_uint64(data);
287 if (tmp_u64 < samplerates[0] || tmp_u64 > samplerates[1])
288 return SR_ERR_SAMPLERATE;
289 ret = ols_set_samplerate(sdi, g_variant_get_uint64(data));
0aba65da 290 break;
1953564a 291 case SR_CONF_LIMIT_SAMPLES:
e46aa4f6
BV
292 tmp_u64 = g_variant_get_uint64(data);
293 if (tmp_u64 < MIN_NUM_SAMPLES)
0aba65da 294 return SR_ERR;
e46aa4f6 295 devc->limit_samples = tmp_u64;
0aba65da
UH
296 ret = SR_OK;
297 break;
1953564a 298 case SR_CONF_CAPTURE_RATIO:
e46aa4f6 299 devc->capture_ratio = g_variant_get_uint64(data);
0aba65da
UH
300 if (devc->capture_ratio < 0 || devc->capture_ratio > 100) {
301 devc->capture_ratio = 0;
302 ret = SR_ERR;
303 } else
304 ret = SR_OK;
305 break;
1953564a 306 case SR_CONF_RLE:
e46aa4f6 307 if (g_variant_get_boolean(data)) {
0aba65da
UH
308 sr_info("Enabling RLE.");
309 devc->flag_reg |= FLAG_RLE;
aeea0572
BV
310 } else {
311 sr_info("Disabling RLE.");
312 devc->flag_reg &= ~FLAG_RLE;
0aba65da
UH
313 }
314 ret = SR_OK;
315 break;
316 default:
bd6fbf62 317 ret = SR_ERR_NA;
0aba65da
UH
318 }
319
320 return ret;
321}
322
e46aa4f6 323static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi)
a1c743fc 324{
e46aa4f6
BV
325 GVariant *gvar;
326 GVariantBuilder gvb;
a1c743fc
BV
327
328 (void)sdi;
329
330 switch (key) {
0d485e30 331 case SR_CONF_SCAN_OPTIONS:
e46aa4f6
BV
332 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
333 hwopts, ARRAY_SIZE(hwopts), sizeof(int32_t));
0d485e30 334 break;
9a6517d1 335 case SR_CONF_DEVICE_OPTIONS:
e46aa4f6
BV
336 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
337 hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
9a6517d1 338 break;
a1c743fc 339 case SR_CONF_SAMPLERATE:
e46aa4f6
BV
340 g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}"));
341 gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), samplerates,
342 ARRAY_SIZE(samplerates), sizeof(uint64_t));
343 g_variant_builder_add(&gvb, "{sv}", "samplerate-steps", gvar);
344 *data = g_variant_builder_end(&gvb);
a1c743fc 345 break;
c50277a6 346 case SR_CONF_TRIGGER_TYPE:
e46aa4f6 347 *data = g_variant_new_string(TRIGGER_TYPE);
c50277a6 348 break;
a1c743fc 349 default:
bd6fbf62 350 return SR_ERR_NA;
a1c743fc
BV
351 }
352
353 return SR_OK;
354}
355
0aba65da
UH
356static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi,
357 void *cb_data)
358{
0aba65da
UH
359 struct dev_context *devc;
360 uint32_t trigger_config[4];
361 uint32_t data;
362 uint16_t readcount, delaycount;
363 uint8_t changrp_mask;
364 int num_channels;
365 int i;
366
367 devc = sdi->priv;
368
369 if (sdi->status != SR_ST_ACTIVE)
370 return SR_ERR;
371
372 if (ols_configure_probes(sdi) != SR_OK) {
373 sr_err("Failed to configure probes.");
374 return SR_ERR;
375 }
376
377 /*
378 * Enable/disable channel groups in the flag register according to the
379 * probe mask. Calculate this here, because num_channels is needed
380 * to limit readcount.
381 */
382 changrp_mask = 0;
383 num_channels = 0;
384 for (i = 0; i < 4; i++) {
385 if (devc->probe_mask & (0xff << (i * 8))) {
386 changrp_mask |= (1 << i);
387 num_channels++;
388 }
389 }
390
391 /*
392 * Limit readcount to prevent reading past the end of the hardware
393 * buffer.
394 */
395 readcount = MIN(devc->max_samples / num_channels, devc->limit_samples) / 4;
396
397 memset(trigger_config, 0, 16);
398 trigger_config[devc->num_stages - 1] |= 0x08;
399 if (devc->trigger_mask[0]) {
400 delaycount = readcount * (1 - devc->capture_ratio / 100.0);
401 devc->trigger_at = (readcount - delaycount) * 4 - devc->num_stages;
402
403 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_MASK_0,
404 reverse32(devc->trigger_mask[0])) != SR_OK)
405 return SR_ERR;
406 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_VALUE_0,
407 reverse32(devc->trigger_value[0])) != SR_OK)
408 return SR_ERR;
409 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_CONFIG_0,
410 trigger_config[0]) != SR_OK)
411 return SR_ERR;
412
413 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_MASK_1,
414 reverse32(devc->trigger_mask[1])) != SR_OK)
415 return SR_ERR;
416 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_VALUE_1,
417 reverse32(devc->trigger_value[1])) != SR_OK)
418 return SR_ERR;
419 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_CONFIG_1,
420 trigger_config[1]) != SR_OK)
421 return SR_ERR;
422
423 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_MASK_2,
424 reverse32(devc->trigger_mask[2])) != SR_OK)
425 return SR_ERR;
426 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_VALUE_2,
427 reverse32(devc->trigger_value[2])) != SR_OK)
428 return SR_ERR;
429 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_CONFIG_2,
430 trigger_config[2]) != SR_OK)
431 return SR_ERR;
432
433 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_MASK_3,
434 reverse32(devc->trigger_mask[3])) != SR_OK)
435 return SR_ERR;
436 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_VALUE_3,
437 reverse32(devc->trigger_value[3])) != SR_OK)
438 return SR_ERR;
439 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_CONFIG_3,
440 trigger_config[3]) != SR_OK)
441 return SR_ERR;
442 } else {
443 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_MASK_0,
444 devc->trigger_mask[0]) != SR_OK)
445 return SR_ERR;
446 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_VALUE_0,
447 devc->trigger_value[0]) != SR_OK)
448 return SR_ERR;
449 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_CONFIG_0,
450 0x00000008) != SR_OK)
451 return SR_ERR;
452 delaycount = readcount;
453 }
454
455 sr_info("Setting samplerate to %" PRIu64 "Hz (divider %u, "
456 "demux %s)", devc->cur_samplerate, devc->cur_samplerate_divider,
457 devc->flag_reg & FLAG_DEMUX ? "on" : "off");
458 if (send_longcommand(devc->serial, CMD_SET_DIVIDER,
459 reverse32(devc->cur_samplerate_divider)) != SR_OK)
460 return SR_ERR;
461
462 /* Send sample limit and pre/post-trigger capture ratio. */
463 data = ((readcount - 1) & 0xffff) << 16;
464 data |= (delaycount - 1) & 0xffff;
465 if (send_longcommand(devc->serial, CMD_CAPTURE_SIZE, reverse16(data)) != SR_OK)
466 return SR_ERR;
467
468 /* The flag register wants them here, and 1 means "disable channel". */
469 devc->flag_reg |= ~(changrp_mask << 2) & 0x3c;
470 devc->flag_reg |= FLAG_FILTER;
471 devc->rle_count = 0;
472 data = (devc->flag_reg << 24) | ((devc->flag_reg << 8) & 0xff0000);
473 if (send_longcommand(devc->serial, CMD_SET_FLAGS, data) != SR_OK)
474 return SR_ERR;
475
476 /* Start acquisition on the device. */
477 if (send_shortcommand(devc->serial, CMD_RUN) != SR_OK)
478 return SR_ERR;
479
bf256783
BV
480 /* Reset all operational states. */
481 devc->num_transfers = devc->num_samples = devc->num_bytes = 0;
482
4afdfd46
UH
483 /* Send header packet to the session bus. */
484 std_session_send_df_header(cb_data, DRIVER_LOG_DOMAIN);
485
0aba65da
UH
486 sr_source_add(devc->serial->fd, G_IO_IN, -1, ols_receive_data,
487 cb_data);
488
0aba65da
UH
489 return SR_OK;
490}
491
0aba65da
UH
492static int hw_dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
493{
494 /* Avoid compiler warnings. */
495 (void)cb_data;
496
497 abort_acquisition(sdi);
498
499 return SR_OK;
500}
501
502SR_PRIV struct sr_dev_driver ols_driver_info = {
503 .name = "ols",
504 .longname = "Openbench Logic Sniffer",
505 .api_version = 1,
506 .init = hw_init,
507 .cleanup = hw_cleanup,
508 .scan = hw_scan,
509 .dev_list = hw_dev_list,
510 .dev_clear = hw_cleanup,
035a1078
BV
511 .config_get = config_get,
512 .config_set = config_set,
a1c743fc 513 .config_list = config_list,
0aba65da
UH
514 .dev_open = hw_dev_open,
515 .dev_close = hw_dev_close,
0aba65da
UH
516 .dev_acquisition_start = hw_dev_acquisition_start,
517 .dev_acquisition_stop = hw_dev_acquisition_stop,
518 .priv = NULL,
519};