]> sigrok.org Git - libsigrok.git/blame - hardware/openbench-logic-sniffer/api.c
Deprecate SR_DI_HWCAPS.
[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;
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) {
9a6517d1
BV
329 case SR_CONF_DEVICE_OPTIONS:
330 *data = hwcaps;
331 break;
a1c743fc
BV
332 case SR_CONF_SAMPLERATE:
333 *data = &samplerates;
334 break;
c50277a6
BV
335 case SR_CONF_TRIGGER_TYPE:
336 *data = (char *)TRIGGER_TYPE;
337 break;
a1c743fc
BV
338 default:
339 return SR_ERR_ARG;
340 }
341
342 return SR_OK;
343}
344
0aba65da
UH
345static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi,
346 void *cb_data)
347{
348 struct sr_datafeed_packet *packet;
349 struct sr_datafeed_header *header;
0aba65da
UH
350 struct dev_context *devc;
351 uint32_t trigger_config[4];
352 uint32_t data;
353 uint16_t readcount, delaycount;
354 uint8_t changrp_mask;
355 int num_channels;
356 int i;
357
358 devc = sdi->priv;
359
360 if (sdi->status != SR_ST_ACTIVE)
361 return SR_ERR;
362
363 if (ols_configure_probes(sdi) != SR_OK) {
364 sr_err("Failed to configure probes.");
365 return SR_ERR;
366 }
367
368 /*
369 * Enable/disable channel groups in the flag register according to the
370 * probe mask. Calculate this here, because num_channels is needed
371 * to limit readcount.
372 */
373 changrp_mask = 0;
374 num_channels = 0;
375 for (i = 0; i < 4; i++) {
376 if (devc->probe_mask & (0xff << (i * 8))) {
377 changrp_mask |= (1 << i);
378 num_channels++;
379 }
380 }
381
382 /*
383 * Limit readcount to prevent reading past the end of the hardware
384 * buffer.
385 */
386 readcount = MIN(devc->max_samples / num_channels, devc->limit_samples) / 4;
387
388 memset(trigger_config, 0, 16);
389 trigger_config[devc->num_stages - 1] |= 0x08;
390 if (devc->trigger_mask[0]) {
391 delaycount = readcount * (1 - devc->capture_ratio / 100.0);
392 devc->trigger_at = (readcount - delaycount) * 4 - devc->num_stages;
393
394 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_MASK_0,
395 reverse32(devc->trigger_mask[0])) != SR_OK)
396 return SR_ERR;
397 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_VALUE_0,
398 reverse32(devc->trigger_value[0])) != SR_OK)
399 return SR_ERR;
400 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_CONFIG_0,
401 trigger_config[0]) != SR_OK)
402 return SR_ERR;
403
404 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_MASK_1,
405 reverse32(devc->trigger_mask[1])) != SR_OK)
406 return SR_ERR;
407 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_VALUE_1,
408 reverse32(devc->trigger_value[1])) != SR_OK)
409 return SR_ERR;
410 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_CONFIG_1,
411 trigger_config[1]) != SR_OK)
412 return SR_ERR;
413
414 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_MASK_2,
415 reverse32(devc->trigger_mask[2])) != SR_OK)
416 return SR_ERR;
417 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_VALUE_2,
418 reverse32(devc->trigger_value[2])) != SR_OK)
419 return SR_ERR;
420 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_CONFIG_2,
421 trigger_config[2]) != SR_OK)
422 return SR_ERR;
423
424 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_MASK_3,
425 reverse32(devc->trigger_mask[3])) != SR_OK)
426 return SR_ERR;
427 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_VALUE_3,
428 reverse32(devc->trigger_value[3])) != SR_OK)
429 return SR_ERR;
430 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_CONFIG_3,
431 trigger_config[3]) != SR_OK)
432 return SR_ERR;
433 } else {
434 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_MASK_0,
435 devc->trigger_mask[0]) != SR_OK)
436 return SR_ERR;
437 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_VALUE_0,
438 devc->trigger_value[0]) != SR_OK)
439 return SR_ERR;
440 if (send_longcommand(devc->serial, CMD_SET_TRIGGER_CONFIG_0,
441 0x00000008) != SR_OK)
442 return SR_ERR;
443 delaycount = readcount;
444 }
445
446 sr_info("Setting samplerate to %" PRIu64 "Hz (divider %u, "
447 "demux %s)", devc->cur_samplerate, devc->cur_samplerate_divider,
448 devc->flag_reg & FLAG_DEMUX ? "on" : "off");
449 if (send_longcommand(devc->serial, CMD_SET_DIVIDER,
450 reverse32(devc->cur_samplerate_divider)) != SR_OK)
451 return SR_ERR;
452
453 /* Send sample limit and pre/post-trigger capture ratio. */
454 data = ((readcount - 1) & 0xffff) << 16;
455 data |= (delaycount - 1) & 0xffff;
456 if (send_longcommand(devc->serial, CMD_CAPTURE_SIZE, reverse16(data)) != SR_OK)
457 return SR_ERR;
458
459 /* The flag register wants them here, and 1 means "disable channel". */
460 devc->flag_reg |= ~(changrp_mask << 2) & 0x3c;
461 devc->flag_reg |= FLAG_FILTER;
462 devc->rle_count = 0;
463 data = (devc->flag_reg << 24) | ((devc->flag_reg << 8) & 0xff0000);
464 if (send_longcommand(devc->serial, CMD_SET_FLAGS, data) != SR_OK)
465 return SR_ERR;
466
467 /* Start acquisition on the device. */
468 if (send_shortcommand(devc->serial, CMD_RUN) != SR_OK)
469 return SR_ERR;
470
471 sr_source_add(devc->serial->fd, G_IO_IN, -1, ols_receive_data,
472 cb_data);
473
474 if (!(packet = g_try_malloc(sizeof(struct sr_datafeed_packet)))) {
475 sr_err("Datafeed packet malloc failed.");
476 return SR_ERR_MALLOC;
477 }
478
479 if (!(header = g_try_malloc(sizeof(struct sr_datafeed_header)))) {
480 sr_err("Datafeed header malloc failed.");
481 g_free(packet);
482 return SR_ERR_MALLOC;
483 }
484
485 /* Send header packet to the session bus. */
486 packet->type = SR_DF_HEADER;
487 packet->payload = (unsigned char *)header;
488 header->feed_version = 1;
489 gettimeofday(&header->starttime, NULL);
490 sr_session_send(cb_data, packet);
491
0aba65da
UH
492 g_free(header);
493 g_free(packet);
494
495 return SR_OK;
496}
497
498/* TODO: This stops acquisition on ALL devices, ignoring dev_index. */
499static int hw_dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
500{
501 /* Avoid compiler warnings. */
502 (void)cb_data;
503
504 abort_acquisition(sdi);
505
506 return SR_OK;
507}
508
509SR_PRIV struct sr_dev_driver ols_driver_info = {
510 .name = "ols",
511 .longname = "Openbench Logic Sniffer",
512 .api_version = 1,
513 .init = hw_init,
514 .cleanup = hw_cleanup,
515 .scan = hw_scan,
516 .dev_list = hw_dev_list,
517 .dev_clear = hw_cleanup,
035a1078
BV
518 .config_get = config_get,
519 .config_set = config_set,
a1c743fc 520 .config_list = config_list,
0aba65da
UH
521 .dev_open = hw_dev_open,
522 .dev_close = hw_dev_close,
0aba65da
UH
523 .dev_acquisition_start = hw_dev_acquisition_start,
524 .dev_acquisition_stop = hw_dev_acquisition_stop,
525 .priv = NULL,
526};