]> sigrok.org Git - libsigrok.git/blame - hardware/openbench-logic-sniffer/api.c
ols: fixed parallel stage triggers
[libsigrok.git] / hardware / openbench-logic-sniffer / api.c
CommitLineData
0aba65da 1/*
50985c20 2 * This file is part of the libsigrok project.
0aba65da 3 *
13d8e03c 4 * Copyright (C) 2013 Bert Vermeulen <bert@biot.com>
0aba65da
UH
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
e46aa4f6 24static const int32_t hwopts[] = {
1953564a
BV
25 SR_CONF_CONN,
26 SR_CONF_SERIALCOMM,
aeabd308
UH
27};
28
e46aa4f6 29static const int32_t hwcaps[] = {
1953564a
BV
30 SR_CONF_LOGIC_ANALYZER,
31 SR_CONF_SAMPLERATE,
0c05591a 32 SR_CONF_TRIGGER_TYPE,
1953564a
BV
33 SR_CONF_CAPTURE_RATIO,
34 SR_CONF_LIMIT_SAMPLES,
35 SR_CONF_RLE,
0aba65da
UH
36};
37
38/* Probes are numbered 0-31 (on the PCB silkscreen). */
39SR_PRIV const char *ols_probe_names[NUM_PROBES + 1] = {
78693401
UH
40 "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12",
41 "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23",
42 "24", "25", "26", "27", "28", "29", "30", "31",
0aba65da
UH
43 NULL,
44};
45
d3b38ad3 46/* Default supported samplerates, can be overridden by device metadata. */
e46aa4f6
BV
47static const uint64_t samplerates[] = {
48 SR_HZ(10),
49 SR_MHZ(200),
50 SR_HZ(1),
0aba65da
UH
51};
52
53SR_PRIV struct sr_dev_driver ols_driver_info;
54static struct sr_dev_driver *di = &ols_driver_info;
55
eea49cf1
UH
56static int dev_clear(void)
57{
58 return std_dev_clear(di, NULL);
59}
60
03f4de8c 61static int init(struct sr_context *sr_ctx)
0aba65da 62{
f6beaac5 63 return std_init(sr_ctx, di, LOG_PREFIX);
0aba65da
UH
64}
65
03f4de8c 66static GSList *scan(GSList *options)
0aba65da 67{
1987b8d6 68 struct sr_config *src;
0aba65da
UH
69 struct sr_dev_inst *sdi;
70 struct drv_context *drvc;
71 struct dev_context *devc;
72 struct sr_probe *probe;
73 struct sr_serial_dev_inst *serial;
74 GPollFD probefd;
75 GSList *l, *devices;
76 int ret, i;
77 const char *conn, *serialcomm;
78 char buf[8];
79
0aba65da 80 drvc = di->priv;
4b97c74e 81
0aba65da
UH
82 devices = NULL;
83
84 conn = serialcomm = NULL;
85 for (l = options; l; l = l->next) {
1987b8d6
BV
86 src = l->data;
87 switch (src->key) {
1953564a 88 case SR_CONF_CONN:
e46aa4f6 89 conn = g_variant_get_string(src->data, NULL);
0aba65da 90 break;
1953564a 91 case SR_CONF_SERIALCOMM:
e46aa4f6 92 serialcomm = g_variant_get_string(src->data, NULL);
0aba65da
UH
93 break;
94 }
95 }
96 if (!conn)
97 return NULL;
98
99 if (serialcomm == NULL)
100 serialcomm = SERIALCOMM;
101
102 if (!(serial = sr_serial_dev_inst_new(conn, serialcomm)))
103 return NULL;
104
105 /* The discovery procedure is like this: first send the Reset
106 * command (0x00) 5 times, since the device could be anywhere
107 * in a 5-byte command. Then send the ID command (0x02).
108 * If the device responds with 4 bytes ("OLS1" or "SLA1"), we
109 * have a match.
110 */
111 sr_info("Probing %s.", conn);
112 if (serial_open(serial, SERIAL_RDWR | SERIAL_NONBLOCK) != SR_OK)
113 return NULL;
114
115 ret = SR_OK;
116 for (i = 0; i < 5; i++) {
117 if ((ret = send_shortcommand(serial, CMD_RESET)) != SR_OK) {
118 sr_err("Port %s is not writable.", conn);
119 break;
120 }
121 }
122 if (ret != SR_OK) {
123 serial_close(serial);
124 sr_err("Could not use port %s. Quitting.", conn);
125 return NULL;
126 }
127 send_shortcommand(serial, CMD_ID);
128
129 /* Wait 10ms for a response. */
130 g_usleep(10000);
131
132 probefd.fd = serial->fd;
133 probefd.events = G_IO_IN;
134 g_poll(&probefd, 1, 1);
135
136 if (probefd.revents != G_IO_IN)
137 return NULL;
138 if (serial_read(serial, buf, 4) != 4)
139 return NULL;
140 if (strncmp(buf, "1SLO", 4) && strncmp(buf, "1ALS", 4))
141 return NULL;
142
143 /* Definitely using the OLS protocol, check if it supports
144 * the metadata command.
145 */
146 send_shortcommand(serial, CMD_METADATA);
147 if (g_poll(&probefd, 1, 10) > 0) {
148 /* Got metadata. */
149 sdi = get_metadata(serial);
150 sdi->index = 0;
151 devc = sdi->priv;
152 } else {
153 /* Not an OLS -- some other board that uses the sump protocol. */
72cd99b8 154 sr_info("Device does not support metadata.");
0aba65da
UH
155 sdi = sr_dev_inst_new(0, SR_ST_INACTIVE,
156 "Sump", "Logic Analyzer", "v1.0");
157 sdi->driver = di;
0aba65da
UH
158 for (i = 0; i < 32; i++) {
159 if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE,
160 ols_probe_names[i])))
161 return 0;
162 sdi->probes = g_slist_append(sdi->probes, probe);
163 }
bf256783 164 devc = ols_dev_new();
0aba65da
UH
165 sdi->priv = devc;
166 }
bf256783
BV
167 /* Configure samplerate and divider. */
168 if (ols_set_samplerate(sdi, DEFAULT_SAMPLERATE) != SR_OK)
169 sr_dbg("Failed to set default samplerate (%"PRIu64").",
170 DEFAULT_SAMPLERATE);
171 /* Clear trigger masks, values and stages. */
172 ols_configure_probes(sdi);
459a0f26
BV
173 sdi->inst_type = SR_INST_SERIAL;
174 sdi->conn = serial;
bf256783 175
0aba65da
UH
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
03f4de8c 184static GSList *dev_list(void)
0aba65da 185{
0e94d524 186 return ((struct drv_context *)(di->priv))->instances;
0aba65da
UH
187}
188
03f4de8c 189static int dev_open(struct sr_dev_inst *sdi)
0aba65da 190{
459a0f26 191 struct sr_serial_dev_inst *serial;
0aba65da 192
459a0f26
BV
193 serial = sdi->conn;
194 if (serial_open(serial, SERIAL_RDWR) != SR_OK)
0aba65da
UH
195 return SR_ERR;
196
197 sdi->status = SR_ST_ACTIVE;
198
199 return SR_OK;
200}
201
03f4de8c 202static int dev_close(struct sr_dev_inst *sdi)
0aba65da 203{
459a0f26 204 struct sr_serial_dev_inst *serial;
0aba65da 205
459a0f26
BV
206 serial = sdi->conn;
207 if (serial && serial->fd != -1) {
208 serial_close(serial);
0aba65da
UH
209 sdi->status = SR_ST_INACTIVE;
210 }
211
212 return SR_OK;
213}
214
eea49cf1 215static int cleanup(void)
0aba65da 216{
eea49cf1 217 return dev_clear();
0aba65da
UH
218}
219
e46aa4f6 220static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi)
0aba65da
UH
221{
222 struct dev_context *devc;
223
0c05591a
BV
224 if (!sdi)
225 return SR_ERR_ARG;
226
227 devc = sdi->priv;
035a1078 228 switch (id) {
123e1313 229 case SR_CONF_SAMPLERATE:
0c05591a
BV
230 *data = g_variant_new_uint64(devc->cur_samplerate);
231 break;
232 case SR_CONF_CAPTURE_RATIO:
233 *data = g_variant_new_uint64(devc->capture_ratio);
234 break;
235 case SR_CONF_LIMIT_SAMPLES:
236 *data = g_variant_new_uint64(devc->limit_samples);
237 break;
238 case SR_CONF_RLE:
239 *data = g_variant_new_boolean(devc->flag_reg & FLAG_RLE ? TRUE : FALSE);
0aba65da
UH
240 break;
241 default:
bd6fbf62 242 return SR_ERR_NA;
0aba65da
UH
243 }
244
245 return SR_OK;
246}
247
e46aa4f6 248static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi)
0aba65da
UH
249{
250 struct dev_context *devc;
251 int ret;
e46aa4f6 252 uint64_t tmp_u64;
0aba65da 253
e73ffd42
BV
254 if (sdi->status != SR_ST_ACTIVE)
255 return SR_ERR_DEV_CLOSED;
256
0aba65da
UH
257 devc = sdi->priv;
258
035a1078 259 switch (id) {
1953564a 260 case SR_CONF_SAMPLERATE:
e46aa4f6
BV
261 tmp_u64 = g_variant_get_uint64(data);
262 if (tmp_u64 < samplerates[0] || tmp_u64 > samplerates[1])
263 return SR_ERR_SAMPLERATE;
264 ret = ols_set_samplerate(sdi, g_variant_get_uint64(data));
0aba65da 265 break;
1953564a 266 case SR_CONF_LIMIT_SAMPLES:
e46aa4f6
BV
267 tmp_u64 = g_variant_get_uint64(data);
268 if (tmp_u64 < MIN_NUM_SAMPLES)
0aba65da 269 return SR_ERR;
e46aa4f6 270 devc->limit_samples = tmp_u64;
0aba65da
UH
271 ret = SR_OK;
272 break;
1953564a 273 case SR_CONF_CAPTURE_RATIO:
e46aa4f6 274 devc->capture_ratio = g_variant_get_uint64(data);
0aba65da
UH
275 if (devc->capture_ratio < 0 || devc->capture_ratio > 100) {
276 devc->capture_ratio = 0;
277 ret = SR_ERR;
278 } else
279 ret = SR_OK;
280 break;
1953564a 281 case SR_CONF_RLE:
e46aa4f6 282 if (g_variant_get_boolean(data)) {
0aba65da
UH
283 sr_info("Enabling RLE.");
284 devc->flag_reg |= FLAG_RLE;
aeea0572
BV
285 } else {
286 sr_info("Disabling RLE.");
287 devc->flag_reg &= ~FLAG_RLE;
0aba65da
UH
288 }
289 ret = SR_OK;
290 break;
291 default:
bd6fbf62 292 ret = SR_ERR_NA;
0aba65da
UH
293 }
294
295 return ret;
296}
297
e46aa4f6 298static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi)
a1c743fc 299{
e46aa4f6
BV
300 GVariant *gvar;
301 GVariantBuilder gvb;
a1c743fc
BV
302
303 (void)sdi;
304
305 switch (key) {
0d485e30 306 case SR_CONF_SCAN_OPTIONS:
e46aa4f6
BV
307 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
308 hwopts, ARRAY_SIZE(hwopts), sizeof(int32_t));
0d485e30 309 break;
9a6517d1 310 case SR_CONF_DEVICE_OPTIONS:
e46aa4f6
BV
311 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
312 hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
9a6517d1 313 break;
a1c743fc 314 case SR_CONF_SAMPLERATE:
e46aa4f6
BV
315 g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}"));
316 gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), samplerates,
317 ARRAY_SIZE(samplerates), sizeof(uint64_t));
318 g_variant_builder_add(&gvb, "{sv}", "samplerate-steps", gvar);
319 *data = g_variant_builder_end(&gvb);
a1c743fc 320 break;
c50277a6 321 case SR_CONF_TRIGGER_TYPE:
e46aa4f6 322 *data = g_variant_new_string(TRIGGER_TYPE);
c50277a6 323 break;
a1c743fc 324 default:
bd6fbf62 325 return SR_ERR_NA;
a1c743fc
BV
326 }
327
328 return SR_OK;
329}
330
03f4de8c 331static int dev_acquisition_start(const struct sr_dev_inst *sdi,
0aba65da
UH
332 void *cb_data)
333{
0aba65da 334 struct dev_context *devc;
459a0f26 335 struct sr_serial_dev_inst *serial;
0aba65da
UH
336 uint32_t trigger_config[4];
337 uint32_t data;
338 uint16_t readcount, delaycount;
339 uint8_t changrp_mask;
340 int num_channels;
341 int i;
342
e73ffd42
BV
343 if (sdi->status != SR_ST_ACTIVE)
344 return SR_ERR_DEV_CLOSED;
345
0aba65da 346 devc = sdi->priv;
459a0f26 347 serial = sdi->conn;
0aba65da 348
0aba65da
UH
349 if (ols_configure_probes(sdi) != SR_OK) {
350 sr_err("Failed to configure probes.");
351 return SR_ERR;
352 }
353
354 /*
355 * Enable/disable channel groups in the flag register according to the
356 * probe mask. Calculate this here, because num_channels is needed
357 * to limit readcount.
358 */
359 changrp_mask = 0;
360 num_channels = 0;
361 for (i = 0; i < 4; i++) {
362 if (devc->probe_mask & (0xff << (i * 8))) {
363 changrp_mask |= (1 << i);
364 num_channels++;
365 }
366 }
367
368 /*
369 * Limit readcount to prevent reading past the end of the hardware
370 * buffer.
371 */
372 readcount = MIN(devc->max_samples / num_channels, devc->limit_samples) / 4;
373
374 memset(trigger_config, 0, 16);
2e5b73c0 375 trigger_config[devc->num_stages] |= 0x08;
0aba65da
UH
376 if (devc->trigger_mask[0]) {
377 delaycount = readcount * (1 - devc->capture_ratio / 100.0);
378 devc->trigger_at = (readcount - delaycount) * 4 - devc->num_stages;
379
459a0f26 380 if (send_longcommand(serial, CMD_SET_TRIGGER_MASK_0,
0aba65da
UH
381 reverse32(devc->trigger_mask[0])) != SR_OK)
382 return SR_ERR;
459a0f26 383 if (send_longcommand(serial, CMD_SET_TRIGGER_VALUE_0,
0aba65da
UH
384 reverse32(devc->trigger_value[0])) != SR_OK)
385 return SR_ERR;
459a0f26 386 if (send_longcommand(serial, CMD_SET_TRIGGER_CONFIG_0,
0aba65da
UH
387 trigger_config[0]) != SR_OK)
388 return SR_ERR;
389
459a0f26 390 if (send_longcommand(serial, CMD_SET_TRIGGER_MASK_1,
0aba65da
UH
391 reverse32(devc->trigger_mask[1])) != SR_OK)
392 return SR_ERR;
459a0f26 393 if (send_longcommand(serial, CMD_SET_TRIGGER_VALUE_1,
0aba65da
UH
394 reverse32(devc->trigger_value[1])) != SR_OK)
395 return SR_ERR;
459a0f26 396 if (send_longcommand(serial, CMD_SET_TRIGGER_CONFIG_1,
0aba65da
UH
397 trigger_config[1]) != SR_OK)
398 return SR_ERR;
399
459a0f26 400 if (send_longcommand(serial, CMD_SET_TRIGGER_MASK_2,
0aba65da
UH
401 reverse32(devc->trigger_mask[2])) != SR_OK)
402 return SR_ERR;
459a0f26 403 if (send_longcommand(serial, CMD_SET_TRIGGER_VALUE_2,
0aba65da
UH
404 reverse32(devc->trigger_value[2])) != SR_OK)
405 return SR_ERR;
459a0f26 406 if (send_longcommand(serial, CMD_SET_TRIGGER_CONFIG_2,
0aba65da
UH
407 trigger_config[2]) != SR_OK)
408 return SR_ERR;
409
459a0f26 410 if (send_longcommand(serial, CMD_SET_TRIGGER_MASK_3,
0aba65da
UH
411 reverse32(devc->trigger_mask[3])) != SR_OK)
412 return SR_ERR;
459a0f26 413 if (send_longcommand(serial, CMD_SET_TRIGGER_VALUE_3,
0aba65da
UH
414 reverse32(devc->trigger_value[3])) != SR_OK)
415 return SR_ERR;
459a0f26 416 if (send_longcommand(serial, CMD_SET_TRIGGER_CONFIG_3,
0aba65da
UH
417 trigger_config[3]) != SR_OK)
418 return SR_ERR;
419 } else {
459a0f26 420 if (send_longcommand(serial, CMD_SET_TRIGGER_MASK_0,
0aba65da
UH
421 devc->trigger_mask[0]) != SR_OK)
422 return SR_ERR;
459a0f26 423 if (send_longcommand(serial, CMD_SET_TRIGGER_VALUE_0,
0aba65da
UH
424 devc->trigger_value[0]) != SR_OK)
425 return SR_ERR;
459a0f26 426 if (send_longcommand(serial, CMD_SET_TRIGGER_CONFIG_0,
0aba65da
UH
427 0x00000008) != SR_OK)
428 return SR_ERR;
429 delaycount = readcount;
430 }
431
432 sr_info("Setting samplerate to %" PRIu64 "Hz (divider %u, "
433 "demux %s)", devc->cur_samplerate, devc->cur_samplerate_divider,
434 devc->flag_reg & FLAG_DEMUX ? "on" : "off");
459a0f26 435 if (send_longcommand(serial, CMD_SET_DIVIDER,
0aba65da
UH
436 reverse32(devc->cur_samplerate_divider)) != SR_OK)
437 return SR_ERR;
438
439 /* Send sample limit and pre/post-trigger capture ratio. */
440 data = ((readcount - 1) & 0xffff) << 16;
441 data |= (delaycount - 1) & 0xffff;
459a0f26 442 if (send_longcommand(serial, CMD_CAPTURE_SIZE, reverse16(data)) != SR_OK)
0aba65da
UH
443 return SR_ERR;
444
445 /* The flag register wants them here, and 1 means "disable channel". */
446 devc->flag_reg |= ~(changrp_mask << 2) & 0x3c;
447 devc->flag_reg |= FLAG_FILTER;
448 devc->rle_count = 0;
449 data = (devc->flag_reg << 24) | ((devc->flag_reg << 8) & 0xff0000);
459a0f26 450 if (send_longcommand(serial, CMD_SET_FLAGS, data) != SR_OK)
0aba65da
UH
451 return SR_ERR;
452
453 /* Start acquisition on the device. */
459a0f26 454 if (send_shortcommand(serial, CMD_RUN) != SR_OK)
0aba65da
UH
455 return SR_ERR;
456
bf256783
BV
457 /* Reset all operational states. */
458 devc->num_transfers = devc->num_samples = devc->num_bytes = 0;
459
4afdfd46 460 /* Send header packet to the session bus. */
29a27196 461 std_session_send_df_header(cb_data, LOG_PREFIX);
4afdfd46 462
459a0f26 463 sr_source_add(serial->fd, G_IO_IN, -1, ols_receive_data, cb_data);
0aba65da 464
0aba65da
UH
465 return SR_OK;
466}
467
03f4de8c 468static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
0aba65da 469{
0aba65da
UH
470 (void)cb_data;
471
472 abort_acquisition(sdi);
473
474 return SR_OK;
475}
476
477SR_PRIV struct sr_dev_driver ols_driver_info = {
478 .name = "ols",
479 .longname = "Openbench Logic Sniffer",
480 .api_version = 1,
03f4de8c 481 .init = init,
eea49cf1 482 .cleanup = cleanup,
03f4de8c
BV
483 .scan = scan,
484 .dev_list = dev_list,
485 .dev_clear = dev_clear,
035a1078
BV
486 .config_get = config_get,
487 .config_set = config_set,
a1c743fc 488 .config_list = config_list,
03f4de8c
BV
489 .dev_open = dev_open,
490 .dev_close = dev_close,
491 .dev_acquisition_start = dev_acquisition_start,
492 .dev_acquisition_stop = dev_acquisition_stop,
0aba65da
UH
493 .priv = NULL,
494};