]> sigrok.org Git - libsigrok.git/blame - src/hardware/openbench-logic-sniffer/api.c
ols: make connection ID available
[libsigrok.git] / src / 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
6ec6c43b 20#include <config.h>
515ab088 21#include "protocol.h"
0aba65da
UH
22
23#define SERIALCOMM "115200/8n1"
24
a0e0bb41 25static const uint32_t scanopts[] = {
1953564a
BV
26 SR_CONF_CONN,
27 SR_CONF_SERIALCOMM,
aeabd308
UH
28};
29
55fb76b3
UH
30static const uint32_t drvopts[] = {
31 SR_CONF_LOGIC_ANALYZER,
32};
33
f254bc4b 34static const uint32_t devopts[] = {
2f67be51 35 SR_CONF_CONN | SR_CONF_GET,
5827f61b
BV
36 SR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
37 SR_CONF_SAMPLERATE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
38 SR_CONF_TRIGGER_MATCH | SR_CONF_LIST,
39 SR_CONF_CAPTURE_RATIO | SR_CONF_GET | SR_CONF_SET,
50b15953 40 SR_CONF_EXTERNAL_CLOCK | SR_CONF_GET | SR_CONF_SET,
f20c39d9 41 SR_CONF_CLOCK_EDGE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
5827f61b
BV
42 SR_CONF_PATTERN_MODE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
43 SR_CONF_SWAP | SR_CONF_SET,
44 SR_CONF_RLE | SR_CONF_GET | SR_CONF_SET,
0aba65da
UH
45};
46
91fd0f72
BV
47static const int32_t trigger_matches[] = {
48 SR_TRIGGER_ZERO,
49 SR_TRIGGER_ONE,
50};
51
55eca716 52static const char *external_clock_edges[] = {
53 "rising", /* positive edge */
54 "falling" /* negative edge */
f20c39d9 55};
56
6d16fdfb
BV
57#define STR_PATTERN_NONE "None"
58#define STR_PATTERN_EXTERNAL "External"
59#define STR_PATTERN_INTERNAL "Internal"
967760a8
MR
60
61/* Supported methods of test pattern outputs */
62enum {
63 /**
64 * Capture pins 31:16 (unbuffered wing) output a test pattern
65 * that can captured on pins 0:15.
66 */
67 PATTERN_EXTERNAL,
68
69 /** Route test pattern internally to capture buffer. */
70 PATTERN_INTERNAL,
71};
72
7c07a178 73static const char *patterns[] = {
6d16fdfb 74 STR_PATTERN_NONE,
7c07a178
UH
75 STR_PATTERN_EXTERNAL,
76 STR_PATTERN_INTERNAL,
77};
78
ba7dd8bb 79/* Channels are numbered 0-31 (on the PCB silkscreen). */
53cda65a 80SR_PRIV const char *ols_channel_names[] = {
78693401
UH
81 "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12",
82 "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23",
83 "24", "25", "26", "27", "28", "29", "30", "31",
0aba65da
UH
84};
85
d3b38ad3 86/* Default supported samplerates, can be overridden by device metadata. */
e46aa4f6
BV
87static const uint64_t samplerates[] = {
88 SR_HZ(10),
89 SR_MHZ(200),
90 SR_HZ(1),
0aba65da
UH
91};
92
ae4e6999 93#define RESPONSE_DELAY_US (20 * 1000)
1a46cc62 94
4f840ce9 95static GSList *scan(struct sr_dev_driver *di, GSList *options)
0aba65da 96{
1987b8d6 97 struct sr_config *src;
0aba65da 98 struct sr_dev_inst *sdi;
0aba65da 99 struct sr_serial_dev_inst *serial;
43376f33 100 GSList *l;
35be304b 101 int num_read;
07ffa5b3 102 unsigned int i;
0aba65da 103 const char *conn, *serialcomm;
35be304b 104 char buf[4] = { 0, 0, 0, 0 };
0aba65da 105
0aba65da
UH
106 conn = serialcomm = NULL;
107 for (l = options; l; l = l->next) {
1987b8d6
BV
108 src = l->data;
109 switch (src->key) {
1953564a 110 case SR_CONF_CONN:
e46aa4f6 111 conn = g_variant_get_string(src->data, NULL);
0aba65da 112 break;
1953564a 113 case SR_CONF_SERIALCOMM:
e46aa4f6 114 serialcomm = g_variant_get_string(src->data, NULL);
0aba65da
UH
115 break;
116 }
117 }
118 if (!conn)
119 return NULL;
120
98fec29e 121 if (!serialcomm)
0aba65da
UH
122 serialcomm = SERIALCOMM;
123
91219afc 124 serial = sr_serial_dev_inst_new(conn, serialcomm);
0aba65da
UH
125
126 /* The discovery procedure is like this: first send the Reset
127 * command (0x00) 5 times, since the device could be anywhere
128 * in a 5-byte command. Then send the ID command (0x02).
129 * If the device responds with 4 bytes ("OLS1" or "SLA1"), we
130 * have a match.
131 */
132 sr_info("Probing %s.", conn);
4ded59ee 133 if (serial_open(serial, SERIAL_RDWR) != SR_OK)
0aba65da
UH
134 return NULL;
135
244995a2 136 if (ols_send_reset(serial) != SR_OK) {
0aba65da
UH
137 serial_close(serial);
138 sr_err("Could not use port %s. Quitting.", conn);
139 return NULL;
140 }
141 send_shortcommand(serial, CMD_ID);
142
1a46cc62 143 g_usleep(RESPONSE_DELAY_US);
0aba65da 144
f9921513 145 if (serial_has_receive_data(serial) == 0) {
35be304b 146 sr_dbg("Didn't get any ID reply.");
0aba65da 147 return NULL;
ed936ccc
UH
148 }
149
55eca716 150 num_read =
151 serial_read_blocking(serial, buf, 4, serial_timeout(serial, 4));
35be304b
WS
152 if (num_read < 0) {
153 sr_err("Getting ID reply failed (%d).", num_read);
0aba65da 154 return NULL;
ed936ccc
UH
155 }
156
157 if (strncmp(buf, "1SLO", 4) && strncmp(buf, "1ALS", 4)) {
35be304b
WS
158 GString *id = sr_hexdump_new((uint8_t *)buf, num_read);
159
160 sr_err("Invalid ID reply (got %s).", id->str);
161
162 sr_hexdump_free(id);
0aba65da 163 return NULL;
ed936ccc 164 }
0aba65da
UH
165
166 /* Definitely using the OLS protocol, check if it supports
167 * the metadata command.
168 */
169 send_shortcommand(serial, CMD_METADATA);
ed936ccc 170
1a46cc62 171 g_usleep(RESPONSE_DELAY_US);
ed936ccc 172
f9921513 173 if (serial_has_receive_data(serial) != 0) {
0aba65da
UH
174 /* Got metadata. */
175 sdi = get_metadata(serial);
0aba65da
UH
176 } else {
177 /* Not an OLS -- some other board that uses the sump protocol. */
72cd99b8 178 sr_info("Device does not support metadata.");
aac29cc1 179 sdi = g_malloc0(sizeof(struct sr_dev_inst));
0af636be
UH
180 sdi->status = SR_ST_INACTIVE;
181 sdi->vendor = g_strdup("Sump");
182 sdi->model = g_strdup("Logic Analyzer");
183 sdi->version = g_strdup("v1.0");
07ffa5b3 184 for (i = 0; i < ARRAY_SIZE(ols_channel_names); i++)
5e23fcab 185 sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE,
55eca716 186 ols_channel_names[i]);
e57057ae 187 sdi->priv = ols_dev_new();
0aba65da 188 }
bf256783
BV
189 /* Configure samplerate and divider. */
190 if (ols_set_samplerate(sdi, DEFAULT_SAMPLERATE) != SR_OK)
55eca716 191 sr_dbg("Failed to set default samplerate (%" PRIu64 ").",
192 DEFAULT_SAMPLERATE);
459a0f26
BV
193 sdi->inst_type = SR_INST_SERIAL;
194 sdi->conn = serial;
2f67be51 195 sdi->connection_id = g_strdup(serial->port);
bf256783 196
0aba65da
UH
197 serial_close(serial);
198
43376f33 199 return std_scan_complete(di, g_slist_append(NULL, sdi));
0aba65da
UH
200}
201
dd7a72ea 202static int config_get(uint32_t key, GVariant **data,
55eca716 203 const struct sr_dev_inst *sdi,
204 const struct sr_channel_group *cg)
0aba65da
UH
205{
206 struct dev_context *devc;
207
53b4680f 208 (void)cg;
8f996b89 209
0c05591a
BV
210 if (!sdi)
211 return SR_ERR_ARG;
212
213 devc = sdi->priv;
758906aa 214
584560f1 215 switch (key) {
2f67be51
GS
216 case SR_CONF_CONN:
217 if (!sdi->conn || !sdi->connection_id)
218 return SR_ERR_NA;
219 *data = g_variant_new_string(sdi->connection_id);
220 break;
123e1313 221 case SR_CONF_SAMPLERATE:
0c05591a
BV
222 *data = g_variant_new_uint64(devc->cur_samplerate);
223 break;
224 case SR_CONF_CAPTURE_RATIO:
225 *data = g_variant_new_uint64(devc->capture_ratio);
226 break;
227 case SR_CONF_LIMIT_SAMPLES:
228 *data = g_variant_new_uint64(devc->limit_samples);
229 break;
967760a8 230 case SR_CONF_PATTERN_MODE:
a80bed76 231 if (devc->capture_flags & CAPTURE_FLAG_EXTERNAL_TEST_MODE)
967760a8 232 *data = g_variant_new_string(STR_PATTERN_EXTERNAL);
a80bed76 233 else if (devc->capture_flags & CAPTURE_FLAG_INTERNAL_TEST_MODE)
967760a8 234 *data = g_variant_new_string(STR_PATTERN_INTERNAL);
6d16fdfb
BV
235 else
236 *data = g_variant_new_string(STR_PATTERN_NONE);
967760a8 237 break;
0c05591a 238 case SR_CONF_RLE:
55eca716 239 *data = g_variant_new_boolean(
240 devc->capture_flags & CAPTURE_FLAG_RLE ? TRUE : FALSE);
7730e4f0 241 break;
50b15953 242 case SR_CONF_EXTERNAL_CLOCK:
243 *data = g_variant_new_boolean(
55eca716 244 devc->capture_flags & CAPTURE_FLAG_CLOCK_EXTERNAL
245 ? TRUE : FALSE);
50b15953 246 break;
f20c39d9 247 case SR_CONF_CLOCK_EDGE:
248 *data = g_variant_new_string(external_clock_edges[
55eca716 249 devc->capture_flags & CAPTURE_FLAG_INVERT_EXT_CLOCK
250 ? 1 : 0]);
f20c39d9 251 break;
0aba65da 252 default:
bd6fbf62 253 return SR_ERR_NA;
0aba65da
UH
254 }
255
256 return SR_OK;
257}
258
dd7a72ea 259static int config_set(uint32_t key, GVariant *data,
55eca716 260 const struct sr_dev_inst *sdi,
261 const struct sr_channel_group *cg)
0aba65da
UH
262{
263 struct dev_context *devc;
6d16fdfb 264 uint16_t flag;
e46aa4f6 265 uint64_t tmp_u64;
967760a8 266 const char *stropt;
0aba65da 267
53b4680f 268 (void)cg;
8f996b89 269
0aba65da
UH
270 devc = sdi->priv;
271
584560f1 272 switch (key) {
1953564a 273 case SR_CONF_SAMPLERATE:
e46aa4f6
BV
274 tmp_u64 = g_variant_get_uint64(data);
275 if (tmp_u64 < samplerates[0] || tmp_u64 > samplerates[1])
276 return SR_ERR_SAMPLERATE;
758906aa 277 return ols_set_samplerate(sdi, g_variant_get_uint64(data));
1953564a 278 case SR_CONF_LIMIT_SAMPLES:
e46aa4f6
BV
279 tmp_u64 = g_variant_get_uint64(data);
280 if (tmp_u64 < MIN_NUM_SAMPLES)
0aba65da 281 return SR_ERR;
e46aa4f6 282 devc->limit_samples = tmp_u64;
0aba65da 283 break;
1953564a 284 case SR_CONF_CAPTURE_RATIO:
e46aa4f6 285 devc->capture_ratio = g_variant_get_uint64(data);
0aba65da 286 break;
eb1b610b
MR
287 case SR_CONF_EXTERNAL_CLOCK:
288 if (g_variant_get_boolean(data)) {
289 sr_info("Enabling external clock.");
a80bed76 290 devc->capture_flags |= CAPTURE_FLAG_CLOCK_EXTERNAL;
eb1b610b
MR
291 } else {
292 sr_info("Disabled external clock.");
a80bed76 293 devc->capture_flags &= ~CAPTURE_FLAG_CLOCK_EXTERNAL;
eb1b610b 294 }
eb1b610b 295 break;
f20c39d9 296 case SR_CONF_CLOCK_EDGE:
297 stropt = g_variant_get_string(data, NULL);
298 if (!strcmp(stropt, external_clock_edges[1])) {
299 sr_info("Triggering on falling edge of external clock.");
300 devc->capture_flags |= CAPTURE_FLAG_INVERT_EXT_CLOCK;
301 } else {
302 sr_info("Triggering on rising edge of external clock.");
303 devc->capture_flags &= ~CAPTURE_FLAG_INVERT_EXT_CLOCK;
304 }
305 break;
967760a8
MR
306 case SR_CONF_PATTERN_MODE:
307 stropt = g_variant_get_string(data, NULL);
6d16fdfb
BV
308 if (!strcmp(stropt, STR_PATTERN_NONE)) {
309 sr_info("Disabling test modes.");
310 flag = 0x0000;
758906aa 311 } else if (!strcmp(stropt, STR_PATTERN_INTERNAL)) {
967760a8 312 sr_info("Enabling internal test mode.");
a80bed76 313 flag = CAPTURE_FLAG_INTERNAL_TEST_MODE;
967760a8
MR
314 } else if (!strcmp(stropt, STR_PATTERN_EXTERNAL)) {
315 sr_info("Enabling external test mode.");
a80bed76 316 flag = CAPTURE_FLAG_EXTERNAL_TEST_MODE;
967760a8 317 } else {
758906aa 318 return SR_ERR;
967760a8 319 }
a80bed76 320 devc->capture_flags &= ~CAPTURE_FLAG_INTERNAL_TEST_MODE;
321 devc->capture_flags &= ~CAPTURE_FLAG_EXTERNAL_TEST_MODE;
322 devc->capture_flags |= flag;
967760a8 323 break;
7b0a57fd
MR
324 case SR_CONF_SWAP:
325 if (g_variant_get_boolean(data)) {
326 sr_info("Enabling channel swapping.");
a80bed76 327 devc->capture_flags |= CAPTURE_FLAG_SWAP_CHANNELS;
7b0a57fd
MR
328 } else {
329 sr_info("Disabling channel swapping.");
a80bed76 330 devc->capture_flags &= ~CAPTURE_FLAG_SWAP_CHANNELS;
7b0a57fd 331 }
7b0a57fd 332 break;
1953564a 333 case SR_CONF_RLE:
e46aa4f6 334 if (g_variant_get_boolean(data)) {
0aba65da 335 sr_info("Enabling RLE.");
a80bed76 336 devc->capture_flags |= CAPTURE_FLAG_RLE;
aeea0572
BV
337 } else {
338 sr_info("Disabling RLE.");
a80bed76 339 devc->capture_flags &= ~CAPTURE_FLAG_RLE;
0aba65da 340 }
0aba65da
UH
341 break;
342 default:
758906aa 343 return SR_ERR_NA;
0aba65da
UH
344 }
345
758906aa 346 return SR_OK;
0aba65da
UH
347}
348
dd7a72ea 349static int config_list(uint32_t key, GVariant **data,
55eca716 350 const struct sr_dev_inst *sdi,
351 const struct sr_channel_group *cg)
a1c743fc 352{
f0de2dd0 353 struct dev_context *devc;
91fd0f72 354 int num_ols_changrp, i;
a1c743fc 355
a1c743fc 356 switch (key) {
0d485e30 357 case SR_CONF_SCAN_OPTIONS:
9a6517d1 358 case SR_CONF_DEVICE_OPTIONS:
55eca716 359 return STD_CONFIG_LIST(key, data, sdi, cg, scanopts, drvopts,
360 devopts);
a1c743fc 361 case SR_CONF_SAMPLERATE:
53012da6 362 *data = std_gvar_samplerates_steps(ARRAY_AND_SIZE(samplerates));
a1c743fc 363 break;
91fd0f72 364 case SR_CONF_TRIGGER_MATCH:
53012da6 365 *data = std_gvar_array_i32(ARRAY_AND_SIZE(trigger_matches));
c50277a6 366 break;
f20c39d9 367 case SR_CONF_CLOCK_EDGE:
368 *data = std_gvar_array_str(ARRAY_AND_SIZE(external_clock_edges));
369 break;
7c07a178 370 case SR_CONF_PATTERN_MODE:
53012da6 371 *data = g_variant_new_strv(ARRAY_AND_SIZE(patterns));
7c07a178 372 break;
f0de2dd0
BV
373 case SR_CONF_LIMIT_SAMPLES:
374 if (!sdi)
375 return SR_ERR_ARG;
376 devc = sdi->priv;
f0de2dd0
BV
377 if (devc->max_samples == 0)
378 /* Device didn't specify sample memory size in metadata. */
379 return SR_ERR_NA;
380 /*
ba7dd8bb 381 * Channel groups are turned off if no channels in that group are
f0de2dd0
BV
382 * enabled, making more room for samples for the enabled group.
383 */
f8fd8420 384 uint32_t channel_mask = ols_channel_mask(sdi);
91fd0f72 385 num_ols_changrp = 0;
f0de2dd0 386 for (i = 0; i < 4; i++) {
f8fd8420 387 if (channel_mask & (0xff << (i * 8)))
91fd0f72 388 num_ols_changrp++;
1e1dac0c 389 }
a162eeb2 390
55eca716 391 *data = std_gvar_tuple_u64(MIN_NUM_SAMPLES, (num_ols_changrp)
392 ? devc->max_samples / num_ols_changrp : MIN_NUM_SAMPLES);
f0de2dd0 393 break;
a1c743fc 394 default:
bd6fbf62 395 return SR_ERR_NA;
a1c743fc
BV
396 }
397
398 return SR_OK;
399}
400
695dc859 401static int dev_acquisition_start(const struct sr_dev_inst *sdi)
0aba65da 402{
f8fd8420 403 int ret;
0aba65da 404 struct dev_context *devc;
459a0f26 405 struct sr_serial_dev_inst *serial;
0aba65da
UH
406
407 devc = sdi->priv;
459a0f26 408 serial = sdi->conn;
0aba65da 409
f8fd8420 410 ret = ols_prepare_acquisition(sdi);
411 if (ret != SR_OK)
412 return ret;
0aba65da
UH
413
414 /* Start acquisition on the device. */
6f9234e6 415 if (send_shortcommand(serial, CMD_ARM_BASIC_TRIGGER) != SR_OK)
0aba65da
UH
416 return SR_ERR;
417
bf256783 418 /* Reset all operational states. */
6d16fdfb
BV
419 devc->rle_count = devc->num_transfers = 0;
420 devc->num_samples = devc->num_bytes = 0;
625763e2 421 devc->cnt_bytes = devc->cnt_samples = devc->cnt_samples_rle = 0;
abb39e6b 422 memset(devc->sample, 0, 4);
bf256783 423
bee2b016 424 std_session_send_df_header(sdi);
4afdfd46 425
8105e829
DE
426 /* If the device stops sending for longer than it takes to send a byte,
427 * that means it's finished. But wait at least 100 ms to be safe.
428 */
74e28c06 429 return serial_source_add(sdi->session, serial, G_IO_IN, 100,
430 ols_receive_data, (struct sr_dev_inst *)sdi);
0aba65da
UH
431}
432
695dc859 433static int dev_acquisition_stop(struct sr_dev_inst *sdi)
0aba65da 434{
0aba65da
UH
435 abort_acquisition(sdi);
436
437 return SR_OK;
438}
439
15a5bfe4 440static struct sr_dev_driver ols_driver_info = {
0aba65da 441 .name = "ols",
60143473 442 .longname = "Openbench Logic Sniffer & SUMP compatibles",
0aba65da 443 .api_version = 1,
c2fdcc25 444 .init = std_init,
700d6b64 445 .cleanup = std_cleanup,
03f4de8c 446 .scan = scan,
c01bf34c 447 .dev_list = std_dev_list,
f778bf02 448 .dev_clear = std_dev_clear,
035a1078
BV
449 .config_get = config_get,
450 .config_set = config_set,
a1c743fc 451 .config_list = config_list,
854434de 452 .dev_open = std_serial_dev_open,
bf2c987f 453 .dev_close = std_serial_dev_close,
03f4de8c
BV
454 .dev_acquisition_start = dev_acquisition_start,
455 .dev_acquisition_stop = dev_acquisition_stop,
41812aca 456 .context = NULL,
0aba65da 457};
dd5c48a6 458SR_REGISTER_DEV_DRIVER(ols_driver_info);