]> sigrok.org Git - libsigrok.git/blame - hardware/openbench-logic-sniffer/api.c
sr_driver_scan(): Improve checks.
[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 }
c0eea11c 66
0aba65da
UH
67 drvc->sr_ctx = sr_ctx;
68 di->priv = drvc;
69
70 return SR_OK;
71}
72
73static GSList *hw_scan(GSList *options)
74{
1987b8d6 75 struct sr_config *src;
0aba65da
UH
76 struct sr_dev_inst *sdi;
77 struct drv_context *drvc;
78 struct dev_context *devc;
79 struct sr_probe *probe;
80 struct sr_serial_dev_inst *serial;
81 GPollFD probefd;
82 GSList *l, *devices;
83 int ret, i;
84 const char *conn, *serialcomm;
85 char buf[8];
86
87 (void)options;
4b97c74e 88
0aba65da 89 drvc = di->priv;
4b97c74e 90
0aba65da
UH
91 devices = NULL;
92
93 conn = serialcomm = NULL;
94 for (l = options; l; l = l->next) {
1987b8d6
BV
95 src = l->data;
96 switch (src->key) {
1953564a 97 case SR_CONF_CONN:
1987b8d6 98 conn = src->value;
0aba65da 99 break;
1953564a 100 case SR_CONF_SERIALCOMM:
1987b8d6 101 serialcomm = src->value;
0aba65da
UH
102 break;
103 }
104 }
105 if (!conn)
106 return NULL;
107
108 if (serialcomm == NULL)
109 serialcomm = SERIALCOMM;
110
111 if (!(serial = sr_serial_dev_inst_new(conn, serialcomm)))
112 return NULL;
113
114 /* The discovery procedure is like this: first send the Reset
115 * command (0x00) 5 times, since the device could be anywhere
116 * in a 5-byte command. Then send the ID command (0x02).
117 * If the device responds with 4 bytes ("OLS1" or "SLA1"), we
118 * have a match.
119 */
120 sr_info("Probing %s.", conn);
121 if (serial_open(serial, SERIAL_RDWR | SERIAL_NONBLOCK) != SR_OK)
122 return NULL;
123
124 ret = SR_OK;
125 for (i = 0; i < 5; i++) {
126 if ((ret = send_shortcommand(serial, CMD_RESET)) != SR_OK) {
127 sr_err("Port %s is not writable.", conn);
128 break;
129 }
130 }
131 if (ret != SR_OK) {
132 serial_close(serial);
133 sr_err("Could not use port %s. Quitting.", conn);
134 return NULL;
135 }
136 send_shortcommand(serial, CMD_ID);
137
138 /* Wait 10ms for a response. */
139 g_usleep(10000);
140
141 probefd.fd = serial->fd;
142 probefd.events = G_IO_IN;
143 g_poll(&probefd, 1, 1);
144
145 if (probefd.revents != G_IO_IN)
146 return NULL;
147 if (serial_read(serial, buf, 4) != 4)
148 return NULL;
149 if (strncmp(buf, "1SLO", 4) && strncmp(buf, "1ALS", 4))
150 return NULL;
151
152 /* Definitely using the OLS protocol, check if it supports
153 * the metadata command.
154 */
155 send_shortcommand(serial, CMD_METADATA);
156 if (g_poll(&probefd, 1, 10) > 0) {
157 /* Got metadata. */
158 sdi = get_metadata(serial);
159 sdi->index = 0;
160 devc = sdi->priv;
161 } else {
162 /* Not an OLS -- some other board that uses the sump protocol. */
163 sdi = sr_dev_inst_new(0, SR_ST_INACTIVE,
164 "Sump", "Logic Analyzer", "v1.0");
165 sdi->driver = di;
166 devc = ols_dev_new();
167 for (i = 0; i < 32; i++) {
168 if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE,
169 ols_probe_names[i])))
170 return 0;
171 sdi->probes = g_slist_append(sdi->probes, probe);
172 }
173 sdi->priv = devc;
174 }
175 devc->serial = serial;
176 drvc->instances = g_slist_append(drvc->instances, sdi);
177 devices = g_slist_append(devices, sdi);
178
179 serial_close(serial);
180
181 return devices;
182}
183
184static GSList *hw_dev_list(void)
185{
186 struct drv_context *drvc;
187
188 drvc = di->priv;
189
190 return drvc->instances;
191}
192
193static int hw_dev_open(struct sr_dev_inst *sdi)
194{
195 struct dev_context *devc;
196
197 devc = sdi->priv;
198
199 if (serial_open(devc->serial, SERIAL_RDWR) != SR_OK)
200 return SR_ERR;
201
202 sdi->status = SR_ST_ACTIVE;
203
204 return SR_OK;
205}
206
207static int hw_dev_close(struct sr_dev_inst *sdi)
208{
209 struct dev_context *devc;
210
211 devc = sdi->priv;
212
213 if (devc->serial && devc->serial->fd != -1) {
214 serial_close(devc->serial);
215 sdi->status = SR_ST_INACTIVE;
216 }
217
218 return SR_OK;
219}
220
221static int hw_cleanup(void)
222{
223 GSList *l;
224 struct sr_dev_inst *sdi;
225 struct drv_context *drvc;
226 struct dev_context *devc;
227 int ret = SR_OK;
228
229 if (!(drvc = di->priv))
230 return SR_OK;
231
232 /* Properly close and free all devices. */
233 for (l = drvc->instances; l; l = l->next) {
234 if (!(sdi = l->data)) {
235 /* Log error, but continue cleaning up the rest. */
236 sr_err("%s: sdi was NULL, continuing", __func__);
237 ret = SR_ERR_BUG;
238 continue;
239 }
240 if (!(devc = sdi->priv)) {
241 /* Log error, but continue cleaning up the rest. */
242 sr_err("%s: sdi->priv was NULL, continuing", __func__);
243 ret = SR_ERR_BUG;
244 continue;
245 }
246 hw_dev_close(sdi);
247 sr_serial_dev_inst_free(devc->serial);
248 sr_dev_inst_free(sdi);
249 }
250 g_slist_free(drvc->instances);
251 drvc->instances = NULL;
252
253 return ret;
254}
255
035a1078 256static int config_get(int id, const void **data, const struct sr_dev_inst *sdi)
0aba65da
UH
257{
258 struct dev_context *devc;
259
035a1078 260 switch (id) {
123e1313 261 case SR_CONF_SAMPLERATE:
0aba65da
UH
262 if (sdi) {
263 devc = sdi->priv;
264 *data = &devc->cur_samplerate;
265 } else
266 return SR_ERR;
267 break;
268 default:
269 return SR_ERR_ARG;
270 }
271
272 return SR_OK;
273}
274
035a1078 275static int config_set(int id, const void *value, const struct sr_dev_inst *sdi)
0aba65da
UH
276{
277 struct dev_context *devc;
278 int ret;
279 const uint64_t *tmp_u64;
280
281 devc = sdi->priv;
282
283 if (sdi->status != SR_ST_ACTIVE)
284 return SR_ERR;
285
035a1078 286 switch (id) {
1953564a 287 case SR_CONF_SAMPLERATE:
0aba65da
UH
288 ret = ols_set_samplerate(sdi, *(const uint64_t *)value,
289 &samplerates);
290 break;
1953564a 291 case SR_CONF_LIMIT_SAMPLES:
0aba65da
UH
292 tmp_u64 = value;
293 if (*tmp_u64 < MIN_NUM_SAMPLES)
294 return SR_ERR;
295 if (*tmp_u64 > devc->max_samples)
296 sr_err("Sample limit exceeds hardware maximum.");
297 devc->limit_samples = *tmp_u64;
298 sr_info("Sample limit is %" PRIu64 ".", devc->limit_samples);
299 ret = SR_OK;
300 break;
1953564a 301 case SR_CONF_CAPTURE_RATIO:
0aba65da
UH
302 devc->capture_ratio = *(const uint64_t *)value;
303 if (devc->capture_ratio < 0 || devc->capture_ratio > 100) {
304 devc->capture_ratio = 0;
305 ret = SR_ERR;
306 } else
307 ret = SR_OK;
308 break;
1953564a 309 case SR_CONF_RLE:
0aba65da
UH
310 if (GPOINTER_TO_INT(value)) {
311 sr_info("Enabling RLE.");
312 devc->flag_reg |= FLAG_RLE;
313 }
314 ret = SR_OK;
315 break;
316 default:
317 ret = SR_ERR;
318 }
319
320 return ret;
321}
322
a1c743fc
BV
323static int config_list(int key, const void **data, const struct sr_dev_inst *sdi)
324{
325
326 (void)sdi;
327
328 switch (key) {
0d485e30
BV
329 case SR_CONF_SCAN_OPTIONS:
330 *data = hwopts;
331 break;
9a6517d1
BV
332 case SR_CONF_DEVICE_OPTIONS:
333 *data = hwcaps;
334 break;
a1c743fc
BV
335 case SR_CONF_SAMPLERATE:
336 *data = &samplerates;
337 break;
c50277a6
BV
338 case SR_CONF_TRIGGER_TYPE:
339 *data = (char *)TRIGGER_TYPE;
340 break;
a1c743fc
BV
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};