]> sigrok.org Git - libsigrok.git/blame - hardware/asix-sigma/asix-sigma.c
Sigma: Fix simple trigger LUT calculation.
[libsigrok.git] / hardware / asix-sigma / asix-sigma.c
CommitLineData
28a35d8a
HE
1/*
2 * This file is part of the sigrok project.
3 *
911f1834
UH
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>
28a35d8a
HE
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
911f1834
UH
22/*
23 * ASIX Sigma Logic Analyzer Driver
24 */
25
28a35d8a
HE
26#include <ftdi.h>
27#include <string.h>
28#include <zlib.h>
fefa1800 29#include <sigrok.h>
28a35d8a
HE
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 ""
ee492173 38#define TRIGGER_TYPES "rf10"
28a35d8a
HE
39
40static GSList *device_instances = NULL;
41
42// XXX These should be per device
43static struct ftdi_context ftdic;
f78898e9 44static uint64_t cur_samplerate = 0;
28a35d8a
HE
45static uint32_t limit_msec = 0;
46static struct timeval start_tv;
f6564c8d 47static int cur_firmware = -1;
f78898e9
HE
48static int num_probes = 0;
49static int samples_per_event = 0;
57bbf56b
HE
50static int capture_ratio = 50;
51
ee492173 52/* Single-pin trigger support (100 and 200 MHz).*/
57bbf56b
HE
53static uint8_t triggerpin = 1;
54static uint8_t triggerfall = 0;
28a35d8a 55
ee492173
HE
56/* Simple trigger support (<= 50 MHz). */
57static uint16_t triggermask = 1;
58static uint16_t triggervalue = 1;
59
28a35d8a 60static uint64_t supported_samplerates[] = {
ed09fd07 61 KHZ(200),
edca2c5c 62 KHZ(250),
ed09fd07 63 KHZ(500),
edca2c5c 64 MHZ(1),
ed09fd07 65 MHZ(5),
edca2c5c
HE
66 MHZ(10),
67 MHZ(25),
e8397563
HE
68 MHZ(50),
69 MHZ(100),
28a35d8a
HE
70 MHZ(200),
71 0,
72};
73
74static struct samplerates samplerates = {
ed09fd07 75 KHZ(200),
28a35d8a
HE
76 MHZ(200),
77 0,
78 supported_samplerates,
79};
80
81static int capabilities[] = {
82 HWCAP_LOGIC_ANALYZER,
83 HWCAP_SAMPLERATE,
57bbf56b
HE
84 HWCAP_CAPTURE_RATIO,
85 HWCAP_PROBECONFIG,
28a35d8a 86
28a35d8a
HE
87 HWCAP_LIMIT_MSEC,
88 0,
89};
90
fefa1800
UH
91/* Force the FPGA to reboot. */
92static uint8_t suicide[] = {
93 0x84, 0x84, 0x88, 0x84, 0x88, 0x84, 0x88, 0x84,
94};
95
96/* Prepare to upload firmware (FPGA specific). */
97static uint8_t init[] = {
98 0x03, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
99};
100
101/* Initialize the logic analyzer mode. */
102static uint8_t logic_mode_start[] = {
103 0x00, 0x40, 0x0f, 0x25, 0x35, 0x40,
104 0x2a, 0x3a, 0x40, 0x03, 0x20, 0x38,
105};
106
eec5275e 107static const char *firmware_files[] = {
a8116d76
HE
108 "asix-sigma-50.fw", /* 50 MHz, supports 8 bit fractions */
109 "asix-sigma-100.fw", /* 100 MHz */
110 "asix-sigma-200.fw", /* 200 MHz */
ed09fd07 111 "asix-sigma-50sync.fw", /* Synchronous clock from pin */
a8116d76 112 "asix-sigma-phasor.fw", /* Frequency counter */
f6564c8d
HE
113};
114
9ddb2a12 115static int sigma_read(void *buf, size_t size)
28a35d8a
HE
116{
117 int ret;
fefa1800
UH
118
119 ret = ftdi_read_data(&ftdic, (unsigned char *)buf, size);
28a35d8a
HE
120 if (ret < 0) {
121 g_warning("ftdi_read_data failed: %s",
fefa1800 122 ftdi_get_error_string(&ftdic));
28a35d8a
HE
123 }
124
125 return ret;
126}
127
fefa1800 128static int sigma_write(void *buf, size_t size)
28a35d8a
HE
129{
130 int ret;
fefa1800
UH
131
132 ret = ftdi_write_data(&ftdic, (unsigned char *)buf, size);
28a35d8a
HE
133 if (ret < 0) {
134 g_warning("ftdi_write_data failed: %s",
fefa1800
UH
135 ftdi_get_error_string(&ftdic));
136 } else if ((size_t) ret != size) {
28a35d8a
HE
137 g_warning("ftdi_write_data did not complete write\n");
138 }
139
140 return ret;
141}
142
143static int sigma_write_register(uint8_t reg, uint8_t *data, size_t len)
144{
145 size_t i;
146 uint8_t buf[len + 2];
147 int idx = 0;
148
149 buf[idx++] = REG_ADDR_LOW | (reg & 0xf);
150 buf[idx++] = REG_ADDR_HIGH | (reg >> 4);
151
fefa1800 152 for (i = 0; i < len; ++i) {
28a35d8a
HE
153 buf[idx++] = REG_DATA_LOW | (data[i] & 0xf);
154 buf[idx++] = REG_DATA_HIGH_WRITE | (data[i] >> 4);
155 }
156
157 return sigma_write(buf, idx);
158}
159
160static int sigma_set_register(uint8_t reg, uint8_t value)
161{
162 return sigma_write_register(reg, &value, 1);
163}
164
165static int sigma_read_register(uint8_t reg, uint8_t *data, size_t len)
166{
167 uint8_t buf[3];
fefa1800 168
28a35d8a
HE
169 buf[0] = REG_ADDR_LOW | (reg & 0xf);
170 buf[1] = REG_ADDR_HIGH | (reg >> 4);
28a35d8a
HE
171 buf[2] = REG_READ_ADDR;
172
173 sigma_write(buf, sizeof(buf));
174
175 return sigma_read(data, len);
176}
177
178static uint8_t sigma_get_register(uint8_t reg)
179{
180 uint8_t value;
fefa1800 181
28a35d8a
HE
182 if (1 != sigma_read_register(reg, &value, 1)) {
183 g_warning("Sigma_get_register: 1 byte expected");
184 return 0;
185 }
186
187 return value;
188}
189
190static int sigma_read_pos(uint32_t *stoppos, uint32_t *triggerpos)
191{
192 uint8_t buf[] = {
193 REG_ADDR_LOW | READ_TRIGGER_POS_LOW,
194
195 REG_READ_ADDR | NEXT_REG,
196 REG_READ_ADDR | NEXT_REG,
197 REG_READ_ADDR | NEXT_REG,
198 REG_READ_ADDR | NEXT_REG,
199 REG_READ_ADDR | NEXT_REG,
200 REG_READ_ADDR | NEXT_REG,
201 };
28a35d8a
HE
202 uint8_t result[6];
203
204 sigma_write(buf, sizeof(buf));
205
206 sigma_read(result, sizeof(result));
207
208 *triggerpos = result[0] | (result[1] << 8) | (result[2] << 16);
209 *stoppos = result[3] | (result[4] << 8) | (result[5] << 16);
210
57bbf56b
HE
211 /* Not really sure why this must be done, but according to spec. */
212 if ((--*stoppos & 0x1ff) == 0x1ff)
213 stoppos -= 64;
214
215 if ((*--triggerpos & 0x1ff) == 0x1ff)
216 triggerpos -= 64;
217
28a35d8a
HE
218 return 1;
219}
220
221static int sigma_read_dram(uint16_t startchunk, size_t numchunks, uint8_t *data)
222{
223 size_t i;
224 uint8_t buf[4096];
225 int idx = 0;
226
fefa1800 227 /* Send the startchunk. Index start with 1. */
28a35d8a
HE
228 buf[0] = startchunk >> 8;
229 buf[1] = startchunk & 0xff;
230 sigma_write_register(WRITE_MEMROW, buf, 2);
231
fefa1800 232 /* Read the DRAM. */
28a35d8a
HE
233 buf[idx++] = REG_DRAM_BLOCK;
234 buf[idx++] = REG_DRAM_WAIT_ACK;
235
236 for (i = 0; i < numchunks; ++i) {
fefa1800
UH
237 /* Alternate bit to copy from DRAM to cache. */
238 if (i != (numchunks - 1))
239 buf[idx++] = REG_DRAM_BLOCK | (((i + 1) % 2) << 4);
28a35d8a
HE
240
241 buf[idx++] = REG_DRAM_BLOCK_DATA | ((i % 2) << 4);
242
fefa1800 243 if (i != (numchunks - 1))
28a35d8a
HE
244 buf[idx++] = REG_DRAM_WAIT_ACK;
245 }
246
247 sigma_write(buf, idx);
248
249 return sigma_read(data, numchunks * CHUNK_SIZE);
250}
251
ee492173
HE
252/* Upload trigger look-up tables to Sigma */
253static int sigma_write_trigger_lut(struct triggerlut *lut)
254{
255 int i;
256 uint8_t tmp[2];
257 uint16_t bit;
258
259 /* Transpose the table and send to Sigma. */
260 for (i = 0; i < 16; ++i) {
261 bit = 1 << i;
262
263 tmp[0] = tmp[1] = 0;
264
265 if (lut->m2d[0] & bit)
266 tmp[0] |= 0x01;
267 if (lut->m2d[1] & bit)
268 tmp[0] |= 0x02;
269 if (lut->m2d[2] & bit)
270 tmp[0] |= 0x04;
271 if (lut->m2d[3] & bit)
272 tmp[0] |= 0x08;
273
274 if (lut->m3 & bit)
275 tmp[0] |= 0x10;
276 if (lut->m3s & bit)
277 tmp[0] |= 0x20;
278 if (lut->m4 & bit)
279 tmp[0] |= 0x40;
280
281 if (lut->m0d[0] & bit)
282 tmp[1] |= 0x01;
283 if (lut->m0d[1] & bit)
284 tmp[1] |= 0x02;
285 if (lut->m0d[2] & bit)
286 tmp[1] |= 0x04;
287 if (lut->m0d[3] & bit)
288 tmp[1] |= 0x08;
289
290 if (lut->m1d[0] & bit)
291 tmp[1] |= 0x10;
292 if (lut->m1d[1] & bit)
293 tmp[1] |= 0x20;
294 if (lut->m1d[2] & bit)
295 tmp[1] |= 0x40;
296 if (lut->m1d[3] & bit)
297 tmp[1] |= 0x80;
298
299 sigma_write_register(WRITE_TRIGGER_SELECT0, tmp, sizeof(tmp));
300 sigma_set_register(WRITE_TRIGGER_SELECT1, 0x30 | i);
301 }
302
303 /* Send the parameters */
304 sigma_write_register(WRITE_TRIGGER_SELECT0, (uint8_t *) &lut->params,
305 sizeof(lut->params));
306
307 return SIGROK_OK;
308}
309
fefa1800 310/* Generate the bitbang stream for programming the FPGA. */
28a35d8a 311static int bin2bitbang(const char *filename,
fefa1800 312 unsigned char **buf, size_t *buf_size)
28a35d8a 313{
fefa1800 314 FILE *f;
28a35d8a
HE
315 long file_size;
316 unsigned long offset = 0;
317 unsigned char *p;
318 uint8_t *compressed_buf, *firmware;
319 uLongf csize, fwsize;
320 const int buffer_size = 65536;
321 size_t i;
fefa1800
UH
322 int c, ret, bit, v;
323 uint32_t imm = 0x3f6df2ab;
28a35d8a 324
fefa1800 325 f = fopen(filename, "r");
28a35d8a
HE
326 if (!f) {
327 g_warning("fopen(\"%s\", \"r\")", filename);
328 return -1;
329 }
330
331 if (-1 == fseek(f, 0, SEEK_END)) {
332 g_warning("fseek on %s failed", filename);
333 fclose(f);
334 return -1;
335 }
336
337 file_size = ftell(f);
338
339 fseek(f, 0, SEEK_SET);
340
28a35d8a
HE
341 compressed_buf = g_malloc(file_size);
342 firmware = g_malloc(buffer_size);
343
344 if (!compressed_buf || !firmware) {
345 g_warning("Error allocating buffers");
346 return -1;
347 }
348
28a35d8a
HE
349 csize = 0;
350 while ((c = getc(f)) != EOF) {
351 imm = (imm + 0xa853753) % 177 + (imm * 0x8034052);
352 compressed_buf[csize++] = c ^ imm;
353 }
354 fclose(f);
355
356 fwsize = buffer_size;
357 ret = uncompress(firmware, &fwsize, compressed_buf, csize);
358 if (ret < 0) {
359 g_free(compressed_buf);
360 g_free(firmware);
361 g_warning("Could not unpack Sigma firmware. (Error %d)\n", ret);
362 return -1;
363 }
364
365 g_free(compressed_buf);
366
367 *buf_size = fwsize * 2 * 8;
368
fefa1800 369 *buf = p = (unsigned char *)g_malloc(*buf_size);
28a35d8a
HE
370
371 if (!p) {
372 g_warning("Error allocating buffers");
373 return -1;
374 }
375
376 for (i = 0; i < fwsize; ++i) {
28a35d8a 377 for (bit = 7; bit >= 0; --bit) {
fefa1800 378 v = firmware[i] & 1 << bit ? 0x40 : 0x00;
28a35d8a
HE
379 p[offset++] = v | 0x01;
380 p[offset++] = v;
381 }
382 }
383
384 g_free(firmware);
385
386 if (offset != *buf_size) {
387 g_free(*buf);
388 g_warning("Error reading firmware %s "
fefa1800
UH
389 "offset=%ld, file_size=%ld, buf_size=%zd\n",
390 filename, offset, file_size, *buf_size);
28a35d8a
HE
391
392 return -1;
393 }
394
395 return 0;
396}
397
398static int hw_init(char *deviceinfo)
399{
400 struct sigrok_device_instance *sdi;
401
402 deviceinfo = deviceinfo;
403
404 ftdi_init(&ftdic);
405
fefa1800
UH
406 /* Look for SIGMAs. */
407 if (ftdi_usb_open_desc(&ftdic, USB_VENDOR, USB_PRODUCT,
408 USB_DESCRIPTION, NULL) < 0)
28a35d8a
HE
409 return 0;
410
fefa1800 411 /* Register SIGMA device. */
28a35d8a
HE
412 sdi = sigrok_device_instance_new(0, ST_INITIALIZING,
413 USB_VENDOR_NAME, USB_MODEL_NAME, USB_MODEL_VERSION);
414 if (!sdi)
415 return 0;
416
417 device_instances = g_slist_append(device_instances, sdi);
418
fefa1800 419 /* We will open the device again when we need it. */
28a35d8a
HE
420 ftdi_usb_close(&ftdic);
421
422 return 1;
423}
424
f6564c8d 425static int upload_firmware(int firmware_idx)
28a35d8a
HE
426{
427 int ret;
428 unsigned char *buf;
429 unsigned char pins;
430 size_t buf_size;
28a35d8a 431 unsigned char result[32];
e8397563 432 char firmware_path[128];
28a35d8a 433
fefa1800 434 /* Make sure it's an ASIX SIGMA. */
28a35d8a
HE
435 if ((ret = ftdi_usb_open_desc(&ftdic,
436 USB_VENDOR, USB_PRODUCT, USB_DESCRIPTION, NULL)) < 0) {
28a35d8a 437 g_warning("ftdi_usb_open failed: %s",
fefa1800 438 ftdi_get_error_string(&ftdic));
28a35d8a
HE
439 return 0;
440 }
441
442 if ((ret = ftdi_set_bitmode(&ftdic, 0xdf, BITMODE_BITBANG)) < 0) {
443 g_warning("ftdi_set_bitmode failed: %s",
fefa1800 444 ftdi_get_error_string(&ftdic));
28a35d8a
HE
445 return 0;
446 }
447
fefa1800 448 /* Four times the speed of sigmalogan - Works well. */
28a35d8a
HE
449 if ((ret = ftdi_set_baudrate(&ftdic, 750000)) < 0) {
450 g_warning("ftdi_set_baudrate failed: %s",
fefa1800 451 ftdi_get_error_string(&ftdic));
28a35d8a
HE
452 return 0;
453 }
454
fefa1800 455 /* Force the FPGA to reboot. */
28a35d8a
HE
456 sigma_write(suicide, sizeof(suicide));
457 sigma_write(suicide, sizeof(suicide));
458 sigma_write(suicide, sizeof(suicide));
459 sigma_write(suicide, sizeof(suicide));
460
fefa1800 461 /* Prepare to upload firmware (FPGA specific). */
28a35d8a
HE
462 sigma_write(init, sizeof(init));
463
464 ftdi_usb_purge_buffers(&ftdic);
465
fefa1800 466 /* Wait until the FPGA asserts INIT_B. */
28a35d8a
HE
467 while (1) {
468 ret = sigma_read(result, 1);
469 if (result[0] & 0x20)
470 break;
471 }
472
9ddb2a12 473 /* Prepare firmware. */
e8397563 474 snprintf(firmware_path, sizeof(firmware_path), "%s/%s", FIRMWARE_DIR,
f6564c8d
HE
475 firmware_files[firmware_idx]);
476
e8397563 477 if (-1 == bin2bitbang(firmware_path, &buf, &buf_size)) {
28a35d8a 478 g_warning("An error occured while reading the firmware: %s",
e8397563 479 firmware_path);
28a35d8a
HE
480 return SIGROK_ERR;
481 }
482
fefa1800 483 /* Upload firmare. */
28a35d8a
HE
484 sigma_write(buf, buf_size);
485
486 g_free(buf);
487
488 if ((ret = ftdi_set_bitmode(&ftdic, 0x00, BITMODE_RESET)) < 0) {
9ddb2a12 489 g_warning("ftdi_set_bitmode failed: %s",
fefa1800 490 ftdi_get_error_string(&ftdic));
28a35d8a
HE
491 return SIGROK_ERR;
492 }
493
494 ftdi_usb_purge_buffers(&ftdic);
495
fefa1800 496 /* Discard garbage. */
28a35d8a
HE
497 while (1 == sigma_read(&pins, 1))
498 ;
499
fefa1800 500 /* Initialize the logic analyzer mode. */
28a35d8a
HE
501 sigma_write(logic_mode_start, sizeof(logic_mode_start));
502
fefa1800 503 /* Expect a 3 byte reply. */
28a35d8a
HE
504 ret = sigma_read(result, 3);
505 if (ret != 3 ||
506 result[0] != 0xa6 || result[1] != 0x55 || result[2] != 0xaa) {
fefa1800 507 g_warning("Configuration failed. Invalid reply received.");
28a35d8a
HE
508 return SIGROK_ERR;
509 }
510
f6564c8d
HE
511 cur_firmware = firmware_idx;
512
513 return SIGROK_OK;
514}
515
516static int hw_opendev(int device_index)
517{
518 struct sigrok_device_instance *sdi;
519 int ret;
520
9ddb2a12 521 /* Make sure it's an ASIX SIGMA. */
f6564c8d
HE
522 if ((ret = ftdi_usb_open_desc(&ftdic,
523 USB_VENDOR, USB_PRODUCT, USB_DESCRIPTION, NULL)) < 0) {
524
525 g_warning("ftdi_usb_open failed: %s",
526 ftdi_get_error_string(&ftdic));
527
528 return 0;
529 }
28a35d8a
HE
530
531 if (!(sdi = get_sigrok_device_instance(device_instances, device_index)))
532 return SIGROK_ERR;
533
534 sdi->status = ST_ACTIVE;
535
f6564c8d
HE
536 return SIGROK_OK;
537}
538
539static int set_samplerate(struct sigrok_device_instance *sdi, uint64_t samplerate)
540{
e8397563 541 int i, ret;
f6564c8d
HE
542
543 sdi = sdi;
544
545 for (i = 0; supported_samplerates[i]; i++) {
546 if (supported_samplerates[i] == samplerate)
547 break;
548 }
549 if (supported_samplerates[i] == 0)
550 return SIGROK_ERR_SAMPLERATE;
551
e8397563
HE
552 if (samplerate <= MHZ(50)) {
553 ret = upload_firmware(0);
f78898e9 554 num_probes = 16;
e8397563 555 }
f78898e9 556 if (samplerate == MHZ(100)) {
e8397563 557 ret = upload_firmware(1);
f78898e9
HE
558 num_probes = 8;
559 }
560 else if (samplerate == MHZ(200)) {
e8397563 561 ret = upload_firmware(2);
f78898e9
HE
562 num_probes = 4;
563 }
f6564c8d 564
e8397563 565 cur_samplerate = samplerate;
f78898e9 566 samples_per_event = 16 / num_probes;
f6564c8d 567
28a35d8a
HE
568 g_message("Firmware uploaded");
569
e8397563 570 return ret;
28a35d8a
HE
571}
572
eec5275e 573/* Only trigger on single pin supported (in 100-200 MHz modes). */
57bbf56b
HE
574static int configure_probes(GSList *probes)
575{
576 struct probe *probe;
577 GSList *l;
578 int trigger_set = 0;
579
ee492173
HE
580 triggermask = 0;
581 triggervalue = 0;
eec5275e 582
57bbf56b
HE
583 for (l = probes; l; l = l->next) {
584 probe = (struct probe *)l->data;
585
586 if (!probe->enabled || !probe->trigger)
587 continue;
588
ee492173
HE
589 if (cur_samplerate >= MHZ(100)) {
590 /* Fast trigger support */
591 if (trigger_set) {
592 g_warning("Asix Sigma only supports a single pin trigger "
593 "in 100 and 200 MHz mode.");
594 return SIGROK_ERR;
595 }
596 if (probe->trigger[0] == 'f')
597 triggerfall = 1;
598 else if (probe->trigger[0] == 'r')
599 triggerfall = 0;
600 else {
601 g_warning("Asix Sigma only supports "
602 "rising/falling trigger in 100 "
603 "and 200 MHz mode.");
604 return SIGROK_ERR;
605 }
57bbf56b 606
ee492173
HE
607 triggerpin = probe->index - 1;
608 } else {
609 /* Normal trigger support */
610 triggermask |= 1 << (probe->index - 1);
611
612 if (probe->trigger[0] == '1')
613 triggervalue |= 1 << (probe->index - 1);
614 else if (probe->trigger[0] == '0')
615 triggervalue |= 0 << (probe->index - 1);
616 else {
617 g_warning("Asix Sigma only supports "
618 "trigger values in <= 50"
619 " MHz mode.");
620 return SIGROK_ERR;
621 }
57bbf56b 622
ee492173
HE
623 }
624
625 ++trigger_set;
57bbf56b
HE
626 }
627
628 return SIGROK_OK;
629}
630
28a35d8a
HE
631static void hw_closedev(int device_index)
632{
633 device_index = device_index;
634
635 ftdi_usb_close(&ftdic);
636}
637
28a35d8a
HE
638static void hw_cleanup(void)
639{
640}
641
28a35d8a
HE
642static void *hw_get_device_info(int device_index, int device_info_id)
643{
644 struct sigrok_device_instance *sdi;
645 void *info = NULL;
646
647 if (!(sdi = get_sigrok_device_instance(device_instances, device_index))) {
648 fprintf(stderr, "It's NULL.\n");
649 return NULL;
650 }
651
652 switch (device_info_id) {
653 case DI_INSTANCE:
654 info = sdi;
655 break;
656 case DI_NUM_PROBES:
edca2c5c 657 info = GINT_TO_POINTER(16);
28a35d8a
HE
658 break;
659 case DI_SAMPLERATES:
660 info = &samplerates;
661 break;
662 case DI_TRIGGER_TYPES:
57bbf56b 663 info = (char *)TRIGGER_TYPES;
28a35d8a
HE
664 break;
665 case DI_CUR_SAMPLERATE:
666 info = &cur_samplerate;
667 break;
668 }
669
670 return info;
671}
672
28a35d8a
HE
673static int hw_get_status(int device_index)
674{
675 struct sigrok_device_instance *sdi;
676
677 sdi = get_sigrok_device_instance(device_instances, device_index);
678 if (sdi)
679 return sdi->status;
680 else
681 return ST_NOT_FOUND;
682}
683
28a35d8a
HE
684static int *hw_get_capabilities(void)
685{
686 return capabilities;
687}
688
689static int hw_set_configuration(int device_index, int capability, void *value)
690{
691 struct sigrok_device_instance *sdi;
692 int ret;
f6564c8d 693
28a35d8a
HE
694 if (!(sdi = get_sigrok_device_instance(device_instances, device_index)))
695 return SIGROK_ERR;
696
697 if (capability == HWCAP_SAMPLERATE) {
f6564c8d 698 ret = set_samplerate(sdi, *(uint64_t*) value);
28a35d8a 699 } else if (capability == HWCAP_PROBECONFIG) {
57bbf56b 700 ret = configure_probes(value);
28a35d8a
HE
701 } else if (capability == HWCAP_LIMIT_MSEC) {
702 limit_msec = strtoull(value, NULL, 10);
703 ret = SIGROK_OK;
57bbf56b
HE
704 } else if (capability == HWCAP_CAPTURE_RATIO) {
705 capture_ratio = strtoull(value, NULL, 10);
706 ret = SIGROK_OK;
707 } else if (capability == HWCAP_PROBECONFIG) {
708 ret = configure_probes((GSList *) value);
28a35d8a
HE
709 } else {
710 ret = SIGROK_ERR;
711 }
712
713 return ret;
714}
715
28a35d8a 716/*
fefa1800
UH
717 * Decode chunk of 1024 bytes, 64 clusters, 7 events per cluster.
718 * Each event is 20ns apart, and can contain multiple samples.
f78898e9
HE
719 *
720 * For 200 MHz, events contain 4 samples for each channel, spread 5 ns apart.
721 * For 100 MHz, events contain 2 samples for each channel, spread 10 ns apart.
722 * For 50 MHz and below, events contain one sample for each channel,
723 * spread 20 ns apart.
28a35d8a
HE
724 */
725static int decode_chunk_ts(uint8_t *buf, uint16_t *lastts,
57bbf56b 726 uint16_t *lastsample, int triggerpos, void *user_data)
28a35d8a 727{
fefa1800 728 uint16_t tsdiff, ts;
f78898e9 729 uint16_t samples[65536 * samples_per_event];
28a35d8a 730 struct datafeed_packet packet;
f78898e9 731 int i, j, k, l, numpad, tosend;
fefa1800 732 size_t n = 0, sent = 0;
f78898e9 733 int clustersize = EVENTS_PER_CLUSTER * samples_per_event;
fefa1800 734 uint16_t *event;
f78898e9 735 uint16_t cur_sample;
57bbf56b 736 int triggerts = -1;
ee492173
HE
737 int triggeroff = 0;
738
739 if (triggerpos != -1) {
740 if (cur_samplerate <= MHZ(50))
741 triggerpos -= EVENTS_PER_CLUSTER;
742 else
743 triggeroff = 3;
744
745 if (triggerpos < 0)
746 triggerpos = 0;
57bbf56b 747
ee492173
HE
748 /* Find in which cluster the trigger occured. */
749 triggerts = triggerpos / 7;
750 }
28a35d8a 751
eec5275e 752 /* For each ts. */
28a35d8a 753 for (i = 0; i < 64; ++i) {
fefa1800 754 ts = *(uint16_t *) &buf[i * 16];
28a35d8a
HE
755 tsdiff = ts - *lastts;
756 *lastts = ts;
757
fefa1800
UH
758 /* Pad last sample up to current point. */
759 numpad = tsdiff * samples_per_event - clustersize;
28a35d8a 760 if (numpad > 0) {
f78898e9
HE
761 for (j = 0; j < numpad; ++j)
762 samples[j] = *lastsample;
763
764 n = numpad;
28a35d8a
HE
765 }
766
57bbf56b
HE
767 /* Send samples between previous and this timestamp to sigrok. */
768 sent = 0;
769 while (sent < n) {
770 tosend = MIN(2048, n - sent);
771
772 packet.type = DF_LOGIC16;
773 packet.length = tosend * sizeof(uint16_t);
774 packet.payload = samples + sent;
775 session_bus(user_data, &packet);
28a35d8a 776
57bbf56b
HE
777 sent += tosend;
778 }
779 n = 0;
780
781 event = (uint16_t *) &buf[i * 16 + 2];
f78898e9
HE
782 cur_sample = 0;
783
784 /* For each event in cluster. */
28a35d8a 785 for (j = 0; j < 7; ++j) {
f78898e9
HE
786
787 /* For each sample in event. */
28a35d8a 788 for (k = 0; k < samples_per_event; ++k) {
f78898e9
HE
789 cur_sample = 0;
790
791 /* For each probe. */
792 for (l = 0; l < num_probes; ++l)
edca2c5c
HE
793 cur_sample |= (!!(event[j] & (1 << (l *
794 samples_per_event + k))))
795 << l;
f78898e9
HE
796
797 samples[n++] = cur_sample;
28a35d8a
HE
798 }
799 }
800
eec5275e 801 /* Send data up to trigger point (if triggered). */
fefa1800 802 sent = 0;
57bbf56b
HE
803 if (i == triggerts) {
804 /*
805 * Trigger is presumptively only accurate to event, i.e.
806 * for 100 and 200 MHz, where multiple samples are coded
807 * in a single event, the trigger does not match the
808 * exact sample.
809 */
ee492173 810 tosend = (triggerpos % 7) - triggeroff;
57bbf56b
HE
811
812 if (tosend > 0) {
813 packet.type = DF_LOGIC16;
814 packet.length = tosend * sizeof(uint16_t);
815 packet.payload = samples;
816 session_bus(user_data, &packet);
817
818 sent += tosend;
819 }
28a35d8a 820
57bbf56b
HE
821 packet.type = DF_TRIGGER;
822 packet.length = 0;
823 packet.payload = 0;
28a35d8a 824 session_bus(user_data, &packet);
28a35d8a 825 }
57bbf56b 826
eec5275e 827 /* Send rest of the chunk to sigrok. */
57bbf56b
HE
828 tosend = n - sent;
829
830 packet.type = DF_LOGIC16;
831 packet.length = tosend * sizeof(uint16_t);
832 packet.payload = samples + sent;
833 session_bus(user_data, &packet);
ee492173
HE
834
835 *lastsample = samples[n - 1];
28a35d8a
HE
836 }
837
f78898e9 838 return SIGROK_OK;
28a35d8a
HE
839}
840
841static int receive_data(int fd, int revents, void *user_data)
842{
843 struct datafeed_packet packet;
28a35d8a
HE
844 const int chunks_per_read = 32;
845 unsigned char buf[chunks_per_read * CHUNK_SIZE];
fefa1800
UH
846 int bufsz, numchunks, curchunk, i, newchunks;
847 uint32_t triggerpos, stoppos, running_msec;
28a35d8a 848 struct timeval tv;
28a35d8a 849 uint16_t lastts = 0;
f78898e9 850 uint16_t lastsample = 0;
57bbf56b
HE
851 uint8_t modestatus;
852 int triggerchunk = -1;
28a35d8a
HE
853
854 fd = fd;
855 revents = revents;
856
fefa1800 857 /* Get the current position. */
28a35d8a
HE
858 sigma_read_pos(&stoppos, &triggerpos);
859 numchunks = stoppos / 512;
860
fefa1800 861 /* Check if the has expired, or memory is full. */
28a35d8a
HE
862 gettimeofday(&tv, 0);
863 running_msec = (tv.tv_sec - start_tv.tv_sec) * 1000 +
fefa1800 864 (tv.tv_usec - start_tv.tv_usec) / 1000;
28a35d8a
HE
865
866 if (running_msec < limit_msec && numchunks < 32767)
867 return FALSE;
868
fefa1800 869 /* Stop acqusition. */
28a35d8a
HE
870 sigma_set_register(WRITE_MODE, 0x11);
871
fefa1800 872 /* Set SDRAM Read Enable. */
28a35d8a
HE
873 sigma_set_register(WRITE_MODE, 0x02);
874
fefa1800 875 /* Get the current position. */
28a35d8a
HE
876 sigma_read_pos(&stoppos, &triggerpos);
877
eec5275e 878 /* Check if trigger has fired. */
57bbf56b
HE
879 modestatus = sigma_get_register(READ_MODE);
880 if (modestatus & 0x20) {
881 triggerchunk = triggerpos / 512;
882 }
f78898e9 883
fefa1800 884 /* Download sample data. */
28a35d8a 885 for (curchunk = 0; curchunk < numchunks;) {
fefa1800 886 newchunks = MIN(chunks_per_read, numchunks - curchunk);
28a35d8a
HE
887
888 g_message("Downloading sample data: %.0f %%",
fefa1800 889 100.0 * curchunk / numchunks);
28a35d8a
HE
890
891 bufsz = sigma_read_dram(curchunk, newchunks, buf);
892
fefa1800
UH
893 /* Find first ts. */
894 if (curchunk == 0)
895 lastts = *(uint16_t *) buf - 1;
28a35d8a 896
fefa1800 897 /* Decode chunks and send them to sigrok. */
28a35d8a 898 for (i = 0; i < newchunks; ++i) {
57bbf56b
HE
899 if (curchunk + i == triggerchunk)
900 decode_chunk_ts(buf + (i * CHUNK_SIZE),
901 &lastts, &lastsample,
902 triggerpos & 0x1ff, user_data);
903 else
904 decode_chunk_ts(buf + (i * CHUNK_SIZE),
905 &lastts, &lastsample,
906 -1, user_data);
28a35d8a
HE
907 }
908
909 curchunk += newchunks;
910 }
911
eec5275e 912 /* End of data. */
28a35d8a
HE
913 packet.type = DF_END;
914 packet.length = 0;
915 session_bus(user_data, &packet);
916
917 return TRUE;
918}
919
ee492173
HE
920/*
921 * Build trigger LUTs used by 50 MHz and lower sample rates for supporting
922 * simple pin change and state triggers. Only two transitions (rise/fall) can be
923 * set at any time, but a full mask and value can be set (0/1).
924 */
925static int build_basic_trigger(struct triggerlut *lut)
926{
927 int i, j, k, bit;
928
929 memset(lut, 0, sizeof(struct triggerlut));
930
931 /* Unknown */
932 lut->m4 = 0xa000;
933
934 /* Set the LUT for controlling value/maske trigger */
f758d074
HE
935
936 /* For each quad probe. */
ee492173
HE
937 for (i = 0; i < 4; ++i) {
938 lut->m2d[i] = 0xffff;
939
f758d074 940 /* For each bit in LUT. */
ee492173
HE
941 for (j = 0; j < 16; ++j)
942
f758d074 943 /* For each probe in quad. */
ee492173
HE
944 for (k = 0; k < 4; ++k) {
945 bit = 1 << (i * 4 + k);
946
947 if ((triggermask & bit) &&
f758d074
HE
948 ((!(triggervalue & bit)) !=
949 (!(j & (1 << k)))))
ee492173 950 lut->m2d[i] &= ~(1 << j);
ee492173
HE
951 }
952 }
953
ee492173
HE
954 /* Unused when not triggering on transitions */
955 lut->m3 = 0xffff;
956
957 /* Triggertype: event */
958 lut->params.selres = 3;
959
960 return SIGROK_OK;
961}
962
28a35d8a
HE
963static int hw_start_acquisition(int device_index, gpointer session_device_id)
964{
965 struct sigrok_device_instance *sdi;
966 struct datafeed_packet packet;
967 struct datafeed_header header;
9ddb2a12
UH
968 struct clockselect_50 clockselect;
969 int frac;
57bbf56b
HE
970 uint8_t triggerselect;
971 struct triggerinout triggerinout_conf;
ee492173 972 struct triggerlut lut;
28a35d8a
HE
973
974 session_device_id = session_device_id;
975
976 if (!(sdi = get_sigrok_device_instance(device_instances, device_index)))
977 return SIGROK_ERR;
978
979 device_index = device_index;
980
ed09fd07 981 /* If the samplerate has not been set, default to 50 MHz. */
9ddb2a12 982 if (cur_firmware == -1)
ed09fd07 983 set_samplerate(sdi, MHZ(50));
e8397563 984
eec5275e 985 /* Enter trigger programming mode. */
28a35d8a
HE
986 sigma_set_register(WRITE_TRIGGER_SELECT1, 0x20);
987
eec5275e 988 /* 100 and 200 MHz mode. */
57bbf56b
HE
989 if (cur_samplerate >= MHZ(100)) {
990 sigma_set_register(WRITE_TRIGGER_SELECT1, 0x81);
991
992 triggerselect = (1 << LEDSEL1) | (triggerfall << 3) |
993 (triggerpin & 0x7);
994
eec5275e 995 /* All other modes. */
57bbf56b 996 } else if (cur_samplerate <= MHZ(50)) {
ee492173
HE
997 build_basic_trigger(&lut);
998
999 sigma_write_trigger_lut(&lut);
57bbf56b
HE
1000
1001 triggerselect = (1 << LEDSEL1) | (1 << LEDSEL0);
1002 }
1003
eec5275e 1004 /* Setup trigger in and out pins to default values. */
57bbf56b
HE
1005 memset(&triggerinout_conf, 0, sizeof(struct triggerinout));
1006 triggerinout_conf.trgout_bytrigger = 1;
1007 triggerinout_conf.trgout_enable = 1;
1008
28a35d8a 1009 sigma_write_register(WRITE_TRIGGER_OPTION,
57bbf56b
HE
1010 (uint8_t *) &triggerinout_conf,
1011 sizeof(struct triggerinout));
28a35d8a 1012
eec5275e 1013 /* Go back to normal mode. */
57bbf56b 1014 sigma_set_register(WRITE_TRIGGER_SELECT1, triggerselect);
28a35d8a 1015
edca2c5c
HE
1016 /* Set clock select register. */
1017 if (cur_samplerate == MHZ(200))
1018 /* Enable 4 probes. */
1019 sigma_set_register(WRITE_CLOCK_SELECT, 0xf0);
1020 else if (cur_samplerate == MHZ(100))
1021 /* Enable 8 probes. */
1022 sigma_set_register(WRITE_CLOCK_SELECT, 0x00);
1023 else {
1024 /*
9ddb2a12 1025 * 50 MHz mode (or fraction thereof). Any fraction down to
eec5275e 1026 * 50 MHz / 256 can be used, but is not supported by sigrok API.
edca2c5c 1027 */
9ddb2a12 1028 frac = MHZ(50) / cur_samplerate - 1;
edca2c5c 1029
9ddb2a12
UH
1030 clockselect.async = 0;
1031 clockselect.fraction = frac;
1032 clockselect.disabled_probes = 0;
edca2c5c
HE
1033
1034 sigma_write_register(WRITE_CLOCK_SELECT,
9ddb2a12
UH
1035 (uint8_t *) &clockselect,
1036 sizeof(clockselect));
edca2c5c
HE
1037 }
1038
fefa1800 1039 /* Setup maximum post trigger time. */
57bbf56b 1040 sigma_set_register(WRITE_POST_TRIGGER, (capture_ratio * 256) / 100);
28a35d8a 1041
eec5275e 1042 /* Start acqusition. */
28a35d8a
HE
1043 gettimeofday(&start_tv, 0);
1044 sigma_set_register(WRITE_MODE, 0x0d);
1045
28a35d8a
HE
1046 /* Send header packet to the session bus. */
1047 packet.type = DF_HEADER;
1048 packet.length = sizeof(struct datafeed_header);
1049 packet.payload = &header;
1050 header.feed_version = 1;
1051 gettimeofday(&header.starttime, NULL);
1052 header.samplerate = cur_samplerate;
1053 header.protocol_id = PROTO_RAW;
edca2c5c 1054 header.num_probes = num_probes;
28a35d8a
HE
1055 session_bus(session_device_id, &packet);
1056
57bbf56b
HE
1057 /* Add capture source. */
1058 source_add(0, G_IO_IN, 10, receive_data, session_device_id);
1059
28a35d8a
HE
1060 return SIGROK_OK;
1061}
1062
28a35d8a
HE
1063static void hw_stop_acquisition(int device_index, gpointer session_device_id)
1064{
1065 device_index = device_index;
1066 session_device_id = session_device_id;
1067
fefa1800 1068 /* Stop acquisition. */
28a35d8a
HE
1069 sigma_set_register(WRITE_MODE, 0x11);
1070
1071 // XXX Set some state to indicate that data should be sent to sigrok
1072 // Now, we just wait for timeout
1073}
1074
28a35d8a
HE
1075struct device_plugin asix_sigma_plugin_info = {
1076 "asix-sigma",
1077 1,
1078 hw_init,
1079 hw_cleanup,
28a35d8a
HE
1080 hw_opendev,
1081 hw_closedev,
1082 hw_get_device_info,
1083 hw_get_status,
1084 hw_get_capabilities,
1085 hw_set_configuration,
1086 hw_start_acquisition,
9ddb2a12 1087 hw_stop_acquisition,
28a35d8a 1088};