]> sigrok.org Git - libsigrok.git/blame - hardware/asix-sigma/asix-sigma.c
Sigma: Minor cleanup and add more samplesrates.
[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 ""
28a35d8a
HE
38
39static GSList *device_instances = NULL;
40
41// XXX These should be per device
42static struct ftdi_context ftdic;
f78898e9 43static uint64_t cur_samplerate = 0;
28a35d8a
HE
44static uint32_t limit_msec = 0;
45static struct timeval start_tv;
f6564c8d 46static int cur_firmware = -1;
f78898e9
HE
47static int num_probes = 0;
48static int samples_per_event = 0;
28a35d8a
HE
49
50static uint64_t supported_samplerates[] = {
ed09fd07 51 KHZ(200),
edca2c5c 52 KHZ(250),
ed09fd07 53 KHZ(500),
edca2c5c 54 MHZ(1),
ed09fd07 55 MHZ(5),
edca2c5c
HE
56 MHZ(10),
57 MHZ(25),
e8397563
HE
58 MHZ(50),
59 MHZ(100),
28a35d8a
HE
60 MHZ(200),
61 0,
62};
63
64static struct samplerates samplerates = {
ed09fd07 65 KHZ(200),
28a35d8a
HE
66 MHZ(200),
67 0,
68 supported_samplerates,
69};
70
71static int capabilities[] = {
72 HWCAP_LOGIC_ANALYZER,
73 HWCAP_SAMPLERATE,
74
75 /* These are really implemented in the driver, not the hardware. */
76 HWCAP_LIMIT_MSEC,
77 0,
78};
79
fefa1800
UH
80/* Force the FPGA to reboot. */
81static uint8_t suicide[] = {
82 0x84, 0x84, 0x88, 0x84, 0x88, 0x84, 0x88, 0x84,
83};
84
85/* Prepare to upload firmware (FPGA specific). */
86static uint8_t init[] = {
87 0x03, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
88};
89
90/* Initialize the logic analyzer mode. */
91static uint8_t logic_mode_start[] = {
92 0x00, 0x40, 0x0f, 0x25, 0x35, 0x40,
93 0x2a, 0x3a, 0x40, 0x03, 0x20, 0x38,
94};
95
f6564c8d
HE
96static const char *firmware_files[] =
97{
a8116d76
HE
98 "asix-sigma-50.fw", /* 50 MHz, supports 8 bit fractions */
99 "asix-sigma-100.fw", /* 100 MHz */
100 "asix-sigma-200.fw", /* 200 MHz */
ed09fd07 101 "asix-sigma-50sync.fw", /* Synchronous clock from pin */
a8116d76 102 "asix-sigma-phasor.fw", /* Frequency counter */
f6564c8d
HE
103};
104
9ddb2a12 105static int sigma_read(void *buf, size_t size)
28a35d8a
HE
106{
107 int ret;
fefa1800
UH
108
109 ret = ftdi_read_data(&ftdic, (unsigned char *)buf, size);
28a35d8a
HE
110 if (ret < 0) {
111 g_warning("ftdi_read_data failed: %s",
fefa1800 112 ftdi_get_error_string(&ftdic));
28a35d8a
HE
113 }
114
115 return ret;
116}
117
fefa1800 118static int sigma_write(void *buf, size_t size)
28a35d8a
HE
119{
120 int ret;
fefa1800
UH
121
122 ret = ftdi_write_data(&ftdic, (unsigned char *)buf, size);
28a35d8a
HE
123 if (ret < 0) {
124 g_warning("ftdi_write_data failed: %s",
fefa1800
UH
125 ftdi_get_error_string(&ftdic));
126 } else if ((size_t) ret != size) {
28a35d8a
HE
127 g_warning("ftdi_write_data did not complete write\n");
128 }
129
130 return ret;
131}
132
133static int sigma_write_register(uint8_t reg, uint8_t *data, size_t len)
134{
135 size_t i;
136 uint8_t buf[len + 2];
137 int idx = 0;
138
139 buf[idx++] = REG_ADDR_LOW | (reg & 0xf);
140 buf[idx++] = REG_ADDR_HIGH | (reg >> 4);
141
fefa1800 142 for (i = 0; i < len; ++i) {
28a35d8a
HE
143 buf[idx++] = REG_DATA_LOW | (data[i] & 0xf);
144 buf[idx++] = REG_DATA_HIGH_WRITE | (data[i] >> 4);
145 }
146
147 return sigma_write(buf, idx);
148}
149
150static int sigma_set_register(uint8_t reg, uint8_t value)
151{
152 return sigma_write_register(reg, &value, 1);
153}
154
155static int sigma_read_register(uint8_t reg, uint8_t *data, size_t len)
156{
157 uint8_t buf[3];
fefa1800 158
28a35d8a
HE
159 buf[0] = REG_ADDR_LOW | (reg & 0xf);
160 buf[1] = REG_ADDR_HIGH | (reg >> 4);
28a35d8a
HE
161 buf[2] = REG_READ_ADDR;
162
163 sigma_write(buf, sizeof(buf));
164
165 return sigma_read(data, len);
166}
167
168static uint8_t sigma_get_register(uint8_t reg)
169{
170 uint8_t value;
fefa1800 171
28a35d8a
HE
172 if (1 != sigma_read_register(reg, &value, 1)) {
173 g_warning("Sigma_get_register: 1 byte expected");
174 return 0;
175 }
176
177 return value;
178}
179
180static int sigma_read_pos(uint32_t *stoppos, uint32_t *triggerpos)
181{
182 uint8_t buf[] = {
183 REG_ADDR_LOW | READ_TRIGGER_POS_LOW,
184
185 REG_READ_ADDR | NEXT_REG,
186 REG_READ_ADDR | NEXT_REG,
187 REG_READ_ADDR | NEXT_REG,
188 REG_READ_ADDR | NEXT_REG,
189 REG_READ_ADDR | NEXT_REG,
190 REG_READ_ADDR | NEXT_REG,
191 };
28a35d8a
HE
192 uint8_t result[6];
193
194 sigma_write(buf, sizeof(buf));
195
196 sigma_read(result, sizeof(result));
197
198 *triggerpos = result[0] | (result[1] << 8) | (result[2] << 16);
199 *stoppos = result[3] | (result[4] << 8) | (result[5] << 16);
200
201 return 1;
202}
203
204static int sigma_read_dram(uint16_t startchunk, size_t numchunks, uint8_t *data)
205{
206 size_t i;
207 uint8_t buf[4096];
208 int idx = 0;
209
fefa1800 210 /* Send the startchunk. Index start with 1. */
28a35d8a
HE
211 buf[0] = startchunk >> 8;
212 buf[1] = startchunk & 0xff;
213 sigma_write_register(WRITE_MEMROW, buf, 2);
214
fefa1800 215 /* Read the DRAM. */
28a35d8a
HE
216 buf[idx++] = REG_DRAM_BLOCK;
217 buf[idx++] = REG_DRAM_WAIT_ACK;
218
219 for (i = 0; i < numchunks; ++i) {
fefa1800
UH
220 /* Alternate bit to copy from DRAM to cache. */
221 if (i != (numchunks - 1))
222 buf[idx++] = REG_DRAM_BLOCK | (((i + 1) % 2) << 4);
28a35d8a
HE
223
224 buf[idx++] = REG_DRAM_BLOCK_DATA | ((i % 2) << 4);
225
fefa1800 226 if (i != (numchunks - 1))
28a35d8a
HE
227 buf[idx++] = REG_DRAM_WAIT_ACK;
228 }
229
230 sigma_write(buf, idx);
231
232 return sigma_read(data, numchunks * CHUNK_SIZE);
233}
234
fefa1800 235/* Generate the bitbang stream for programming the FPGA. */
28a35d8a 236static int bin2bitbang(const char *filename,
fefa1800 237 unsigned char **buf, size_t *buf_size)
28a35d8a 238{
fefa1800 239 FILE *f;
28a35d8a
HE
240 long file_size;
241 unsigned long offset = 0;
242 unsigned char *p;
243 uint8_t *compressed_buf, *firmware;
244 uLongf csize, fwsize;
245 const int buffer_size = 65536;
246 size_t i;
fefa1800
UH
247 int c, ret, bit, v;
248 uint32_t imm = 0x3f6df2ab;
28a35d8a 249
fefa1800 250 f = fopen(filename, "r");
28a35d8a
HE
251 if (!f) {
252 g_warning("fopen(\"%s\", \"r\")", filename);
253 return -1;
254 }
255
256 if (-1 == fseek(f, 0, SEEK_END)) {
257 g_warning("fseek on %s failed", filename);
258 fclose(f);
259 return -1;
260 }
261
262 file_size = ftell(f);
263
264 fseek(f, 0, SEEK_SET);
265
28a35d8a
HE
266 compressed_buf = g_malloc(file_size);
267 firmware = g_malloc(buffer_size);
268
269 if (!compressed_buf || !firmware) {
270 g_warning("Error allocating buffers");
271 return -1;
272 }
273
28a35d8a
HE
274 csize = 0;
275 while ((c = getc(f)) != EOF) {
276 imm = (imm + 0xa853753) % 177 + (imm * 0x8034052);
277 compressed_buf[csize++] = c ^ imm;
278 }
279 fclose(f);
280
281 fwsize = buffer_size;
282 ret = uncompress(firmware, &fwsize, compressed_buf, csize);
283 if (ret < 0) {
284 g_free(compressed_buf);
285 g_free(firmware);
286 g_warning("Could not unpack Sigma firmware. (Error %d)\n", ret);
287 return -1;
288 }
289
290 g_free(compressed_buf);
291
292 *buf_size = fwsize * 2 * 8;
293
fefa1800 294 *buf = p = (unsigned char *)g_malloc(*buf_size);
28a35d8a
HE
295
296 if (!p) {
297 g_warning("Error allocating buffers");
298 return -1;
299 }
300
301 for (i = 0; i < fwsize; ++i) {
28a35d8a 302 for (bit = 7; bit >= 0; --bit) {
fefa1800 303 v = firmware[i] & 1 << bit ? 0x40 : 0x00;
28a35d8a
HE
304 p[offset++] = v | 0x01;
305 p[offset++] = v;
306 }
307 }
308
309 g_free(firmware);
310
311 if (offset != *buf_size) {
312 g_free(*buf);
313 g_warning("Error reading firmware %s "
fefa1800
UH
314 "offset=%ld, file_size=%ld, buf_size=%zd\n",
315 filename, offset, file_size, *buf_size);
28a35d8a
HE
316
317 return -1;
318 }
319
320 return 0;
321}
322
323static int hw_init(char *deviceinfo)
324{
325 struct sigrok_device_instance *sdi;
326
327 deviceinfo = deviceinfo;
328
329 ftdi_init(&ftdic);
330
fefa1800
UH
331 /* Look for SIGMAs. */
332 if (ftdi_usb_open_desc(&ftdic, USB_VENDOR, USB_PRODUCT,
333 USB_DESCRIPTION, NULL) < 0)
28a35d8a
HE
334 return 0;
335
fefa1800 336 /* Register SIGMA device. */
28a35d8a
HE
337 sdi = sigrok_device_instance_new(0, ST_INITIALIZING,
338 USB_VENDOR_NAME, USB_MODEL_NAME, USB_MODEL_VERSION);
339 if (!sdi)
340 return 0;
341
342 device_instances = g_slist_append(device_instances, sdi);
343
fefa1800 344 /* We will open the device again when we need it. */
28a35d8a
HE
345 ftdi_usb_close(&ftdic);
346
347 return 1;
348}
349
f6564c8d 350static int upload_firmware(int firmware_idx)
28a35d8a
HE
351{
352 int ret;
353 unsigned char *buf;
354 unsigned char pins;
355 size_t buf_size;
28a35d8a 356 unsigned char result[32];
e8397563 357 char firmware_path[128];
28a35d8a 358
fefa1800 359 /* Make sure it's an ASIX SIGMA. */
28a35d8a
HE
360 if ((ret = ftdi_usb_open_desc(&ftdic,
361 USB_VENDOR, USB_PRODUCT, USB_DESCRIPTION, NULL)) < 0) {
28a35d8a 362 g_warning("ftdi_usb_open failed: %s",
fefa1800 363 ftdi_get_error_string(&ftdic));
28a35d8a
HE
364 return 0;
365 }
366
367 if ((ret = ftdi_set_bitmode(&ftdic, 0xdf, BITMODE_BITBANG)) < 0) {
368 g_warning("ftdi_set_bitmode failed: %s",
fefa1800 369 ftdi_get_error_string(&ftdic));
28a35d8a
HE
370 return 0;
371 }
372
fefa1800 373 /* Four times the speed of sigmalogan - Works well. */
28a35d8a
HE
374 if ((ret = ftdi_set_baudrate(&ftdic, 750000)) < 0) {
375 g_warning("ftdi_set_baudrate failed: %s",
fefa1800 376 ftdi_get_error_string(&ftdic));
28a35d8a
HE
377 return 0;
378 }
379
fefa1800 380 /* Force the FPGA to reboot. */
28a35d8a
HE
381 sigma_write(suicide, sizeof(suicide));
382 sigma_write(suicide, sizeof(suicide));
383 sigma_write(suicide, sizeof(suicide));
384 sigma_write(suicide, sizeof(suicide));
385
fefa1800 386 /* Prepare to upload firmware (FPGA specific). */
28a35d8a
HE
387 sigma_write(init, sizeof(init));
388
389 ftdi_usb_purge_buffers(&ftdic);
390
fefa1800 391 /* Wait until the FPGA asserts INIT_B. */
28a35d8a
HE
392 while (1) {
393 ret = sigma_read(result, 1);
394 if (result[0] & 0x20)
395 break;
396 }
397
9ddb2a12 398 /* Prepare firmware. */
e8397563 399 snprintf(firmware_path, sizeof(firmware_path), "%s/%s", FIRMWARE_DIR,
f6564c8d
HE
400 firmware_files[firmware_idx]);
401
e8397563 402 if (-1 == bin2bitbang(firmware_path, &buf, &buf_size)) {
28a35d8a 403 g_warning("An error occured while reading the firmware: %s",
e8397563 404 firmware_path);
28a35d8a
HE
405 return SIGROK_ERR;
406 }
407
fefa1800 408 /* Upload firmare. */
28a35d8a
HE
409 sigma_write(buf, buf_size);
410
411 g_free(buf);
412
413 if ((ret = ftdi_set_bitmode(&ftdic, 0x00, BITMODE_RESET)) < 0) {
9ddb2a12 414 g_warning("ftdi_set_bitmode failed: %s",
fefa1800 415 ftdi_get_error_string(&ftdic));
28a35d8a
HE
416 return SIGROK_ERR;
417 }
418
419 ftdi_usb_purge_buffers(&ftdic);
420
fefa1800 421 /* Discard garbage. */
28a35d8a
HE
422 while (1 == sigma_read(&pins, 1))
423 ;
424
fefa1800 425 /* Initialize the logic analyzer mode. */
28a35d8a
HE
426 sigma_write(logic_mode_start, sizeof(logic_mode_start));
427
fefa1800 428 /* Expect a 3 byte reply. */
28a35d8a
HE
429 ret = sigma_read(result, 3);
430 if (ret != 3 ||
431 result[0] != 0xa6 || result[1] != 0x55 || result[2] != 0xaa) {
fefa1800 432 g_warning("Configuration failed. Invalid reply received.");
28a35d8a
HE
433 return SIGROK_ERR;
434 }
435
f6564c8d
HE
436 cur_firmware = firmware_idx;
437
438 return SIGROK_OK;
439}
440
441static int hw_opendev(int device_index)
442{
443 struct sigrok_device_instance *sdi;
444 int ret;
445
9ddb2a12 446 /* Make sure it's an ASIX SIGMA. */
f6564c8d
HE
447 if ((ret = ftdi_usb_open_desc(&ftdic,
448 USB_VENDOR, USB_PRODUCT, USB_DESCRIPTION, NULL)) < 0) {
449
450 g_warning("ftdi_usb_open failed: %s",
451 ftdi_get_error_string(&ftdic));
452
453 return 0;
454 }
28a35d8a
HE
455
456 if (!(sdi = get_sigrok_device_instance(device_instances, device_index)))
457 return SIGROK_ERR;
458
459 sdi->status = ST_ACTIVE;
460
f6564c8d
HE
461 return SIGROK_OK;
462}
463
464static int set_samplerate(struct sigrok_device_instance *sdi, uint64_t samplerate)
465{
e8397563 466 int i, ret;
f6564c8d
HE
467
468 sdi = sdi;
469
470 for (i = 0; supported_samplerates[i]; i++) {
471 if (supported_samplerates[i] == samplerate)
472 break;
473 }
474 if (supported_samplerates[i] == 0)
475 return SIGROK_ERR_SAMPLERATE;
476
e8397563
HE
477 if (samplerate <= MHZ(50)) {
478 ret = upload_firmware(0);
f78898e9 479 num_probes = 16;
e8397563 480 }
f78898e9 481 if (samplerate == MHZ(100)) {
e8397563 482 ret = upload_firmware(1);
f78898e9
HE
483 num_probes = 8;
484 }
485 else if (samplerate == MHZ(200)) {
e8397563 486 ret = upload_firmware(2);
f78898e9
HE
487 num_probes = 4;
488 }
f6564c8d 489
e8397563 490 cur_samplerate = samplerate;
f78898e9 491 samples_per_event = 16 / num_probes;
f6564c8d 492
28a35d8a
HE
493 g_message("Firmware uploaded");
494
e8397563 495 return ret;
28a35d8a
HE
496}
497
28a35d8a
HE
498static void hw_closedev(int device_index)
499{
500 device_index = device_index;
501
502 ftdi_usb_close(&ftdic);
503}
504
28a35d8a
HE
505static void hw_cleanup(void)
506{
507}
508
28a35d8a
HE
509static void *hw_get_device_info(int device_index, int device_info_id)
510{
511 struct sigrok_device_instance *sdi;
512 void *info = NULL;
513
514 if (!(sdi = get_sigrok_device_instance(device_instances, device_index))) {
515 fprintf(stderr, "It's NULL.\n");
516 return NULL;
517 }
518
519 switch (device_info_id) {
520 case DI_INSTANCE:
521 info = sdi;
522 break;
523 case DI_NUM_PROBES:
edca2c5c 524 info = GINT_TO_POINTER(16);
28a35d8a
HE
525 break;
526 case DI_SAMPLERATES:
527 info = &samplerates;
528 break;
529 case DI_TRIGGER_TYPES:
ed09fd07 530 info = 0;
28a35d8a
HE
531 break;
532 case DI_CUR_SAMPLERATE:
533 info = &cur_samplerate;
534 break;
535 }
536
537 return info;
538}
539
28a35d8a
HE
540static int hw_get_status(int device_index)
541{
542 struct sigrok_device_instance *sdi;
543
544 sdi = get_sigrok_device_instance(device_instances, device_index);
545 if (sdi)
546 return sdi->status;
547 else
548 return ST_NOT_FOUND;
549}
550
28a35d8a
HE
551static int *hw_get_capabilities(void)
552{
553 return capabilities;
554}
555
556static int hw_set_configuration(int device_index, int capability, void *value)
557{
558 struct sigrok_device_instance *sdi;
559 int ret;
f6564c8d 560
28a35d8a
HE
561 if (!(sdi = get_sigrok_device_instance(device_instances, device_index)))
562 return SIGROK_ERR;
563
564 if (capability == HWCAP_SAMPLERATE) {
f6564c8d 565 ret = set_samplerate(sdi, *(uint64_t*) value);
28a35d8a
HE
566 } else if (capability == HWCAP_PROBECONFIG) {
567 ret = SIGROK_OK;
568 } else if (capability == HWCAP_LIMIT_MSEC) {
569 limit_msec = strtoull(value, NULL, 10);
570 ret = SIGROK_OK;
571 } else {
572 ret = SIGROK_ERR;
573 }
574
575 return ret;
576}
577
28a35d8a 578/*
fefa1800
UH
579 * Decode chunk of 1024 bytes, 64 clusters, 7 events per cluster.
580 * Each event is 20ns apart, and can contain multiple samples.
f78898e9
HE
581 *
582 * For 200 MHz, events contain 4 samples for each channel, spread 5 ns apart.
583 * For 100 MHz, events contain 2 samples for each channel, spread 10 ns apart.
584 * For 50 MHz and below, events contain one sample for each channel,
585 * spread 20 ns apart.
28a35d8a
HE
586 */
587static int decode_chunk_ts(uint8_t *buf, uint16_t *lastts,
f78898e9 588 uint16_t *lastsample, void *user_data)
28a35d8a 589{
fefa1800 590 uint16_t tsdiff, ts;
f78898e9 591 uint16_t samples[65536 * samples_per_event];
28a35d8a 592 struct datafeed_packet packet;
f78898e9 593 int i, j, k, l, numpad, tosend;
fefa1800 594 size_t n = 0, sent = 0;
f78898e9 595 int clustersize = EVENTS_PER_CLUSTER * samples_per_event;
fefa1800 596 uint16_t *event;
f78898e9 597 uint16_t cur_sample;
28a35d8a
HE
598
599 /* For each ts */
600 for (i = 0; i < 64; ++i) {
fefa1800 601 ts = *(uint16_t *) &buf[i * 16];
28a35d8a
HE
602 tsdiff = ts - *lastts;
603 *lastts = ts;
604
fefa1800
UH
605 /* Pad last sample up to current point. */
606 numpad = tsdiff * samples_per_event - clustersize;
28a35d8a 607 if (numpad > 0) {
f78898e9
HE
608 for (j = 0; j < numpad; ++j)
609 samples[j] = *lastsample;
610
611 n = numpad;
28a35d8a
HE
612 }
613
fefa1800 614 event = (uint16_t *) &buf[i * 16 + 2];
28a35d8a 615
f78898e9
HE
616 cur_sample = 0;
617
618 /* For each event in cluster. */
28a35d8a 619 for (j = 0; j < 7; ++j) {
f78898e9
HE
620
621 /* For each sample in event. */
28a35d8a 622 for (k = 0; k < samples_per_event; ++k) {
f78898e9
HE
623 cur_sample = 0;
624
625 /* For each probe. */
626 for (l = 0; l < num_probes; ++l)
edca2c5c
HE
627 cur_sample |= (!!(event[j] & (1 << (l *
628 samples_per_event + k))))
629 << l;
f78898e9
HE
630
631 samples[n++] = cur_sample;
28a35d8a
HE
632 }
633 }
634
fefa1800 635 *lastsample = samples[n - 1];
28a35d8a 636
fefa1800
UH
637 /* Send to sigrok. */
638 sent = 0;
28a35d8a 639 while (sent < n) {
f78898e9 640 tosend = MIN(2048, n - sent);
28a35d8a 641
f78898e9
HE
642 packet.type = DF_LOGIC16;
643 packet.length = tosend * sizeof(uint16_t);
fefa1800 644 packet.payload = samples + sent;
28a35d8a
HE
645 session_bus(user_data, &packet);
646
647 sent += tosend;
648 }
649 }
650
f78898e9 651 return SIGROK_OK;
28a35d8a
HE
652}
653
654static int receive_data(int fd, int revents, void *user_data)
655{
656 struct datafeed_packet packet;
28a35d8a
HE
657 const int chunks_per_read = 32;
658 unsigned char buf[chunks_per_read * CHUNK_SIZE];
fefa1800
UH
659 int bufsz, numchunks, curchunk, i, newchunks;
660 uint32_t triggerpos, stoppos, running_msec;
28a35d8a 661 struct timeval tv;
28a35d8a 662 uint16_t lastts = 0;
f78898e9 663 uint16_t lastsample = 0;
28a35d8a
HE
664
665 fd = fd;
666 revents = revents;
667
fefa1800 668 /* Get the current position. */
28a35d8a
HE
669 sigma_read_pos(&stoppos, &triggerpos);
670 numchunks = stoppos / 512;
671
fefa1800 672 /* Check if the has expired, or memory is full. */
28a35d8a
HE
673 gettimeofday(&tv, 0);
674 running_msec = (tv.tv_sec - start_tv.tv_sec) * 1000 +
fefa1800 675 (tv.tv_usec - start_tv.tv_usec) / 1000;
28a35d8a
HE
676
677 if (running_msec < limit_msec && numchunks < 32767)
678 return FALSE;
679
fefa1800 680 /* Stop acqusition. */
28a35d8a
HE
681 sigma_set_register(WRITE_MODE, 0x11);
682
fefa1800 683 /* Set SDRAM Read Enable. */
28a35d8a
HE
684 sigma_set_register(WRITE_MODE, 0x02);
685
fefa1800 686 /* Get the current position. */
28a35d8a
HE
687 sigma_read_pos(&stoppos, &triggerpos);
688
f78898e9
HE
689 /* Read mode status. We will care for this later. */
690 sigma_get_register(READ_MODE);
691
fefa1800 692 /* Download sample data. */
28a35d8a 693 for (curchunk = 0; curchunk < numchunks;) {
fefa1800 694 newchunks = MIN(chunks_per_read, numchunks - curchunk);
28a35d8a
HE
695
696 g_message("Downloading sample data: %.0f %%",
fefa1800 697 100.0 * curchunk / numchunks);
28a35d8a
HE
698
699 bufsz = sigma_read_dram(curchunk, newchunks, buf);
700
fefa1800
UH
701 /* Find first ts. */
702 if (curchunk == 0)
703 lastts = *(uint16_t *) buf - 1;
28a35d8a 704
fefa1800 705 /* Decode chunks and send them to sigrok. */
28a35d8a
HE
706 for (i = 0; i < newchunks; ++i) {
707 decode_chunk_ts(buf + (i * CHUNK_SIZE),
708 &lastts, &lastsample, user_data);
709 }
710
711 curchunk += newchunks;
712 }
713
714 /* End of data */
715 packet.type = DF_END;
716 packet.length = 0;
717 session_bus(user_data, &packet);
718
719 return TRUE;
720}
721
722static int hw_start_acquisition(int device_index, gpointer session_device_id)
723{
724 struct sigrok_device_instance *sdi;
725 struct datafeed_packet packet;
726 struct datafeed_header header;
fefa1800 727 uint8_t trigger_option[2] = { 0x38, 0x00 };
9ddb2a12
UH
728 struct clockselect_50 clockselect;
729 int frac;
28a35d8a
HE
730
731 session_device_id = session_device_id;
732
733 if (!(sdi = get_sigrok_device_instance(device_instances, device_index)))
734 return SIGROK_ERR;
735
736 device_index = device_index;
737
ed09fd07 738 /* If the samplerate has not been set, default to 50 MHz. */
9ddb2a12 739 if (cur_firmware == -1)
ed09fd07 740 set_samplerate(sdi, MHZ(50));
e8397563 741
fefa1800 742 /* Setup trigger (by trigger-in). */
28a35d8a
HE
743 sigma_set_register(WRITE_TRIGGER_SELECT1, 0x20);
744
fefa1800 745 /* More trigger setup. */
28a35d8a 746 sigma_write_register(WRITE_TRIGGER_OPTION,
fefa1800 747 trigger_option, sizeof(trigger_option));
28a35d8a 748
fefa1800 749 /* Trigger normal (falling edge). */
28a35d8a
HE
750 sigma_set_register(WRITE_TRIGGER_SELECT1, 0x08);
751
edca2c5c
HE
752 /* Set clock select register. */
753 if (cur_samplerate == MHZ(200))
754 /* Enable 4 probes. */
755 sigma_set_register(WRITE_CLOCK_SELECT, 0xf0);
756 else if (cur_samplerate == MHZ(100))
757 /* Enable 8 probes. */
758 sigma_set_register(WRITE_CLOCK_SELECT, 0x00);
759 else {
760 /*
9ddb2a12
UH
761 * 50 MHz mode (or fraction thereof). Any fraction down to
762 * 50 MHz / 256 can be used, but is not suppoted by sigrok API.
edca2c5c 763 */
9ddb2a12 764 frac = MHZ(50) / cur_samplerate - 1;
edca2c5c 765
9ddb2a12
UH
766 clockselect.async = 0;
767 clockselect.fraction = frac;
768 clockselect.disabled_probes = 0;
edca2c5c
HE
769
770 sigma_write_register(WRITE_CLOCK_SELECT,
9ddb2a12
UH
771 (uint8_t *) &clockselect,
772 sizeof(clockselect));
edca2c5c
HE
773 }
774
fefa1800 775 /* Setup maximum post trigger time. */
28a35d8a
HE
776 sigma_set_register(WRITE_POST_TRIGGER, 0xff);
777
fefa1800 778 /* Start acqusition (software trigger start). */
28a35d8a
HE
779 gettimeofday(&start_tv, 0);
780 sigma_set_register(WRITE_MODE, 0x0d);
781
fefa1800 782 /* Add capture source. */
28a35d8a
HE
783 source_add(0, G_IO_IN, 10, receive_data, session_device_id);
784
785 receive_data(0, 1, session_device_id);
786
787 /* Send header packet to the session bus. */
788 packet.type = DF_HEADER;
789 packet.length = sizeof(struct datafeed_header);
790 packet.payload = &header;
791 header.feed_version = 1;
792 gettimeofday(&header.starttime, NULL);
793 header.samplerate = cur_samplerate;
794 header.protocol_id = PROTO_RAW;
edca2c5c 795 header.num_probes = num_probes;
28a35d8a
HE
796 session_bus(session_device_id, &packet);
797
798 return SIGROK_OK;
799}
800
28a35d8a
HE
801static void hw_stop_acquisition(int device_index, gpointer session_device_id)
802{
803 device_index = device_index;
804 session_device_id = session_device_id;
805
fefa1800 806 /* Stop acquisition. */
28a35d8a
HE
807 sigma_set_register(WRITE_MODE, 0x11);
808
809 // XXX Set some state to indicate that data should be sent to sigrok
810 // Now, we just wait for timeout
811}
812
28a35d8a
HE
813struct device_plugin asix_sigma_plugin_info = {
814 "asix-sigma",
815 1,
816 hw_init,
817 hw_cleanup,
28a35d8a
HE
818 hw_opendev,
819 hw_closedev,
820 hw_get_device_info,
821 hw_get_status,
822 hw_get_capabilities,
823 hw_set_configuration,
824 hw_start_acquisition,
9ddb2a12 825 hw_stop_acquisition,
28a35d8a 826};