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