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