]> sigrok.org Git - libsigrok.git/blob - hardware/chronovu-la8/chronovu-la8.c
13f07b063a0fced7b42d814f8447f853c87365d5
[libsigrok.git] / hardware / chronovu-la8 / chronovu-la8.c
1 /*
2  * This file is part of the sigrok project.
3  *
4  * Copyright (C) 2011 Uwe Hermann <uwe@hermann-uwe.de>
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 2 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, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
19  */
20
21 #include <ftdi.h>
22 #include <sigrok.h>
23 #include <sigrok-internal.h>
24
25 #define USB_VENDOR_ID                   0x0403
26 #define USB_PRODUCT_ID                  0x6001
27 #define USB_DESCRIPTION                 "ChronoVu LA8"
28 #define USB_VENDOR_NAME                 "ChronoVu"
29 #define USB_MODEL_NAME                  "LA8"
30 #define USB_MODEL_VERSION               ""
31
32 #define NUM_PROBES                      8
33 #define TRIGGER_TYPES                   "01"
34 #define SDRAM_SIZE                      (8 * 1024 * 1024)
35 #define MIN_NUM_SAMPLES                 1
36
37 static GSList *device_instances = NULL;
38
39 struct la8 {
40         /** FTDI device context (used by libftdi). */
41         struct ftdi_context *ftdic;
42
43         /** The currently configured samplerate of the device. */
44         uint64_t cur_samplerate;
45
46         /** The current sampling limit (in ms). */
47         uint64_t limit_msec;
48
49         /** The current sampling limit (in number of samples). */
50         uint64_t limit_samples;
51
52         /** The number of probes. */
53         int num_probes;
54
55         /** TODO */
56         gpointer session_id;
57
58         /**
59          * An 8MB buffer containing the (mangled) samples from the device.
60          * Format: Pretty mangled-up (due to hardware reasons), see code.
61          */
62         uint8_t *mangled_buf;
63
64         /**
65          * An 8MB buffer where we'll store the de-mangled samples.
66          * Format: Each sample is 1 byte, MSB is channel 7, LSB is channel 0.
67          */
68         uint8_t *final_buf;
69
70         /**
71          * Trigger pattern (MSB = channel 7, LSB = channel 0).
72          * A 1 bit matches a high signal, 0 matches a low signal on a probe.
73          * Only low/high triggers (but not e.g. rising/falling) are supported.
74          */
75         uint8_t trigger_pattern;
76
77         /**
78          * Trigger mask (MSB = channel 7, LSB = channel 0).
79          * A 1 bit means "must match trigger_pattern", 0 means "don't care".
80          */
81         uint8_t trigger_mask;
82
83         /** Time (in seconds) before the trigger times out. */
84         uint64_t trigger_timeout;
85
86         /** TODO */
87         time_t done;
88
89         /** Counter/index for the data block (0..2047) to be read. */
90         int block_counter;
91
92         /** The divcount value (determines the sample period) for the LA8. */
93         uint8_t divcount;
94 };
95
96 /* This will be initialized via hw_get_device_info()/SR_DI_SAMPLERATES. */
97 static uint64_t supported_samplerates[255 + 1] = { 0 };
98
99 /*
100  * Min: 1 sample per 0.01us -> sample time is 0.084s, samplerate 100MHz
101  * Max: 1 sample per 2.55us -> sample time is 21.391s, samplerate 392.15kHz
102  */
103 static struct sr_samplerates samplerates = {
104         .low  = 0,
105         .high = 0,
106         .step = 0,
107         .list = supported_samplerates,
108 };
109
110 /* Note: Continuous sampling is not supported by the hardware. */
111 static int capabilities[] = {
112         SR_HWCAP_LOGIC_ANALYZER,
113         SR_HWCAP_SAMPLERATE,
114         SR_HWCAP_LIMIT_MSEC, /* TODO: Not yet implemented. */
115         SR_HWCAP_LIMIT_SAMPLES, /* TODO: Not yet implemented. */
116         0,
117 };
118
119 /* Function prototypes. */
120 static int la8_close_usb_reset_sequencer(struct la8 *la8);
121 static void hw_stop_acquisition(int device_index, gpointer session_device_id);
122 static int la8_reset(struct la8 *la8);
123
124 static void fill_supported_samplerates_if_needed(void)
125 {
126         int i;
127
128         /* Do nothing if supported_samplerates[] is already filled. */
129         if (supported_samplerates[0] != 0)
130                 return;
131
132         /* Fill supported_samplerates[] with the proper values. */
133         for (i = 0; i < 255; i++)
134                 supported_samplerates[254 - i] = SR_MHZ(100) / (i + 1);
135         supported_samplerates[255] = 0;
136 }
137
138 /**
139  * Check if the given samplerate is supported by the LA8 hardware.
140  *
141  * @param samplerate The samplerate (in Hz) to check.
142  * @return 1 if the samplerate is supported/valid, 0 otherwise.
143  */
144 static int is_valid_samplerate(uint64_t samplerate)
145 {
146         int i;
147
148         fill_supported_samplerates_if_needed();
149
150         for (i = 0; i < 255; i++) {
151                 if (supported_samplerates[i] == samplerate)
152                         return 1;
153         }
154
155         sr_warn("la8: %s: invalid samplerate (%" PRIu64 "Hz)",
156                 __func__, samplerate);
157
158         return 0;
159 }
160
161 /**
162  * Convert a samplerate (in Hz) to the 'divcount' value the LA8 wants.
163  *
164  * LA8 hardware: sample period = (divcount + 1) * 10ns.
165  * Min. value for divcount: 0x00 (10ns sample period, 100MHz samplerate).
166  * Max. value for divcount: 0xfe (2550ns sample period, 392.15kHz samplerate).
167  *
168  * @param samplerate The samplerate in Hz.
169  * @return The divcount value as needed by the hardware, or 0xff upon errors.
170  */
171 static uint8_t samplerate_to_divcount(uint64_t samplerate)
172 {
173         if (samplerate == 0) {
174                 sr_warn("la8: %s: samplerate was 0", __func__);
175                 return 0xff;
176         }
177
178         if (!is_valid_samplerate(samplerate)) {
179                 sr_warn("la8: %s: can't get divcount, samplerate invalid",
180                         __func__);
181                 return 0xff;
182         }
183
184         return (SR_MHZ(100) / samplerate) - 1;
185 }
186
187 /**
188  * Write data of a certain length to the LA8's FTDI device.
189  *
190  * @param la8 The LA8 struct containing private per-device-instance data.
191  * @param buf The buffer containing the data to write.
192  * @param size The number of bytes to write.
193  * @return The number of bytes written, or a negative value upon errors.
194  */
195 static int la8_write(struct la8 *la8, uint8_t *buf, int size)
196 {
197         int bytes_written;
198
199         if (!la8) {
200                 sr_warn("la8: %s: la8 was NULL", __func__);
201                 return SR_ERR_ARG;
202         }
203
204         if (!la8->ftdic) {
205                 sr_warn("la8: %s: la8->ftdic was NULL", __func__);
206                 return SR_ERR_ARG;
207         }
208
209         if (!buf) {
210                 sr_warn("la8: %s: buf was NULL", __func__);
211                 return SR_ERR_ARG;
212         }
213
214         if (size < 0) {
215                 sr_warn("la8: %s: size was < 0", __func__);
216                 return SR_ERR_ARG;
217         }
218
219         bytes_written = ftdi_write_data(la8->ftdic, buf, size);
220
221         if (bytes_written < 0) {
222                 sr_warn("la8: %s: ftdi_write_data: (%d) %s", __func__,
223                         bytes_written, ftdi_get_error_string(la8->ftdic));
224                 (void) la8_close_usb_reset_sequencer(la8); /* Ignore errors. */
225         } else if (bytes_written != size) {
226                 sr_warn("la8: %s: bytes to write: %d, bytes written: %d",
227                         __func__, size, bytes_written);
228                 (void) la8_close_usb_reset_sequencer(la8); /* Ignore errors. */
229         }
230
231         return bytes_written;
232 }
233
234 /**
235  * Read a certain amount of bytes from the LA8's FTDI device.
236  *
237  * @param la8 The LA8 struct containing private per-device-instance data.
238  * @param buf The buffer where the received data will be stored.
239  * @param size The number of bytes to read.
240  * @return The number of bytes read, or a negative value upon errors.
241  */
242 static int la8_read(struct la8 *la8, uint8_t *buf, int size)
243 {
244         int bytes_read;
245
246         if (!la8) {
247                 sr_warn("la8: %s: la8 was NULL", __func__);
248                 return SR_ERR_ARG;
249         }
250
251         if (!la8->ftdic) {
252                 sr_warn("la8: %s: la8->ftdic was NULL", __func__);
253                 return SR_ERR_ARG;
254         }
255
256         if (!buf) {
257                 sr_warn("la8: %s: buf was NULL", __func__);
258                 return SR_ERR_ARG;
259         }
260
261         if (size <= 0) {
262                 sr_warn("la8: %s: size was <= 0", __func__);
263                 return SR_ERR_ARG;
264         }
265
266         bytes_read = ftdi_read_data(la8->ftdic, buf, size);
267
268         if (bytes_read < 0) {
269                 sr_warn("la8: %s: ftdi_read_data: (%d) %s", __func__,
270                         bytes_read, ftdi_get_error_string(la8->ftdic));
271         } else if (bytes_read != size) {
272                 // sr_warn("la8: %s: bytes to read: %d, bytes read: %d",
273                 //      __func__, size, bytes_read);
274         }
275
276         return bytes_read;
277 }
278
279 static int la8_close(struct la8 *la8)
280 {
281         int ret;
282
283         if (!la8) {
284                 sr_warn("la8: %s: la8 was NULL", __func__);
285                 return SR_ERR_ARG;
286         }
287
288         if (!la8->ftdic) {
289                 sr_warn("la8: %s: la8->ftdic was NULL", __func__);
290                 return SR_ERR_ARG;
291         }
292
293         if ((ret = ftdi_usb_close(la8->ftdic)) < 0) {
294                 sr_warn("la8: %s: ftdi_usb_close: (%d) %s",
295                         __func__, ret, ftdi_get_error_string(la8->ftdic));
296         }
297
298         return ret;
299 }
300
301 /**
302  * Close the ChronoVu LA8 USB port and reset the LA8 sequencer logic.
303  *
304  * @param la8 The LA8 struct containing private per-device-instance data.
305  * @return SR_OK upon success, SR_ERR upon failure.
306  */
307 static int la8_close_usb_reset_sequencer(struct la8 *la8)
308 {
309         /* Magic sequence of bytes for resetting the LA8 sequencer logic. */
310         uint8_t buf[8] = {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01};
311         int ret;
312
313         sr_dbg("la8: entering %s", __func__);
314
315         if (!la8) {
316                 sr_warn("la8: %s: la8 was NULL", __func__);
317                 return SR_ERR_ARG;
318         }
319
320         if (!la8->ftdic) {
321                 sr_warn("la8: %s: la8->ftdic was NULL", __func__);
322                 return SR_ERR_ARG;
323         }
324
325         if (la8->ftdic->usb_dev) {
326                 /* Reset the LA8 sequencer logic, then wait 100ms. */
327                 sr_dbg("la8: resetting sequencer logic");
328                 (void) la8_write(la8, buf, 8); /* Ignore errors. */
329                 g_usleep(100 * 1000);
330
331                 /* Purge FTDI buffers, then reset and close the FTDI device. */
332                 sr_dbg("la8: purging buffers, resetting+closing FTDI device");
333
334                 /* Log errors, but ignore them (i.e., don't abort). */
335                 if ((ret = ftdi_usb_purge_buffers(la8->ftdic)) < 0)
336                         sr_warn("la8: %s: ftdi_usb_purge_buffers: (%d) %s",
337                             __func__, ret, ftdi_get_error_string(la8->ftdic));
338                 if ((ret = ftdi_usb_reset(la8->ftdic)) < 0)
339                         sr_warn("la8: %s: ftdi_usb_reset: (%d) %s", __func__,
340                                 ret, ftdi_get_error_string(la8->ftdic));
341                 if ((ret = ftdi_usb_close(la8->ftdic)) < 0)
342                         sr_warn("la8: %s: ftdi_usb_close: (%d) %s", __func__,
343                                 ret, ftdi_get_error_string(la8->ftdic));
344         } else {
345                 sr_dbg("la8: %s: usb_dev was NULL, nothing to do", __func__);
346         }
347
348         ftdi_free(la8->ftdic); /* Returns void. */
349         la8->ftdic = NULL;
350
351         return SR_OK;
352 }
353
354 /**
355  * Reset the ChronoVu LA8.
356  *
357  * The LA8 must be reset after a failed read/write operation or upon timeouts.
358  *
359  * @param la8 The LA8 struct containing private per-device-instance data.
360  * @return SR_OK upon success, SR_ERR upon failure.
361  */
362 static int la8_reset(struct la8 *la8)
363 {
364         uint8_t buf[4096];
365         time_t done, now;
366         int bytes_read;
367
368         if (!la8) {
369                 sr_warn("la8: %s: la8 was NULL", __func__);
370                 return SR_ERR_ARG;
371         }
372
373         if (!la8->ftdic) {
374                 sr_warn("la8: %s: la8->ftdic was NULL", __func__);
375                 return SR_ERR_ARG;
376         }
377
378         sr_dbg("la8: resetting the device");
379
380         /*
381          * Purge pending read data from the FTDI hardware FIFO until
382          * no more data is left, or a timeout occurs (after 20s).
383          */
384         done = 20 + time(NULL);
385         do {
386                 /* TODO: Ignore errors? Check for < 0 at least! */
387                 bytes_read = la8_read(la8, (uint8_t *)&buf, 4096);
388                 now = time(NULL);
389         } while ((done > now) && (bytes_read > 0));
390
391         /* Reset the LA8 sequencer logic and close the USB port. */
392         (void) la8_close_usb_reset_sequencer(la8); /* Ignore errors. */
393
394         sr_dbg("la8: device reset finished");
395
396         return SR_OK;
397 }
398
399 static int hw_init(const char *deviceinfo)
400 {
401         int ret;
402         struct sr_device_instance *sdi;
403         struct la8 *la8;
404
405         sr_dbg("la8: entering %s", __func__);
406
407         /* Avoid compiler errors. */
408         deviceinfo = deviceinfo;
409
410         /* Allocate memory for our private driver context. */
411         if (!(la8 = malloc(sizeof(struct la8)))) {
412                 sr_warn("la8: %s: struct la8 malloc failed", __func__);
413                 ret = SR_ERR_MALLOC;
414                 goto err_free_nothing;
415         }
416
417         /* Set some sane defaults. */
418         la8->ftdic = NULL;
419         la8->cur_samplerate = SR_MHZ(100); /* 100MHz == max. samplerate */
420         la8->limit_msec = 0;
421         la8->limit_samples = 0;
422         la8->num_probes = NUM_PROBES;
423         la8->session_id = NULL;
424         la8->mangled_buf = NULL;
425         la8->final_buf = NULL;
426         la8->trigger_pattern = 0x00; /* Value irrelevant, see trigger_mask. */
427         la8->trigger_mask = 0x00; /* All probes are "don't care". */
428         la8->trigger_timeout = 10; /* Default to 10s trigger timeout. */
429         la8->done = 0;
430         la8->block_counter = 0;
431         la8->divcount = 0; /* 10ns sample period == 100MHz samplerate */
432
433         /* Allocate memory for the raw (mangled) data from the LA8. */
434         if (!(la8->mangled_buf = malloc(SDRAM_SIZE))) {
435                 sr_warn("la8: %s: mangled_buf malloc failed", __func__);
436                 ret = SR_ERR_MALLOC;
437                 goto err_free_la8;
438         }
439
440         /* Allocate memory where we'll store the de-mangled data. */
441         if (!(la8->final_buf = malloc(SDRAM_SIZE))) {
442                 sr_warn("la8: %s: final_buf malloc failed", __func__);
443                 ret = SR_ERR_MALLOC;
444                 goto err_free_mangled_buf;
445         }
446
447         /* Allocate memory for the FTDI context (ftdic) and initialize it. */
448         if (!(la8->ftdic = ftdi_new())) {
449                 sr_warn("la8: %s: ftdi_new failed", __func__);
450                 ret = SR_ERR; /* TODO: More specific error? */
451                 goto err_free_final_buf;
452         }
453
454         /* Check for the device and temporarily open it. */
455         if ((ret = ftdi_usb_open_desc(la8->ftdic, USB_VENDOR_ID,
456                         USB_PRODUCT_ID, USB_DESCRIPTION, NULL)) < 0) {
457                 sr_warn("la8: %s: ftdi_usb_open_desc: (%d) %s",
458                         __func__, ret, ftdi_get_error_string(la8->ftdic));
459                 (void) la8_close_usb_reset_sequencer(la8); /* Ignore errors. */
460                 ret = SR_ERR; /* TODO: More specific error? */
461                 goto err_free_ftdic;
462         }
463         sr_dbg("la8: found device");
464
465         /* Register the device with libsigrok. */
466         sdi = sr_device_instance_new(0, SR_ST_INITIALIZING,
467                         USB_VENDOR_NAME, USB_MODEL_NAME, USB_MODEL_VERSION);
468         if (!sdi) {
469                 sr_warn("la8: %s: sr_device_instance_new failed", __func__);
470                 ret = SR_ERR; /* TODO: More specific error? */
471                 goto err_close_ftdic;
472         }
473
474         sdi->priv = la8;
475
476         device_instances = g_slist_append(device_instances, sdi);
477
478         sr_dbg("la8: %s finished successfully", __func__);
479
480         /* Close device. We'll reopen it again when we need it. */
481         (void) la8_close(la8); /* Log, but ignore errors. */
482
483         // return SR_OK; /* TODO */
484         return 1;
485
486 err_close_ftdic:
487         (void) la8_close(la8); /* Log, but ignore errors. */
488 err_free_ftdic:
489         free(la8->ftdic);
490 err_free_final_buf:
491         free(la8->final_buf);
492 err_free_mangled_buf:
493         free(la8->mangled_buf);
494 err_free_la8:
495         free(la8);
496 err_free_nothing:
497         // return ret; /* TODO */
498         return 0;
499 }
500
501 static int hw_opendev(int device_index)
502 {
503         int ret;
504         struct sr_device_instance *sdi;
505         struct la8 *la8;
506
507         if (!(sdi = sr_get_device_instance(device_instances, device_index))) {
508                 sr_warn("la8: %s: sdi was NULL", __func__);
509                 return SR_ERR; /* TODO: SR_ERR_ARG? */
510         }
511
512         if (!(la8 = sdi->priv)) {
513                 sr_warn("la8: %s: sdi->priv was NULL", __func__);
514                 return SR_ERR; /* TODO: SR_ERR_ARG? */
515         }
516
517         sr_dbg("la8: opening device");
518
519         /* Open the device. */
520         if ((ret = ftdi_usb_open_desc(la8->ftdic, USB_VENDOR_ID,
521                         USB_PRODUCT_ID, USB_DESCRIPTION, NULL)) < 0) {
522                 sr_warn("la8: %s: ftdi_usb_open_desc: (%d) %s",
523                         __func__, ret, ftdi_get_error_string(la8->ftdic));
524                 (void) la8_close_usb_reset_sequencer(la8); /* Ignore errors. */
525                 return SR_ERR;
526         }
527         sr_dbg("la8: device opened successfully");
528
529         /* Purge RX/TX buffers in the FTDI chip. */
530         if ((ret = ftdi_usb_purge_buffers(la8->ftdic)) < 0) {
531                 sr_warn("la8: %s: ftdi_usb_purge_buffers: (%d) %s",
532                         __func__, ret, ftdi_get_error_string(la8->ftdic));
533                 (void) la8_close_usb_reset_sequencer(la8); /* Ignore errors. */
534                 goto err_opendev_close_ftdic;
535         }
536         sr_dbg("la8: FTDI buffers purged successfully");
537
538         /* Enable flow control in the FTDI chip. */
539         if ((ret = ftdi_setflowctrl(la8->ftdic, SIO_RTS_CTS_HS)) < 0) {
540                 sr_warn("la8: %s: ftdi_setflowcontrol: (%d) %s",
541                         __func__, ret, ftdi_get_error_string(la8->ftdic));
542                 (void) la8_close_usb_reset_sequencer(la8); /* Ignore errors. */
543                 goto err_opendev_close_ftdic;
544         }
545         sr_dbg("la8: FTDI flow control enabled successfully");
546
547         /* Wait 100ms. */
548         g_usleep(100 * 1000);
549
550         sdi->status = SR_ST_ACTIVE;
551
552         return SR_OK;
553
554 err_opendev_close_ftdic:
555         (void) la8_close(la8); /* Log, but ignore errors. */
556         return SR_ERR;
557 }
558
559 static int set_samplerate(struct sr_device_instance *sdi, uint64_t samplerate)
560 {
561         struct la8 *la8;
562
563         if (!sdi) {
564                 sr_warn("la8: %s: sdi was NULL", __func__);
565                 return SR_ERR_ARG;
566         }
567
568         if (!(la8 = sdi->priv)) {
569                 sr_warn("la8: %s: sdi->priv was NULL", __func__);
570                 return SR_ERR_ARG;
571         }
572
573         sr_dbg("la8: setting samplerate");
574
575         fill_supported_samplerates_if_needed();
576
577         /* Check if this is a samplerate supported by the hardware. */
578         if (!is_valid_samplerate(samplerate))
579                 return SR_ERR;
580
581         /* Set the new samplerate. */
582         la8->cur_samplerate = samplerate;
583
584         sr_dbg("la8: samplerate set to %" PRIu64 "Hz", la8->cur_samplerate);
585
586         return SR_OK;
587 }
588
589 static void hw_closedev(int device_index)
590 {
591         struct sr_device_instance *sdi;
592         struct la8 *la8;
593
594         if (!(sdi = sr_get_device_instance(device_instances, device_index))) {
595                 sr_warn("la8: %s: sdi was NULL", __func__);
596                 return;
597         }
598
599         if (!(la8 = sdi->priv)) {
600                 sr_warn("la8: %s: sdi->priv was NULL", __func__);
601                 return;
602         }
603
604         sr_dbg("la8: closing device");
605
606         if (sdi->status == SR_ST_ACTIVE) {
607                 sr_dbg("la8: %s: status ACTIVE, closing device", __func__);
608                 (void) la8_close_usb_reset_sequencer(la8); /* Ignore errors. */
609         } else {
610                 sr_dbg("la8: %s: status not ACTIVE, nothing to do", __func__);
611         }
612
613         sdi->status = SR_ST_INACTIVE;
614
615         sr_dbg("la8: %s: freeing sample buffers", __func__);
616         free(la8->mangled_buf);
617         free(la8->final_buf);
618 }
619
620 static void hw_cleanup(void)
621 {
622         GSList *l;
623         struct sr_device_instance *sdi;
624
625         sr_dbg("la8: entering %s", __func__);
626
627         /* Properly close all devices. */
628         for (l = device_instances; l; l = l->next) {
629                 if ((sdi = l->data) == NULL) {
630                         sr_warn("la8: %s: sdi was NULL", __func__);
631                         continue;
632                 }
633                 if (sdi->priv != NULL)
634                         free(sdi->priv);
635                 else
636                         sr_warn("la8: %s: sdi->priv was NULL", __func__);
637                 sr_device_instance_free(sdi); /* Returns void. */
638         }
639         g_slist_free(device_instances); /* Returns void. */
640         device_instances = NULL;
641 }
642
643 static void *hw_get_device_info(int device_index, int device_info_id)
644 {
645         struct sr_device_instance *sdi;
646         struct la8 *la8;
647         void *info;
648
649         sr_dbg("la8: entering %s", __func__);
650
651         if (!(sdi = sr_get_device_instance(device_instances, device_index))) {
652                 sr_warn("la8: %s: sdi was NULL", __func__);
653                 return NULL;
654         }
655
656         if (!(la8 = sdi->priv)) {
657                 sr_warn("la8: %s: sdi->priv was NULL", __func__);
658                 return NULL;
659         }
660
661         switch (device_info_id) {
662         case SR_DI_INSTANCE:
663                 info = sdi;
664                 break;
665         case SR_DI_NUM_PROBES:
666                 info = GINT_TO_POINTER(NUM_PROBES);
667                 break;
668         case SR_DI_SAMPLERATES:
669                 fill_supported_samplerates_if_needed();
670                 info = &samplerates;
671                 break;
672         case SR_DI_TRIGGER_TYPES:
673                 info = (char *)TRIGGER_TYPES;
674                 break;
675         case SR_DI_CUR_SAMPLERATE:
676                 info = &la8->cur_samplerate;
677                 break;
678         default:
679                 /* Unknown device info ID, return NULL. */
680                 sr_warn("la8: %s: Unknown device info ID", __func__);
681                 info = NULL;
682                 break;
683         }
684
685         return info;
686 }
687
688 static int hw_get_status(int device_index)
689 {
690         struct sr_device_instance *sdi;
691
692         if (!(sdi = sr_get_device_instance(device_instances, device_index))) {
693                 sr_warn("la8: %s: sdi was NULL, device not found", __func__);
694                 return SR_ST_NOT_FOUND;
695         }
696
697         sr_dbg("la8: %s: returning status %d", __func__, sdi->status);
698
699         return sdi->status;
700 }
701
702 static int *hw_get_capabilities(void)
703 {
704         sr_dbg("la8: entering %s", __func__);
705
706         return capabilities;
707 }
708
709 static int hw_set_configuration(int device_index, int capability, void *value)
710 {
711         struct sr_device_instance *sdi;
712         struct la8 *la8;
713
714         sr_dbg("la8: entering %s", __func__);
715
716         if (!(sdi = sr_get_device_instance(device_instances, device_index))) {
717                 sr_warn("la8: %s: sdi was NULL", __func__);
718                 return SR_ERR; /* TODO: SR_ERR_ARG? */
719         }
720
721         if (!(la8 = sdi->priv)) {
722                 sr_warn("la8: %s: sdi->priv was NULL", __func__);
723                 return SR_ERR; /* TODO: SR_ERR_ARG? */
724         }
725
726         switch (capability) {
727         case SR_HWCAP_SAMPLERATE:
728                 if (set_samplerate(sdi, *(uint64_t *)value) == SR_ERR)
729                         return SR_ERR;
730                 sr_dbg("la8: SAMPLERATE = %" PRIu64, la8->cur_samplerate);
731                 break;
732         case SR_HWCAP_PROBECONFIG:
733                 /* Nothing to do, but this entry must exist. Fix this. */
734                 /* TODO? */
735                 sr_dbg("la8: %s: SR_HWCAP_PROBECONFIG called", __func__);
736                 return SR_OK;
737                 break;
738         case SR_HWCAP_LIMIT_MSEC:
739                 if (*(uint64_t *)value == 0) {
740                         sr_warn("la8: %s: LIMIT_MSEC can't be 0", __func__);
741                         return SR_ERR;
742                 }
743                 la8->limit_msec = *(uint64_t *)value;
744                 sr_dbg("la8: LIMIT_MSEC = %" PRIu64, la8->limit_msec);
745                 break;
746         case SR_HWCAP_LIMIT_SAMPLES:
747                 if (*(uint64_t *)value < MIN_NUM_SAMPLES) {
748                         sr_warn("la8: %s: LIMIT_SAMPLES too small", __func__);
749                         return SR_ERR;
750                 }
751                 la8->limit_samples = *(uint64_t *)value;
752                 sr_dbg("la8: LIMIT_SAMPLES = %" PRIu64, la8->limit_samples);
753                 break;
754         default:
755                 /* Unknown capability, return SR_ERR. */
756                 sr_warn("la8: %s: Unknown capability", __func__);
757                 return SR_ERR;
758                 break;
759         }
760
761         return SR_OK;
762 }
763
764 /**
765  * Get a block of 4096 bytes of data from the LA8.
766  *
767  * @param la8 The LA8 struct containing private per-device-instance data.
768  * @return SR_OK upon success, or SR_ERR upon errors.
769  */
770 static int la8_read_block(struct la8 *la8)
771 {
772         int i, byte_offset, m, mi, p, index, bytes_read;
773         time_t now;
774
775         if (!la8) {
776                 sr_warn("la8: %s: la8 was NULL", __func__);
777                 return SR_ERR_ARG;
778         }
779
780         if (!la8->ftdic) {
781                 sr_warn("la8: %s: la8->ftdic was NULL", __func__);
782                 return SR_ERR_ARG;
783         }
784
785         // sr_dbg("la8: %s: reading block %d", __func__, la8->block_counter);
786
787         bytes_read = la8_read(la8, la8->mangled_buf, 4096);
788
789         /* If first block read got 0 bytes, retry until success or timeout. */
790         if ((bytes_read == 0) && (la8->block_counter == 0)) {
791                 do {
792                         // sr_dbg("la8: %s: reading block 0 again", __func__);
793                         bytes_read = la8_read(la8, la8->mangled_buf, 4096);
794                         /* TODO: How to handle read errors here? */
795                         now = time(NULL);
796                 } while ((la8->done > now) && (bytes_read == 0));
797         }
798
799         /* Check if block read was successful or a timeout occured. */
800         if (bytes_read != 4096) {
801                 sr_warn("la8: %s: trigger timed out", __func__);
802                 (void) la8_reset(la8); /* Ignore errors. */
803                 return SR_ERR;
804         }
805
806         /* De-mangle the data. */
807         // sr_dbg("la8: de-mangling samples of block %d", la8->block_counter);
808         byte_offset = la8->block_counter * 4096;
809         m = byte_offset / (1024 * 1024);
810         mi = m * (1024 * 1024);
811         for (i = 0; i < 4096; i++) {
812                 p = i & (1 << 0);
813                 index = m * 2 + (((byte_offset + i) - mi) / 2) * 16;
814                 index += (la8->divcount == 0) ? p : (1 - p);
815                 la8->final_buf[index] = la8->mangled_buf[i];
816         }
817
818         return SR_OK;
819 }
820
821 static int receive_data(int fd, int revents, void *user_data)
822 {
823         int i, ret;
824         struct sr_device_instance *sdi;
825         struct sr_datafeed_packet packet;
826         struct la8 *la8;
827
828         /* Avoid compiler errors. */
829         fd = fd;
830         revents = revents;
831
832         if (!(sdi = user_data)) {
833                 sr_warn("la8: %s: user_data was NULL", __func__);
834                 return FALSE;
835         }
836
837         if (!(la8 = sdi->priv)) {
838                 sr_warn("la8: %s: sdi->priv was NULL", __func__);
839                 return FALSE;
840         }
841
842         /* Get one block of data (4096 bytes). */
843         if ((ret = la8_read_block(la8)) < 0) {
844                 sr_warn("la8: %s: la8_read_block error: %d", __func__, ret);
845                 return FALSE;
846         }
847
848         /* We need to get exactly 2048 blocks (i.e. 8MB) of data. */
849         if (la8->block_counter != 2047) {
850                 la8->block_counter++;
851                 return TRUE;
852         }
853
854         sr_dbg("la8: sampling finished, sending data to session bus now");
855
856         /* All data was received and demangled, send it to the session bus. */
857         for (i = 0; i < 2048; i++) {
858                 /* Send a 4096 byte SR_DF_LOGIC packet to the session bus. */
859                 // sr_dbg("la8: %s: sending SR_DF_LOGIC packet", __func__);
860                 packet.type = SR_DF_LOGIC;
861                 packet.length = 4096;
862                 packet.unitsize = 1;
863                 packet.payload = la8->final_buf + (i * 4096);
864                 sr_session_bus(la8->session_id, &packet);
865         }
866
867         hw_stop_acquisition(sdi->index, user_data);
868
869         // return FALSE; /* FIXME? */
870         return TRUE;
871 }
872
873 static int hw_start_acquisition(int device_index, gpointer session_device_id)
874 {
875         struct sr_device_instance *sdi;
876         struct la8 *la8;
877         struct sr_datafeed_packet packet;
878         struct sr_datafeed_header header;
879         uint8_t buf[4];
880         int bytes_written;
881
882         sr_dbg("la8: entering %s", __func__);
883
884         if (!(sdi = sr_get_device_instance(device_instances, device_index))) {
885                 sr_warn("la8: %s: sdi was NULL", __func__);
886                 return SR_ERR; /* TODO: SR_ERR_ARG? */
887         }
888
889         if (!(la8 = sdi->priv)) {
890                 sr_warn("la8: %s: sdi->priv was NULL", __func__);
891                 return SR_ERR; /* TODO: SR_ERR_ARG? */
892         }
893
894         if (!la8->ftdic) {
895                 sr_warn("la8: %s: la8->ftdic was NULL", __func__);
896                 return SR_ERR_ARG;
897         }
898
899         la8->divcount = samplerate_to_divcount(la8->cur_samplerate);
900         if (la8->divcount == 0xff) {
901                 sr_warn("la8: %s: invalid divcount/samplerate", __func__);
902                 return SR_ERR;
903         }
904
905         /* Fill acquisition parameters into buf[]. */
906         buf[0] = la8->divcount;
907         buf[1] = 0xff; /* This byte must always be 0xff. */
908         buf[2] = la8->trigger_pattern;
909         buf[3] = la8->trigger_mask;
910
911         /* Start acquisition. */
912         bytes_written = la8_write(la8, buf, 4);
913
914         if (bytes_written < 0) {
915                 sr_warn("la8: acquisition failed to start");
916                 return SR_ERR;
917         } else if (bytes_written != 4) {
918                 sr_warn("la8: acquisition failed to start");
919                 return SR_ERR; /* TODO: Other error and return code? */
920         }
921
922         sr_dbg("la8: acquisition started successfully");
923
924         la8->session_id = session_device_id;
925
926         /* Send header packet to the session bus. */
927         sr_dbg("la8: %s: sending SR_DF_HEADER", __func__);
928         packet.type = SR_DF_HEADER;
929         packet.length = sizeof(struct sr_datafeed_header);
930         packet.unitsize = 0;
931         packet.payload = &header;
932         header.feed_version = 1;
933         gettimeofday(&header.starttime, NULL);
934         header.samplerate = la8->cur_samplerate;
935         header.protocol_id = SR_PROTO_RAW;
936         header.num_logic_probes = la8->num_probes;
937         header.num_analog_probes = 0;
938         sr_session_bus(session_device_id, &packet);
939
940         /* Time when we should be done (for detecting trigger timeouts). */
941         la8->done = (la8->divcount + 1) * 0.08388608 + time(NULL)
942                         + la8->trigger_timeout;
943         la8->block_counter = 0;
944
945         /* Hook up a dummy handler to receive data from the LA8. */
946         sr_source_add(-1, G_IO_IN, 0, receive_data, sdi);
947
948         return SR_OK;
949 }
950
951 static void hw_stop_acquisition(int device_index, gpointer session_device_id)
952 {
953         struct sr_device_instance *sdi;
954         struct la8 *la8;
955         struct sr_datafeed_packet packet;
956
957         sr_dbg("la8: stopping acquisition");
958
959         if (!(sdi = sr_get_device_instance(device_instances, device_index))) {
960                 sr_warn("la8: %s: sdi was NULL", __func__);
961                 return;
962         }
963
964         if (!(la8 = sdi->priv)) {
965                 sr_warn("la8: %s: sdi->priv was NULL", __func__);
966                 return;
967         }
968
969         /* Send end packet to the session bus. */
970         sr_dbg("la8: %s: sending SR_DF_END", __func__);
971         packet.type = SR_DF_END;
972         packet.length = 0;
973         packet.unitsize = 0;
974         packet.payload = NULL;
975         sr_session_bus(session_device_id, &packet);
976 }
977
978 struct sr_device_plugin chronovu_la8_plugin_info = {
979         .name = "chronovu-la8",
980         .longname = "ChronoVu LA8",
981         .api_version = 1,
982         .init = hw_init,
983         .cleanup = hw_cleanup,
984         .open = hw_opendev,
985         .close = hw_closedev,
986         .get_device_info = hw_get_device_info,
987         .get_status = hw_get_status,
988         .get_capabilities = hw_get_capabilities,
989         .set_configuration = hw_set_configuration,
990         .start_acquisition = hw_start_acquisition,
991         .stop_acquisition = hw_stop_acquisition,
992 };