]> sigrok.org Git - libsigrok.git/blame - hardware/asix-sigma/asix-sigma.c
sr: rename all sr_hwplugin(s)_* functions to sr_hw_*
[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 22/*
da0918aa 23 * ASIX SIGMA Logic Analyzer Driver
911f1834
UH
24 */
25
3bbd9849
UH
26#include <glib.h>
27#include <glib/gstdio.h>
28a35d8a
HE
28#include <ftdi.h>
29#include <string.h>
30#include <zlib.h>
b7f09cf8
UH
31#include "sigrok.h"
32#include "sigrok-internal.h"
28a35d8a
HE
33#include "asix-sigma.h"
34
35#define USB_VENDOR 0xa600
36#define USB_PRODUCT 0xa000
37#define USB_DESCRIPTION "ASIX SIGMA"
38#define USB_VENDOR_NAME "ASIX"
39#define USB_MODEL_NAME "SIGMA"
40#define USB_MODEL_VERSION ""
ee492173 41#define TRIGGER_TYPES "rf10"
464d12c7 42#define NUM_PROBES 16
28a35d8a
HE
43
44static GSList *device_instances = NULL;
45
28a35d8a 46static uint64_t supported_samplerates[] = {
59df0c77
UH
47 SR_KHZ(200),
48 SR_KHZ(250),
49 SR_KHZ(500),
50 SR_MHZ(1),
51 SR_MHZ(5),
52 SR_MHZ(10),
53 SR_MHZ(25),
54 SR_MHZ(50),
55 SR_MHZ(100),
56 SR_MHZ(200),
28a35d8a
HE
57 0,
58};
59
c37d2b1b 60static const char *probe_names[NUM_PROBES + 1] = {
464d12c7
KS
61 "0",
62 "1",
63 "2",
64 "3",
65 "4",
66 "5",
67 "6",
68 "7",
69 "8",
70 "9",
71 "10",
72 "11",
73 "12",
74 "13",
75 "14",
76 "15",
77 NULL,
78};
79
60679b18 80static struct sr_samplerates samplerates = {
59df0c77
UH
81 SR_KHZ(200),
82 SR_MHZ(200),
c9140419 83 SR_HZ(0),
28a35d8a
HE
84 supported_samplerates,
85};
86
87static int capabilities[] = {
5a2326a7
UH
88 SR_HWCAP_LOGIC_ANALYZER,
89 SR_HWCAP_SAMPLERATE,
90 SR_HWCAP_CAPTURE_RATIO,
91 SR_HWCAP_PROBECONFIG,
28a35d8a 92
5a2326a7 93 SR_HWCAP_LIMIT_MSEC,
28a35d8a
HE
94 0,
95};
96
fefa1800
UH
97/* Force the FPGA to reboot. */
98static uint8_t suicide[] = {
99 0x84, 0x84, 0x88, 0x84, 0x88, 0x84, 0x88, 0x84,
100};
101
102/* Prepare to upload firmware (FPGA specific). */
103static uint8_t init[] = {
104 0x03, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
105};
106
107/* Initialize the logic analyzer mode. */
108static uint8_t logic_mode_start[] = {
109 0x00, 0x40, 0x0f, 0x25, 0x35, 0x40,
110 0x2a, 0x3a, 0x40, 0x03, 0x20, 0x38,
111};
112
eec5275e 113static const char *firmware_files[] = {
a8116d76
HE
114 "asix-sigma-50.fw", /* 50 MHz, supports 8 bit fractions */
115 "asix-sigma-100.fw", /* 100 MHz */
116 "asix-sigma-200.fw", /* 200 MHz */
ed09fd07 117 "asix-sigma-50sync.fw", /* Synchronous clock from pin */
a8116d76 118 "asix-sigma-phasor.fw", /* Frequency counter */
f6564c8d
HE
119};
120
3010f21c 121static int hw_stop_acquisition(int device_index, gpointer session_data);
6aac7737 122
99965709 123static int sigma_read(void *buf, size_t size, struct sigma *sigma)
28a35d8a
HE
124{
125 int ret;
fefa1800 126
99965709 127 ret = ftdi_read_data(&sigma->ftdic, (unsigned char *)buf, size);
28a35d8a 128 if (ret < 0) {
133a37bf
UH
129 sr_err("ftdi_read_data failed: %s",
130 ftdi_get_error_string(&sigma->ftdic));
28a35d8a
HE
131 }
132
133 return ret;
134}
135
99965709 136static int sigma_write(void *buf, size_t size, struct sigma *sigma)
28a35d8a
HE
137{
138 int ret;
fefa1800 139
99965709 140 ret = ftdi_write_data(&sigma->ftdic, (unsigned char *)buf, size);
28a35d8a 141 if (ret < 0) {
133a37bf
UH
142 sr_err("ftdi_write_data failed: %s",
143 ftdi_get_error_string(&sigma->ftdic));
fefa1800 144 } else if ((size_t) ret != size) {
133a37bf 145 sr_err("ftdi_write_data did not complete write\n");
28a35d8a
HE
146 }
147
148 return ret;
149}
150
99965709
HE
151static int sigma_write_register(uint8_t reg, uint8_t *data, size_t len,
152 struct sigma *sigma)
28a35d8a
HE
153{
154 size_t i;
155 uint8_t buf[len + 2];
156 int idx = 0;
157
158 buf[idx++] = REG_ADDR_LOW | (reg & 0xf);
159 buf[idx++] = REG_ADDR_HIGH | (reg >> 4);
160
fefa1800 161 for (i = 0; i < len; ++i) {
28a35d8a
HE
162 buf[idx++] = REG_DATA_LOW | (data[i] & 0xf);
163 buf[idx++] = REG_DATA_HIGH_WRITE | (data[i] >> 4);
164 }
165
99965709 166 return sigma_write(buf, idx, sigma);
28a35d8a
HE
167}
168
99965709 169static int sigma_set_register(uint8_t reg, uint8_t value, struct sigma *sigma)
28a35d8a 170{
99965709 171 return sigma_write_register(reg, &value, 1, sigma);
28a35d8a
HE
172}
173
99965709
HE
174static int sigma_read_register(uint8_t reg, uint8_t *data, size_t len,
175 struct sigma *sigma)
28a35d8a
HE
176{
177 uint8_t buf[3];
fefa1800 178
28a35d8a
HE
179 buf[0] = REG_ADDR_LOW | (reg & 0xf);
180 buf[1] = REG_ADDR_HIGH | (reg >> 4);
28a35d8a
HE
181 buf[2] = REG_READ_ADDR;
182
99965709 183 sigma_write(buf, sizeof(buf), sigma);
28a35d8a 184
99965709 185 return sigma_read(data, len, sigma);
28a35d8a
HE
186}
187
99965709 188static uint8_t sigma_get_register(uint8_t reg, struct sigma *sigma)
28a35d8a
HE
189{
190 uint8_t value;
fefa1800 191
99965709 192 if (1 != sigma_read_register(reg, &value, 1, sigma)) {
133a37bf 193 sr_err("sigma_get_register: 1 byte expected");
28a35d8a
HE
194 return 0;
195 }
196
197 return value;
198}
199
99965709
HE
200static int sigma_read_pos(uint32_t *stoppos, uint32_t *triggerpos,
201 struct sigma *sigma)
28a35d8a
HE
202{
203 uint8_t buf[] = {
204 REG_ADDR_LOW | READ_TRIGGER_POS_LOW,
205
206 REG_READ_ADDR | NEXT_REG,
207 REG_READ_ADDR | NEXT_REG,
208 REG_READ_ADDR | NEXT_REG,
209 REG_READ_ADDR | NEXT_REG,
210 REG_READ_ADDR | NEXT_REG,
211 REG_READ_ADDR | NEXT_REG,
212 };
28a35d8a
HE
213 uint8_t result[6];
214
99965709 215 sigma_write(buf, sizeof(buf), sigma);
28a35d8a 216
99965709 217 sigma_read(result, sizeof(result), sigma);
28a35d8a
HE
218
219 *triggerpos = result[0] | (result[1] << 8) | (result[2] << 16);
220 *stoppos = result[3] | (result[4] << 8) | (result[5] << 16);
221
57bbf56b
HE
222 /* Not really sure why this must be done, but according to spec. */
223 if ((--*stoppos & 0x1ff) == 0x1ff)
224 stoppos -= 64;
225
226 if ((*--triggerpos & 0x1ff) == 0x1ff)
227 triggerpos -= 64;
228
28a35d8a
HE
229 return 1;
230}
231
99965709
HE
232static int sigma_read_dram(uint16_t startchunk, size_t numchunks,
233 uint8_t *data, struct sigma *sigma)
28a35d8a
HE
234{
235 size_t i;
236 uint8_t buf[4096];
237 int idx = 0;
238
fefa1800 239 /* Send the startchunk. Index start with 1. */
28a35d8a
HE
240 buf[0] = startchunk >> 8;
241 buf[1] = startchunk & 0xff;
99965709 242 sigma_write_register(WRITE_MEMROW, buf, 2, sigma);
28a35d8a 243
fefa1800 244 /* Read the DRAM. */
28a35d8a
HE
245 buf[idx++] = REG_DRAM_BLOCK;
246 buf[idx++] = REG_DRAM_WAIT_ACK;
247
248 for (i = 0; i < numchunks; ++i) {
fefa1800
UH
249 /* Alternate bit to copy from DRAM to cache. */
250 if (i != (numchunks - 1))
251 buf[idx++] = REG_DRAM_BLOCK | (((i + 1) % 2) << 4);
28a35d8a
HE
252
253 buf[idx++] = REG_DRAM_BLOCK_DATA | ((i % 2) << 4);
254
fefa1800 255 if (i != (numchunks - 1))
28a35d8a
HE
256 buf[idx++] = REG_DRAM_WAIT_ACK;
257 }
258
99965709 259 sigma_write(buf, idx, sigma);
28a35d8a 260
99965709 261 return sigma_read(data, numchunks * CHUNK_SIZE, sigma);
28a35d8a
HE
262}
263
4ae1f451 264/* Upload trigger look-up tables to Sigma. */
99965709 265static int sigma_write_trigger_lut(struct triggerlut *lut, struct sigma *sigma)
ee492173
HE
266{
267 int i;
268 uint8_t tmp[2];
269 uint16_t bit;
270
271 /* Transpose the table and send to Sigma. */
272 for (i = 0; i < 16; ++i) {
273 bit = 1 << i;
274
275 tmp[0] = tmp[1] = 0;
276
277 if (lut->m2d[0] & bit)
278 tmp[0] |= 0x01;
279 if (lut->m2d[1] & bit)
280 tmp[0] |= 0x02;
281 if (lut->m2d[2] & bit)
282 tmp[0] |= 0x04;
283 if (lut->m2d[3] & bit)
284 tmp[0] |= 0x08;
285
286 if (lut->m3 & bit)
287 tmp[0] |= 0x10;
288 if (lut->m3s & bit)
289 tmp[0] |= 0x20;
290 if (lut->m4 & bit)
291 tmp[0] |= 0x40;
292
293 if (lut->m0d[0] & bit)
294 tmp[1] |= 0x01;
295 if (lut->m0d[1] & bit)
296 tmp[1] |= 0x02;
297 if (lut->m0d[2] & bit)
298 tmp[1] |= 0x04;
299 if (lut->m0d[3] & bit)
300 tmp[1] |= 0x08;
301
302 if (lut->m1d[0] & bit)
303 tmp[1] |= 0x10;
304 if (lut->m1d[1] & bit)
305 tmp[1] |= 0x20;
306 if (lut->m1d[2] & bit)
307 tmp[1] |= 0x40;
308 if (lut->m1d[3] & bit)
309 tmp[1] |= 0x80;
310
99965709
HE
311 sigma_write_register(WRITE_TRIGGER_SELECT0, tmp, sizeof(tmp),
312 sigma);
313 sigma_set_register(WRITE_TRIGGER_SELECT1, 0x30 | i, sigma);
ee492173
HE
314 }
315
316 /* Send the parameters */
317 sigma_write_register(WRITE_TRIGGER_SELECT0, (uint8_t *) &lut->params,
99965709 318 sizeof(lut->params), sigma);
ee492173 319
e46b8fb1 320 return SR_OK;
ee492173
HE
321}
322
fefa1800 323/* Generate the bitbang stream for programming the FPGA. */
28a35d8a 324static int bin2bitbang(const char *filename,
fefa1800 325 unsigned char **buf, size_t *buf_size)
28a35d8a 326{
fefa1800 327 FILE *f;
28a35d8a
HE
328 long file_size;
329 unsigned long offset = 0;
330 unsigned char *p;
331 uint8_t *compressed_buf, *firmware;
332 uLongf csize, fwsize;
333 const int buffer_size = 65536;
334 size_t i;
fefa1800
UH
335 int c, ret, bit, v;
336 uint32_t imm = 0x3f6df2ab;
28a35d8a 337
868d8cef 338 f = g_fopen(filename, "rb");
28a35d8a 339 if (!f) {
133a37bf 340 sr_err("g_fopen(\"%s\", \"rb\")", filename);
b53738ba 341 return SR_ERR;
28a35d8a
HE
342 }
343
344 if (-1 == fseek(f, 0, SEEK_END)) {
133a37bf 345 sr_err("fseek on %s failed", filename);
28a35d8a 346 fclose(f);
b53738ba 347 return SR_ERR;
28a35d8a
HE
348 }
349
350 file_size = ftell(f);
351
352 fseek(f, 0, SEEK_SET);
353
b53738ba 354 if (!(compressed_buf = g_try_malloc(file_size))) {
340cfac0 355 sr_err("sigma: %s: compressed_buf malloc failed", __func__);
12ad53f5 356 fclose(f);
b53738ba
UH
357 return SR_ERR_MALLOC;
358 }
28a35d8a 359
b53738ba 360 if (!(firmware = g_try_malloc(buffer_size))) {
340cfac0 361 sr_err("sigma: %s: firmware malloc failed", __func__);
12ad53f5
UH
362 fclose(f);
363 g_free(compressed_buf);
b53738ba 364 return SR_ERR_MALLOC;
28a35d8a
HE
365 }
366
28a35d8a
HE
367 csize = 0;
368 while ((c = getc(f)) != EOF) {
369 imm = (imm + 0xa853753) % 177 + (imm * 0x8034052);
370 compressed_buf[csize++] = c ^ imm;
371 }
372 fclose(f);
373
374 fwsize = buffer_size;
375 ret = uncompress(firmware, &fwsize, compressed_buf, csize);
376 if (ret < 0) {
377 g_free(compressed_buf);
378 g_free(firmware);
133a37bf 379 sr_err("Could not unpack Sigma firmware. (Error %d)\n", ret);
b53738ba 380 return SR_ERR;
28a35d8a
HE
381 }
382
383 g_free(compressed_buf);
384
385 *buf_size = fwsize * 2 * 8;
386
b53738ba 387 *buf = p = (unsigned char *)g_try_malloc(*buf_size);
28a35d8a 388 if (!p) {
340cfac0 389 sr_err("sigma: %s: buf/p malloc failed", __func__);
12ad53f5
UH
390 g_free(compressed_buf);
391 g_free(firmware);
b53738ba 392 return SR_ERR_MALLOC;
28a35d8a
HE
393 }
394
395 for (i = 0; i < fwsize; ++i) {
28a35d8a 396 for (bit = 7; bit >= 0; --bit) {
fefa1800 397 v = firmware[i] & 1 << bit ? 0x40 : 0x00;
28a35d8a
HE
398 p[offset++] = v | 0x01;
399 p[offset++] = v;
400 }
401 }
402
403 g_free(firmware);
404
405 if (offset != *buf_size) {
406 g_free(*buf);
133a37bf
UH
407 sr_err("Error reading firmware %s "
408 "offset=%ld, file_size=%ld, buf_size=%zd\n",
409 filename, offset, file_size, *buf_size);
28a35d8a 410
b53738ba 411 return SR_ERR;
28a35d8a
HE
412 }
413
b53738ba 414 return SR_OK;
28a35d8a
HE
415}
416
54ac5277 417static int hw_init(const char *deviceinfo)
28a35d8a 418{
a00ba012 419 struct sr_device_instance *sdi;
b53738ba 420 struct sigma *sigma;
28a35d8a 421
b53738ba 422 /* Avoid compiler warnings. */
cb93f8a9 423 (void)deviceinfo;
28a35d8a 424
b53738ba 425 if (!(sigma = g_try_malloc(sizeof(struct sigma)))) {
340cfac0 426 sr_err("sigma: %s: sigma malloc failed", __func__);
b53738ba
UH
427 return 0; /* FIXME: Should be SR_ERR_MALLOC. */
428 }
99965709
HE
429
430 ftdi_init(&sigma->ftdic);
28a35d8a 431
fefa1800 432 /* Look for SIGMAs. */
99965709 433 if (ftdi_usb_open_desc(&sigma->ftdic, USB_VENDOR, USB_PRODUCT,
fefa1800 434 USB_DESCRIPTION, NULL) < 0)
99965709
HE
435 goto free;
436
437 sigma->cur_samplerate = 0;
9c939c51 438 sigma->period_ps = 0;
99965709
HE
439 sigma->limit_msec = 0;
440 sigma->cur_firmware = -1;
441 sigma->num_probes = 0;
442 sigma->samples_per_event = 0;
443 sigma->capture_ratio = 50;
5b5ea7c6 444 sigma->use_triggers = 0;
28a35d8a 445
fefa1800 446 /* Register SIGMA device. */
d3683c42 447 sdi = sr_dev_inst_new(0, SR_ST_INITIALIZING,
28a35d8a
HE
448 USB_VENDOR_NAME, USB_MODEL_NAME, USB_MODEL_VERSION);
449 if (!sdi)
99965709
HE
450 goto free;
451
452 sdi->priv = sigma;
28a35d8a
HE
453
454 device_instances = g_slist_append(device_instances, sdi);
455
fefa1800 456 /* We will open the device again when we need it. */
99965709 457 ftdi_usb_close(&sigma->ftdic);
28a35d8a
HE
458
459 return 1;
99965709 460free:
12ad53f5 461 g_free(sigma);
99965709 462 return 0;
28a35d8a
HE
463}
464
99965709 465static int upload_firmware(int firmware_idx, struct sigma *sigma)
28a35d8a
HE
466{
467 int ret;
468 unsigned char *buf;
469 unsigned char pins;
470 size_t buf_size;
28a35d8a 471 unsigned char result[32];
e8397563 472 char firmware_path[128];
28a35d8a 473
fefa1800 474 /* Make sure it's an ASIX SIGMA. */
99965709 475 if ((ret = ftdi_usb_open_desc(&sigma->ftdic,
28a35d8a 476 USB_VENDOR, USB_PRODUCT, USB_DESCRIPTION, NULL)) < 0) {
133a37bf
UH
477 sr_err("ftdi_usb_open failed: %s",
478 ftdi_get_error_string(&sigma->ftdic));
28a35d8a
HE
479 return 0;
480 }
481
99965709 482 if ((ret = ftdi_set_bitmode(&sigma->ftdic, 0xdf, BITMODE_BITBANG)) < 0) {
133a37bf
UH
483 sr_err("ftdi_set_bitmode failed: %s",
484 ftdi_get_error_string(&sigma->ftdic));
28a35d8a
HE
485 return 0;
486 }
487
fefa1800 488 /* Four times the speed of sigmalogan - Works well. */
99965709 489 if ((ret = ftdi_set_baudrate(&sigma->ftdic, 750000)) < 0) {
133a37bf
UH
490 sr_err("ftdi_set_baudrate failed: %s",
491 ftdi_get_error_string(&sigma->ftdic));
28a35d8a
HE
492 return 0;
493 }
494
fefa1800 495 /* Force the FPGA to reboot. */
99965709
HE
496 sigma_write(suicide, sizeof(suicide), sigma);
497 sigma_write(suicide, sizeof(suicide), sigma);
498 sigma_write(suicide, sizeof(suicide), sigma);
499 sigma_write(suicide, sizeof(suicide), sigma);
28a35d8a 500
fefa1800 501 /* Prepare to upload firmware (FPGA specific). */
99965709 502 sigma_write(init, sizeof(init), sigma);
28a35d8a 503
99965709 504 ftdi_usb_purge_buffers(&sigma->ftdic);
28a35d8a 505
fefa1800 506 /* Wait until the FPGA asserts INIT_B. */
28a35d8a 507 while (1) {
99965709 508 ret = sigma_read(result, 1, sigma);
28a35d8a
HE
509 if (result[0] & 0x20)
510 break;
511 }
512
9ddb2a12 513 /* Prepare firmware. */
e8397563 514 snprintf(firmware_path, sizeof(firmware_path), "%s/%s", FIRMWARE_DIR,
f6564c8d
HE
515 firmware_files[firmware_idx]);
516
b53738ba 517 if ((ret = bin2bitbang(firmware_path, &buf, &buf_size)) != SR_OK) {
133a37bf
UH
518 sr_err("An error occured while reading the firmware: %s",
519 firmware_path);
b53738ba 520 return ret;
28a35d8a
HE
521 }
522
fefa1800 523 /* Upload firmare. */
99965709 524 sigma_write(buf, buf_size, sigma);
28a35d8a
HE
525
526 g_free(buf);
527
99965709 528 if ((ret = ftdi_set_bitmode(&sigma->ftdic, 0x00, BITMODE_RESET)) < 0) {
133a37bf
UH
529 sr_err("ftdi_set_bitmode failed: %s",
530 ftdi_get_error_string(&sigma->ftdic));
e46b8fb1 531 return SR_ERR;
28a35d8a
HE
532 }
533
99965709 534 ftdi_usb_purge_buffers(&sigma->ftdic);
28a35d8a 535
fefa1800 536 /* Discard garbage. */
99965709 537 while (1 == sigma_read(&pins, 1, sigma))
28a35d8a
HE
538 ;
539
fefa1800 540 /* Initialize the logic analyzer mode. */
99965709 541 sigma_write(logic_mode_start, sizeof(logic_mode_start), sigma);
28a35d8a 542
fefa1800 543 /* Expect a 3 byte reply. */
99965709 544 ret = sigma_read(result, 3, sigma);
28a35d8a
HE
545 if (ret != 3 ||
546 result[0] != 0xa6 || result[1] != 0x55 || result[2] != 0xaa) {
133a37bf 547 sr_err("Configuration failed. Invalid reply received.");
e46b8fb1 548 return SR_ERR;
28a35d8a
HE
549 }
550
99965709 551 sigma->cur_firmware = firmware_idx;
f6564c8d 552
e46b8fb1 553 return SR_OK;
f6564c8d
HE
554}
555
556static int hw_opendev(int device_index)
557{
a00ba012 558 struct sr_device_instance *sdi;
99965709 559 struct sigma *sigma;
f6564c8d
HE
560 int ret;
561
da1466d6 562 if (!(sdi = sr_dev_inst_get(device_instances, device_index)))
e46b8fb1 563 return SR_ERR;
99965709
HE
564
565 sigma = sdi->priv;
566
9ddb2a12 567 /* Make sure it's an ASIX SIGMA. */
99965709 568 if ((ret = ftdi_usb_open_desc(&sigma->ftdic,
f6564c8d
HE
569 USB_VENDOR, USB_PRODUCT, USB_DESCRIPTION, NULL)) < 0) {
570
133a37bf
UH
571 sr_err("ftdi_usb_open failed: %s",
572 ftdi_get_error_string(&sigma->ftdic));
f6564c8d
HE
573
574 return 0;
575 }
28a35d8a 576
5a2326a7 577 sdi->status = SR_ST_ACTIVE;
28a35d8a 578
e46b8fb1 579 return SR_OK;
f6564c8d
HE
580}
581
a00ba012 582static int set_samplerate(struct sr_device_instance *sdi,
6aac7737 583 uint64_t samplerate)
f6564c8d 584{
e8397563 585 int i, ret;
99965709 586 struct sigma *sigma = sdi->priv;
f6564c8d
HE
587
588 for (i = 0; supported_samplerates[i]; i++) {
589 if (supported_samplerates[i] == samplerate)
590 break;
591 }
592 if (supported_samplerates[i] == 0)
e46b8fb1 593 return SR_ERR_SAMPLERATE;
f6564c8d 594
59df0c77 595 if (samplerate <= SR_MHZ(50)) {
99965709
HE
596 ret = upload_firmware(0, sigma);
597 sigma->num_probes = 16;
e8397563 598 }
59df0c77 599 if (samplerate == SR_MHZ(100)) {
99965709
HE
600 ret = upload_firmware(1, sigma);
601 sigma->num_probes = 8;
f78898e9 602 }
59df0c77 603 else if (samplerate == SR_MHZ(200)) {
99965709
HE
604 ret = upload_firmware(2, sigma);
605 sigma->num_probes = 4;
f78898e9 606 }
f6564c8d 607
99965709 608 sigma->cur_samplerate = samplerate;
9c939c51 609 sigma->period_ps = 1000000000000 / samplerate;
99965709
HE
610 sigma->samples_per_event = 16 / sigma->num_probes;
611 sigma->state.state = SIGMA_IDLE;
f6564c8d 612
b08024a8 613 sr_info("Firmware uploaded");
28a35d8a 614
e8397563 615 return ret;
28a35d8a
HE
616}
617
c53d793f
HE
618/*
619 * In 100 and 200 MHz mode, only a single pin rising/falling can be
620 * set as trigger. In other modes, two rising/falling triggers can be set,
621 * in addition to value/mask trigger for any number of probes.
622 *
623 * The Sigma supports complex triggers using boolean expressions, but this
624 * has not been implemented yet.
625 */
a00ba012 626static int configure_probes(struct sr_device_instance *sdi, GSList *probes)
57bbf56b 627{
99965709 628 struct sigma *sigma = sdi->priv;
1afe8989 629 struct sr_probe *probe;
57bbf56b
HE
630 GSList *l;
631 int trigger_set = 0;
a42aec7f 632 int probebit;
57bbf56b 633
99965709 634 memset(&sigma->trigger, 0, sizeof(struct sigma_trigger));
eec5275e 635
57bbf56b 636 for (l = probes; l; l = l->next) {
1afe8989 637 probe = (struct sr_probe *)l->data;
a42aec7f 638 probebit = 1 << (probe->index - 1);
57bbf56b
HE
639
640 if (!probe->enabled || !probe->trigger)
641 continue;
642
59df0c77 643 if (sigma->cur_samplerate >= SR_MHZ(100)) {
c53d793f 644 /* Fast trigger support. */
ee492173 645 if (trigger_set) {
133a37bf
UH
646 sr_err("ASIX SIGMA only supports a single "
647 "pin trigger in 100 and 200MHz mode.");
e46b8fb1 648 return SR_ERR;
ee492173
HE
649 }
650 if (probe->trigger[0] == 'f')
99965709 651 sigma->trigger.fallingmask |= probebit;
ee492173 652 else if (probe->trigger[0] == 'r')
99965709 653 sigma->trigger.risingmask |= probebit;
ee492173 654 else {
133a37bf
UH
655 sr_err("ASIX SIGMA only supports "
656 "rising/falling trigger in 100 "
657 "and 200MHz mode.");
e46b8fb1 658 return SR_ERR;
ee492173 659 }
57bbf56b 660
c53d793f 661 ++trigger_set;
ee492173 662 } else {
c53d793f
HE
663 /* Simple trigger support (event). */
664 if (probe->trigger[0] == '1') {
99965709
HE
665 sigma->trigger.simplevalue |= probebit;
666 sigma->trigger.simplemask |= probebit;
c53d793f
HE
667 }
668 else if (probe->trigger[0] == '0') {
99965709
HE
669 sigma->trigger.simplevalue &= ~probebit;
670 sigma->trigger.simplemask |= probebit;
c53d793f
HE
671 }
672 else if (probe->trigger[0] == 'f') {
99965709 673 sigma->trigger.fallingmask |= probebit;
c53d793f
HE
674 ++trigger_set;
675 }
676 else if (probe->trigger[0] == 'r') {
99965709 677 sigma->trigger.risingmask |= probebit;
c53d793f
HE
678 ++trigger_set;
679 }
ee492173 680
98b8cbc1
HE
681 /*
682 * Actually, Sigma supports 2 rising/falling triggers,
683 * but they are ORed and the current trigger syntax
684 * does not permit ORed triggers.
685 */
686 if (trigger_set > 1) {
133a37bf
UH
687 sr_err("ASIX SIGMA only supports 1 rising/"
688 "falling triggers.");
e46b8fb1 689 return SR_ERR;
ee492173 690 }
ee492173 691 }
5b5ea7c6
HE
692
693 if (trigger_set)
694 sigma->use_triggers = 1;
57bbf56b
HE
695 }
696
e46b8fb1 697 return SR_OK;
57bbf56b
HE
698}
699
697785d1 700static int hw_closedev(int device_index)
28a35d8a 701{
a00ba012 702 struct sr_device_instance *sdi;
99965709 703 struct sigma *sigma;
28a35d8a 704
da1466d6 705 if (!(sdi = sr_dev_inst_get(device_instances, device_index))) {
340cfac0 706 sr_err("sigma: %s: sdi was NULL", __func__);
697785d1
UH
707 return SR_ERR; /* TODO: SR_ERR_ARG? */
708 }
9be9893e 709
697785d1 710 if (!(sigma = sdi->priv)) {
340cfac0 711 sr_err("sigma: %s: sdi->priv was NULL", __func__);
697785d1 712 return SR_ERR; /* TODO: SR_ERR_ARG? */
9be9893e 713 }
697785d1
UH
714
715 /* TODO */
716 if (sdi->status == SR_ST_ACTIVE)
717 ftdi_usb_close(&sigma->ftdic);
718
719 sdi->status = SR_ST_INACTIVE;
720
721 return SR_OK;
28a35d8a
HE
722}
723
57ab7d9f 724static int hw_cleanup(void)
28a35d8a 725{
99965709 726 GSList *l;
a00ba012 727 struct sr_device_instance *sdi;
57ab7d9f 728 int ret = SR_OK;
99965709
HE
729
730 /* Properly close all devices. */
731 for (l = device_instances; l; l = l->next) {
57ab7d9f
UH
732 if (!(sdi = l->data)) {
733 /* Log error, but continue cleaning up the rest. */
734 sr_err("asix: %s: sdi was NULL, continuing", __func__);
735 ret = SR_ERR_BUG;
736 continue;
737 }
d3683c42 738 sr_dev_inst_free(sdi);
99965709
HE
739 }
740 g_slist_free(device_instances);
741 device_instances = NULL;
57ab7d9f
UH
742
743 return ret;
28a35d8a
HE
744}
745
28a35d8a
HE
746static void *hw_get_device_info(int device_index, int device_info_id)
747{
a00ba012 748 struct sr_device_instance *sdi;
99965709 749 struct sigma *sigma;
28a35d8a
HE
750 void *info = NULL;
751
da1466d6 752 if (!(sdi = sr_dev_inst_get(device_instances, device_index))) {
a562c3a2 753 sr_err("It's NULL.\n");
28a35d8a
HE
754 return NULL;
755 }
756
99965709
HE
757 sigma = sdi->priv;
758
28a35d8a 759 switch (device_info_id) {
5a2326a7 760 case SR_DI_INSTANCE:
28a35d8a
HE
761 info = sdi;
762 break;
5a2326a7 763 case SR_DI_NUM_PROBES:
464d12c7
KS
764 info = GINT_TO_POINTER(NUM_PROBES);
765 break;
766 case SR_DI_PROBE_NAMES:
767 info = probe_names;
28a35d8a 768 break;
5a2326a7 769 case SR_DI_SAMPLERATES:
28a35d8a
HE
770 info = &samplerates;
771 break;
5a2326a7 772 case SR_DI_TRIGGER_TYPES:
57bbf56b 773 info = (char *)TRIGGER_TYPES;
28a35d8a 774 break;
5a2326a7 775 case SR_DI_CUR_SAMPLERATE:
99965709 776 info = &sigma->cur_samplerate;
28a35d8a
HE
777 break;
778 }
779
780 return info;
781}
782
28a35d8a
HE
783static int hw_get_status(int device_index)
784{
a00ba012 785 struct sr_device_instance *sdi;
28a35d8a 786
da1466d6 787 sdi = sr_dev_inst_get(device_instances, device_index);
28a35d8a
HE
788 if (sdi)
789 return sdi->status;
790 else
5a2326a7 791 return SR_ST_NOT_FOUND;
28a35d8a
HE
792}
793
28a35d8a
HE
794static int *hw_get_capabilities(void)
795{
796 return capabilities;
797}
798
799static int hw_set_configuration(int device_index, int capability, void *value)
800{
a00ba012 801 struct sr_device_instance *sdi;
99965709 802 struct sigma *sigma;
28a35d8a 803 int ret;
f6564c8d 804
da1466d6 805 if (!(sdi = sr_dev_inst_get(device_instances, device_index)))
e46b8fb1 806 return SR_ERR;
28a35d8a 807
99965709
HE
808 sigma = sdi->priv;
809
5a2326a7 810 if (capability == SR_HWCAP_SAMPLERATE) {
f6564c8d 811 ret = set_samplerate(sdi, *(uint64_t*) value);
5a2326a7 812 } else if (capability == SR_HWCAP_PROBECONFIG) {
99965709 813 ret = configure_probes(sdi, value);
5a2326a7 814 } else if (capability == SR_HWCAP_LIMIT_MSEC) {
94ba4bd6
HE
815 sigma->limit_msec = *(uint64_t*) value;
816 if (sigma->limit_msec > 0)
e46b8fb1 817 ret = SR_OK;
94ba4bd6 818 else
e46b8fb1 819 ret = SR_ERR;
5a2326a7 820 } else if (capability == SR_HWCAP_CAPTURE_RATIO) {
94ba4bd6
HE
821 sigma->capture_ratio = *(uint64_t*) value;
822 if (sigma->capture_ratio < 0 || sigma->capture_ratio > 100)
e46b8fb1 823 ret = SR_ERR;
94ba4bd6 824 else
e46b8fb1 825 ret = SR_OK;
28a35d8a 826 } else {
e46b8fb1 827 ret = SR_ERR;
28a35d8a
HE
828 }
829
830 return ret;
831}
832
36b1c8e6
HE
833/* Software trigger to determine exact trigger position. */
834static int get_trigger_offset(uint16_t *samples, uint16_t last_sample,
835 struct sigma_trigger *t)
836{
837 int i;
838
839 for (i = 0; i < 8; ++i) {
840 if (i > 0)
841 last_sample = samples[i-1];
842
843 /* Simple triggers. */
844 if ((samples[i] & t->simplemask) != t->simplevalue)
845 continue;
846
847 /* Rising edge. */
848 if ((last_sample & t->risingmask) != 0 || (samples[i] &
849 t->risingmask) != t->risingmask)
850 continue;
851
852 /* Falling edge. */
bdfc7a89
HE
853 if ((last_sample & t->fallingmask) != t->fallingmask ||
854 (samples[i] & t->fallingmask) != 0)
36b1c8e6
HE
855 continue;
856
857 break;
858 }
859
860 /* If we did not match, return original trigger pos. */
861 return i & 0x7;
862}
863
28a35d8a 864/*
fefa1800
UH
865 * Decode chunk of 1024 bytes, 64 clusters, 7 events per cluster.
866 * Each event is 20ns apart, and can contain multiple samples.
f78898e9
HE
867 *
868 * For 200 MHz, events contain 4 samples for each channel, spread 5 ns apart.
869 * For 100 MHz, events contain 2 samples for each channel, spread 10 ns apart.
870 * For 50 MHz and below, events contain one sample for each channel,
871 * spread 20 ns apart.
28a35d8a
HE
872 */
873static int decode_chunk_ts(uint8_t *buf, uint16_t *lastts,
88c51afe 874 uint16_t *lastsample, int triggerpos,
9c939c51 875 uint16_t limit_chunk, void *session_data)
28a35d8a 876{
9c939c51 877 struct sr_device_instance *sdi = session_data;
99965709 878 struct sigma *sigma = sdi->priv;
fefa1800 879 uint16_t tsdiff, ts;
99965709 880 uint16_t samples[65536 * sigma->samples_per_event];
b9c735a2 881 struct sr_datafeed_packet packet;
9c939c51 882 struct sr_datafeed_logic logic;
f78898e9 883 int i, j, k, l, numpad, tosend;
fefa1800 884 size_t n = 0, sent = 0;
99965709 885 int clustersize = EVENTS_PER_CLUSTER * sigma->samples_per_event;
fefa1800 886 uint16_t *event;
f78898e9 887 uint16_t cur_sample;
57bbf56b 888 int triggerts = -1;
ee492173 889
4ae1f451 890 /* Check if trigger is in this chunk. */
ee492173 891 if (triggerpos != -1) {
59df0c77 892 if (sigma->cur_samplerate <= SR_MHZ(50))
36b1c8e6 893 triggerpos -= EVENTS_PER_CLUSTER - 1;
ee492173
HE
894
895 if (triggerpos < 0)
896 triggerpos = 0;
57bbf56b 897
ee492173
HE
898 /* Find in which cluster the trigger occured. */
899 triggerts = triggerpos / 7;
900 }
28a35d8a 901
eec5275e 902 /* For each ts. */
28a35d8a 903 for (i = 0; i < 64; ++i) {
fefa1800 904 ts = *(uint16_t *) &buf[i * 16];
28a35d8a
HE
905 tsdiff = ts - *lastts;
906 *lastts = ts;
907
88c51afe
HE
908 /* Decode partial chunk. */
909 if (limit_chunk && ts > limit_chunk)
e46b8fb1 910 return SR_OK;
88c51afe 911
fefa1800 912 /* Pad last sample up to current point. */
99965709 913 numpad = tsdiff * sigma->samples_per_event - clustersize;
28a35d8a 914 if (numpad > 0) {
f78898e9
HE
915 for (j = 0; j < numpad; ++j)
916 samples[j] = *lastsample;
917
918 n = numpad;
28a35d8a
HE
919 }
920
57bbf56b
HE
921 /* Send samples between previous and this timestamp to sigrok. */
922 sent = 0;
923 while (sent < n) {
924 tosend = MIN(2048, n - sent);
925
5a2326a7 926 packet.type = SR_DF_LOGIC;
9c939c51
BV
927 packet.payload = &logic;
928 logic.length = tosend * sizeof(uint16_t);
929 logic.unitsize = 2;
930 logic.data = samples + sent;
8a2efef2 931 sr_session_bus(sigma->session_id, &packet);
28a35d8a 932
57bbf56b
HE
933 sent += tosend;
934 }
935 n = 0;
936
937 event = (uint16_t *) &buf[i * 16 + 2];
f78898e9
HE
938 cur_sample = 0;
939
940 /* For each event in cluster. */
28a35d8a 941 for (j = 0; j < 7; ++j) {
f78898e9
HE
942
943 /* For each sample in event. */
99965709 944 for (k = 0; k < sigma->samples_per_event; ++k) {
f78898e9
HE
945 cur_sample = 0;
946
947 /* For each probe. */
99965709 948 for (l = 0; l < sigma->num_probes; ++l)
edca2c5c 949 cur_sample |= (!!(event[j] & (1 << (l *
99965709
HE
950 sigma->samples_per_event
951 + k))))
edca2c5c 952 << l;
f78898e9
HE
953
954 samples[n++] = cur_sample;
28a35d8a
HE
955 }
956 }
957
eec5275e 958 /* Send data up to trigger point (if triggered). */
fefa1800 959 sent = 0;
57bbf56b
HE
960 if (i == triggerts) {
961 /*
36b1c8e6
HE
962 * Trigger is not always accurate to sample because of
963 * pipeline delay. However, it always triggers before
964 * the actual event. We therefore look at the next
965 * samples to pinpoint the exact position of the trigger.
57bbf56b 966 */
bdfc7a89 967 tosend = get_trigger_offset(samples, *lastsample,
99965709 968 &sigma->trigger);
57bbf56b
HE
969
970 if (tosend > 0) {
5a2326a7 971 packet.type = SR_DF_LOGIC;
9c939c51
BV
972 packet.payload = &logic;
973 logic.length = tosend * sizeof(uint16_t);
974 logic.unitsize = 2;
975 logic.data = samples;
8a2efef2 976 sr_session_bus(sigma->session_id, &packet);
57bbf56b
HE
977
978 sent += tosend;
979 }
28a35d8a 980
5b5ea7c6
HE
981 /* Only send trigger if explicitly enabled. */
982 if (sigma->use_triggers) {
5a2326a7 983 packet.type = SR_DF_TRIGGER;
8a2efef2 984 sr_session_bus(sigma->session_id, &packet);
5b5ea7c6 985 }
28a35d8a 986 }
57bbf56b 987
eec5275e 988 /* Send rest of the chunk to sigrok. */
57bbf56b
HE
989 tosend = n - sent;
990
abda62ce 991 if (tosend > 0) {
5a2326a7 992 packet.type = SR_DF_LOGIC;
9c939c51
BV
993 packet.payload = &logic;
994 logic.length = tosend * sizeof(uint16_t);
995 logic.unitsize = 2;
996 logic.data = samples + sent;
8a2efef2 997 sr_session_bus(sigma->session_id, &packet);
abda62ce 998 }
ee492173
HE
999
1000 *lastsample = samples[n - 1];
28a35d8a
HE
1001 }
1002
e46b8fb1 1003 return SR_OK;
28a35d8a
HE
1004}
1005
9c939c51 1006static int receive_data(int fd, int revents, void *session_data)
28a35d8a 1007{
9c939c51 1008 struct sr_device_instance *sdi = session_data;
99965709 1009 struct sigma *sigma = sdi->priv;
b9c735a2 1010 struct sr_datafeed_packet packet;
28a35d8a
HE
1011 const int chunks_per_read = 32;
1012 unsigned char buf[chunks_per_read * CHUNK_SIZE];
6aac7737 1013 int bufsz, numchunks, i, newchunks;
94ba4bd6 1014 uint64_t running_msec;
28a35d8a 1015 struct timeval tv;
28a35d8a 1016
cb93f8a9
UH
1017 /* Avoid compiler warnings. */
1018 (void)fd;
1019 (void)revents;
28a35d8a 1020
31facdd3 1021 numchunks = (sigma->state.stoppos + 511) / 512;
28a35d8a 1022
99965709 1023 if (sigma->state.state == SIGMA_IDLE)
28a35d8a
HE
1024 return FALSE;
1025
99965709 1026 if (sigma->state.state == SIGMA_CAPTURE) {
28a35d8a 1027
6aac7737
HE
1028 /* Check if the timer has expired, or memory is full. */
1029 gettimeofday(&tv, 0);
99965709
HE
1030 running_msec = (tv.tv_sec - sigma->start_tv.tv_sec) * 1000 +
1031 (tv.tv_usec - sigma->start_tv.tv_usec) / 1000;
28a35d8a 1032
99965709 1033 if (running_msec < sigma->limit_msec && numchunks < 32767)
6aac7737 1034 return FALSE;
28a35d8a 1035
9c939c51 1036 hw_stop_acquisition(sdi->index, session_data);
6aac7737
HE
1037
1038 return FALSE;
1039
99965709
HE
1040 } else if (sigma->state.state == SIGMA_DOWNLOAD) {
1041 if (sigma->state.chunks_downloaded >= numchunks) {
6aac7737 1042 /* End of samples. */
5a2326a7 1043 packet.type = SR_DF_END;
8a2efef2 1044 sr_session_bus(sigma->session_id, &packet);
6aac7737 1045
99965709 1046 sigma->state.state = SIGMA_IDLE;
f78898e9 1047
6aac7737
HE
1048 return TRUE;
1049 }
1050
1051 newchunks = MIN(chunks_per_read,
99965709 1052 numchunks - sigma->state.chunks_downloaded);
28a35d8a 1053
b08024a8
UH
1054 sr_info("Downloading sample data: %.0f %%",
1055 100.0 * sigma->state.chunks_downloaded / numchunks);
28a35d8a 1056
99965709
HE
1057 bufsz = sigma_read_dram(sigma->state.chunks_downloaded,
1058 newchunks, buf, sigma);
719c5a93
UH
1059 /* TODO: Check bufsz. For now, just avoid compiler warnings. */
1060 (void)bufsz;
28a35d8a 1061
fefa1800 1062 /* Find first ts. */
99965709
HE
1063 if (sigma->state.chunks_downloaded == 0) {
1064 sigma->state.lastts = *(uint16_t *) buf - 1;
1065 sigma->state.lastsample = 0;
6aac7737 1066 }
28a35d8a 1067
fefa1800 1068 /* Decode chunks and send them to sigrok. */
28a35d8a 1069 for (i = 0; i < newchunks; ++i) {
88c51afe
HE
1070 int limit_chunk = 0;
1071
1072 /* The last chunk may potentially be only in part. */
1073 if (sigma->state.chunks_downloaded == numchunks - 1)
1074 {
1075 /* Find the last valid timestamp */
1076 limit_chunk = sigma->state.stoppos % 512 + sigma->state.lastts;
1077 }
1078
99965709 1079 if (sigma->state.chunks_downloaded + i == sigma->state.triggerchunk)
57bbf56b 1080 decode_chunk_ts(buf + (i * CHUNK_SIZE),
99965709
HE
1081 &sigma->state.lastts,
1082 &sigma->state.lastsample,
1083 sigma->state.triggerpos & 0x1ff,
9c939c51 1084 limit_chunk, session_data);
57bbf56b
HE
1085 else
1086 decode_chunk_ts(buf + (i * CHUNK_SIZE),
99965709
HE
1087 &sigma->state.lastts,
1088 &sigma->state.lastsample,
9c939c51 1089 -1, limit_chunk, session_data);
28a35d8a 1090
88c51afe
HE
1091 ++sigma->state.chunks_downloaded;
1092 }
28a35d8a
HE
1093 }
1094
28a35d8a
HE
1095 return TRUE;
1096}
1097
c53d793f
HE
1098/* Build a LUT entry used by the trigger functions. */
1099static void build_lut_entry(uint16_t value, uint16_t mask, uint16_t *entry)
ee492173
HE
1100{
1101 int i, j, k, bit;
1102
f758d074 1103 /* For each quad probe. */
ee492173 1104 for (i = 0; i < 4; ++i) {
c53d793f 1105 entry[i] = 0xffff;
ee492173 1106
f758d074 1107 /* For each bit in LUT. */
ee492173
HE
1108 for (j = 0; j < 16; ++j)
1109
f758d074 1110 /* For each probe in quad. */
ee492173
HE
1111 for (k = 0; k < 4; ++k) {
1112 bit = 1 << (i * 4 + k);
1113
c53d793f
HE
1114 /* Set bit in entry */
1115 if ((mask & bit) &&
1116 ((!(value & bit)) !=
4ae1f451 1117 (!(j & (1 << k)))))
c53d793f 1118 entry[i] &= ~(1 << j);
ee492173
HE
1119 }
1120 }
c53d793f 1121}
ee492173 1122
c53d793f
HE
1123/* Add a logical function to LUT mask. */
1124static void add_trigger_function(enum triggerop oper, enum triggerfunc func,
1125 int index, int neg, uint16_t *mask)
1126{
1127 int i, j;
1128 int x[2][2], tmp, a, b, aset, bset, rset;
1129
1130 memset(x, 0, 4 * sizeof(int));
1131
1132 /* Trigger detect condition. */
1133 switch (oper) {
1134 case OP_LEVEL:
1135 x[0][1] = 1;
1136 x[1][1] = 1;
1137 break;
1138 case OP_NOT:
1139 x[0][0] = 1;
1140 x[1][0] = 1;
1141 break;
1142 case OP_RISE:
1143 x[0][1] = 1;
1144 break;
1145 case OP_FALL:
1146 x[1][0] = 1;
1147 break;
1148 case OP_RISEFALL:
1149 x[0][1] = 1;
1150 x[1][0] = 1;
1151 break;
1152 case OP_NOTRISE:
1153 x[1][1] = 1;
1154 x[0][0] = 1;
1155 x[1][0] = 1;
1156 break;
1157 case OP_NOTFALL:
1158 x[1][1] = 1;
1159 x[0][0] = 1;
1160 x[0][1] = 1;
1161 break;
1162 case OP_NOTRISEFALL:
1163 x[1][1] = 1;
1164 x[0][0] = 1;
1165 break;
1166 }
1167
1168 /* Transpose if neg is set. */
1169 if (neg) {
1170 for (i = 0; i < 2; ++i)
1171 for (j = 0; j < 2; ++j) {
1172 tmp = x[i][j];
1173 x[i][j] = x[1-i][1-j];
1174 x[1-i][1-j] = tmp;
1175 }
1176 }
1177
1178 /* Update mask with function. */
1179 for (i = 0; i < 16; ++i) {
1180 a = (i >> (2 * index + 0)) & 1;
1181 b = (i >> (2 * index + 1)) & 1;
1182
1183 aset = (*mask >> i) & 1;
1184 bset = x[b][a];
1185
1186 if (func == FUNC_AND || func == FUNC_NAND)
1187 rset = aset & bset;
1188 else if (func == FUNC_OR || func == FUNC_NOR)
1189 rset = aset | bset;
1190 else if (func == FUNC_XOR || func == FUNC_NXOR)
1191 rset = aset ^ bset;
1192
1193 if (func == FUNC_NAND || func == FUNC_NOR || func == FUNC_NXOR)
1194 rset = !rset;
1195
1196 *mask &= ~(1 << i);
1197
1198 if (rset)
1199 *mask |= 1 << i;
1200 }
1201}
1202
1203/*
1204 * Build trigger LUTs used by 50 MHz and lower sample rates for supporting
1205 * simple pin change and state triggers. Only two transitions (rise/fall) can be
1206 * set at any time, but a full mask and value can be set (0/1).
1207 */
99965709 1208static int build_basic_trigger(struct triggerlut *lut, struct sigma *sigma)
c53d793f
HE
1209{
1210 int i,j;
4ae1f451 1211 uint16_t masks[2] = { 0, 0 };
c53d793f
HE
1212
1213 memset(lut, 0, sizeof(struct triggerlut));
1214
1215 /* Contant for simple triggers. */
1216 lut->m4 = 0xa000;
1217
1218 /* Value/mask trigger support. */
99965709
HE
1219 build_lut_entry(sigma->trigger.simplevalue, sigma->trigger.simplemask,
1220 lut->m2d);
c53d793f
HE
1221
1222 /* Rise/fall trigger support. */
1223 for (i = 0, j = 0; i < 16; ++i) {
99965709
HE
1224 if (sigma->trigger.risingmask & (1 << i) ||
1225 sigma->trigger.fallingmask & (1 << i))
c53d793f
HE
1226 masks[j++] = 1 << i;
1227 }
1228
1229 build_lut_entry(masks[0], masks[0], lut->m0d);
1230 build_lut_entry(masks[1], masks[1], lut->m1d);
1231
1232 /* Add glue logic */
1233 if (masks[0] || masks[1]) {
1234 /* Transition trigger. */
99965709 1235 if (masks[0] & sigma->trigger.risingmask)
c53d793f 1236 add_trigger_function(OP_RISE, FUNC_OR, 0, 0, &lut->m3);
99965709 1237 if (masks[0] & sigma->trigger.fallingmask)
c53d793f 1238 add_trigger_function(OP_FALL, FUNC_OR, 0, 0, &lut->m3);
99965709 1239 if (masks[1] & sigma->trigger.risingmask)
c53d793f 1240 add_trigger_function(OP_RISE, FUNC_OR, 1, 0, &lut->m3);
99965709 1241 if (masks[1] & sigma->trigger.fallingmask)
c53d793f
HE
1242 add_trigger_function(OP_FALL, FUNC_OR, 1, 0, &lut->m3);
1243 } else {
1244 /* Only value/mask trigger. */
1245 lut->m3 = 0xffff;
1246 }
ee492173 1247
c53d793f 1248 /* Triggertype: event. */
ee492173
HE
1249 lut->params.selres = 3;
1250
e46b8fb1 1251 return SR_OK;
ee492173
HE
1252}
1253
9c939c51 1254static int hw_start_acquisition(int device_index, gpointer session_data)
28a35d8a 1255{
a00ba012 1256 struct sr_device_instance *sdi;
99965709 1257 struct sigma *sigma;
b9c735a2
UH
1258 struct sr_datafeed_packet packet;
1259 struct sr_datafeed_header header;
9ddb2a12 1260 struct clockselect_50 clockselect;
82957b65 1261 int frac, triggerpin, ret;
57bbf56b
HE
1262 uint8_t triggerselect;
1263 struct triggerinout triggerinout_conf;
ee492173 1264 struct triggerlut lut;
28a35d8a 1265
cb93f8a9
UH
1266 /* Avoid compiler warnings. */
1267 (void)session_data;
28a35d8a 1268
da1466d6 1269 if (!(sdi = sr_dev_inst_get(device_instances, device_index)))
e46b8fb1 1270 return SR_ERR;
28a35d8a 1271
99965709 1272 sigma = sdi->priv;
28a35d8a 1273
7c70c538 1274 /* If the samplerate has not been set, default to 200 KHz. */
82957b65
UH
1275 if (sigma->cur_firmware == -1) {
1276 if ((ret = set_samplerate(sdi, SR_KHZ(200))) != SR_OK)
1277 return ret;
1278 }
e8397563 1279
eec5275e 1280 /* Enter trigger programming mode. */
99965709 1281 sigma_set_register(WRITE_TRIGGER_SELECT1, 0x20, sigma);
28a35d8a 1282
eec5275e 1283 /* 100 and 200 MHz mode. */
59df0c77 1284 if (sigma->cur_samplerate >= SR_MHZ(100)) {
99965709 1285 sigma_set_register(WRITE_TRIGGER_SELECT1, 0x81, sigma);
57bbf56b 1286
a42aec7f
HE
1287 /* Find which pin to trigger on from mask. */
1288 for (triggerpin = 0; triggerpin < 8; ++triggerpin)
99965709 1289 if ((sigma->trigger.risingmask | sigma->trigger.fallingmask) &
a42aec7f
HE
1290 (1 << triggerpin))
1291 break;
1292
1293 /* Set trigger pin and light LED on trigger. */
1294 triggerselect = (1 << LEDSEL1) | (triggerpin & 0x7);
1295
1296 /* Default rising edge. */
99965709 1297 if (sigma->trigger.fallingmask)
a42aec7f 1298 triggerselect |= 1 << 3;
57bbf56b 1299
eec5275e 1300 /* All other modes. */
59df0c77 1301 } else if (sigma->cur_samplerate <= SR_MHZ(50)) {
99965709 1302 build_basic_trigger(&lut, sigma);
ee492173 1303
99965709 1304 sigma_write_trigger_lut(&lut, sigma);
57bbf56b
HE
1305
1306 triggerselect = (1 << LEDSEL1) | (1 << LEDSEL0);
1307 }
1308
eec5275e 1309 /* Setup trigger in and out pins to default values. */
57bbf56b
HE
1310 memset(&triggerinout_conf, 0, sizeof(struct triggerinout));
1311 triggerinout_conf.trgout_bytrigger = 1;
1312 triggerinout_conf.trgout_enable = 1;
1313
28a35d8a 1314 sigma_write_register(WRITE_TRIGGER_OPTION,
57bbf56b 1315 (uint8_t *) &triggerinout_conf,
99965709 1316 sizeof(struct triggerinout), sigma);
28a35d8a 1317
eec5275e 1318 /* Go back to normal mode. */
99965709 1319 sigma_set_register(WRITE_TRIGGER_SELECT1, triggerselect, sigma);
28a35d8a 1320
edca2c5c 1321 /* Set clock select register. */
59df0c77 1322 if (sigma->cur_samplerate == SR_MHZ(200))
edca2c5c 1323 /* Enable 4 probes. */
99965709 1324 sigma_set_register(WRITE_CLOCK_SELECT, 0xf0, sigma);
59df0c77 1325 else if (sigma->cur_samplerate == SR_MHZ(100))
edca2c5c 1326 /* Enable 8 probes. */
99965709 1327 sigma_set_register(WRITE_CLOCK_SELECT, 0x00, sigma);
edca2c5c
HE
1328 else {
1329 /*
9ddb2a12 1330 * 50 MHz mode (or fraction thereof). Any fraction down to
eec5275e 1331 * 50 MHz / 256 can be used, but is not supported by sigrok API.
edca2c5c 1332 */
59df0c77 1333 frac = SR_MHZ(50) / sigma->cur_samplerate - 1;
edca2c5c 1334
9ddb2a12
UH
1335 clockselect.async = 0;
1336 clockselect.fraction = frac;
1337 clockselect.disabled_probes = 0;
edca2c5c
HE
1338
1339 sigma_write_register(WRITE_CLOCK_SELECT,
9ddb2a12 1340 (uint8_t *) &clockselect,
99965709 1341 sizeof(clockselect), sigma);
edca2c5c
HE
1342 }
1343
fefa1800 1344 /* Setup maximum post trigger time. */
99965709
HE
1345 sigma_set_register(WRITE_POST_TRIGGER,
1346 (sigma->capture_ratio * 255) / 100, sigma);
28a35d8a 1347
eec5275e 1348 /* Start acqusition. */
99965709
HE
1349 gettimeofday(&sigma->start_tv, 0);
1350 sigma_set_register(WRITE_MODE, 0x0d, sigma);
1351
9c939c51 1352 sigma->session_id = session_data;
28a35d8a 1353
28a35d8a 1354 /* Send header packet to the session bus. */
5a2326a7 1355 packet.type = SR_DF_HEADER;
28a35d8a
HE
1356 packet.payload = &header;
1357 header.feed_version = 1;
1358 gettimeofday(&header.starttime, NULL);
99965709 1359 header.samplerate = sigma->cur_samplerate;
99965709 1360 header.num_logic_probes = sigma->num_probes;
9c939c51 1361 sr_session_bus(session_data, &packet);
28a35d8a 1362
57bbf56b 1363 /* Add capture source. */
6f1be0a2 1364 sr_source_add(0, G_IO_IN, 10, receive_data, sdi);
57bbf56b 1365
99965709 1366 sigma->state.state = SIGMA_CAPTURE;
6aac7737 1367
e46b8fb1 1368 return SR_OK;
28a35d8a
HE
1369}
1370
3010f21c 1371static int hw_stop_acquisition(int device_index, gpointer session_data)
28a35d8a 1372{
a00ba012 1373 struct sr_device_instance *sdi;
99965709 1374 struct sigma *sigma;
6aac7737
HE
1375 uint8_t modestatus;
1376
cb93f8a9
UH
1377 /* Avoid compiler warnings. */
1378 (void)session_data;
28a35d8a 1379
da1466d6 1380 if (!(sdi = sr_dev_inst_get(device_instances, device_index))) {
3010f21c
UH
1381 sr_err("asix: %s: sdi was NULL", __func__);
1382 return SR_ERR_BUG;
1383 }
1384
1385 if (!(sigma = sdi->priv)) {
1386 sr_err("asix: %s: sdi->priv was NULL", __func__);
1387 return SR_ERR_BUG;
1388 }
1389
fefa1800 1390 /* Stop acquisition. */
99965709 1391 sigma_set_register(WRITE_MODE, 0x11, sigma);
28a35d8a 1392
6aac7737 1393 /* Set SDRAM Read Enable. */
99965709 1394 sigma_set_register(WRITE_MODE, 0x02, sigma);
6aac7737
HE
1395
1396 /* Get the current position. */
99965709 1397 sigma_read_pos(&sigma->state.stoppos, &sigma->state.triggerpos, sigma);
6aac7737
HE
1398
1399 /* Check if trigger has fired. */
99965709 1400 modestatus = sigma_get_register(READ_MODE, sigma);
3010f21c 1401 if (modestatus & 0x20)
99965709 1402 sigma->state.triggerchunk = sigma->state.triggerpos / 512;
3010f21c 1403 else
99965709 1404 sigma->state.triggerchunk = -1;
6aac7737 1405
99965709 1406 sigma->state.chunks_downloaded = 0;
6aac7737 1407
99965709 1408 sigma->state.state = SIGMA_DOWNLOAD;
3010f21c
UH
1409
1410 return SR_OK;
28a35d8a
HE
1411}
1412
ca070ed9 1413SR_PRIV struct sr_device_plugin asix_sigma_plugin_info = {
e519ba86
UH
1414 .name = "asix-sigma",
1415 .longname = "ASIX SIGMA",
1416 .api_version = 1,
1417 .init = hw_init,
1418 .cleanup = hw_cleanup,
86f5e3d8
UH
1419 .opendev = hw_opendev,
1420 .closedev = hw_closedev,
e519ba86
UH
1421 .get_device_info = hw_get_device_info,
1422 .get_status = hw_get_status,
1423 .get_capabilities = hw_get_capabilities,
1424 .set_configuration = hw_set_configuration,
1425 .start_acquisition = hw_start_acquisition,
1426 .stop_acquisition = hw_stop_acquisition,
28a35d8a 1427};