]> sigrok.org Git - libsigrok.git/blame - hardware/openbench-logic-sniffer/api.c
Deprecate SR_DI_CUR_SAMPLERATE.
[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_TRIGGER_TYPES:
265 *data = (char *)TRIGGER_TYPES;
266 break;
123e1313 267 case SR_CONF_SAMPLERATE:
0aba65da
UH
268 if (sdi) {
269 devc = sdi->priv;
270 *data = &devc->cur_samplerate;
271 } else
272 return SR_ERR;
273 break;
274 default:
275 return SR_ERR_ARG;
276 }
277
278 return SR_OK;
279}
280
035a1078 281static int config_set(int id, const void *value, const struct sr_dev_inst *sdi)
0aba65da
UH
282{
283 struct dev_context *devc;
284 int ret;
285 const uint64_t *tmp_u64;
286
287 devc = sdi->priv;
288
289 if (sdi->status != SR_ST_ACTIVE)
290 return SR_ERR;
291
035a1078 292 switch (id) {
1953564a 293 case SR_CONF_SAMPLERATE:
0aba65da
UH
294 ret = ols_set_samplerate(sdi, *(const uint64_t *)value,
295 &samplerates);
296 break;
1953564a 297 case SR_CONF_LIMIT_SAMPLES:
0aba65da
UH
298 tmp_u64 = value;
299 if (*tmp_u64 < MIN_NUM_SAMPLES)
300 return SR_ERR;
301 if (*tmp_u64 > devc->max_samples)
302 sr_err("Sample limit exceeds hardware maximum.");
303 devc->limit_samples = *tmp_u64;
304 sr_info("Sample limit is %" PRIu64 ".", devc->limit_samples);
305 ret = SR_OK;
306 break;
1953564a 307 case SR_CONF_CAPTURE_RATIO:
0aba65da
UH
308 devc->capture_ratio = *(const uint64_t *)value;
309 if (devc->capture_ratio < 0 || devc->capture_ratio > 100) {
310 devc->capture_ratio = 0;
311 ret = SR_ERR;
312 } else
313 ret = SR_OK;
314 break;
1953564a 315 case SR_CONF_RLE:
0aba65da
UH
316 if (GPOINTER_TO_INT(value)) {
317 sr_info("Enabling RLE.");
318 devc->flag_reg |= FLAG_RLE;
319 }
320 ret = SR_OK;
321 break;
322 default:
323 ret = SR_ERR;
324 }
325
326 return ret;
327}
328
a1c743fc
BV
329static int config_list(int key, const void **data, const struct sr_dev_inst *sdi)
330{
331
332 (void)sdi;
333
334 switch (key) {
335 case SR_CONF_SAMPLERATE:
336 *data = &samplerates;
337 break;
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};