]> sigrok.org Git - libsigrok.git/blob - hardware/link-mso19/api.c
Eveything seems to work now except for triggers.
[libsigrok.git] / hardware / link-mso19 / api.c
1 /*
2  * This file is part of the sigrok project.
3  *
4  * Copyright (C) 2010-2012 Bert Vermeulen <bert@biot.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
22 static const int hwcaps[] = {
23         SR_HWCAP_LOGIC_ANALYZER,
24         SR_HWCAP_SAMPLERATE,
25 //      SR_HWCAP_CAPTURE_RATIO,
26         SR_HWCAP_LIMIT_SAMPLES,
27 //      SR_HWCAP_RLE,
28         0,
29 };
30
31 /*
32  * Probes are numbered 0 to 7.
33  *
34  * See also: http://www.linkinstruments.com/images/mso19_1113.gif
35  */
36 SR_PRIV const char *mso19_probe_names[NUM_PROBES + 1] = {
37         "0", "1", "2", "3", "4", "5", "6", "7", NULL
38 };
39
40 /*supported samplerates */
41 static const struct sr_samplerates samplerates = {
42         SR_HZ(100),
43         SR_MHZ(200),
44         SR_HZ(100),
45         NULL,
46 };
47
48 SR_PRIV struct sr_dev_driver link_mso19_driver_info;
49 static struct sr_dev_driver *di = &link_mso19_driver_info;
50
51 static int hw_init(struct sr_context *sr_ctx)
52 {
53         struct drv_context *drvc;
54
55         if (!(drvc = g_try_malloc0(sizeof(struct drv_context)))) {
56                 sr_err("Driver context malloc failed.");
57                 return SR_ERR_MALLOC;
58         }
59         drvc->sr_ctx = sr_ctx;
60         di->priv = drvc;
61
62         return SR_OK;
63 }
64
65 static GSList *hw_scan(GSList *options)
66 {
67   int i;
68
69         (void)options;
70         GSList *devices = NULL;
71
72         const char* conn = NULL;
73   const char* serialcomm = NULL;
74   GSList *l;
75         for (l = options; l; l = l->next) {
76                 struct sr_hwopt* opt = l->data;
77                 switch (opt->hwopt) {
78                 case SR_HWOPT_CONN:
79                         conn = opt->value;
80                         break;
81                 case SR_HWOPT_SERIALCOMM:
82                         serialcomm = opt->value;
83                         break;
84                 }
85         }
86         if (!conn)
87     conn = SERIALCONN;
88         if (serialcomm == NULL)
89                 serialcomm = SERIALCOMM;
90
91         struct udev *udev = udev_new();
92         if (!udev) {
93                 sr_err("Failed to initialize udev.");
94         }
95         struct udev_enumerate *enumerate = udev_enumerate_new(udev);
96         udev_enumerate_add_match_subsystem(enumerate, "usb-serial");
97         udev_enumerate_scan_devices(enumerate);
98         struct udev_list_entry *devs = udev_enumerate_get_list_entry(enumerate);
99         struct udev_list_entry *dev_list_entry;
100   for (dev_list_entry = devs; 
101       dev_list_entry != NULL; 
102       dev_list_entry = udev_list_entry_get_next(dev_list_entry))
103   {
104                 const char *syspath = udev_list_entry_get_name(dev_list_entry);
105                 struct udev_device *dev = udev_device_new_from_syspath(udev, syspath);
106                 const char *sysname = udev_device_get_sysname(dev);
107                 struct udev_device *parent = udev_device_get_parent_with_subsystem_devtype(
108         dev, "usb", "usb_device");
109
110                 if (!parent) {
111                         sr_err("Unable to find parent usb device for %s",
112                                sysname);
113                         continue;
114                 }
115
116                 const char *idVendor = udev_device_get_sysattr_value(parent, "idVendor");
117                 const char *idProduct = udev_device_get_sysattr_value(parent, "idProduct");
118                 if (strcmp(USB_VENDOR, idVendor)
119                                 || strcmp(USB_PRODUCT, idProduct))
120                         continue;
121
122                 const char* iSerial = udev_device_get_sysattr_value(parent, "serial");
123                 const char* iProduct = udev_device_get_sysattr_value(parent, "product");
124
125     char path[32];
126                 snprintf(path, sizeof(path), "/dev/%s", sysname);
127     conn = path;
128
129                 size_t s = strcspn(iProduct, " ");
130     char product[32];
131     char manufacturer[32];
132                 if (s > sizeof(product) ||
133                                 strlen(iProduct) - s > sizeof(manufacturer)) {
134       sr_err("Could not parse iProduct: %s.", iProduct);
135                         continue;
136                 }
137                 strncpy(product, iProduct, s);
138                 product[s] = 0;
139                 strcpy(manufacturer, iProduct + s + 1);
140     
141     //Create the device context and set its params
142     struct dev_context *devc;
143     if (!(devc = g_try_malloc0(sizeof(struct dev_context)))) {
144       sr_err("Device context malloc failed.");
145       return devices;
146     }
147
148     if (mso_parse_serial(iSerial, iProduct, devc) != SR_OK) {
149       sr_err("Invalid iSerial: %s.", iSerial);
150       g_free(devc);
151       return devices;
152     }
153     
154     char hwrev[32];
155     sprintf(hwrev, "r%d", devc->hwrev);
156     devc->ctlbase1 = 0;
157     devc->protocol_trigger.spimode = 0;
158     for (i = 0; i < 4; i++) {
159       devc->protocol_trigger.word[i] = 0;
160       devc->protocol_trigger.mask[i] = 0xff;
161     }
162
163     if (!(devc->serial = sr_serial_dev_inst_new(conn, serialcomm)))
164     {
165       g_free(devc);
166       return devices;
167     }
168
169     struct sr_dev_inst *sdi = sr_dev_inst_new(0, SR_ST_INACTIVE,
170         manufacturer, product, hwrev);
171
172     if (!sdi) {
173       sr_err("Unable to create device instance for %s",
174           sysname);
175       sr_dev_inst_free(sdi);
176       g_free(devc);
177       return devices;
178     }
179     
180     sdi->driver = di;
181     sdi->priv = devc;
182
183     for (i = 0; i < NUM_PROBES; i++) { 
184       struct sr_probe *probe;
185       if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, 
186               mso19_probe_names[i]))) 
187         return 0; 
188       sdi->probes = g_slist_append(sdi->probes, probe); 
189     }
190
191     //Add the driver
192     struct drv_context *drvc = di->priv;
193     drvc->instances = g_slist_append(drvc->instances, sdi);
194     devices = g_slist_append(devices, sdi);
195   }
196
197         return devices;
198 }
199
200 static GSList *hw_dev_list(void)
201 {
202         struct drv_context *drvc;
203
204         drvc = di->priv;
205
206         return drvc->instances;
207 }
208
209 static int hw_dev_open(struct sr_dev_inst *sdi)
210 {
211         struct dev_context *devc;
212
213         devc = sdi->priv;
214
215         if (serial_open(devc->serial, SERIAL_RDWR) != SR_OK)
216                 return SR_ERR;
217
218         sdi->status = SR_ST_ACTIVE;
219
220         /* FIXME: discard serial buffer */
221         mso_check_trigger(devc->serial, &devc->trigger_state);
222         sr_dbg("Trigger state: 0x%x.", devc->trigger_state);
223
224         int ret = mso_reset_adc(sdi);
225         if (ret != SR_OK)
226                 return ret;
227
228         mso_check_trigger(devc->serial, &devc->trigger_state);
229         sr_dbg("Trigger state: 0x%x.", devc->trigger_state);
230
231   //    ret = mso_reset_fsm(sdi);
232   //    if (ret != SR_OK)
233   //            return ret;
234   //    return SR_ERR;
235
236         return SR_OK;
237 }
238
239 static int hw_dev_close(struct sr_dev_inst *sdi)
240 {
241   printf("dev close\n");
242         struct dev_context *devc;
243
244         devc = sdi->priv;
245
246         if (devc->serial && devc->serial->fd != -1) {
247                 serial_close(devc->serial);
248                 sdi->status = SR_ST_INACTIVE;
249         }
250
251         return SR_OK;
252 }
253
254 static int hw_cleanup(void)
255 {
256         GSList *l;
257         struct sr_dev_inst *sdi;
258         struct drv_context *drvc;
259         struct dev_context *devc;
260         int ret = SR_OK;
261
262         if (!(drvc = di->priv))
263                 return SR_OK;
264
265         /* Properly close and free all devices. */
266         for (l = drvc->instances; l; l = l->next) {
267                 if (!(sdi = l->data)) {
268                         /* Log error, but continue cleaning up the rest. */
269                         sr_err("%s: sdi was NULL, continuing", __func__);
270                         ret = SR_ERR_BUG;
271                         continue;
272                 }
273                 if (!(devc = sdi->priv)) {
274                         /* Log error, but continue cleaning up the rest. */
275                         sr_err("%s: sdi->priv was NULL, continuing", __func__);
276                         ret = SR_ERR_BUG;
277                         continue;
278                 }
279                 hw_dev_close(sdi);
280                 sr_serial_dev_inst_free(devc->serial);
281                 sr_dev_inst_free(sdi);
282         }
283         g_slist_free(drvc->instances);
284         drvc->instances = NULL;
285
286         return ret;
287 }
288
289 static int hw_info_get(int info_id, const void **data,
290        const struct sr_dev_inst *sdi)
291 {
292         struct dev_context *devc;
293
294         switch (info_id) {
295         case SR_DI_HWCAPS:
296                 *data = hwcaps;
297                 break;
298         case SR_DI_NUM_PROBES:
299                 *data = GINT_TO_POINTER(1);
300                 break;
301         case SR_DI_PROBE_NAMES:
302                 *data = mso19_probe_names;
303                 break;
304         case SR_DI_SAMPLERATES:
305                 *data = &samplerates;
306                 break;
307         case SR_DI_TRIGGER_TYPES:
308                 *data = (char *)TRIGGER_TYPES;
309                 break;
310         case SR_DI_CUR_SAMPLERATE:
311                 if (sdi) {
312                         devc = sdi->priv;
313                         *data = &devc->cur_rate;
314                 } else
315                         return SR_ERR;
316                 break;
317         default:
318                 return SR_ERR_ARG;
319         }
320
321         return SR_OK;
322 }
323
324 static int hw_dev_config_set(const struct sr_dev_inst *sdi, int hwcap,
325                 const void *value)
326 {
327         int ret;
328
329         if (sdi->status != SR_ST_ACTIVE)
330                 return SR_ERR;
331
332         switch (hwcap) {
333         case SR_HWCAP_SAMPLERATE:
334                 return mso_configure_rate(sdi, *(const uint64_t *) value);
335                 ret = SR_OK;
336                 break;
337         case SR_HWCAP_LIMIT_SAMPLES:
338                 ret = SR_OK;
339                 break;
340   case SR_HWCAP_CAPTURE_RATIO:
341     ret = SR_OK;
342                 break;
343         case SR_HWCAP_RLE:
344     ret = SR_OK;
345                 break;
346         default:
347                 ret = SR_ERR;
348         }
349
350         return ret;
351 }
352
353 static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi,
354                 void *cb_data)
355 {
356         struct sr_datafeed_packet *packet;
357         struct sr_datafeed_header *header;
358         struct sr_datafeed_meta_logic meta;
359         struct dev_context *devc;
360         int ret = SR_ERR;
361   
362   
363   printf("Accquistion start\n");
364         devc = sdi->priv;
365
366         if (sdi->status != SR_ST_ACTIVE)
367                 return SR_ERR;
368
369         if (mso_configure_probes(sdi) != SR_OK) {
370                 sr_err("Failed to configure probes.");
371                 return SR_ERR;
372         }
373
374         /*
375          * Enable/disable channel groups in the flag register according to the
376          * probe mask. Calculate this here, because num_channels is needed
377          * to limit readcount.
378          */
379         //changrp_mask = 0;
380         //num_channels = 0;
381         //for (i = 0; i < 4; i++) {
382         //      if (devc->probe_mask & (0xff << (i * 8))) {
383         //              changrp_mask |= (1 << i);
384         //              num_channels++;
385         //      }
386         //}
387
388         /* FIXME: No need to do full reconfigure every time */
389 //      ret = mso_reset_fsm(sdi);
390 //      if (ret != SR_OK)
391 //              return ret;
392
393         /* FIXME: ACDC Mode */
394         devc->ctlbase1 &= 0x7f;
395 //      devc->ctlbase1 |= devc->acdcmode;
396
397   printf("Configure rate\n");
398         ret = mso_configure_rate(sdi, devc->cur_rate);
399         if (ret != SR_OK)
400                 return ret;
401
402         /* set dac offset */
403   printf("Configure dac\n");
404         ret = mso_dac_out(sdi, devc->dac_offset);
405         if (ret != SR_OK)
406                 return ret;
407
408   printf("Configure threshold level\n");
409         ret = mso_configure_threshold_level(sdi);
410         if (ret != SR_OK)
411                 return ret;
412
413   printf("Configure trigger\n");
414         ret = mso_configure_trigger(sdi);
415         if (ret != SR_OK)
416                 return ret;
417
418         /* FIXME: trigger_position */
419
420
421         /* END of config hardware part */
422
423         /* with trigger */
424   printf("arm\n");
425         ret = mso_arm(sdi);
426         if (ret != SR_OK)
427                 return ret;
428
429         /* without trigger */
430 //      ret = mso_force_capture(sdi);
431 //      if (ret != SR_OK)
432 //              return ret;
433
434         /* Start acquisition on the device. */
435   printf("Check trigger\n");
436         mso_check_trigger(devc->serial, &devc->trigger_state);
437         ret = mso_check_trigger(devc->serial, NULL);
438         if (ret != SR_OK)
439                 return ret;
440
441   printf("Source add\n");
442   sr_source_add(devc->serial->fd, G_IO_IN, -1, mso_receive_data, cb_data);
443
444   printf("Create packet\n");
445         if (!(packet = g_try_malloc(sizeof(struct sr_datafeed_packet)))) {
446                 sr_err("Datafeed packet malloc failed.");
447                 return SR_ERR_MALLOC;
448         }
449
450         if (!(header = g_try_malloc(sizeof(struct sr_datafeed_header)))) {
451                 sr_err("Datafeed header malloc failed.");
452                 g_free(packet);
453                 return SR_ERR_MALLOC;
454         }
455
456         packet->type = SR_DF_HEADER;
457         packet->payload = (unsigned char *)header;
458         header->feed_version = 1;
459         gettimeofday(&header->starttime, NULL);
460         sr_session_send(cb_data, packet);
461
462         packet->type = SR_DF_META_LOGIC;
463         packet->payload = &meta;
464         meta.samplerate = devc->cur_rate;
465         meta.num_probes = NUM_PROBES;
466         sr_session_send(cb_data, packet);
467   
468         g_free(header);
469         g_free(packet);
470
471         return SR_OK;
472 }
473
474 /* TODO: This stops acquisition on ALL devices, ignoring dev_index. */
475 static int hw_dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
476 {
477         /* Avoid compiler warnings. */
478         (void)cb_data;
479
480         stop_acquisition(sdi);
481
482         return SR_OK;
483 }
484
485 SR_PRIV struct sr_dev_driver link_mso19_driver_info = {
486         .name = "link-mso19",
487         .longname = "Link Instruments MSO-19",
488         .api_version = 1,
489         .init = hw_init,
490         .cleanup = hw_cleanup,
491         .scan = hw_scan,
492         .dev_list = hw_dev_list,
493         .dev_clear = hw_cleanup,
494         .dev_open = hw_dev_open,
495         .dev_close = hw_dev_close,
496         .info_get = hw_info_get,
497         .dev_config_set = hw_dev_config_set,
498         .dev_acquisition_start = hw_dev_acquisition_start,
499         .dev_acquisition_stop = hw_dev_acquisition_stop,
500         .priv = NULL,
501 };