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