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