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