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