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