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