]> sigrok.org Git - libsigrok.git/blame - hardware/sysclk-lwla/api.c
hwdriver: Add SR_CONF_CLOCK_EDGE option.
[libsigrok.git] / hardware / sysclk-lwla / api.c
CommitLineData
aeaad0b0
DE
1/*
2 * This file is part of the libsigrok project.
3 *
4 * Copyright (C) 2014 Daniel Elstner <daniel.kitta@gmail.com>
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"
5874e88d
DE
21#include "libsigrok.h"
22#include "libsigrok-internal.h"
23#include <glib.h>
24#include <libusb.h>
25#include <stdlib.h>
26#include <string.h>
27
99c76642
DE
28static const int32_t hwopts[] = {
29 SR_CONF_CONN,
30};
31
5874e88d
DE
32static const int32_t hwcaps[] = {
33 SR_CONF_LOGIC_ANALYZER,
34 SR_CONF_SAMPLERATE,
35 SR_CONF_EXTERNAL_CLOCK,
36 SR_CONF_TRIGGER_TYPE,
e6e54bd2
DE
37 SR_CONF_TRIGGER_SOURCE,
38 SR_CONF_TRIGGER_SLOPE,
29d58767 39 SR_CONF_LIMIT_MSEC,
5874e88d
DE
40 SR_CONF_LIMIT_SAMPLES,
41};
42
43/* The hardware supports more samplerates than these, but these are the
44 * options hardcoded into the vendor's Windows GUI.
45 */
46static const uint64_t samplerates[] = {
47 SR_MHZ(125), SR_MHZ(100),
48 SR_MHZ(50), SR_MHZ(20), SR_MHZ(10),
49 SR_MHZ(5), SR_MHZ(2), SR_MHZ(1),
50 SR_KHZ(500), SR_KHZ(200), SR_KHZ(100),
51 SR_KHZ(50), SR_KHZ(20), SR_KHZ(10),
52 SR_KHZ(5), SR_KHZ(2), SR_KHZ(1),
53 SR_HZ(500), SR_HZ(200), SR_HZ(100),
54};
aeaad0b0 55
e6e54bd2
DE
56/* Names assigned to available trigger sources. Indices must match
57 * trigger_source enum values.
58 */
59static const char *const trigger_source_names[] = { "CH", "TRG" };
60
61/* Names assigned to available trigger slope choices. Indices must
62 * match trigger_slope enum values.
63 */
64static const char *const trigger_slope_names[] = { "r", "f" };
65
aeaad0b0 66SR_PRIV struct sr_dev_driver sysclk_lwla_driver_info;
5874e88d 67static struct sr_dev_driver *const di = &sysclk_lwla_driver_info;
aeaad0b0
DE
68
69static int init(struct sr_context *sr_ctx)
70{
71 return std_init(sr_ctx, di, LOG_PREFIX);
72}
73
5874e88d
DE
74static GSList *gen_probe_list(int num_probes)
75{
76 GSList *list;
77 struct sr_probe *probe;
78 int i;
79 char name[8];
80
81 list = NULL;
82
83 for (i = num_probes; i > 0; --i) {
84 /* The LWLA series simply number probes from CH1 to CHxx. */
1f98295d 85 g_snprintf(name, sizeof(name), "CH%d", i);
5874e88d
DE
86
87 probe = sr_probe_new(i - 1, SR_PROBE_LOGIC, TRUE, name);
88 list = g_slist_prepend(list, probe);
89 }
90
91 return list;
92}
93
43db3436
DE
94static struct sr_dev_inst *dev_inst_new(int device_index)
95{
96 struct sr_dev_inst *sdi;
97 struct dev_context *devc;
98
99 /* Allocate memory for our private driver context. */
100 devc = g_try_new0(struct dev_context, 1);
101 if (!devc) {
102 sr_err("Device context malloc failed.");
103 return NULL;
104 }
105
106 /* Register the device with libsigrok. */
107 sdi = sr_dev_inst_new(device_index, SR_ST_INACTIVE,
108 VENDOR_NAME, MODEL_NAME, NULL);
109 if (!sdi) {
110 sr_err("Failed to instantiate device.");
111 g_free(devc);
112 return NULL;
113 }
114
115 /* Enable all channels to match the default probe configuration. */
116 devc->channel_mask = ALL_CHANNELS_MASK;
117 devc->samplerate = DEFAULT_SAMPLERATE;
118
119 sdi->priv = devc;
120 sdi->probes = gen_probe_list(NUM_PROBES);
121
122 return sdi;
123}
124
aeaad0b0
DE
125static GSList *scan(GSList *options)
126{
5874e88d 127 GSList *usb_devices, *devices, *node;
aeaad0b0 128 struct drv_context *drvc;
5874e88d 129 struct sr_dev_inst *sdi;
5874e88d 130 struct sr_usb_dev_inst *usb;
7ebe9b9e
DE
131 struct sr_config *src;
132 const char *conn;
5874e88d 133 int device_index;
aeaad0b0 134
aeaad0b0 135 drvc = di->priv;
7ebe9b9e 136 conn = USB_VID_PID;
5874e88d 137
7ebe9b9e
DE
138 for (node = options; node != NULL; node = node->next) {
139 src = node->data;
140 if (src->key == SR_CONF_CONN) {
141 conn = g_variant_get_string(src->data, NULL);
142 break;
143 }
144 }
145 usb_devices = sr_usb_find(drvc->sr_ctx->libusb_ctx, conn);
146 devices = NULL;
50cad98d 147 device_index = g_slist_length(drvc->instances);
5874e88d
DE
148
149 for (node = usb_devices; node != NULL; node = node->next) {
150 usb = node->data;
151
43db3436
DE
152 /* Create sigrok device instance. */
153 sdi = dev_inst_new(device_index);
5874e88d 154 if (!sdi) {
5874e88d
DE
155 sr_usb_dev_inst_free(usb);
156 continue;
157 }
158 sdi->driver = di;
5874e88d
DE
159 sdi->inst_type = SR_INST_USB;
160 sdi->conn = usb;
5874e88d 161
43db3436 162 /* Register device instance with driver. */
5874e88d
DE
163 drvc->instances = g_slist_append(drvc->instances, sdi);
164 devices = g_slist_append(devices, sdi);
165 }
aeaad0b0 166
5874e88d 167 g_slist_free(usb_devices);
aeaad0b0
DE
168
169 return devices;
170}
171
172static GSList *dev_list(void)
173{
5874e88d
DE
174 struct drv_context *drvc;
175
176 drvc = di->priv;
177
178 return drvc->instances;
179}
180
181static void clear_dev_context(void *priv)
182{
183 struct dev_context *devc;
184
185 devc = priv;
186
187 sr_dbg("Device context cleared.");
188
189 lwla_free_acquisition_state(devc->acquisition);
190 g_free(devc);
aeaad0b0
DE
191}
192
193static int dev_clear(void)
194{
5874e88d 195 return std_dev_clear(di, &clear_dev_context);
aeaad0b0
DE
196}
197
198static int dev_open(struct sr_dev_inst *sdi)
199{
5874e88d 200 struct drv_context *drvc;
5874e88d
DE
201 struct sr_usb_dev_inst *usb;
202 int ret;
aeaad0b0 203
5874e88d 204 drvc = di->priv;
aeaad0b0 205
5874e88d
DE
206 if (!drvc) {
207 sr_err("Driver was not initialized.");
208 return SR_ERR;
209 }
aeaad0b0 210
43db3436 211 usb = sdi->conn;
5874e88d
DE
212
213 ret = sr_usb_open(drvc->sr_ctx->libusb_ctx, usb);
214 if (ret != SR_OK)
215 return ret;
216
217 ret = libusb_claim_interface(usb->devhdl, USB_INTERFACE);
218 if (ret < 0) {
219 sr_err("Failed to claim interface: %s.",
220 libusb_error_name(ret));
221 return SR_ERR;
222 }
223
224 sdi->status = SR_ST_INITIALIZING;
225
5874e88d
DE
226 ret = lwla_init_device(sdi);
227
228 if (ret == SR_OK)
229 sdi->status = SR_ST_ACTIVE;
230
231 return ret;
aeaad0b0
DE
232}
233
234static int dev_close(struct sr_dev_inst *sdi)
235{
5874e88d
DE
236 struct sr_usb_dev_inst *usb;
237 struct dev_context *devc;
238
239 if (!di->priv) {
240 sr_err("Driver was not initialized.");
241 return SR_ERR;
242 }
243
244 usb = sdi->conn;
245 devc = sdi->priv;
aeaad0b0 246
5874e88d
DE
247 if (!usb->devhdl)
248 return SR_OK;
aeaad0b0 249
5874e88d
DE
250 /* Trigger download of the shutdown bitstream. */
251 devc->selected_clock_source = CLOCK_SOURCE_NONE;
252
253 if (lwla_set_clock_source(sdi) != SR_OK)
254 sr_err("Unable to shut down device.");
255
256 libusb_release_interface(usb->devhdl, USB_INTERFACE);
257 libusb_close(usb->devhdl);
258
259 usb->devhdl = NULL;
aeaad0b0
DE
260 sdi->status = SR_ST_INACTIVE;
261
262 return SR_OK;
263}
264
265static int cleanup(void)
266{
5874e88d 267 return dev_clear();
aeaad0b0
DE
268}
269
270static int config_get(int key, GVariant **data, const struct sr_dev_inst *sdi,
5874e88d 271 const struct sr_probe_group *probe_group)
aeaad0b0 272{
5874e88d 273 struct dev_context *devc;
e6e54bd2 274 size_t idx;
aeaad0b0 275
aeaad0b0
DE
276 (void)probe_group;
277
5874e88d
DE
278 if (!sdi)
279 return SR_ERR_ARG;
280
281 devc = sdi->priv;
282
aeaad0b0 283 switch (key) {
5874e88d
DE
284 case SR_CONF_SAMPLERATE:
285 *data = g_variant_new_uint64(devc->samplerate);
286 break;
29d58767
DE
287 case SR_CONF_LIMIT_MSEC:
288 *data = g_variant_new_uint64(devc->limit_msec);
289 break;
5874e88d
DE
290 case SR_CONF_LIMIT_SAMPLES:
291 *data = g_variant_new_uint64(devc->limit_samples);
292 break;
293 case SR_CONF_EXTERNAL_CLOCK:
294 *data = g_variant_new_boolean(devc->selected_clock_source
295 >= CLOCK_SOURCE_EXT_RISE);
296 break;
e6e54bd2
DE
297 case SR_CONF_TRIGGER_SOURCE:
298 idx = devc->cfg_trigger_source;
299 if (idx >= G_N_ELEMENTS(trigger_source_names))
300 return SR_ERR_BUG;
301 *data = g_variant_new_string(trigger_source_names[idx]);
302 break;
303 case SR_CONF_TRIGGER_SLOPE:
304 idx = devc->cfg_trigger_slope;
305 if (idx >= G_N_ELEMENTS(trigger_slope_names))
306 return SR_ERR_BUG;
307 *data = g_variant_new_string(trigger_slope_names[idx]);
308 break;
aeaad0b0
DE
309 default:
310 return SR_ERR_NA;
311 }
312
5874e88d 313 return SR_OK;
aeaad0b0
DE
314}
315
e6e54bd2
DE
316/* Helper for mapping a string-typed configuration value to an index
317 * within a table of possible values.
318 */
319static int lookup_index(GVariant *value, const char *const *table, int len)
320{
321 const char *entry;
322 int i;
323
324 entry = g_variant_get_string(value, NULL);
325 if (!entry)
326 return -1;
327
328 /* Linear search is fine for very small tables. */
329 for (i = 0; i < len; ++i) {
330 if (strcmp(entry, table[i]) == 0)
331 return i;
332 }
333 return -1;
334}
335
aeaad0b0 336static int config_set(int key, GVariant *data, const struct sr_dev_inst *sdi,
5874e88d 337 const struct sr_probe_group *probe_group)
aeaad0b0 338{
29d58767 339 uint64_t value;
5874e88d 340 struct dev_context *devc;
e6e54bd2 341 int idx;
aeaad0b0 342
aeaad0b0
DE
343 (void)probe_group;
344
5874e88d
DE
345 devc = sdi->priv;
346 if (!devc)
aeaad0b0
DE
347 return SR_ERR_DEV_CLOSED;
348
aeaad0b0 349 switch (key) {
5874e88d 350 case SR_CONF_SAMPLERATE:
29d58767 351 value = g_variant_get_uint64(data);
29d58767
DE
352 if (value < samplerates[G_N_ELEMENTS(samplerates) - 1]
353 || value > samplerates[0])
5874e88d 354 return SR_ERR_SAMPLERATE;
29d58767
DE
355 devc->samplerate = value;
356 break;
357 case SR_CONF_LIMIT_MSEC:
358 value = g_variant_get_uint64(data);
359 if (value > MAX_LIMIT_MSEC)
360 return SR_ERR_ARG;
361 devc->limit_msec = value;
5874e88d
DE
362 break;
363 case SR_CONF_LIMIT_SAMPLES:
29d58767
DE
364 value = g_variant_get_uint64(data);
365 if (value > MAX_LIMIT_SAMPLES)
366 return SR_ERR_ARG;
367 devc->limit_samples = value;
5874e88d
DE
368 break;
369 case SR_CONF_EXTERNAL_CLOCK:
370 if (g_variant_get_boolean(data)) {
371 sr_info("Enabling external clock.");
372 /* TODO: Allow the external clock to be inverted */
373 devc->selected_clock_source = CLOCK_SOURCE_EXT_RISE;
374 } else {
375 sr_info("Disabling external clock.");
376 devc->selected_clock_source = CLOCK_SOURCE_INT;
377 }
5874e88d 378 break;
e6e54bd2
DE
379 case SR_CONF_TRIGGER_SOURCE:
380 idx = lookup_index(data, trigger_source_names,
381 G_N_ELEMENTS(trigger_source_names));
382 if (idx < 0)
383 return SR_ERR_ARG;
384 devc->cfg_trigger_source = idx;
385 break;
386 case SR_CONF_TRIGGER_SLOPE:
387 idx = lookup_index(data, trigger_slope_names,
388 G_N_ELEMENTS(trigger_slope_names));
389 if (idx < 0)
390 return SR_ERR_ARG;
391 devc->cfg_trigger_slope = idx;
392 break;
aeaad0b0 393 default:
5874e88d 394 return SR_ERR_NA;
aeaad0b0
DE
395 }
396
5874e88d 397 return SR_OK;
aeaad0b0
DE
398}
399
43db3436
DE
400static int config_probe_set(const struct sr_dev_inst *sdi,
401 struct sr_probe *probe, unsigned int changes)
402{
403 uint64_t probe_bit;
404 uint64_t trigger_mask;
405 uint64_t trigger_values;
406 uint64_t trigger_edge_mask;
407 struct dev_context *devc;
408
409 devc = sdi->priv;
410 if (!devc)
411 return SR_ERR_DEV_CLOSED;
412
413 if (probe->index < 0 || probe->index >= NUM_PROBES) {
414 sr_err("Probe index %d out of range.", probe->index);
415 return SR_ERR_BUG;
416 }
417 probe_bit = (uint64_t)1 << probe->index;
418
419 if ((changes & SR_PROBE_SET_ENABLED) != 0) {
420 /* Enable or disable input channel for this probe. */
421 if (probe->enabled)
422 devc->channel_mask |= probe_bit;
423 else
424 devc->channel_mask &= ~probe_bit;
425 }
426
427 if ((changes & SR_PROBE_SET_TRIGGER) != 0) {
428 trigger_mask = devc->trigger_mask & ~probe_bit;
429 trigger_values = devc->trigger_values & ~probe_bit;
430 trigger_edge_mask = devc->trigger_edge_mask & ~probe_bit;
431
432 if (probe->trigger && probe->trigger[0] != '\0') {
433 if (probe->trigger[1] != '\0') {
434 sr_warn("Trigger configuration \"%s\" with "
435 "multiple stages is not supported.",
436 probe->trigger);
437 return SR_ERR_ARG;
438 }
439 /* Enable trigger for this probe. */
440 trigger_mask |= probe_bit;
441
442 /* Configure edge mask and trigger value. */
443 switch (probe->trigger[0]) {
444 case '1': trigger_values |= probe_bit;
445 case '0': break;
446
447 case 'r': trigger_values |= probe_bit;
448 case 'f': trigger_edge_mask |= probe_bit;
449 break;
450 default:
451 sr_warn("Trigger type '%c' is not supported.",
452 probe->trigger[0]);
453 return SR_ERR_ARG;
454 }
455 }
456 /* Store validated trigger setup. */
457 devc->trigger_mask = trigger_mask;
458 devc->trigger_values = trigger_values;
459 devc->trigger_edge_mask = trigger_edge_mask;
460 }
461
462 return SR_OK;
463}
464
ee38c8ba
DE
465static int config_commit(const struct sr_dev_inst *sdi)
466{
467 if (sdi->status != SR_ST_ACTIVE) {
468 sr_err("Device not ready (status %d).", (int)sdi->status);
469 return SR_ERR;
470 }
471
472 return lwla_set_clock_source(sdi);
473}
474
aeaad0b0 475static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
5874e88d 476 const struct sr_probe_group *probe_group)
aeaad0b0 477{
5874e88d
DE
478 GVariant *gvar;
479 GVariantBuilder gvb;
aeaad0b0
DE
480
481 (void)sdi;
aeaad0b0
DE
482 (void)probe_group;
483
aeaad0b0 484 switch (key) {
99c76642
DE
485 case SR_CONF_SCAN_OPTIONS:
486 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
487 hwopts, G_N_ELEMENTS(hwopts), sizeof(int32_t));
488 break;
5874e88d
DE
489 case SR_CONF_DEVICE_OPTIONS:
490 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
99c76642 491 hwcaps, G_N_ELEMENTS(hwcaps), sizeof(int32_t));
5874e88d
DE
492 break;
493 case SR_CONF_SAMPLERATE:
494 g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}"));
495 gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"),
99c76642 496 samplerates, G_N_ELEMENTS(samplerates),
5874e88d
DE
497 sizeof(uint64_t));
498 g_variant_builder_add(&gvb, "{sv}", "samplerates", gvar);
499 *data = g_variant_builder_end(&gvb);
500 break;
501 case SR_CONF_TRIGGER_TYPE:
502 *data = g_variant_new_string(TRIGGER_TYPES);
503 break;
e6e54bd2
DE
504 case SR_CONF_TRIGGER_SOURCE:
505 *data = g_variant_new_strv(trigger_source_names,
506 G_N_ELEMENTS(trigger_source_names));
507 break;
508 case SR_CONF_TRIGGER_SLOPE:
509 *data = g_variant_new_strv(trigger_slope_names,
510 G_N_ELEMENTS(trigger_slope_names));
511 break;
aeaad0b0
DE
512 default:
513 return SR_ERR_NA;
514 }
515
5874e88d 516 return SR_OK;
aeaad0b0
DE
517}
518
5874e88d
DE
519static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
520{
521 struct drv_context *drvc;
522 struct dev_context *devc;
523 struct acquisition_state *acq;
524 int ret;
525
aeaad0b0
DE
526 (void)cb_data;
527
528 if (sdi->status != SR_ST_ACTIVE)
529 return SR_ERR_DEV_CLOSED;
530
5874e88d
DE
531 devc = sdi->priv;
532 drvc = di->priv;
533
534 if (devc->acquisition) {
535 sr_err("Acquisition still in progress?");
536 return SR_ERR;
537 }
538 acq = lwla_alloc_acquisition_state();
539 if (!acq)
540 return SR_ERR_MALLOC;
541
542 devc->stopping_in_progress = FALSE;
543 devc->transfer_error = FALSE;
544
5874e88d
DE
545 sr_info("Starting acquisition.");
546
547 devc->acquisition = acq;
548 ret = lwla_setup_acquisition(sdi);
549 if (ret != SR_OK) {
550 sr_err("Failed to set up aquisition.");
551 devc->acquisition = NULL;
552 lwla_free_acquisition_state(acq);
553 return ret;
554 }
555
556 ret = lwla_start_acquisition(sdi);
557 if (ret != SR_OK) {
558 sr_err("Failed to start aquisition.");
559 devc->acquisition = NULL;
560 lwla_free_acquisition_state(acq);
561 return ret;
562 }
563 usb_source_add(drvc->sr_ctx, 100, &lwla_receive_data,
564 (struct sr_dev_inst *)sdi);
565
566 sr_info("Waiting for data.");
567
568 /* Send header packet to the session bus. */
569 std_session_send_df_header(sdi, LOG_PREFIX);
aeaad0b0
DE
570
571 return SR_OK;
572}
573
574static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
575{
576 (void)cb_data;
577
578 if (sdi->status != SR_ST_ACTIVE)
579 return SR_ERR_DEV_CLOSED;
580
5874e88d
DE
581 sr_dbg("Stopping acquisition.");
582
583 sdi->status = SR_ST_STOPPING;
aeaad0b0
DE
584
585 return SR_OK;
586}
587
588SR_PRIV struct sr_dev_driver sysclk_lwla_driver_info = {
589 .name = "sysclk-lwla",
5874e88d 590 .longname = "SysClk LWLA series",
aeaad0b0
DE
591 .api_version = 1,
592 .init = init,
593 .cleanup = cleanup,
594 .scan = scan,
595 .dev_list = dev_list,
596 .dev_clear = dev_clear,
597 .config_get = config_get,
598 .config_set = config_set,
43db3436 599 .config_probe_set = config_probe_set,
ee38c8ba 600 .config_commit = config_commit,
aeaad0b0
DE
601 .config_list = config_list,
602 .dev_open = dev_open,
603 .dev_close = dev_close,
604 .dev_acquisition_start = dev_acquisition_start,
605 .dev_acquisition_stop = dev_acquisition_stop,
606 .priv = NULL,
607};