]> sigrok.org Git - libsigrok.git/blob - src/hardware/ftdi-la/api.c
output/csv: use intermediate time_t var, silence compiler warning
[libsigrok.git] / src / hardware / ftdi-la / api.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2015 Sergey Alirzaev <zl29ah@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 <ftdi.h>
22 #include <libusb.h>
23 #include <libsigrok/libsigrok.h>
24 #include "libsigrok-internal.h"
25 #include "protocol.h"
26
27 static const uint32_t scanopts[] = {
28         SR_CONF_CONN,
29 };
30
31 static const uint32_t drvopts[] = {
32         SR_CONF_LOGIC_ANALYZER,
33 };
34
35 static const uint32_t devopts[] = {
36         SR_CONF_CONTINUOUS,
37         SR_CONF_LIMIT_SAMPLES | SR_CONF_SET,
38         SR_CONF_SAMPLERATE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
39         SR_CONF_CONN | SR_CONF_GET,
40 };
41
42 static const uint64_t samplerates[] = {
43         SR_HZ(3600),
44         SR_MHZ(10),
45         SR_HZ(1),
46 };
47
48 static const struct ftdi_chip_desc ft2232h_desc = {
49         .vendor = 0x0403,
50         .product = 0x6010,
51         .samplerate_div = 20,
52         .channel_names = {
53                 "ADBUS0", "ADBUS1", "ADBUS2", "ADBUS3",
54                 "ADBUS4", "ADBUS5", "ADBUS6", "ADBUS7",
55                 /* TODO: BDBUS[0..7] channels. */
56                 NULL
57         }
58 };
59
60 static const struct ftdi_chip_desc ft2232h_tumpa_desc = {
61         .vendor = 0x0403,
62         .product = 0x8a98,
63         .samplerate_div = 20,
64         /* 20 pin JTAG header */
65         .channel_names = {
66                 "TCK", "TDI", "TDO", "TMS", "RST", "nTRST", "DBGRQ", "RTCK",
67                 NULL
68         }
69 };
70
71 static const struct ftdi_chip_desc ft4232h_desc = {
72         .vendor = 0x0403,
73         .product = 0x6011,
74         .samplerate_div = 20,
75         .channel_names = {
76                 "ADBUS0", "ADBUS1", "ADBUS2", "ADBUS3", "ADBUS4", "ADBUS5", "ADBUS6", "ADBUS7",
77                 /* TODO: BDBUS[0..7], CDBUS[0..7], DDBUS[0..7] channels. */
78                 NULL
79         }
80 };
81
82 static const struct ftdi_chip_desc ft232r_desc = {
83         .vendor = 0x0403,
84         .product = 0x6001,
85         .samplerate_div = 30,
86         .channel_names = {
87                 "TXD", "RXD", "RTS#", "CTS#", "DTR#", "DSR#", "DCD#", "RI#",
88                 NULL
89         }
90 };
91
92 static const struct ftdi_chip_desc ft232h_desc = {
93         .vendor = 0x0403,
94         .product = 0x6014,
95         .samplerate_div = 30,
96         .channel_names = {
97                 "ADBUS0", "ADBUS1", "ADBUS2", "ADBUS3", "ADBUS4", "ADBUS5", "ADBUS6", "ADBUS7",
98                 NULL
99         }
100 };
101
102 static const struct ftdi_chip_desc *chip_descs[] = {
103         &ft2232h_desc,
104         &ft2232h_tumpa_desc,
105         &ft4232h_desc,
106         &ft232r_desc,
107         &ft232h_desc,
108         NULL,
109 };
110
111 static void scan_device(struct ftdi_context *ftdic,
112         struct libusb_device *dev, GSList **devices)
113 {
114         static const int usb_str_maxlen = 32;
115
116         struct libusb_device_descriptor usb_desc;
117         const struct ftdi_chip_desc *desc;
118         struct dev_context *devc;
119         char *vendor, *model, *serial_num;
120         struct sr_dev_inst *sdi;
121         int rv;
122
123         libusb_get_device_descriptor(dev, &usb_desc);
124
125         desc = NULL;
126         for (unsigned long i = 0; i < ARRAY_SIZE(chip_descs); i++) {
127                 desc = chip_descs[i];
128                 if (!desc)
129                         break;
130                 if (desc->vendor == usb_desc.idVendor &&
131                         desc->product == usb_desc.idProduct)
132                         break;
133         }
134
135         if (!desc) {
136                 sr_spew("Unsupported FTDI device 0x%04x:0x%04x.",
137                         usb_desc.idVendor, usb_desc.idProduct);
138                 return;
139         }
140
141         devc = g_malloc0(sizeof(struct dev_context));
142
143         /* Allocate memory for the incoming data. */
144         devc->data_buf = g_malloc0(DATA_BUF_SIZE);
145
146         devc->desc = desc;
147
148         vendor = g_malloc(usb_str_maxlen);
149         model = g_malloc(usb_str_maxlen);
150         serial_num = g_malloc(usb_str_maxlen);
151         rv = ftdi_usb_get_strings(ftdic, dev, vendor, usb_str_maxlen,
152                         model, usb_str_maxlen, serial_num, usb_str_maxlen);
153         switch (rv) {
154         case 0:
155                 break;
156         /* ftdi_usb_get_strings() fails on first miss, hence fall through. */
157         case -7:
158                 sr_dbg("The device lacks a manufacturer descriptor.");
159                 g_snprintf(vendor, usb_str_maxlen, "Generic");
160                 /* FALLTHROUGH */
161         case -8:
162                 sr_dbg("The device lacks a product descriptor.");
163                 switch (usb_desc.idProduct) {
164                 case 0x6001:
165                         g_snprintf(model, usb_str_maxlen, "FT232R");
166                         break;
167                 case 0x6010:
168                         g_snprintf(model, usb_str_maxlen, "FT2232H");
169                         break;
170                 case 0x6011:
171                         g_snprintf(model, usb_str_maxlen, "FT4232H");
172                         break;
173                 case 0x6014:
174                         g_snprintf(model, usb_str_maxlen, "FT232H");
175                         break;
176                 case 0x8a98:
177                         g_snprintf(model, usb_str_maxlen, "FT2232H-TUMPA");
178                         break;
179                 default:
180                         g_snprintf(model, usb_str_maxlen, "Unknown");
181                         break;
182                 }
183                 /* FALLTHROUGH */
184         case -9:
185                 sr_dbg("The device lacks a serial number.");
186                 g_free(serial_num);
187                 serial_num = NULL;
188                 break;
189         default:
190                 sr_err("Failed to get the FTDI strings: %d", rv);
191                 goto err_free_strings;
192         }
193         sr_dbg("Found an FTDI device: %s.", model);
194
195         sdi = g_malloc0(sizeof(struct sr_dev_inst));
196         sdi->status = SR_ST_INACTIVE;
197         sdi->vendor = vendor;
198         sdi->model = model;
199         sdi->serial_num = serial_num;
200         sdi->priv = devc;
201         sdi->connection_id = g_strdup_printf("d:%u/%u",
202                 libusb_get_bus_number(dev), libusb_get_device_address(dev));
203
204         for (char *const *chan = &(desc->channel_names[0]); *chan; chan++)
205                 sr_channel_new(sdi, chan - &(desc->channel_names[0]),
206                                 SR_CHANNEL_LOGIC, TRUE, *chan);
207
208         *devices = g_slist_append(*devices, sdi);
209         return;
210
211 err_free_strings:
212         g_free(vendor);
213         g_free(model);
214         g_free(serial_num);
215         g_free(devc->data_buf);
216         g_free(devc);
217 }
218
219 static GSList *scan_all(struct ftdi_context *ftdic, GSList *options)
220 {
221         GSList *devices;
222         struct ftdi_device_list *devlist = 0;
223         struct ftdi_device_list *curdev;
224         int ret;
225
226         (void)options;
227
228         devices = NULL;
229
230         ret = ftdi_usb_find_all(ftdic, &devlist, 0, 0);
231         if (ret < 0) {
232                 sr_err("Failed to list devices (%d): %s", ret,
233                        ftdi_get_error_string(ftdic));
234                 return NULL;
235         }
236
237         curdev = devlist;
238         while (curdev) {
239                 scan_device(ftdic, curdev->dev, &devices);
240                 curdev = curdev->next;
241         }
242
243         ftdi_list_free(&devlist);
244
245         return devices;
246 }
247
248 static GSList *scan(struct sr_dev_driver *di, GSList *options)
249 {
250         struct ftdi_context *ftdic;
251         struct sr_config *src;
252         struct sr_usb_dev_inst *usb;
253         const char *conn;
254         GSList *l, *conn_devices;
255         GSList *devices;
256         struct drv_context *drvc;
257         libusb_device **devlist;
258         int i;
259
260         drvc = di->context;
261         conn = NULL;
262         for (l = options; l; l = l->next) {
263                 src = l->data;
264                 if (src->key == SR_CONF_CONN) {
265                         conn = g_variant_get_string(src->data, NULL);
266                         break;
267                 }
268         }
269
270         ftdic = ftdi_new();
271         if (!ftdic) {
272                 sr_err("Failed to initialize libftdi.");
273                 return NULL;
274         }
275
276         if (conn) {
277                 devices = NULL;
278                 libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist);
279                 for (i = 0; devlist[i]; i++) {
280                         conn_devices = sr_usb_find(drvc->sr_ctx->libusb_ctx, conn);
281                         for (l = conn_devices; l; l = l->next) {
282                                 usb = l->data;
283                                 if (usb->bus == libusb_get_bus_number(devlist[i])
284                                         && usb->address == libusb_get_device_address(devlist[i])) {
285                                         scan_device(ftdic, devlist[i], &devices);
286                                 }
287                         }
288                 }
289                 libusb_free_device_list(devlist, 1);
290         } else
291                 devices = scan_all(ftdic, options);
292
293         ftdi_free(ftdic);
294
295         return std_scan_complete(di, devices);
296 }
297
298 static void clear_helper(struct dev_context *devc)
299 {
300         g_free(devc->data_buf);
301 }
302
303 static int dev_clear(const struct sr_dev_driver *di)
304 {
305         return std_dev_clear_with_callback(di, (std_dev_clear_callback)clear_helper);
306 }
307
308 static int dev_open(struct sr_dev_inst *sdi)
309 {
310         struct dev_context *devc;
311         int ret = SR_OK;
312
313         devc = sdi->priv;
314
315         devc->ftdic = ftdi_new();
316         if (!devc->ftdic)
317                 return SR_ERR;
318
319         ret = ftdi_usb_open_string(devc->ftdic, sdi->connection_id);
320         if (ret < 0) {
321                 /* Log errors, except for -3 ("device not found"). */
322                 if (ret != -3)
323                         sr_err("Failed to open device (%d): %s", ret,
324                                ftdi_get_error_string(devc->ftdic));
325                 goto err_ftdi_free;
326         }
327
328         ret = PURGE_FTDI_BOTH(devc->ftdic);
329         if (ret < 0) {
330                 sr_err("Failed to purge FTDI RX/TX buffers (%d): %s.",
331                        ret, ftdi_get_error_string(devc->ftdic));
332                 goto err_dev_open_close_ftdic;
333         }
334
335         ret = ftdi_set_bitmode(devc->ftdic, 0x00, BITMODE_RESET);
336         if (ret < 0) {
337                 sr_err("Failed to reset the FTDI chip bitmode (%d): %s.",
338                        ret, ftdi_get_error_string(devc->ftdic));
339                 goto err_dev_open_close_ftdic;
340         }
341
342         ret = ftdi_set_bitmode(devc->ftdic, 0x00, BITMODE_BITBANG);
343         if (ret < 0) {
344                 sr_err("Failed to put FTDI chip into bitbang mode (%d): %s.",
345                        ret, ftdi_get_error_string(devc->ftdic));
346                 goto err_dev_open_close_ftdic;
347         }
348
349         return SR_OK;
350
351 err_dev_open_close_ftdic:
352         ftdi_usb_close(devc->ftdic);
353
354 err_ftdi_free:
355         ftdi_free(devc->ftdic);
356
357         return SR_ERR;
358 }
359
360 static int dev_close(struct sr_dev_inst *sdi)
361 {
362         struct dev_context *devc;
363
364         devc = sdi->priv;
365
366         if (!devc->ftdic)
367                 return SR_ERR_BUG;
368
369         ftdi_usb_close(devc->ftdic);
370         ftdi_free(devc->ftdic);
371         devc->ftdic = NULL;
372
373         return SR_OK;
374 }
375
376 static int config_get(uint32_t key, GVariant **data,
377         const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
378 {
379         struct dev_context *devc;
380         struct sr_usb_dev_inst *usb;
381
382         (void)cg;
383
384         devc = sdi->priv;
385
386         switch (key) {
387         case SR_CONF_SAMPLERATE:
388                 *data = g_variant_new_uint64(devc->cur_samplerate);
389                 break;
390         case SR_CONF_CONN:
391                 if (!sdi || !sdi->conn)
392                         return SR_ERR_ARG;
393                 usb = sdi->conn;
394                 *data = g_variant_new_printf("%d.%d", usb->bus, usb->address);
395                 break;
396         default:
397                 return SR_ERR_NA;
398         }
399
400         return SR_OK;
401 }
402
403 static int config_set(uint32_t key, GVariant *data,
404         const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
405 {
406         struct dev_context *devc;
407         uint64_t value;
408
409         (void)cg;
410
411         devc = sdi->priv;
412
413         switch (key) {
414         case SR_CONF_LIMIT_MSEC:
415                 value = g_variant_get_uint64(data);
416                 /* TODO: Implement. */
417                 (void)value;
418                 return SR_ERR_NA;
419         case SR_CONF_LIMIT_SAMPLES:
420                 devc->limit_samples = g_variant_get_uint64(data);
421                 break;
422         case SR_CONF_SAMPLERATE:
423                 value = g_variant_get_uint64(data);
424                 if (value < 3600)
425                         return SR_ERR_SAMPLERATE;
426                 devc->cur_samplerate = value;
427                 return ftdi_la_set_samplerate(devc);
428         default:
429                 return SR_ERR_NA;
430         }
431
432         return SR_OK;
433 }
434
435 static int config_list(uint32_t key, GVariant **data,
436         const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
437 {
438         switch (key) {
439         case SR_CONF_SCAN_OPTIONS:
440         case SR_CONF_DEVICE_OPTIONS:
441                 return STD_CONFIG_LIST(key, data, sdi, cg, scanopts, drvopts, devopts);
442         case SR_CONF_SAMPLERATE:
443                 *data = std_gvar_samplerates_steps(ARRAY_AND_SIZE(samplerates));
444                 break;
445         default:
446                 return SR_ERR_NA;
447         }
448
449         return SR_OK;
450 }
451
452 static int dev_acquisition_start(const struct sr_dev_inst *sdi)
453 {
454         struct dev_context *devc;
455
456         devc = sdi->priv;
457
458         if (!devc->ftdic)
459                 return SR_ERR_BUG;
460
461         ftdi_set_bitmode(devc->ftdic, 0, BITMODE_BITBANG);
462
463         /* Properly reset internal variables before every new acquisition. */
464         devc->samples_sent = 0;
465         devc->bytes_received = 0;
466
467         std_session_send_df_header(sdi);
468
469         /* Hook up a dummy handler to receive data from the device. */
470         sr_session_source_add(sdi->session, -1, G_IO_IN, 0,
471                               ftdi_la_receive_data, (void *)sdi);
472
473         return SR_OK;
474 }
475
476 static int dev_acquisition_stop(struct sr_dev_inst *sdi)
477 {
478         sr_session_source_remove(sdi->session, -1);
479
480         std_session_send_df_end(sdi);
481
482         return SR_OK;
483 }
484
485 static struct sr_dev_driver ftdi_la_driver_info = {
486         .name = "ftdi-la",
487         .longname = "FTDI LA",
488         .api_version = 1,
489         .init = std_init,
490         .cleanup = std_cleanup,
491         .scan = scan,
492         .dev_list = std_dev_list,
493         .dev_clear = dev_clear,
494         .config_get = config_get,
495         .config_set = config_set,
496         .config_list = config_list,
497         .dev_open = dev_open,
498         .dev_close = dev_close,
499         .dev_acquisition_start = dev_acquisition_start,
500         .dev_acquisition_stop = dev_acquisition_stop,
501         .context = NULL,
502 };
503 SR_REGISTER_DEV_DRIVER(ftdi_la_driver_info);