]> sigrok.org Git - libsigrok.git/blob - hardware/chronovu-la8/driver.c
sr: moved sigrok.h so libsigrok/libsigrok.h
[libsigrok.git] / hardware / chronovu-la8 / driver.c
1 /*
2  * This file is part of the sigrok project.
3  *
4  * Copyright (C) 2011-2012 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 <glib.h>
23 #include "libsigrok.h"
24 #include "libsigrok-internal.h"
25 #include "driver.h"
26
27 /* Probes are numbered 0-7. */
28 SR_PRIV const char *probe_names[NUM_PROBES + 1] = {
29         "0",
30         "1",
31         "2",
32         "3",
33         "4",
34         "5",
35         "6",
36         "7",
37         NULL,
38 };
39
40 /* This will be initialized via hw_dev_info_get()/SR_DI_SAMPLERATES. */
41 SR_PRIV uint64_t supported_samplerates[255 + 1] = { 0 };
42
43 /*
44  * Min: 1 sample per 0.01us -> sample time is 0.084s, samplerate 100MHz
45  * Max: 1 sample per 2.55us -> sample time is 21.391s, samplerate 392.15kHz
46  */
47 const struct sr_samplerates samplerates = {
48         .low  = 0,
49         .high = 0,
50         .step = 0,
51         .list = supported_samplerates,
52 };
53
54 /* Note: Continuous sampling is not supported by the hardware. */
55 SR_PRIV const int hwcaps[] = {
56         SR_HWCAP_LOGIC_ANALYZER,
57         SR_HWCAP_SAMPLERATE,
58         SR_HWCAP_LIMIT_MSEC, /* TODO: Not yet implemented. */
59         SR_HWCAP_LIMIT_SAMPLES, /* TODO: Not yet implemented. */
60         0,
61 };
62
63 SR_PRIV void fill_supported_samplerates_if_needed(void)
64 {
65         int i;
66
67         /* Do nothing if supported_samplerates[] is already filled. */
68         if (supported_samplerates[0] != 0)
69                 return;
70
71         /* Fill supported_samplerates[] with the proper values. */
72         for (i = 0; i < 255; i++)
73                 supported_samplerates[254 - i] = SR_MHZ(100) / (i + 1);
74         supported_samplerates[255] = 0;
75 }
76
77 /**
78  * Check if the given samplerate is supported by the LA8 hardware.
79  *
80  * @param samplerate The samplerate (in Hz) to check.
81  * @return 1 if the samplerate is supported/valid, 0 otherwise.
82  */
83 SR_PRIV int is_valid_samplerate(uint64_t samplerate)
84 {
85         int i;
86
87         fill_supported_samplerates_if_needed();
88
89         for (i = 0; i < 255; i++) {
90                 if (supported_samplerates[i] == samplerate)
91                         return 1;
92         }
93
94         sr_err("la8: %s: invalid samplerate (%" PRIu64 "Hz)",
95                __func__, samplerate);
96
97         return 0;
98 }
99
100 /**
101  * Convert a samplerate (in Hz) to the 'divcount' value the LA8 wants.
102  *
103  * LA8 hardware: sample period = (divcount + 1) * 10ns.
104  * Min. value for divcount: 0x00 (10ns sample period, 100MHz samplerate).
105  * Max. value for divcount: 0xfe (2550ns sample period, 392.15kHz samplerate).
106  *
107  * @param samplerate The samplerate in Hz.
108  * @return The divcount value as needed by the hardware, or 0xff upon errors.
109  */
110 SR_PRIV uint8_t samplerate_to_divcount(uint64_t samplerate)
111 {
112         if (samplerate == 0) {
113                 sr_err("la8: %s: samplerate was 0", __func__);
114                 return 0xff;
115         }
116
117         if (!is_valid_samplerate(samplerate)) {
118                 sr_err("la8: %s: can't get divcount, samplerate invalid",
119                        __func__);
120                 return 0xff;
121         }
122
123         return (SR_MHZ(100) / samplerate) - 1;
124 }
125
126 /**
127  * Write data of a certain length to the LA8's FTDI device.
128  *
129  * @param ctx The struct containing private per-device-instance data. Must not
130  *            be NULL. ctx->ftdic must not be NULL either.
131  * @param buf The buffer containing the data to write. Must not be NULL.
132  * @param size The number of bytes to write. Must be >= 0.
133  * @return The number of bytes written, or a negative value upon errors.
134  */
135 SR_PRIV int la8_write(struct context *ctx, uint8_t *buf, int size)
136 {
137         int bytes_written;
138
139         /* Note: Caller checked that ctx and ctx->ftdic != NULL. */
140
141         if (!buf) {
142                 sr_err("la8: %s: buf was NULL", __func__);
143                 return SR_ERR_ARG;
144         }
145
146         if (size < 0) {
147                 sr_err("la8: %s: size was < 0", __func__);
148                 return SR_ERR_ARG;
149         }
150
151         bytes_written = ftdi_write_data(ctx->ftdic, buf, size);
152
153         if (bytes_written < 0) {
154                 sr_err("la8: %s: ftdi_write_data: (%d) %s", __func__,
155                        bytes_written, ftdi_get_error_string(ctx->ftdic));
156                 (void) la8_close_usb_reset_sequencer(ctx); /* Ignore errors. */
157         } else if (bytes_written != size) {
158                 sr_err("la8: %s: bytes to write: %d, bytes written: %d",
159                        __func__, size, bytes_written);
160                 (void) la8_close_usb_reset_sequencer(ctx); /* Ignore errors. */
161         }
162
163         return bytes_written;
164 }
165
166 /**
167  * Read a certain amount of bytes from the LA8's FTDI device.
168  *
169  * @param ctx The struct containing private per-device-instance data. Must not
170  *            be NULL. ctx->ftdic must not be NULL either.
171  * @param buf The buffer where the received data will be stored. Must not
172  *            be NULL.
173  * @param size The number of bytes to read. Must be >= 1.
174  * @return The number of bytes read, or a negative value upon errors.
175  */
176 SR_PRIV int la8_read(struct context *ctx, uint8_t *buf, int size)
177 {
178         int bytes_read;
179
180         /* Note: Caller checked that ctx and ctx->ftdic != NULL. */
181
182         if (!buf) {
183                 sr_err("la8: %s: buf was NULL", __func__);
184                 return SR_ERR_ARG;
185         }
186
187         if (size <= 0) {
188                 sr_err("la8: %s: size was <= 0", __func__);
189                 return SR_ERR_ARG;
190         }
191
192         bytes_read = ftdi_read_data(ctx->ftdic, buf, size);
193
194         if (bytes_read < 0) {
195                 sr_err("la8: %s: ftdi_read_data: (%d) %s", __func__,
196                        bytes_read, ftdi_get_error_string(ctx->ftdic));
197         } else if (bytes_read != size) {
198                 // sr_err("la8: %s: bytes to read: %d, bytes read: %d",
199                 //        __func__, size, bytes_read);
200         }
201
202         return bytes_read;
203 }
204
205 SR_PRIV int la8_close(struct context *ctx)
206 {
207         int ret;
208
209         if (!ctx) {
210                 sr_err("la8: %s: ctx was NULL", __func__);
211                 return SR_ERR_ARG;
212         }
213
214         if (!ctx->ftdic) {
215                 sr_err("la8: %s: ctx->ftdic was NULL", __func__);
216                 return SR_ERR_ARG;
217         }
218
219         if ((ret = ftdi_usb_close(ctx->ftdic)) < 0) {
220                 sr_err("la8: %s: ftdi_usb_close: (%d) %s",
221                        __func__, ret, ftdi_get_error_string(ctx->ftdic));
222         }
223
224         return ret;
225 }
226
227 /**
228  * Close the ChronoVu LA8 USB port and reset the LA8 sequencer logic.
229  *
230  * @param ctx The struct containing private per-device-instance data.
231  * @return SR_OK upon success, SR_ERR_ARG upon invalid arguments.
232  */
233 SR_PRIV int la8_close_usb_reset_sequencer(struct context *ctx)
234 {
235         /* Magic sequence of bytes for resetting the LA8 sequencer logic. */
236         uint8_t buf[8] = {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01};
237         int ret;
238
239         if (!ctx) {
240                 sr_err("la8: %s: ctx was NULL", __func__);
241                 return SR_ERR_ARG;
242         }
243
244         if (!ctx->ftdic) {
245                 sr_err("la8: %s: ctx->ftdic was NULL", __func__);
246                 return SR_ERR_ARG;
247         }
248
249         if (ctx->ftdic->usb_dev) {
250                 /* Reset the LA8 sequencer logic, then wait 100ms. */
251                 sr_dbg("la8: Resetting sequencer logic.");
252                 (void) la8_write(ctx, buf, 8); /* Ignore errors. */
253                 g_usleep(100 * 1000);
254
255                 /* Purge FTDI buffers, then reset and close the FTDI device. */
256                 sr_dbg("la8: Purging buffers, resetting+closing FTDI device.");
257
258                 /* Log errors, but ignore them (i.e., don't abort). */
259                 if ((ret = ftdi_usb_purge_buffers(ctx->ftdic)) < 0)
260                         sr_err("la8: %s: ftdi_usb_purge_buffers: (%d) %s",
261                             __func__, ret, ftdi_get_error_string(ctx->ftdic));
262                 if ((ret = ftdi_usb_reset(ctx->ftdic)) < 0)
263                         sr_err("la8: %s: ftdi_usb_reset: (%d) %s", __func__,
264                                ret, ftdi_get_error_string(ctx->ftdic));
265                 if ((ret = ftdi_usb_close(ctx->ftdic)) < 0)
266                         sr_err("la8: %s: ftdi_usb_close: (%d) %s", __func__,
267                                ret, ftdi_get_error_string(ctx->ftdic));
268         }
269
270         /* Close USB device, deinitialize and free the FTDI context. */
271         ftdi_free(ctx->ftdic); /* Returns void. */
272         ctx->ftdic = NULL;
273
274         return SR_OK;
275 }
276
277 /**
278  * Reset the ChronoVu LA8.
279  *
280  * The LA8 must be reset after a failed read/write operation or upon timeouts.
281  *
282  * @param ctx The struct containing private per-device-instance data.
283  * @return SR_OK upon success, SR_ERR upon failure.
284  */
285 SR_PRIV int la8_reset(struct context *ctx)
286 {
287         uint8_t buf[BS];
288         time_t done, now;
289         int bytes_read;
290
291         if (!ctx) {
292                 sr_err("la8: %s: ctx was NULL", __func__);
293                 return SR_ERR_ARG;
294         }
295
296         if (!ctx->ftdic) {
297                 sr_err("la8: %s: ctx->ftdic was NULL", __func__);
298                 return SR_ERR_ARG;
299         }
300
301         sr_dbg("la8: Resetting the device.");
302
303         /*
304          * Purge pending read data from the FTDI hardware FIFO until
305          * no more data is left, or a timeout occurs (after 20s).
306          */
307         done = 20 + time(NULL);
308         do {
309                 /* TODO: Ignore errors? Check for < 0 at least! */
310                 bytes_read = la8_read(ctx, (uint8_t *)&buf, BS);
311                 now = time(NULL);
312         } while ((done > now) && (bytes_read > 0));
313
314         /* Reset the LA8 sequencer logic and close the USB port. */
315         (void) la8_close_usb_reset_sequencer(ctx); /* Ignore errors. */
316
317         sr_dbg("la8: Device reset finished.");
318
319         return SR_OK;
320 }
321
322 SR_PRIV int configure_probes(struct context *ctx, const GSList *probes)
323 {
324         const struct sr_probe *probe;
325         const GSList *l;
326         uint8_t probe_bit;
327         char *tc;
328
329         /* Note: Caller checked that ctx != NULL. */
330
331         ctx->trigger_pattern = 0;
332         ctx->trigger_mask = 0; /* Default to "don't care" for all probes. */
333
334         for (l = probes; l; l = l->next) {
335                 probe = (struct sr_probe *)l->data;
336
337                 if (!probe) {
338                         sr_err("la8: %s: probe was NULL", __func__);
339                         return SR_ERR;
340                 }
341
342                 /* Skip disabled probes. */
343                 if (!probe->enabled)
344                         continue;
345
346                 /* Skip (enabled) probes with no configured trigger. */
347                 if (!probe->trigger)
348                         continue;
349
350                 /* Note: Must only be run if probe->trigger != NULL. */
351                 if (probe->index < 0 || probe->index > 7) {
352                         sr_err("la8: %s: invalid probe index %d, must be "
353                                "between 0 and 7", __func__, probe->index);
354                         return SR_ERR;
355                 }
356
357                 probe_bit = (1 << (probe->index - 1));
358
359                 /* Configure the probe's trigger mask and trigger pattern. */
360                 for (tc = probe->trigger; tc && *tc; tc++) {
361                         ctx->trigger_mask |= probe_bit;
362
363                         /* Sanity check, LA8 only supports low/high trigger. */
364                         if (*tc != '0' && *tc != '1') {
365                                 sr_err("la8: %s: invalid trigger '%c', only "
366                                        "'0'/'1' supported", __func__, *tc);
367                                 return SR_ERR;
368                         }
369
370                         if (*tc == '1')
371                                 ctx->trigger_pattern |= probe_bit;
372                 }
373         }
374
375         sr_dbg("la8: trigger_mask = 0x%x, trigger_pattern = 0x%x",
376                ctx->trigger_mask, ctx->trigger_pattern);
377
378         return SR_OK;
379 }
380
381 SR_PRIV int set_samplerate(struct sr_dev_inst *sdi, uint64_t samplerate)
382 {
383         struct context *ctx;
384
385         /* Note: Caller checked that sdi and sdi->priv != NULL. */
386
387         ctx = sdi->priv;
388
389         sr_spew("la8: Trying to set samplerate to %" PRIu64 "Hz.", samplerate);
390
391         fill_supported_samplerates_if_needed();
392
393         /* Check if this is a samplerate supported by the hardware. */
394         if (!is_valid_samplerate(samplerate))
395                 return SR_ERR;
396
397         /* Set the new samplerate. */
398         ctx->cur_samplerate = samplerate;
399
400         sr_dbg("la8: Samplerate set to %" PRIu64 "Hz.", ctx->cur_samplerate);
401
402         return SR_OK;
403 }
404
405 /**
406  * Get a block of data from the LA8.
407  *
408  * @param ctx The struct containing private per-device-instance data. Must not
409  *            be NULL. ctx->ftdic must not be NULL either.
410  * @return SR_OK upon success, or SR_ERR upon errors.
411  */
412 SR_PRIV int la8_read_block(struct context *ctx)
413 {
414         int i, byte_offset, m, mi, p, index, bytes_read;
415         time_t now;
416
417         /* Note: Caller checked that ctx and ctx->ftdic != NULL. */
418
419         sr_spew("la8: Reading block %d.", ctx->block_counter);
420
421         bytes_read = la8_read(ctx, ctx->mangled_buf, BS);
422
423         /* If first block read got 0 bytes, retry until success or timeout. */
424         if ((bytes_read == 0) && (ctx->block_counter == 0)) {
425                 do {
426                         sr_spew("la8: Reading block 0 (again).");
427                         bytes_read = la8_read(ctx, ctx->mangled_buf, BS);
428                         /* TODO: How to handle read errors here? */
429                         now = time(NULL);
430                 } while ((ctx->done > now) && (bytes_read == 0));
431         }
432
433         /* Check if block read was successful or a timeout occured. */
434         if (bytes_read != BS) {
435                 sr_err("la8: Trigger timed out. Bytes read: %d.", bytes_read);
436                 (void) la8_reset(ctx); /* Ignore errors. */
437                 return SR_ERR;
438         }
439
440         /* De-mangle the data. */
441         sr_spew("la8: Demangling block %d.", ctx->block_counter);
442         byte_offset = ctx->block_counter * BS;
443         m = byte_offset / (1024 * 1024);
444         mi = m * (1024 * 1024);
445         for (i = 0; i < BS; i++) {
446                 p = i & (1 << 0);
447                 index = m * 2 + (((byte_offset + i) - mi) / 2) * 16;
448                 index += (ctx->divcount == 0) ? p : (1 - p);
449                 ctx->final_buf[index] = ctx->mangled_buf[i];
450         }
451
452         return SR_OK;
453 }
454
455 SR_PRIV void send_block_to_session_bus(struct context *ctx, int block)
456 {
457         int i;
458         uint8_t sample, expected_sample;
459         struct sr_datafeed_packet packet;
460         struct sr_datafeed_logic logic;
461         int trigger_point; /* Relative trigger point (in this block). */
462
463         /* Note: No sanity checks on ctx/block, caller is responsible. */
464
465         /* Check if we can find the trigger condition in this block. */
466         trigger_point = -1;
467         expected_sample = ctx->trigger_pattern & ctx->trigger_mask;
468         for (i = 0; i < BS; i++) {
469                 /* Don't continue if the trigger was found previously. */
470                 if (ctx->trigger_found)
471                         break;
472
473                 /*
474                  * Also, don't continue if triggers are "don't care", i.e. if
475                  * no trigger conditions were specified by the user. In that
476                  * case we don't want to send an SR_DF_TRIGGER packet at all.
477                  */
478                 if (ctx->trigger_mask == 0x00)
479                         break;
480
481                 sample = *(ctx->final_buf + (block * BS) + i);
482
483                 if ((sample & ctx->trigger_mask) == expected_sample) {
484                         trigger_point = i;
485                         ctx->trigger_found = 1;
486                         break;
487                 }
488         }
489
490         /* If no trigger was found, send one SR_DF_LOGIC packet. */
491         if (trigger_point == -1) {
492                 /* Send an SR_DF_LOGIC packet to the session bus. */
493                 sr_spew("la8: sending SR_DF_LOGIC packet (%d bytes) for "
494                         "block %d", BS, block);
495                 packet.type = SR_DF_LOGIC;
496                 packet.payload = &logic;
497                 logic.length = BS;
498                 logic.unitsize = 1;
499                 logic.data = ctx->final_buf + (block * BS);
500                 sr_session_send(ctx->session_dev_id, &packet);
501                 return;
502         }
503
504         /*
505          * We found the trigger, so some special handling is needed. We have
506          * to send an SR_DF_LOGIC packet with the samples before the trigger
507          * (if any), then the SD_DF_TRIGGER packet itself, then another
508          * SR_DF_LOGIC packet with the samples after the trigger (if any).
509          */
510
511         /* TODO: Send SR_DF_TRIGGER packet before or after the actual sample? */
512
513         /* If at least one sample is located before the trigger... */
514         if (trigger_point > 0) {
515                 /* Send pre-trigger SR_DF_LOGIC packet to the session bus. */
516                 sr_spew("la8: sending pre-trigger SR_DF_LOGIC packet, "
517                         "start = %d, length = %d", block * BS, trigger_point);
518                 packet.type = SR_DF_LOGIC;
519                 packet.payload = &logic;
520                 logic.length = trigger_point;
521                 logic.unitsize = 1;
522                 logic.data = ctx->final_buf + (block * BS);
523                 sr_session_send(ctx->session_dev_id, &packet);
524         }
525
526         /* Send the SR_DF_TRIGGER packet to the session bus. */
527         sr_spew("la8: sending SR_DF_TRIGGER packet, sample = %d",
528                 (block * BS) + trigger_point);
529         packet.type = SR_DF_TRIGGER;
530         packet.payload = NULL;
531         sr_session_send(ctx->session_dev_id, &packet);
532
533         /* If at least one sample is located after the trigger... */
534         if (trigger_point < (BS - 1)) {
535                 /* Send post-trigger SR_DF_LOGIC packet to the session bus. */
536                 sr_spew("la8: sending post-trigger SR_DF_LOGIC packet, "
537                         "start = %d, length = %d",
538                         (block * BS) + trigger_point, BS - trigger_point);
539                 packet.type = SR_DF_LOGIC;
540                 packet.payload = &logic;
541                 logic.length = BS - trigger_point;
542                 logic.unitsize = 1;
543                 logic.data = ctx->final_buf + (block * BS) + trigger_point;
544                 sr_session_send(ctx->session_dev_id, &packet);
545         }
546 }