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