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