]> sigrok.org Git - libsigrok.git/blob - hardware/asix-sigma/asix-sigma.c
ASIX SIGMA: Coding style fixes (via indent mostly).
[libsigrok.git] / hardware / asix-sigma / asix-sigma.c
1 /*
2  * This file is part of the sigrok project.
3  *
4  * Copyright (C) 2010 Håvard Espeland <gus@ping.uio.no>,
5  * Copyright (C) 2010 Martin Stensgård <mastensg@ping.uio.no>
6  * Copyright (C) 2010 Carl Henrik Lunde <chlunde@ping.uio.no>
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22 /*
23  * ASIX Sigma Logic Analyzer Driver
24  */
25
26 #include <ftdi.h>
27 #include <string.h>
28 #include <zlib.h>
29 #include <sigrok.h>
30 #include "asix-sigma.h"
31
32 #define USB_VENDOR                      0xa600
33 #define USB_PRODUCT                     0xa000
34 #define USB_DESCRIPTION                 "ASIX SIGMA"
35 #define USB_VENDOR_NAME                 "ASIX"
36 #define USB_MODEL_NAME                  "SIGMA"
37 #define USB_MODEL_VERSION               ""
38 #define FIRMWARE                        FIRMWARE_DIR "/asix-sigma-200.firmware"
39
40 static GSList *device_instances = NULL;
41
42 // XXX These should be per device
43 static struct ftdi_context ftdic;
44 static uint64_t cur_samplerate = MHZ(200);
45 static uint32_t limit_msec = 0;
46 static struct timeval start_tv;
47
48 static uint64_t supported_samplerates[] = {
49         MHZ(200),
50         0,
51 };
52
53 static struct samplerates samplerates = {
54         MHZ(200),
55         MHZ(200),
56         0,
57         supported_samplerates,
58 };
59
60 static int capabilities[] = {
61         HWCAP_LOGIC_ANALYZER,
62         HWCAP_SAMPLERATE,
63
64         /* These are really implemented in the driver, not the hardware. */
65         HWCAP_LIMIT_MSEC,
66         0,
67 };
68
69 /* Force the FPGA to reboot. */
70 static uint8_t suicide[] = {
71         0x84, 0x84, 0x88, 0x84, 0x88, 0x84, 0x88, 0x84,
72 };
73
74 /* Prepare to upload firmware (FPGA specific). */
75 static uint8_t init[] = {
76         0x03, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
77 };
78
79 /* Initialize the logic analyzer mode. */
80 static uint8_t logic_mode_start[] = {
81         0x00, 0x40, 0x0f, 0x25, 0x35, 0x40,
82         0x2a, 0x3a, 0x40, 0x03, 0x20, 0x38,
83 };
84
85 static int sigma_read(void *buf, size_t size)
86 {
87         int ret;
88
89         ret = ftdi_read_data(&ftdic, (unsigned char *)buf, size);
90         if (ret < 0) {
91                 g_warning("ftdi_read_data failed: %s",
92                           ftdi_get_error_string(&ftdic));
93         }
94
95         return ret;
96 }
97
98 static int sigma_write(void *buf, size_t size)
99 {
100         int ret;
101
102         ret = ftdi_write_data(&ftdic, (unsigned char *)buf, size);
103         if (ret < 0) {
104                 g_warning("ftdi_write_data failed: %s",
105                           ftdi_get_error_string(&ftdic));
106         } else if ((size_t) ret != size) {
107                 g_warning("ftdi_write_data did not complete write\n");
108         }
109
110         return ret;
111 }
112
113 static int sigma_write_register(uint8_t reg, uint8_t *data, size_t len)
114 {
115         size_t i;
116         uint8_t buf[len + 2];
117         int idx = 0;
118
119         buf[idx++] = REG_ADDR_LOW | (reg & 0xf);
120         buf[idx++] = REG_ADDR_HIGH | (reg >> 4);
121
122         for (i = 0; i < len; ++i) {
123                 buf[idx++] = REG_DATA_LOW | (data[i] & 0xf);
124                 buf[idx++] = REG_DATA_HIGH_WRITE | (data[i] >> 4);
125         }
126
127         return sigma_write(buf, idx);
128 }
129
130 static int sigma_set_register(uint8_t reg, uint8_t value)
131 {
132         return sigma_write_register(reg, &value, 1);
133 }
134
135 static int sigma_read_register(uint8_t reg, uint8_t *data, size_t len)
136 {
137         uint8_t buf[3];
138
139         buf[0] = REG_ADDR_LOW | (reg & 0xf);
140         buf[1] = REG_ADDR_HIGH | (reg >> 4);
141         buf[2] = REG_READ_ADDR;
142
143         sigma_write(buf, sizeof(buf));
144
145         return sigma_read(data, len);
146 }
147
148 static uint8_t sigma_get_register(uint8_t reg)
149 {
150         uint8_t value;
151
152         if (1 != sigma_read_register(reg, &value, 1)) {
153                 g_warning("Sigma_get_register: 1 byte expected");
154                 return 0;
155         }
156
157         return value;
158 }
159
160 static int sigma_read_pos(uint32_t *stoppos, uint32_t *triggerpos)
161 {
162         uint8_t buf[] = {
163                 REG_ADDR_LOW | READ_TRIGGER_POS_LOW,
164
165                 REG_READ_ADDR | NEXT_REG,
166                 REG_READ_ADDR | NEXT_REG,
167                 REG_READ_ADDR | NEXT_REG,
168                 REG_READ_ADDR | NEXT_REG,
169                 REG_READ_ADDR | NEXT_REG,
170                 REG_READ_ADDR | NEXT_REG,
171         };
172         uint8_t result[6];
173
174         sigma_write(buf, sizeof(buf));
175
176         sigma_read(result, sizeof(result));
177
178         *triggerpos = result[0] | (result[1] << 8) | (result[2] << 16);
179         *stoppos = result[3] | (result[4] << 8) | (result[5] << 16);
180
181         return 1;
182 }
183
184 static int sigma_read_dram(uint16_t startchunk, size_t numchunks, uint8_t *data)
185 {
186         size_t i;
187         uint8_t buf[4096];
188         int idx = 0;
189
190         /* Send the startchunk. Index start with 1. */
191         buf[0] = startchunk >> 8;
192         buf[1] = startchunk & 0xff;
193         sigma_write_register(WRITE_MEMROW, buf, 2);
194
195         /* Read the DRAM. */
196         buf[idx++] = REG_DRAM_BLOCK;
197         buf[idx++] = REG_DRAM_WAIT_ACK;
198
199         for (i = 0; i < numchunks; ++i) {
200                 /* Alternate bit to copy from DRAM to cache. */
201                 if (i != (numchunks - 1))
202                         buf[idx++] = REG_DRAM_BLOCK | (((i + 1) % 2) << 4);
203
204                 buf[idx++] = REG_DRAM_BLOCK_DATA | ((i % 2) << 4);
205
206                 if (i != (numchunks - 1))
207                         buf[idx++] = REG_DRAM_WAIT_ACK;
208         }
209
210         sigma_write(buf, idx);
211
212         return sigma_read(data, numchunks * CHUNK_SIZE);
213 }
214
215 /* Generate the bitbang stream for programming the FPGA. */
216 static int bin2bitbang(const char *filename,
217                        unsigned char **buf, size_t *buf_size)
218 {
219         FILE *f;
220         long file_size;
221         unsigned long offset = 0;
222         unsigned char *p;
223         uint8_t *compressed_buf, *firmware;
224         uLongf csize, fwsize;
225         const int buffer_size = 65536;
226         size_t i;
227         int c, ret, bit, v;
228         uint32_t imm = 0x3f6df2ab;
229
230         f = fopen(filename, "r");
231         if (!f) {
232                 g_warning("fopen(\"%s\", \"r\")", filename);
233                 return -1;
234         }
235
236         if (-1 == fseek(f, 0, SEEK_END)) {
237                 g_warning("fseek on %s failed", filename);
238                 fclose(f);
239                 return -1;
240         }
241
242         file_size = ftell(f);
243
244         fseek(f, 0, SEEK_SET);
245
246         compressed_buf = g_malloc(file_size);
247         firmware = g_malloc(buffer_size);
248
249         if (!compressed_buf || !firmware) {
250                 g_warning("Error allocating buffers");
251                 return -1;
252         }
253
254         csize = 0;
255         while ((c = getc(f)) != EOF) {
256                 imm = (imm + 0xa853753) % 177 + (imm * 0x8034052);
257                 compressed_buf[csize++] = c ^ imm;
258         }
259         fclose(f);
260
261         fwsize = buffer_size;
262         ret = uncompress(firmware, &fwsize, compressed_buf, csize);
263         if (ret < 0) {
264                 g_free(compressed_buf);
265                 g_free(firmware);
266                 g_warning("Could not unpack Sigma firmware. (Error %d)\n", ret);
267                 return -1;
268         }
269
270         g_free(compressed_buf);
271
272         *buf_size = fwsize * 2 * 8;
273
274         *buf = p = (unsigned char *)g_malloc(*buf_size);
275
276         if (!p) {
277                 g_warning("Error allocating buffers");
278                 return -1;
279         }
280
281         for (i = 0; i < fwsize; ++i) {
282                 for (bit = 7; bit >= 0; --bit) {
283                         v = firmware[i] & 1 << bit ? 0x40 : 0x00;
284                         p[offset++] = v | 0x01;
285                         p[offset++] = v;
286                 }
287         }
288
289         g_free(firmware);
290
291         if (offset != *buf_size) {
292                 g_free(*buf);
293                 g_warning("Error reading firmware %s "
294                           "offset=%ld, file_size=%ld, buf_size=%zd\n",
295                           filename, offset, file_size, *buf_size);
296
297                 return -1;
298         }
299
300         return 0;
301 }
302
303 static int hw_init(char *deviceinfo)
304 {
305         struct sigrok_device_instance *sdi;
306
307         deviceinfo = deviceinfo;
308
309         ftdi_init(&ftdic);
310
311         /* Look for SIGMAs. */
312         if (ftdi_usb_open_desc(&ftdic, USB_VENDOR, USB_PRODUCT,
313                                USB_DESCRIPTION, NULL) < 0)
314                 return 0;
315
316         /* Register SIGMA device. */
317         sdi = sigrok_device_instance_new(0, ST_INITIALIZING,
318                         USB_VENDOR_NAME, USB_MODEL_NAME, USB_MODEL_VERSION);
319         if (!sdi)
320                 return 0;
321
322         device_instances = g_slist_append(device_instances, sdi);
323
324         /* We will open the device again when we need it. */
325         ftdi_usb_close(&ftdic);
326
327         return 1;
328 }
329
330 static int hw_opendev(int device_index)
331 {
332         int ret;
333         unsigned char *buf;
334         unsigned char pins;
335         size_t buf_size;
336         struct sigrok_device_instance *sdi;
337         unsigned char result[32];
338
339         /* Make sure it's an ASIX SIGMA. */
340         if ((ret = ftdi_usb_open_desc(&ftdic,
341                 USB_VENDOR, USB_PRODUCT, USB_DESCRIPTION, NULL)) < 0) {
342                 g_warning("ftdi_usb_open failed: %s",
343                           ftdi_get_error_string(&ftdic));
344                 return 0;
345         }
346
347         if ((ret = ftdi_set_bitmode(&ftdic, 0xdf, BITMODE_BITBANG)) < 0) {
348                 g_warning("ftdi_set_bitmode failed: %s",
349                           ftdi_get_error_string(&ftdic));
350                 return 0;
351         }
352
353         /* Four times the speed of sigmalogan - Works well. */
354         if ((ret = ftdi_set_baudrate(&ftdic, 750000)) < 0) {
355                 g_warning("ftdi_set_baudrate failed: %s",
356                           ftdi_get_error_string(&ftdic));
357                 return 0;
358         }
359
360         /* Force the FPGA to reboot. */
361         sigma_write(suicide, sizeof(suicide));
362         sigma_write(suicide, sizeof(suicide));
363         sigma_write(suicide, sizeof(suicide));
364         sigma_write(suicide, sizeof(suicide));
365
366         /* Prepare to upload firmware (FPGA specific). */
367         sigma_write(init, sizeof(init));
368
369         ftdi_usb_purge_buffers(&ftdic);
370
371         /* Wait until the FPGA asserts INIT_B. */
372         while (1) {
373                 ret = sigma_read(result, 1);
374                 if (result[0] & 0x20)
375                         break;
376         }
377
378         /* Prepare firmware. */
379         if (-1 == bin2bitbang(FIRMWARE, &buf, &buf_size)) {
380                 g_warning("An error occured while reading the firmware: %s",
381                           FIRMWARE);
382                 return SIGROK_ERR;
383         }
384
385         /* Upload firmare. */
386         sigma_write(buf, buf_size);
387
388         g_free(buf);
389
390         if ((ret = ftdi_set_bitmode(&ftdic, 0x00, BITMODE_RESET)) < 0) {
391                 g_warning("ftdi_set_bitmode failed: %s",
392                           ftdi_get_error_string(&ftdic));
393                 return SIGROK_ERR;
394         }
395
396         ftdi_usb_purge_buffers(&ftdic);
397
398         /* Discard garbage. */
399         while (1 == sigma_read(&pins, 1))
400                 ;
401
402         /* Initialize the logic analyzer mode. */
403         sigma_write(logic_mode_start, sizeof(logic_mode_start));
404
405         /* Expect a 3 byte reply. */
406         ret = sigma_read(result, 3);
407         if (ret != 3 ||
408             result[0] != 0xa6 || result[1] != 0x55 || result[2] != 0xaa) {
409                 g_warning("Configuration failed. Invalid reply received.");
410                 return SIGROK_ERR;
411         }
412
413         /* Works like a charm... */
414
415         if (!(sdi = get_sigrok_device_instance(device_instances, device_index)))
416                 return SIGROK_ERR;
417
418         sdi->status = ST_ACTIVE;
419
420         g_message("Firmware uploaded");
421
422         return SIGROK_OK;
423 }
424
425 static void hw_closedev(int device_index)
426 {
427         device_index = device_index;
428
429         ftdi_usb_close(&ftdic);
430 }
431
432 static void hw_cleanup(void)
433 {
434 }
435
436 static void *hw_get_device_info(int device_index, int device_info_id)
437 {
438         struct sigrok_device_instance *sdi;
439         void *info = NULL;
440
441         if (!(sdi = get_sigrok_device_instance(device_instances, device_index))) {
442                 fprintf(stderr, "It's NULL.\n");
443                 return NULL;
444         }
445
446         switch (device_info_id) {
447         case DI_INSTANCE:
448                 info = sdi;
449                 break;
450         case DI_NUM_PROBES:
451                 info = GINT_TO_POINTER(4);
452                 break;
453         case DI_SAMPLERATES:
454                 info = &samplerates;
455                 break;
456         case DI_TRIGGER_TYPES:
457                 info = 0;       //TRIGGER_TYPES;
458                 break;
459         case DI_CUR_SAMPLERATE:
460                 info = &cur_samplerate;
461                 break;
462         }
463
464         return info;
465 }
466
467 static int hw_get_status(int device_index)
468 {
469         struct sigrok_device_instance *sdi;
470
471         sdi = get_sigrok_device_instance(device_instances, device_index);
472         if (sdi)
473                 return sdi->status;
474         else
475                 return ST_NOT_FOUND;
476 }
477
478 static int *hw_get_capabilities(void)
479 {
480         return capabilities;
481 }
482
483 static int hw_set_configuration(int device_index, int capability, void *value)
484 {
485         struct sigrok_device_instance *sdi;
486         int ret;
487         uint64_t *tmp_u64;
488
489         if (!(sdi = get_sigrok_device_instance(device_instances, device_index)))
490                 return SIGROK_ERR;
491
492         if (capability == HWCAP_SAMPLERATE) {
493                 tmp_u64 = (uint64_t *) value;
494                 /* Only 200 MHz implemented */
495                 ret = SIGROK_OK;
496         } else if (capability == HWCAP_PROBECONFIG) {
497                 ret = SIGROK_OK;
498         } else if (capability == HWCAP_LIMIT_MSEC) {
499                 limit_msec = strtoull(value, NULL, 10);
500                 ret = SIGROK_OK;
501         } else {
502                 ret = SIGROK_ERR;
503         }
504
505         return ret;
506 }
507
508 /*
509  * Decode chunk of 1024 bytes, 64 clusters, 7 events per cluster.
510  * Each event is 20ns apart, and can contain multiple samples.
511  * For 200 MHz, an event contains 4 samples for each channel,
512  * spread 5 ns apart.
513  */
514 static int decode_chunk_ts(uint8_t *buf, uint16_t *lastts,
515                            uint8_t *lastsample, void *user_data)
516 {
517         const int samples_per_event = 4;
518         uint16_t tsdiff, ts;
519         uint8_t samples[65536 * samples_per_event];
520         struct datafeed_packet packet;
521         int i, j, k, numpad, tosend;
522         size_t n = 0, sent = 0;
523         int clustersize = EVENTS_PER_CLUSTER * samples_per_event; /* 4 for 200 MHz */
524         uint16_t *event;
525
526         /* For each ts */
527         for (i = 0; i < 64; ++i) {
528                 ts = *(uint16_t *) &buf[i * 16];
529                 tsdiff = ts - *lastts;
530                 *lastts = ts;
531
532                 /* Pad last sample up to current point. */
533                 numpad = tsdiff * samples_per_event - clustersize;
534                 if (numpad > 0) {
535                         memset(samples, *lastsample,
536                                tsdiff * samples_per_event - clustersize);
537                         n = tsdiff * samples_per_event - clustersize;
538                 }
539
540                 event = (uint16_t *) &buf[i * 16 + 2];
541
542                 /* For each sample in cluster. */
543                 for (j = 0; j < 7; ++j) {
544                         for (k = 0; k < samples_per_event; ++k) {
545                                 /*
546                                  * Extract samples from bytestream.
547                                  * Samples are packed together in a short.
548                                  */
549                                 samples[n++] =
550                                     ((!!(event[j] & (1 << (k + 0x0)))) << 0) |
551                                     ((!!(event[j] & (1 << (k + 0x4)))) << 1) |
552                                     ((!!(event[j] & (1 << (k + 0x8)))) << 2) |
553                                     ((!!(event[j] & (1 << (k + 0xc)))) << 3);
554                         }
555                 }
556
557                 *lastsample = samples[n - 1];
558
559                 /* Send to sigrok. */
560                 sent = 0;
561                 while (sent < n) {
562                         tosend = MIN(4096, n - sent);
563
564                         packet.type = DF_LOGIC8;
565                         packet.length = tosend;
566                         packet.payload = samples + sent;
567                         session_bus(user_data, &packet);
568
569                         sent += tosend;
570                 }
571         }
572
573         return 0;
574 }
575
576 static int receive_data(int fd, int revents, void *user_data)
577 {
578         struct datafeed_packet packet;
579         const int chunks_per_read = 32;
580         unsigned char buf[chunks_per_read * CHUNK_SIZE];
581         int bufsz, numchunks, curchunk, i, newchunks;
582         uint32_t triggerpos, stoppos, running_msec;
583         struct timeval tv;
584         uint16_t lastts = 0;
585         uint8_t lastsample = 0;
586
587         fd = fd;
588         revents = revents;
589
590         /* Get the current position. */
591         sigma_read_pos(&stoppos, &triggerpos);
592         numchunks = stoppos / 512;
593
594         /* Check if the has expired, or memory is full. */
595         gettimeofday(&tv, 0);
596         running_msec = (tv.tv_sec - start_tv.tv_sec) * 1000 +
597                        (tv.tv_usec - start_tv.tv_usec) / 1000;
598
599         if (running_msec < limit_msec && numchunks < 32767)
600                 return FALSE;
601
602         /* Stop acqusition. */
603         sigma_set_register(WRITE_MODE, 0x11);
604
605         /* Set SDRAM Read Enable. */
606         sigma_set_register(WRITE_MODE, 0x02);
607
608         /* Get the current position. */
609         sigma_read_pos(&stoppos, &triggerpos);
610
611         /* Download sample data. */
612         for (curchunk = 0; curchunk < numchunks;) {
613                 newchunks = MIN(chunks_per_read, numchunks - curchunk);
614
615                 g_message("Downloading sample data: %.0f %%",
616                           100.0 * curchunk / numchunks);
617
618                 bufsz = sigma_read_dram(curchunk, newchunks, buf);
619
620                 /* Find first ts. */
621                 if (curchunk == 0)
622                         lastts = *(uint16_t *) buf - 1;
623
624                 /* Decode chunks and send them to sigrok. */
625                 for (i = 0; i < newchunks; ++i) {
626                         decode_chunk_ts(buf + (i * CHUNK_SIZE),
627                                         &lastts, &lastsample, user_data);
628                 }
629
630                 curchunk += newchunks;
631         }
632
633         /* End of data */
634         packet.type = DF_END;
635         packet.length = 0;
636         session_bus(user_data, &packet);
637
638         return TRUE;
639 }
640
641 static int hw_start_acquisition(int device_index, gpointer session_device_id)
642 {
643         struct sigrok_device_instance *sdi;
644         struct datafeed_packet packet;
645         struct datafeed_header header;
646         uint8_t trigger_option[2] = { 0x38, 0x00 };
647
648         session_device_id = session_device_id;
649
650         if (!(sdi = get_sigrok_device_instance(device_instances, device_index)))
651                 return SIGROK_ERR;
652
653         device_index = device_index;
654
655         /* Setup trigger (by trigger-in). */
656         sigma_set_register(WRITE_TRIGGER_SELECT1, 0x20);
657
658         /* More trigger setup. */
659         sigma_write_register(WRITE_TRIGGER_OPTION,
660                              trigger_option, sizeof(trigger_option));
661
662         /* Trigger normal (falling edge). */
663         sigma_set_register(WRITE_TRIGGER_SELECT1, 0x08);
664
665         /* Enable pins (200 MHz, 4 pins). */
666         sigma_set_register(WRITE_CLOCK_SELECT, 0xf0);
667
668         /* Setup maximum post trigger time. */
669         sigma_set_register(WRITE_POST_TRIGGER, 0xff);
670
671         /* Start acqusition (software trigger start). */
672         gettimeofday(&start_tv, 0);
673         sigma_set_register(WRITE_MODE, 0x0d);
674
675         /* Add capture source. */
676         source_add(0, G_IO_IN, 10, receive_data, session_device_id);
677
678         receive_data(0, 1, session_device_id);
679
680         /* Send header packet to the session bus. */
681         packet.type = DF_HEADER;
682         packet.length = sizeof(struct datafeed_header);
683         packet.payload = &header;
684         header.feed_version = 1;
685         gettimeofday(&header.starttime, NULL);
686         header.samplerate = cur_samplerate;
687         header.protocol_id = PROTO_RAW;
688         header.num_probes = 4;
689         session_bus(session_device_id, &packet);
690
691         return SIGROK_OK;
692 }
693
694 static void hw_stop_acquisition(int device_index, gpointer session_device_id)
695 {
696         device_index = device_index;
697         session_device_id = session_device_id;
698
699         /* Stop acquisition. */
700         sigma_set_register(WRITE_MODE, 0x11);
701
702         // XXX Set some state to indicate that data should be sent to sigrok
703         //     Now, we just wait for timeout
704 }
705
706 struct device_plugin asix_sigma_plugin_info = {
707         "asix-sigma",
708         1,
709         hw_init,
710         hw_cleanup,
711         hw_opendev,
712         hw_closedev,
713         hw_get_device_info,
714         hw_get_status,
715         hw_get_capabilities,
716         hw_set_configuration,
717         hw_start_acquisition,
718         hw_stop_acquisition
719 };