]> sigrok.org Git - libsigrok.git/blame - hardware/asix-sigma/asix-sigma.c
Sigma: Small 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 ""
57bbf56b 38#define TRIGGER_TYPES "rf"
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
eec5275e 52/* Single-pin trigger support. */
57bbf56b
HE
53static uint8_t triggerpin = 1;
54static uint8_t triggerfall = 0;
28a35d8a
HE
55
56static uint64_t supported_samplerates[] = {
ed09fd07 57 KHZ(200),
edca2c5c 58 KHZ(250),
ed09fd07 59 KHZ(500),
edca2c5c 60 MHZ(1),
ed09fd07 61 MHZ(5),
edca2c5c
HE
62 MHZ(10),
63 MHZ(25),
e8397563
HE
64 MHZ(50),
65 MHZ(100),
28a35d8a
HE
66 MHZ(200),
67 0,
68};
69
70static struct samplerates samplerates = {
ed09fd07 71 KHZ(200),
28a35d8a
HE
72 MHZ(200),
73 0,
74 supported_samplerates,
75};
76
77static int capabilities[] = {
78 HWCAP_LOGIC_ANALYZER,
79 HWCAP_SAMPLERATE,
57bbf56b
HE
80 HWCAP_CAPTURE_RATIO,
81 HWCAP_PROBECONFIG,
28a35d8a 82
28a35d8a
HE
83 HWCAP_LIMIT_MSEC,
84 0,
85};
86
fefa1800
UH
87/* Force the FPGA to reboot. */
88static uint8_t suicide[] = {
89 0x84, 0x84, 0x88, 0x84, 0x88, 0x84, 0x88, 0x84,
90};
91
92/* Prepare to upload firmware (FPGA specific). */
93static uint8_t init[] = {
94 0x03, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
95};
96
97/* Initialize the logic analyzer mode. */
98static uint8_t logic_mode_start[] = {
99 0x00, 0x40, 0x0f, 0x25, 0x35, 0x40,
100 0x2a, 0x3a, 0x40, 0x03, 0x20, 0x38,
101};
102
eec5275e 103static const char *firmware_files[] = {
a8116d76
HE
104 "asix-sigma-50.fw", /* 50 MHz, supports 8 bit fractions */
105 "asix-sigma-100.fw", /* 100 MHz */
106 "asix-sigma-200.fw", /* 200 MHz */
ed09fd07 107 "asix-sigma-50sync.fw", /* Synchronous clock from pin */
a8116d76 108 "asix-sigma-phasor.fw", /* Frequency counter */
f6564c8d
HE
109};
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
fefa1800 248/* Generate the bitbang stream for programming the FPGA. */
28a35d8a 249static int bin2bitbang(const char *filename,
fefa1800 250 unsigned char **buf, size_t *buf_size)
28a35d8a 251{
fefa1800 252 FILE *f;
28a35d8a
HE
253 long file_size;
254 unsigned long offset = 0;
255 unsigned char *p;
256 uint8_t *compressed_buf, *firmware;
257 uLongf csize, fwsize;
258 const int buffer_size = 65536;
259 size_t i;
fefa1800
UH
260 int c, ret, bit, v;
261 uint32_t imm = 0x3f6df2ab;
28a35d8a 262
fefa1800 263 f = fopen(filename, "r");
28a35d8a
HE
264 if (!f) {
265 g_warning("fopen(\"%s\", \"r\")", filename);
266 return -1;
267 }
268
269 if (-1 == fseek(f, 0, SEEK_END)) {
270 g_warning("fseek on %s failed", filename);
271 fclose(f);
272 return -1;
273 }
274
275 file_size = ftell(f);
276
277 fseek(f, 0, SEEK_SET);
278
28a35d8a
HE
279 compressed_buf = g_malloc(file_size);
280 firmware = g_malloc(buffer_size);
281
282 if (!compressed_buf || !firmware) {
283 g_warning("Error allocating buffers");
284 return -1;
285 }
286
28a35d8a
HE
287 csize = 0;
288 while ((c = getc(f)) != EOF) {
289 imm = (imm + 0xa853753) % 177 + (imm * 0x8034052);
290 compressed_buf[csize++] = c ^ imm;
291 }
292 fclose(f);
293
294 fwsize = buffer_size;
295 ret = uncompress(firmware, &fwsize, compressed_buf, csize);
296 if (ret < 0) {
297 g_free(compressed_buf);
298 g_free(firmware);
299 g_warning("Could not unpack Sigma firmware. (Error %d)\n", ret);
300 return -1;
301 }
302
303 g_free(compressed_buf);
304
305 *buf_size = fwsize * 2 * 8;
306
fefa1800 307 *buf = p = (unsigned char *)g_malloc(*buf_size);
28a35d8a
HE
308
309 if (!p) {
310 g_warning("Error allocating buffers");
311 return -1;
312 }
313
314 for (i = 0; i < fwsize; ++i) {
28a35d8a 315 for (bit = 7; bit >= 0; --bit) {
fefa1800 316 v = firmware[i] & 1 << bit ? 0x40 : 0x00;
28a35d8a
HE
317 p[offset++] = v | 0x01;
318 p[offset++] = v;
319 }
320 }
321
322 g_free(firmware);
323
324 if (offset != *buf_size) {
325 g_free(*buf);
326 g_warning("Error reading firmware %s "
fefa1800
UH
327 "offset=%ld, file_size=%ld, buf_size=%zd\n",
328 filename, offset, file_size, *buf_size);
28a35d8a
HE
329
330 return -1;
331 }
332
333 return 0;
334}
335
336static int hw_init(char *deviceinfo)
337{
338 struct sigrok_device_instance *sdi;
339
340 deviceinfo = deviceinfo;
341
342 ftdi_init(&ftdic);
343
fefa1800
UH
344 /* Look for SIGMAs. */
345 if (ftdi_usb_open_desc(&ftdic, USB_VENDOR, USB_PRODUCT,
346 USB_DESCRIPTION, NULL) < 0)
28a35d8a
HE
347 return 0;
348
fefa1800 349 /* Register SIGMA device. */
28a35d8a
HE
350 sdi = sigrok_device_instance_new(0, ST_INITIALIZING,
351 USB_VENDOR_NAME, USB_MODEL_NAME, USB_MODEL_VERSION);
352 if (!sdi)
353 return 0;
354
355 device_instances = g_slist_append(device_instances, sdi);
356
fefa1800 357 /* We will open the device again when we need it. */
28a35d8a
HE
358 ftdi_usb_close(&ftdic);
359
360 return 1;
361}
362
f6564c8d 363static int upload_firmware(int firmware_idx)
28a35d8a
HE
364{
365 int ret;
366 unsigned char *buf;
367 unsigned char pins;
368 size_t buf_size;
28a35d8a 369 unsigned char result[32];
e8397563 370 char firmware_path[128];
28a35d8a 371
fefa1800 372 /* Make sure it's an ASIX SIGMA. */
28a35d8a
HE
373 if ((ret = ftdi_usb_open_desc(&ftdic,
374 USB_VENDOR, USB_PRODUCT, USB_DESCRIPTION, NULL)) < 0) {
28a35d8a 375 g_warning("ftdi_usb_open failed: %s",
fefa1800 376 ftdi_get_error_string(&ftdic));
28a35d8a
HE
377 return 0;
378 }
379
380 if ((ret = ftdi_set_bitmode(&ftdic, 0xdf, BITMODE_BITBANG)) < 0) {
381 g_warning("ftdi_set_bitmode failed: %s",
fefa1800 382 ftdi_get_error_string(&ftdic));
28a35d8a
HE
383 return 0;
384 }
385
fefa1800 386 /* Four times the speed of sigmalogan - Works well. */
28a35d8a
HE
387 if ((ret = ftdi_set_baudrate(&ftdic, 750000)) < 0) {
388 g_warning("ftdi_set_baudrate failed: %s",
fefa1800 389 ftdi_get_error_string(&ftdic));
28a35d8a
HE
390 return 0;
391 }
392
fefa1800 393 /* Force the FPGA to reboot. */
28a35d8a
HE
394 sigma_write(suicide, sizeof(suicide));
395 sigma_write(suicide, sizeof(suicide));
396 sigma_write(suicide, sizeof(suicide));
397 sigma_write(suicide, sizeof(suicide));
398
fefa1800 399 /* Prepare to upload firmware (FPGA specific). */
28a35d8a
HE
400 sigma_write(init, sizeof(init));
401
402 ftdi_usb_purge_buffers(&ftdic);
403
fefa1800 404 /* Wait until the FPGA asserts INIT_B. */
28a35d8a
HE
405 while (1) {
406 ret = sigma_read(result, 1);
407 if (result[0] & 0x20)
408 break;
409 }
410
9ddb2a12 411 /* Prepare firmware. */
e8397563 412 snprintf(firmware_path, sizeof(firmware_path), "%s/%s", FIRMWARE_DIR,
f6564c8d
HE
413 firmware_files[firmware_idx]);
414
e8397563 415 if (-1 == bin2bitbang(firmware_path, &buf, &buf_size)) {
28a35d8a 416 g_warning("An error occured while reading the firmware: %s",
e8397563 417 firmware_path);
28a35d8a
HE
418 return SIGROK_ERR;
419 }
420
fefa1800 421 /* Upload firmare. */
28a35d8a
HE
422 sigma_write(buf, buf_size);
423
424 g_free(buf);
425
426 if ((ret = ftdi_set_bitmode(&ftdic, 0x00, BITMODE_RESET)) < 0) {
9ddb2a12 427 g_warning("ftdi_set_bitmode failed: %s",
fefa1800 428 ftdi_get_error_string(&ftdic));
28a35d8a
HE
429 return SIGROK_ERR;
430 }
431
432 ftdi_usb_purge_buffers(&ftdic);
433
fefa1800 434 /* Discard garbage. */
28a35d8a
HE
435 while (1 == sigma_read(&pins, 1))
436 ;
437
fefa1800 438 /* Initialize the logic analyzer mode. */
28a35d8a
HE
439 sigma_write(logic_mode_start, sizeof(logic_mode_start));
440
fefa1800 441 /* Expect a 3 byte reply. */
28a35d8a
HE
442 ret = sigma_read(result, 3);
443 if (ret != 3 ||
444 result[0] != 0xa6 || result[1] != 0x55 || result[2] != 0xaa) {
fefa1800 445 g_warning("Configuration failed. Invalid reply received.");
28a35d8a
HE
446 return SIGROK_ERR;
447 }
448
f6564c8d
HE
449 cur_firmware = firmware_idx;
450
451 return SIGROK_OK;
452}
453
454static int hw_opendev(int device_index)
455{
456 struct sigrok_device_instance *sdi;
457 int ret;
458
9ddb2a12 459 /* Make sure it's an ASIX SIGMA. */
f6564c8d
HE
460 if ((ret = ftdi_usb_open_desc(&ftdic,
461 USB_VENDOR, USB_PRODUCT, USB_DESCRIPTION, NULL)) < 0) {
462
463 g_warning("ftdi_usb_open failed: %s",
464 ftdi_get_error_string(&ftdic));
465
466 return 0;
467 }
28a35d8a
HE
468
469 if (!(sdi = get_sigrok_device_instance(device_instances, device_index)))
470 return SIGROK_ERR;
471
472 sdi->status = ST_ACTIVE;
473
f6564c8d
HE
474 return SIGROK_OK;
475}
476
477static int set_samplerate(struct sigrok_device_instance *sdi, uint64_t samplerate)
478{
e8397563 479 int i, ret;
f6564c8d
HE
480
481 sdi = sdi;
482
483 for (i = 0; supported_samplerates[i]; i++) {
484 if (supported_samplerates[i] == samplerate)
485 break;
486 }
487 if (supported_samplerates[i] == 0)
488 return SIGROK_ERR_SAMPLERATE;
489
e8397563
HE
490 if (samplerate <= MHZ(50)) {
491 ret = upload_firmware(0);
f78898e9 492 num_probes = 16;
e8397563 493 }
f78898e9 494 if (samplerate == MHZ(100)) {
e8397563 495 ret = upload_firmware(1);
f78898e9
HE
496 num_probes = 8;
497 }
498 else if (samplerate == MHZ(200)) {
e8397563 499 ret = upload_firmware(2);
f78898e9
HE
500 num_probes = 4;
501 }
f6564c8d 502
e8397563 503 cur_samplerate = samplerate;
f78898e9 504 samples_per_event = 16 / num_probes;
f6564c8d 505
28a35d8a
HE
506 g_message("Firmware uploaded");
507
e8397563 508 return ret;
28a35d8a
HE
509}
510
eec5275e 511/* Only trigger on single pin supported (in 100-200 MHz modes). */
57bbf56b
HE
512static int configure_probes(GSList *probes)
513{
514 struct probe *probe;
515 GSList *l;
516 int trigger_set = 0;
517
eec5275e
HE
518 if (cur_samplerate <= MHZ(50)) {
519 g_warning("Trigger support only implemented "
520 "in 100 and 200 MHz mode.");
521 return SIGROK_ERR;
522 }
523
57bbf56b
HE
524 for (l = probes; l; l = l->next) {
525 probe = (struct probe *)l->data;
526
527 if (!probe->enabled || !probe->trigger)
528 continue;
529
530 if (trigger_set) {
eec5275e
HE
531 g_warning("Asix Sigma only supports a single pin trigger "
532 "in 100 and 200 MHz mode.");
57bbf56b
HE
533 return SIGROK_ERR;
534 }
535
eec5275e 536 /* Found trigger. */
57bbf56b
HE
537 if (probe->trigger[0] == 'f')
538 triggerfall = 1;
539 else
540 triggerfall = 0;
541
542 triggerpin = probe->index - 1;
543 trigger_set = 1;
544 }
545
546 return SIGROK_OK;
547}
548
28a35d8a
HE
549static void hw_closedev(int device_index)
550{
551 device_index = device_index;
552
553 ftdi_usb_close(&ftdic);
554}
555
28a35d8a
HE
556static void hw_cleanup(void)
557{
558}
559
28a35d8a
HE
560static void *hw_get_device_info(int device_index, int device_info_id)
561{
562 struct sigrok_device_instance *sdi;
563 void *info = NULL;
564
565 if (!(sdi = get_sigrok_device_instance(device_instances, device_index))) {
566 fprintf(stderr, "It's NULL.\n");
567 return NULL;
568 }
569
570 switch (device_info_id) {
571 case DI_INSTANCE:
572 info = sdi;
573 break;
574 case DI_NUM_PROBES:
edca2c5c 575 info = GINT_TO_POINTER(16);
28a35d8a
HE
576 break;
577 case DI_SAMPLERATES:
578 info = &samplerates;
579 break;
580 case DI_TRIGGER_TYPES:
57bbf56b 581 info = (char *)TRIGGER_TYPES;
28a35d8a
HE
582 break;
583 case DI_CUR_SAMPLERATE:
584 info = &cur_samplerate;
585 break;
586 }
587
588 return info;
589}
590
28a35d8a
HE
591static int hw_get_status(int device_index)
592{
593 struct sigrok_device_instance *sdi;
594
595 sdi = get_sigrok_device_instance(device_instances, device_index);
596 if (sdi)
597 return sdi->status;
598 else
599 return ST_NOT_FOUND;
600}
601
28a35d8a
HE
602static int *hw_get_capabilities(void)
603{
604 return capabilities;
605}
606
607static int hw_set_configuration(int device_index, int capability, void *value)
608{
609 struct sigrok_device_instance *sdi;
610 int ret;
f6564c8d 611
28a35d8a
HE
612 if (!(sdi = get_sigrok_device_instance(device_instances, device_index)))
613 return SIGROK_ERR;
614
615 if (capability == HWCAP_SAMPLERATE) {
f6564c8d 616 ret = set_samplerate(sdi, *(uint64_t*) value);
28a35d8a 617 } else if (capability == HWCAP_PROBECONFIG) {
57bbf56b 618 ret = configure_probes(value);
28a35d8a
HE
619 } else if (capability == HWCAP_LIMIT_MSEC) {
620 limit_msec = strtoull(value, NULL, 10);
621 ret = SIGROK_OK;
57bbf56b
HE
622 } else if (capability == HWCAP_CAPTURE_RATIO) {
623 capture_ratio = strtoull(value, NULL, 10);
624 ret = SIGROK_OK;
625 } else if (capability == HWCAP_PROBECONFIG) {
626 ret = configure_probes((GSList *) value);
28a35d8a
HE
627 } else {
628 ret = SIGROK_ERR;
629 }
630
631 return ret;
632}
633
28a35d8a 634/*
fefa1800
UH
635 * Decode chunk of 1024 bytes, 64 clusters, 7 events per cluster.
636 * Each event is 20ns apart, and can contain multiple samples.
f78898e9
HE
637 *
638 * For 200 MHz, events contain 4 samples for each channel, spread 5 ns apart.
639 * For 100 MHz, events contain 2 samples for each channel, spread 10 ns apart.
640 * For 50 MHz and below, events contain one sample for each channel,
641 * spread 20 ns apart.
28a35d8a
HE
642 */
643static int decode_chunk_ts(uint8_t *buf, uint16_t *lastts,
57bbf56b 644 uint16_t *lastsample, int triggerpos, void *user_data)
28a35d8a 645{
fefa1800 646 uint16_t tsdiff, ts;
f78898e9 647 uint16_t samples[65536 * samples_per_event];
28a35d8a 648 struct datafeed_packet packet;
f78898e9 649 int i, j, k, l, numpad, tosend;
fefa1800 650 size_t n = 0, sent = 0;
f78898e9 651 int clustersize = EVENTS_PER_CLUSTER * samples_per_event;
fefa1800 652 uint16_t *event;
f78898e9 653 uint16_t cur_sample;
57bbf56b
HE
654 int triggerts = -1;
655
eec5275e 656 /* Find in which cluster the trigger occured. */
57bbf56b
HE
657 if (triggerpos != -1)
658 triggerts = (triggerpos / 7);
28a35d8a 659
eec5275e 660 /* For each ts. */
28a35d8a 661 for (i = 0; i < 64; ++i) {
fefa1800 662 ts = *(uint16_t *) &buf[i * 16];
28a35d8a
HE
663 tsdiff = ts - *lastts;
664 *lastts = ts;
665
fefa1800
UH
666 /* Pad last sample up to current point. */
667 numpad = tsdiff * samples_per_event - clustersize;
28a35d8a 668 if (numpad > 0) {
f78898e9
HE
669 for (j = 0; j < numpad; ++j)
670 samples[j] = *lastsample;
671
672 n = numpad;
28a35d8a
HE
673 }
674
57bbf56b
HE
675 /* Send samples between previous and this timestamp to sigrok. */
676 sent = 0;
677 while (sent < n) {
678 tosend = MIN(2048, n - sent);
679
680 packet.type = DF_LOGIC16;
681 packet.length = tosend * sizeof(uint16_t);
682 packet.payload = samples + sent;
683 session_bus(user_data, &packet);
28a35d8a 684
57bbf56b
HE
685 sent += tosend;
686 }
687 n = 0;
688
689 event = (uint16_t *) &buf[i * 16 + 2];
f78898e9
HE
690 cur_sample = 0;
691
692 /* For each event in cluster. */
28a35d8a 693 for (j = 0; j < 7; ++j) {
f78898e9
HE
694
695 /* For each sample in event. */
28a35d8a 696 for (k = 0; k < samples_per_event; ++k) {
f78898e9
HE
697 cur_sample = 0;
698
699 /* For each probe. */
700 for (l = 0; l < num_probes; ++l)
edca2c5c
HE
701 cur_sample |= (!!(event[j] & (1 << (l *
702 samples_per_event + k))))
703 << l;
f78898e9
HE
704
705 samples[n++] = cur_sample;
28a35d8a
HE
706 }
707 }
708
fefa1800 709 *lastsample = samples[n - 1];
28a35d8a 710
eec5275e 711 /* Send data up to trigger point (if triggered). */
fefa1800 712 sent = 0;
57bbf56b
HE
713 if (i == triggerts) {
714 /*
715 * Trigger is presumptively only accurate to event, i.e.
716 * for 100 and 200 MHz, where multiple samples are coded
717 * in a single event, the trigger does not match the
718 * exact sample.
719 */
720 tosend = (triggerpos % 7) - 3;
721
722 if (tosend > 0) {
723 packet.type = DF_LOGIC16;
724 packet.length = tosend * sizeof(uint16_t);
725 packet.payload = samples;
726 session_bus(user_data, &packet);
727
728 sent += tosend;
729 }
28a35d8a 730
57bbf56b
HE
731 packet.type = DF_TRIGGER;
732 packet.length = 0;
733 packet.payload = 0;
28a35d8a 734 session_bus(user_data, &packet);
28a35d8a 735 }
57bbf56b 736
eec5275e 737 /* Send rest of the chunk to sigrok. */
57bbf56b
HE
738 tosend = n - sent;
739
740 packet.type = DF_LOGIC16;
741 packet.length = tosend * sizeof(uint16_t);
742 packet.payload = samples + sent;
743 session_bus(user_data, &packet);
28a35d8a
HE
744 }
745
f78898e9 746 return SIGROK_OK;
28a35d8a
HE
747}
748
749static int receive_data(int fd, int revents, void *user_data)
750{
751 struct datafeed_packet packet;
28a35d8a
HE
752 const int chunks_per_read = 32;
753 unsigned char buf[chunks_per_read * CHUNK_SIZE];
fefa1800
UH
754 int bufsz, numchunks, curchunk, i, newchunks;
755 uint32_t triggerpos, stoppos, running_msec;
28a35d8a 756 struct timeval tv;
28a35d8a 757 uint16_t lastts = 0;
f78898e9 758 uint16_t lastsample = 0;
57bbf56b
HE
759 uint8_t modestatus;
760 int triggerchunk = -1;
28a35d8a
HE
761
762 fd = fd;
763 revents = revents;
764
fefa1800 765 /* Get the current position. */
28a35d8a
HE
766 sigma_read_pos(&stoppos, &triggerpos);
767 numchunks = stoppos / 512;
768
fefa1800 769 /* Check if the has expired, or memory is full. */
28a35d8a
HE
770 gettimeofday(&tv, 0);
771 running_msec = (tv.tv_sec - start_tv.tv_sec) * 1000 +
fefa1800 772 (tv.tv_usec - start_tv.tv_usec) / 1000;
28a35d8a
HE
773
774 if (running_msec < limit_msec && numchunks < 32767)
775 return FALSE;
776
fefa1800 777 /* Stop acqusition. */
28a35d8a
HE
778 sigma_set_register(WRITE_MODE, 0x11);
779
fefa1800 780 /* Set SDRAM Read Enable. */
28a35d8a
HE
781 sigma_set_register(WRITE_MODE, 0x02);
782
fefa1800 783 /* Get the current position. */
28a35d8a
HE
784 sigma_read_pos(&stoppos, &triggerpos);
785
eec5275e 786 /* Check if trigger has fired. */
57bbf56b
HE
787 modestatus = sigma_get_register(READ_MODE);
788 if (modestatus & 0x20) {
789 triggerchunk = triggerpos / 512;
790 }
f78898e9 791
fefa1800 792 /* Download sample data. */
28a35d8a 793 for (curchunk = 0; curchunk < numchunks;) {
fefa1800 794 newchunks = MIN(chunks_per_read, numchunks - curchunk);
28a35d8a
HE
795
796 g_message("Downloading sample data: %.0f %%",
fefa1800 797 100.0 * curchunk / numchunks);
28a35d8a
HE
798
799 bufsz = sigma_read_dram(curchunk, newchunks, buf);
800
fefa1800
UH
801 /* Find first ts. */
802 if (curchunk == 0)
803 lastts = *(uint16_t *) buf - 1;
28a35d8a 804
fefa1800 805 /* Decode chunks and send them to sigrok. */
28a35d8a 806 for (i = 0; i < newchunks; ++i) {
57bbf56b
HE
807 if (curchunk + i == triggerchunk)
808 decode_chunk_ts(buf + (i * CHUNK_SIZE),
809 &lastts, &lastsample,
810 triggerpos & 0x1ff, user_data);
811 else
812 decode_chunk_ts(buf + (i * CHUNK_SIZE),
813 &lastts, &lastsample,
814 -1, user_data);
28a35d8a
HE
815 }
816
817 curchunk += newchunks;
818 }
819
eec5275e 820 /* End of data. */
28a35d8a
HE
821 packet.type = DF_END;
822 packet.length = 0;
823 session_bus(user_data, &packet);
824
825 return TRUE;
826}
827
828static int hw_start_acquisition(int device_index, gpointer session_device_id)
829{
830 struct sigrok_device_instance *sdi;
831 struct datafeed_packet packet;
832 struct datafeed_header header;
9ddb2a12
UH
833 struct clockselect_50 clockselect;
834 int frac;
57bbf56b
HE
835 uint8_t triggerselect;
836 struct triggerinout triggerinout_conf;
28a35d8a
HE
837
838 session_device_id = session_device_id;
839
840 if (!(sdi = get_sigrok_device_instance(device_instances, device_index)))
841 return SIGROK_ERR;
842
843 device_index = device_index;
844
ed09fd07 845 /* If the samplerate has not been set, default to 50 MHz. */
9ddb2a12 846 if (cur_firmware == -1)
ed09fd07 847 set_samplerate(sdi, MHZ(50));
e8397563 848
eec5275e 849 /* Enter trigger programming mode. */
28a35d8a
HE
850 sigma_set_register(WRITE_TRIGGER_SELECT1, 0x20);
851
eec5275e 852 /* 100 and 200 MHz mode. */
57bbf56b
HE
853 if (cur_samplerate >= MHZ(100)) {
854 sigma_set_register(WRITE_TRIGGER_SELECT1, 0x81);
855
856 triggerselect = (1 << LEDSEL1) | (triggerfall << 3) |
857 (triggerpin & 0x7);
858
eec5275e 859 /* All other modes. */
57bbf56b
HE
860 } else if (cur_samplerate <= MHZ(50)) {
861 sigma_set_register(WRITE_TRIGGER_SELECT1, 0x20);
862
863 triggerselect = (1 << LEDSEL1) | (1 << LEDSEL0);
864 }
865
eec5275e 866 /* Setup trigger in and out pins to default values. */
57bbf56b
HE
867 memset(&triggerinout_conf, 0, sizeof(struct triggerinout));
868 triggerinout_conf.trgout_bytrigger = 1;
869 triggerinout_conf.trgout_enable = 1;
870
28a35d8a 871 sigma_write_register(WRITE_TRIGGER_OPTION,
57bbf56b
HE
872 (uint8_t *) &triggerinout_conf,
873 sizeof(struct triggerinout));
28a35d8a 874
eec5275e 875 /* Go back to normal mode. */
57bbf56b 876 sigma_set_register(WRITE_TRIGGER_SELECT1, triggerselect);
28a35d8a 877
edca2c5c
HE
878 /* Set clock select register. */
879 if (cur_samplerate == MHZ(200))
880 /* Enable 4 probes. */
881 sigma_set_register(WRITE_CLOCK_SELECT, 0xf0);
882 else if (cur_samplerate == MHZ(100))
883 /* Enable 8 probes. */
884 sigma_set_register(WRITE_CLOCK_SELECT, 0x00);
885 else {
886 /*
9ddb2a12 887 * 50 MHz mode (or fraction thereof). Any fraction down to
eec5275e 888 * 50 MHz / 256 can be used, but is not supported by sigrok API.
edca2c5c 889 */
9ddb2a12 890 frac = MHZ(50) / cur_samplerate - 1;
edca2c5c 891
9ddb2a12
UH
892 clockselect.async = 0;
893 clockselect.fraction = frac;
894 clockselect.disabled_probes = 0;
edca2c5c
HE
895
896 sigma_write_register(WRITE_CLOCK_SELECT,
9ddb2a12
UH
897 (uint8_t *) &clockselect,
898 sizeof(clockselect));
edca2c5c
HE
899 }
900
fefa1800 901 /* Setup maximum post trigger time. */
57bbf56b 902 sigma_set_register(WRITE_POST_TRIGGER, (capture_ratio * 256) / 100);
28a35d8a 903
eec5275e 904 /* Start acqusition. */
28a35d8a
HE
905 gettimeofday(&start_tv, 0);
906 sigma_set_register(WRITE_MODE, 0x0d);
907
28a35d8a
HE
908 /* Send header packet to the session bus. */
909 packet.type = DF_HEADER;
910 packet.length = sizeof(struct datafeed_header);
911 packet.payload = &header;
912 header.feed_version = 1;
913 gettimeofday(&header.starttime, NULL);
914 header.samplerate = cur_samplerate;
915 header.protocol_id = PROTO_RAW;
edca2c5c 916 header.num_probes = num_probes;
28a35d8a
HE
917 session_bus(session_device_id, &packet);
918
57bbf56b
HE
919 /* Add capture source. */
920 source_add(0, G_IO_IN, 10, receive_data, session_device_id);
921
28a35d8a
HE
922 return SIGROK_OK;
923}
924
28a35d8a
HE
925static void hw_stop_acquisition(int device_index, gpointer session_device_id)
926{
927 device_index = device_index;
928 session_device_id = session_device_id;
929
fefa1800 930 /* Stop acquisition. */
28a35d8a
HE
931 sigma_set_register(WRITE_MODE, 0x11);
932
933 // XXX Set some state to indicate that data should be sent to sigrok
934 // Now, we just wait for timeout
935}
936
28a35d8a
HE
937struct device_plugin asix_sigma_plugin_info = {
938 "asix-sigma",
939 1,
940 hw_init,
941 hw_cleanup,
28a35d8a
HE
942 hw_opendev,
943 hw_closedev,
944 hw_get_device_info,
945 hw_get_status,
946 hw_get_capabilities,
947 hw_set_configuration,
948 hw_start_acquisition,
9ddb2a12 949 hw_stop_acquisition,
28a35d8a 950};