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