]> sigrok.org Git - libsigrok.git/blame - hardware/openbench-logic-sniffer/api.c
drivers: implement config_list()
[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
035a1078 253static int config_get(int id, const void **data, const struct sr_dev_inst *sdi)
0aba65da
UH
254{
255 struct dev_context *devc;
256
035a1078 257 switch (id) {
aeabd308
UH
258 case SR_DI_HWOPTS:
259 *data = hwopts;
260 break;
0aba65da
UH
261 case SR_DI_HWCAPS:
262 *data = hwcaps;
263 break;
0aba65da
UH
264 case SR_DI_SAMPLERATES:
265 *data = &samplerates;
266 break;
267 case SR_DI_TRIGGER_TYPES:
268 *data = (char *)TRIGGER_TYPES;
269 break;
270 case SR_DI_CUR_SAMPLERATE:
271 if (sdi) {
272 devc = sdi->priv;
273 *data = &devc->cur_samplerate;
274 } else
275 return SR_ERR;
276 break;
277 default:
278 return SR_ERR_ARG;
279 }
280
281 return SR_OK;
282}
283
035a1078 284static int config_set(int id, const void *value, const struct sr_dev_inst *sdi)
0aba65da
UH
285{
286 struct dev_context *devc;
287 int ret;
288 const uint64_t *tmp_u64;
289
290 devc = sdi->priv;
291
292 if (sdi->status != SR_ST_ACTIVE)
293 return SR_ERR;
294
035a1078 295 switch (id) {
1953564a 296 case SR_CONF_SAMPLERATE:
0aba65da
UH
297 ret = ols_set_samplerate(sdi, *(const uint64_t *)value,
298 &samplerates);
299 break;
1953564a 300 case SR_CONF_LIMIT_SAMPLES:
0aba65da
UH
301 tmp_u64 = value;
302 if (*tmp_u64 < MIN_NUM_SAMPLES)
303 return SR_ERR;
304 if (*tmp_u64 > devc->max_samples)
305 sr_err("Sample limit exceeds hardware maximum.");
306 devc->limit_samples = *tmp_u64;
307 sr_info("Sample limit is %" PRIu64 ".", devc->limit_samples);
308 ret = SR_OK;
309 break;
1953564a 310 case SR_CONF_CAPTURE_RATIO:
0aba65da
UH
311 devc->capture_ratio = *(const uint64_t *)value;
312 if (devc->capture_ratio < 0 || devc->capture_ratio > 100) {
313 devc->capture_ratio = 0;
314 ret = SR_ERR;
315 } else
316 ret = SR_OK;
317 break;
1953564a 318 case SR_CONF_RLE:
0aba65da
UH
319 if (GPOINTER_TO_INT(value)) {
320 sr_info("Enabling RLE.");
321 devc->flag_reg |= FLAG_RLE;
322 }
323 ret = SR_OK;
324 break;
325 default:
326 ret = SR_ERR;
327 }
328
329 return ret;
330}
331
a1c743fc
BV
332static int config_list(int key, const void **data, const struct sr_dev_inst *sdi)
333{
334
335 (void)sdi;
336
337 switch (key) {
338 case SR_CONF_SAMPLERATE:
339 *data = &samplerates;
340 break;
341 default:
342 return SR_ERR_ARG;
343 }
344
345 return SR_OK;
346}
347
0aba65da
UH
348static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi,
349 void *cb_data)
350{
351 struct sr_datafeed_packet *packet;
352 struct sr_datafeed_header *header;
0aba65da
UH
353 struct dev_context *devc;
354 uint32_t trigger_config[4];
355 uint32_t data;
356 uint16_t readcount, delaycount;
357 uint8_t changrp_mask;
358 int num_channels;
359 int i;
360
361 devc = sdi->priv;
362
363 if (sdi->status != SR_ST_ACTIVE)
364 return SR_ERR;
365
366 if (ols_configure_probes(sdi) != SR_OK) {
367 sr_err("Failed to configure probes.");
368 return SR_ERR;
369 }
370
371 /*
372 * Enable/disable channel groups in the flag register according to the
373 * probe mask. Calculate this here, because num_channels is needed
374 * to limit readcount.
375 */
376 changrp_mask = 0;
377 num_channels = 0;
378 for (i = 0; i < 4; i++) {
379 if (devc->probe_mask & (0xff << (i * 8))) {
380 changrp_mask |= (1 << i);
381 num_channels++;
382 }
383 }
384
385 /*
386 * Limit readcount to prevent reading past the end of the hardware
387 * buffer.
388 */
389 readcount = MIN(devc->max_samples / num_channels, devc->limit_samples) / 4;
390
391 memset(trigger_config, 0, 16);
392 trigger_config[devc->num_stages - 1] |= 0x08;
393 if (devc->trigger_mask[0]) {
394 delaycount = readcount * (1 - devc->capture_ratio / 100.0);
395 devc->trigger_at = (readcount - delaycount) * 4 - devc->num_stages;
396
397 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_MASK_0,
398 reverse32(devc->trigger_mask[0])) != SR_OK)
399 return SR_ERR;
400 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_VALUE_0,
401 reverse32(devc->trigger_value[0])) != SR_OK)
402 return SR_ERR;
403 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_CONFIG_0,
404 trigger_config[0]) != SR_OK)
405 return SR_ERR;
406
407 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_MASK_1,
408 reverse32(devc->trigger_mask[1])) != SR_OK)
409 return SR_ERR;
410 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_VALUE_1,
411 reverse32(devc->trigger_value[1])) != SR_OK)
412 return SR_ERR;
413 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_CONFIG_1,
414 trigger_config[1]) != SR_OK)
415 return SR_ERR;
416
417 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_MASK_2,
418 reverse32(devc->trigger_mask[2])) != SR_OK)
419 return SR_ERR;
420 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_VALUE_2,
421 reverse32(devc->trigger_value[2])) != SR_OK)
422 return SR_ERR;
423 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_CONFIG_2,
424 trigger_config[2]) != SR_OK)
425 return SR_ERR;
426
427 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_MASK_3,
428 reverse32(devc->trigger_mask[3])) != SR_OK)
429 return SR_ERR;
430 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_VALUE_3,
431 reverse32(devc->trigger_value[3])) != SR_OK)
432 return SR_ERR;
433 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_CONFIG_3,
434 trigger_config[3]) != SR_OK)
435 return SR_ERR;
436 } else {
437 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_MASK_0,
438 devc->trigger_mask[0]) != SR_OK)
439 return SR_ERR;
440 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_VALUE_0,
441 devc->trigger_value[0]) != SR_OK)
442 return SR_ERR;
443 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_CONFIG_0,
444 0x00000008) != SR_OK)
445 return SR_ERR;
446 delaycount = readcount;
447 }
448
449 sr_info("Setting samplerate to %" PRIu64 "Hz (divider %u, "
450 "demux %s)", devc->cur_samplerate, devc->cur_samplerate_divider,
451 devc->flag_reg & FLAG_DEMUX ? "on" : "off");
452 if (send_longcommand(devc->serial, CMD_SET_DIVIDER,
453 reverse32(devc->cur_samplerate_divider)) != SR_OK)
454 return SR_ERR;
455
456 /* Send sample limit and pre/post-trigger capture ratio. */
457 data = ((readcount - 1) & 0xffff) << 16;
458 data |= (delaycount - 1) & 0xffff;
459 if (send_longcommand(devc->serial, CMD_CAPTURE_SIZE, reverse16(data)) != SR_OK)
460 return SR_ERR;
461
462 /* The flag register wants them here, and 1 means "disable channel". */
463 devc->flag_reg |= ~(changrp_mask << 2) & 0x3c;
464 devc->flag_reg |= FLAG_FILTER;
465 devc->rle_count = 0;
466 data = (devc->flag_reg << 24) | ((devc->flag_reg << 8) & 0xff0000);
467 if (send_longcommand(devc->serial, CMD_SET_FLAGS, data) != SR_OK)
468 return SR_ERR;
469
470 /* Start acquisition on the device. */
471 if (send_shortcommand(devc->serial, CMD_RUN) != SR_OK)
472 return SR_ERR;
473
474 sr_source_add(devc->serial->fd, G_IO_IN, -1, ols_receive_data,
475 cb_data);
476
477 if (!(packet = g_try_malloc(sizeof(struct sr_datafeed_packet)))) {
478 sr_err("Datafeed packet malloc failed.");
479 return SR_ERR_MALLOC;
480 }
481
482 if (!(header = g_try_malloc(sizeof(struct sr_datafeed_header)))) {
483 sr_err("Datafeed header malloc failed.");
484 g_free(packet);
485 return SR_ERR_MALLOC;
486 }
487
488 /* Send header packet to the session bus. */
489 packet->type = SR_DF_HEADER;
490 packet->payload = (unsigned char *)header;
491 header->feed_version = 1;
492 gettimeofday(&header->starttime, NULL);
493 sr_session_send(cb_data, packet);
494
0aba65da
UH
495 g_free(header);
496 g_free(packet);
497
498 return SR_OK;
499}
500
501/* TODO: This stops acquisition on ALL devices, ignoring dev_index. */
502static int hw_dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
503{
504 /* Avoid compiler warnings. */
505 (void)cb_data;
506
507 abort_acquisition(sdi);
508
509 return SR_OK;
510}
511
512SR_PRIV struct sr_dev_driver ols_driver_info = {
513 .name = "ols",
514 .longname = "Openbench Logic Sniffer",
515 .api_version = 1,
516 .init = hw_init,
517 .cleanup = hw_cleanup,
518 .scan = hw_scan,
519 .dev_list = hw_dev_list,
520 .dev_clear = hw_cleanup,
035a1078
BV
521 .config_get = config_get,
522 .config_set = config_set,
a1c743fc 523 .config_list = config_list,
0aba65da
UH
524 .dev_open = hw_dev_open,
525 .dev_close = hw_dev_close,
0aba65da
UH
526 .dev_acquisition_start = hw_dev_acquisition_start,
527 .dev_acquisition_stop = hw_dev_acquisition_stop,
528 .priv = NULL,
529};