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