]> sigrok.org Git - libsigrok.git/blame - hardware/link-mso19/link-mso19.c
Move the probe naming to the creator of the device, and let each driver name its...
[libsigrok.git] / hardware / link-mso19 / link-mso19.c
CommitLineData
01cf8814
DR
1/*
2 * This file is part of the sigrok project.
3 *
4 * Copyright (C) 2011 Daniel Ribeiro <drwyrm@gmail.com>
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
8a839354
UH
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
01cf8814
DR
18 */
19
20#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
23#include <unistd.h>
24#include <fcntl.h>
25#include <sys/time.h>
26#include <inttypes.h>
27#include <glib.h>
28#include <libudev.h>
01cf8814 29#include <arpa/inet.h>
b7f09cf8
UH
30#include "sigrok.h"
31#include "sigrok-internal.h"
01cf8814
DR
32#include "config.h"
33#include "link-mso19.h"
34
35#define USB_VENDOR "3195"
36#define USB_PRODUCT "f190"
37
464d12c7
KS
38#define NUM_PROBES 8
39
01cf8814 40static int capabilities[] = {
5a2326a7
UH
41 SR_HWCAP_LOGIC_ANALYZER,
42// SR_HWCAP_OSCILLOSCOPE,
43// SR_HWCAP_PAT_GENERATOR,
01cf8814 44
5a2326a7
UH
45 SR_HWCAP_SAMPLERATE,
46// SR_HWCAP_CAPTURE_RATIO,
47 SR_HWCAP_LIMIT_SAMPLES,
01cf8814
DR
48 0,
49};
50
464d12c7
KS
51static const char *probe_names[NUM_PROBES + 1] = {
52 "0",
53 "1",
54 "2",
55 "3",
56 "4",
57 "5",
58 "6",
59 "7",
60 NULL,
61};
62
01cf8814 63static uint64_t supported_samplerates[] = {
c9140419
UH
64 SR_HZ(100),
65 SR_HZ(200),
66 SR_HZ(500),
59df0c77
UH
67 SR_KHZ(1),
68 SR_KHZ(2),
69 SR_KHZ(5),
70 SR_KHZ(10),
71 SR_KHZ(20),
72 SR_KHZ(50),
73 SR_KHZ(100),
74 SR_KHZ(200),
75 SR_KHZ(500),
76 SR_MHZ(1),
77 SR_MHZ(2),
78 SR_MHZ(5),
79 SR_MHZ(10),
80 SR_MHZ(20),
81 SR_MHZ(50),
82 SR_MHZ(100),
83 SR_MHZ(200),
84 0,
01cf8814
DR
85};
86
60679b18 87static struct sr_samplerates samplerates = {
c9140419 88 SR_HZ(100),
59df0c77 89 SR_MHZ(200),
c9140419 90 SR_HZ(0),
59df0c77 91 supported_samplerates,
01cf8814
DR
92};
93
94static GSList *device_instances = NULL;
95
a00ba012 96static int mso_send_control_message(struct sr_device_instance *sdi,
01cf8814
DR
97 uint16_t payload[], int n)
98{
99 int fd = sdi->serial->fd;
100 int i, w, ret, s = n * 2 + sizeof(mso_head) + sizeof(mso_foot);
101 char *p, *buf;
102
ecad043f
UH
103 ret = SR_ERR;
104
01cf8814
DR
105 if (fd < 0)
106 goto ret;
107
ecad043f
UH
108 if (!(buf = g_try_malloc(s))) {
109 sr_err("mso19: %s: buf malloc failed", __func__);
110 ret = SR_ERR_MALLOC;
01cf8814 111 goto ret;
ecad043f 112 }
01cf8814
DR
113
114 p = buf;
115 memcpy(p, mso_head, sizeof(mso_head));
116 p += sizeof(mso_head);
117
118 for (i = 0; i < n; i++) {
119 *(uint16_t *) p = htons(payload[i]);
120 p += 2;
121 }
122 memcpy(p, mso_foot, sizeof(mso_foot));
123
124 w = 0;
125 while (w < s) {
2119ab03 126 ret = serial_write(fd, buf + w, s - w);
01cf8814 127 if (ret < 0) {
e46b8fb1 128 ret = SR_ERR;
01cf8814
DR
129 goto free;
130 }
131 w += ret;
132 }
e46b8fb1 133 ret = SR_OK;
01cf8814 134free:
ecad043f 135 g_free(buf);
01cf8814
DR
136ret:
137 return ret;
138}
139
a00ba012 140static int mso_reset_adc(struct sr_device_instance *sdi)
01cf8814
DR
141{
142 struct mso *mso = sdi->priv;
143 uint16_t ops[2];
144
145 ops[0] = mso_trans(REG_CTL, (mso->ctlbase | BIT_CTL_RESETADC));
146 ops[1] = mso_trans(REG_CTL, mso->ctlbase);
147 mso->ctlbase |= BIT_CTL_ADC_UNKNOWN4;
148
149 return mso_send_control_message(sdi, ARRAY_AND_SIZE(ops));
150}
151
a00ba012 152static int mso_reset_fsm(struct sr_device_instance *sdi)
01cf8814
DR
153{
154 struct mso *mso = sdi->priv;
155 uint16_t ops[1];
156
157 mso->ctlbase |= BIT_CTL_RESETFSM;
158 ops[0] = mso_trans(REG_CTL, mso->ctlbase);
159
160 return mso_send_control_message(sdi, ARRAY_AND_SIZE(ops));
161}
162
a00ba012 163static int mso_toggle_led(struct sr_device_instance *sdi, int state)
01cf8814
DR
164{
165 struct mso *mso = sdi->priv;
166 uint16_t ops[1];
167
168 mso->ctlbase &= BIT_CTL_LED;
169 if (state)
170 mso->ctlbase |= BIT_CTL_LED;
171 ops[0] = mso_trans(REG_CTL, mso->ctlbase);
172
173 return mso_send_control_message(sdi, ARRAY_AND_SIZE(ops));
174}
175
a00ba012 176static int mso_check_trigger(struct sr_device_instance *sdi,
01cf8814
DR
177 uint8_t *info)
178{
179 uint16_t ops[] = { mso_trans(REG_TRIGGER, 0) };
180 char buf[1];
181 int ret;
182
183 ret = mso_send_control_message(sdi, ARRAY_AND_SIZE(ops));
e46b8fb1 184 if (info == NULL || ret != SR_OK)
01cf8814
DR
185 return ret;
186
187 buf[0] = 0;
2119ab03 188 if (serial_read(sdi->serial->fd, buf, 1) != 1) /* FIXME: Need timeout */
e46b8fb1 189 ret = SR_ERR;
01cf8814
DR
190 *info = buf[0];
191
192 return ret;
193}
194
a00ba012 195static int mso_read_buffer(struct sr_device_instance *sdi)
01cf8814
DR
196{
197 uint16_t ops[] = { mso_trans(REG_BUFFER, 0) };
198
199 return mso_send_control_message(sdi, ARRAY_AND_SIZE(ops));
200}
201
a00ba012 202static int mso_arm(struct sr_device_instance *sdi)
01cf8814
DR
203{
204 struct mso *mso = sdi->priv;
205 uint16_t ops[] = {
206 mso_trans(REG_CTL, mso->ctlbase | BIT_CTL_RESETFSM),
207 mso_trans(REG_CTL, mso->ctlbase | BIT_CTL_ARM),
208 mso_trans(REG_CTL, mso->ctlbase),
209 };
210
211 return mso_send_control_message(sdi, ARRAY_AND_SIZE(ops));
212}
213
a00ba012 214static int mso_force_capture(struct sr_device_instance *sdi)
01cf8814
DR
215{
216 struct mso *mso = sdi->priv;
217 uint16_t ops[] = {
218 mso_trans(REG_CTL, mso->ctlbase | 8),
219 mso_trans(REG_CTL, mso->ctlbase),
220 };
221
222 return mso_send_control_message(sdi, ARRAY_AND_SIZE(ops));
223}
224
a00ba012 225static int mso_dac_out(struct sr_device_instance *sdi, uint16_t val)
01cf8814
DR
226{
227 struct mso *mso = sdi->priv;
228 uint16_t ops[] = {
229 mso_trans(REG_DAC1, (val >> 8) & 0xff),
230 mso_trans(REG_DAC2, val & 0xff),
231 mso_trans(REG_CTL, mso->ctlbase | BIT_CTL_RESETADC),
232 };
233
234 return mso_send_control_message(sdi, ARRAY_AND_SIZE(ops));
235}
236
a00ba012 237static int mso_clkrate_out(struct sr_device_instance *sdi, uint16_t val)
01cf8814
DR
238{
239 uint16_t ops[] = {
240 mso_trans(REG_CLKRATE1, (val >> 8) & 0xff),
241 mso_trans(REG_CLKRATE2, val & 0xff),
242 };
243
244 return mso_send_control_message(sdi, ARRAY_AND_SIZE(ops));
245}
246
a00ba012 247static int mso_configure_rate(struct sr_device_instance *sdi,
01cf8814
DR
248 uint32_t rate)
249{
250 struct mso *mso = sdi->priv;
251 unsigned int i;
e46b8fb1 252 int ret = SR_ERR;
01cf8814
DR
253
254 for (i = 0; i < ARRAY_SIZE(rate_map); i++) {
255 if (rate_map[i].rate == rate) {
256 mso->slowmode = rate_map[i].slowmode;
257 ret = mso_clkrate_out(sdi, rate_map[i].val);
e46b8fb1 258 if (ret == SR_OK)
01cf8814
DR
259 mso->cur_rate = rate;
260 return ret;
261 }
262 }
263 return ret;
264}
265
01cf8814
DR
266static inline uint16_t mso_calc_raw_from_mv(struct mso *mso)
267{
268 return (uint16_t) (0x200 -
269 ((mso->dso_trigger_voltage / mso->dso_probe_attn) /
270 mso->vbit));
271}
272
a00ba012 273static int mso_configure_trigger(struct sr_device_instance *sdi)
01cf8814
DR
274{
275 struct mso *mso = sdi->priv;
276 uint16_t ops[16];
277 uint16_t dso_trigger = mso_calc_raw_from_mv(mso);
278
279 dso_trigger &= 0x3ff;
280 if ((!mso->trigger_slope && mso->trigger_chan == 1) ||
281 (mso->trigger_slope &&
282 (mso->trigger_chan == 0 ||
283 mso->trigger_chan == 2 ||
284 mso->trigger_chan == 3)))
285 dso_trigger |= 0x400;
286
287 switch (mso->trigger_chan) {
288 case 1:
289 dso_trigger |= 0xe000;
290 case 2:
291 dso_trigger |= 0x4000;
292 break;
293 case 3:
294 dso_trigger |= 0x2000;
295 break;
296 case 4:
297 dso_trigger |= 0xa000;
298 break;
299 case 5:
300 dso_trigger |= 0x8000;
301 break;
302 default:
303 case 0:
304 break;
305 }
306
307 switch (mso->trigger_outsrc) {
308 case 1:
309 dso_trigger |= 0x800;
310 break;
311 case 2:
312 dso_trigger |= 0x1000;
313 break;
314 case 3:
315 dso_trigger |= 0x1800;
316 break;
317
318 }
319
320 ops[0] = mso_trans(5, mso->la_trigger);
321 ops[1] = mso_trans(6, mso->la_trigger_mask);
322 ops[2] = mso_trans(3, dso_trigger & 0xff);
323 ops[3] = mso_trans(4, (dso_trigger >> 8) & 0xff);
324 ops[4] = mso_trans(11,
59df0c77 325 mso->dso_trigger_width / SR_HZ_TO_NS(mso->cur_rate));
01cf8814
DR
326 ops[5] = mso_trans(15, (2 | mso->slowmode));
327
328 /* FIXME SPI/I2C Triggers */
329 ops[6] = mso_trans(0, 0);
330 ops[7] = mso_trans(1, 0);
331 ops[8] = mso_trans(2, 0);
332 ops[9] = mso_trans(3, 0);
333 ops[10] = mso_trans(4, 0xff);
334 ops[11] = mso_trans(5, 0xff);
335 ops[12] = mso_trans(6, 0xff);
336 ops[13] = mso_trans(7, 0xff);
337 ops[14] = mso_trans(8, mso->trigger_spimode);
338 ops[15] = mso_trans(15, mso->slowmode);
339
340 return mso_send_control_message(sdi, ARRAY_AND_SIZE(ops));
341}
342
a00ba012 343static int mso_configure_threshold_level(struct sr_device_instance *sdi)
01cf8814
DR
344{
345 struct mso *mso = sdi->priv;
346
347 return mso_dac_out(sdi, la_threshold_map[mso->la_threshold]);
348}
349
350static int mso_parse_serial(const char *iSerial, const char *iProduct,
351 struct mso *mso)
352{
353 unsigned int u1, u2, u3, u4, u5, u6;
354
355 iProduct = iProduct;
356 /* FIXME: This code is in the original app, but I think its
357 * used only for the GUI */
358/* if (strstr(iProduct, "REV_02") || strstr(iProduct, "REV_03"))
359 mso->num_sample_rates = 0x16;
360 else
361 mso->num_sample_rates = 0x10; */
362
363 /* parse iSerial */
364 if (iSerial[0] != '4' || sscanf(iSerial, "%5u%3u%3u%1u%1u%6u",
365 &u1, &u2, &u3, &u4, &u5, &u6) != 6)
e46b8fb1 366 return SR_ERR;
01cf8814
DR
367 mso->hwmodel = u4;
368 mso->hwrev = u5;
369 mso->serial = u6;
370 mso->vbit = u1 / 10000;
371 if (mso->vbit == 0)
372 mso->vbit = 4.19195;
373 mso->dac_offset = u2;
374 if (mso->dac_offset == 0)
375 mso->dac_offset = 0x1ff;
376 mso->offset_range = u3;
377 if (mso->offset_range == 0)
378 mso->offset_range = 0x17d;
379
380 /*
381 * FIXME: There is more code on the original software to handle
382 * bigger iSerial strings, but as I can't test on my device
383 * I will not implement it yet
384 */
385
e46b8fb1 386 return SR_OK;
01cf8814
DR
387}
388
54ac5277 389static int hw_init(const char *deviceinfo)
01cf8814 390{
a00ba012 391 struct sr_device_instance *sdi;
01cf8814
DR
392 int devcnt = 0;
393 struct udev *udev;
394 struct udev_enumerate *enumerate;
395 struct udev_list_entry *devices, *dev_list_entry;
396 struct mso *mso;
397
398 deviceinfo = deviceinfo;
399
400 /* It's easier to map usb<->serial using udev */
401 /*
402 * FIXME: On windows we can get the same information from the
403 * registry, add an #ifdef here later
404 */
405 udev = udev_new();
406 if (!udev) {
b08024a8 407 sr_warn("Failed to initialize udev.");
01cf8814
DR
408 goto ret;
409 }
410 enumerate = udev_enumerate_new(udev);
411 udev_enumerate_add_match_subsystem(enumerate, "usb-serial");
412 udev_enumerate_scan_devices(enumerate);
413 devices = udev_enumerate_get_list_entry(enumerate);
414 udev_list_entry_foreach(dev_list_entry, devices) {
415 const char *syspath, *sysname, *idVendor, *idProduct,
416 *iSerial, *iProduct;
417 char path[32], manufacturer[32], product[32], hwrev[32];
418 struct udev_device *dev, *parent;
419 size_t s;
420
421 syspath = udev_list_entry_get_name(dev_list_entry);
422 dev = udev_device_new_from_syspath(udev, syspath);
423 sysname = udev_device_get_sysname(dev);
424 parent = udev_device_get_parent_with_subsystem_devtype(
425 dev, "usb", "usb_device");
426 if (!parent) {
b08024a8
UH
427 sr_warn("Unable to find parent usb device for %s",
428 sysname);
01cf8814
DR
429 continue;
430 }
431
432 idVendor = udev_device_get_sysattr_value(parent, "idVendor");
433 idProduct = udev_device_get_sysattr_value(parent, "idProduct");
434 if (strcmp(USB_VENDOR, idVendor)
435 || strcmp(USB_PRODUCT, idProduct))
436 continue;
437
438 iSerial = udev_device_get_sysattr_value(parent, "serial");
439 iProduct = udev_device_get_sysattr_value(parent, "product");
440
441 snprintf(path, sizeof(path), "/dev/%s", sysname);
442
443 s = strcspn(iProduct, " ");
444 if (s > sizeof(product) ||
445 strlen(iProduct) - s > sizeof(manufacturer)) {
b08024a8 446 sr_warn("Could not parse iProduct: %s", iProduct);
01cf8814
DR
447 continue;
448 }
449 strncpy(product, iProduct, s);
450 product[s] = 0;
451 strcpy(manufacturer, iProduct + s);
452 sprintf(hwrev, "r%d", mso->hwrev);
453
ecad043f
UH
454 if (!(mso = g_try_malloc0(sizeof(struct mso)))) {
455 sr_err("mso19: %s: mso malloc failed", __func__);
456 continue; /* TODO: Errors handled correctly? */
457 }
01cf8814 458
e46b8fb1 459 if (mso_parse_serial(iSerial, iProduct, mso) != SR_OK) {
b08024a8 460 sr_warn("Invalid iSerial: %s", iSerial);
01cf8814
DR
461 goto err_free_mso;
462 }
463 /* hardware initial state */
464 mso->ctlbase = 0;
465
5a2326a7 466 sdi = sr_device_instance_new(devcnt, SR_ST_INITIALIZING,
01cf8814
DR
467 manufacturer, product, hwrev);
468 if (!sdi) {
b08024a8
UH
469 sr_warn("Unable to create device instance for %s",
470 sysname);
01cf8814
DR
471 goto err_free_mso;
472 }
473
474 /* save a pointer to our private instance data */
475 sdi->priv = mso;
476
6c290072 477 sdi->serial = sr_serial_device_instance_new(path, -1);
01cf8814
DR
478 if (!sdi->serial)
479 goto err_device_instance_free;
480
481 device_instances = g_slist_append(device_instances, sdi);
482 devcnt++;
483 continue;
484
485err_device_instance_free:
a00ba012 486 sr_device_instance_free(sdi);
01cf8814
DR
487err_free_mso:
488 free(mso);
489 }
490
491 udev_enumerate_unref(enumerate);
492 udev_unref(udev);
493
494ret:
495 return devcnt;
496}
497
498static void hw_cleanup(void)
499{
500 GSList *l;
a00ba012 501 struct sr_device_instance *sdi;
01cf8814
DR
502
503 /* Properly close all devices. */
504 for (l = device_instances; l; l = l->next) {
505 sdi = l->data;
506 if (sdi->serial->fd != -1)
507 serial_close(sdi->serial->fd);
508 if (sdi->priv != NULL)
509 free(sdi->priv);
a00ba012 510 sr_device_instance_free(sdi);
01cf8814
DR
511 }
512 g_slist_free(device_instances);
513 device_instances = NULL;
514}
515
516static int hw_opendev(int device_index)
517{
a00ba012 518 struct sr_device_instance *sdi;
01cf8814 519 struct mso *mso;
e46b8fb1 520 int ret = SR_ERR;
01cf8814 521
d32d961d 522 if (!(sdi = sr_get_device_instance(device_instances, device_index)))
01cf8814
DR
523 return ret;
524
525 mso = sdi->priv;
526 sdi->serial->fd = serial_open(sdi->serial->port, O_RDWR);
527 if (sdi->serial->fd == -1)
528 return ret;
529
530 ret = serial_set_params(sdi->serial->fd, 460800, 8, 0, 1, 2);
e46b8fb1 531 if (ret != SR_OK)
01cf8814
DR
532 return ret;
533
5a2326a7 534 sdi->status = SR_ST_ACTIVE;
01cf8814
DR
535
536 /* FIXME: discard serial buffer */
537
538 mso_check_trigger(sdi, &mso->trigger_state);
b08024a8 539// sr_warn("trigger state: %c", mso->trigger_state);
01cf8814
DR
540
541 ret = mso_reset_adc(sdi);
e46b8fb1 542 if (ret != SR_OK)
01cf8814
DR
543 return ret;
544
545 mso_check_trigger(sdi, &mso->trigger_state);
b08024a8 546// sr_warn("trigger state: %c", mso->trigger_state);
01cf8814
DR
547
548// ret = mso_reset_fsm(sdi);
e46b8fb1 549// if (ret != SR_OK)
01cf8814
DR
550// return ret;
551
e46b8fb1
UH
552// return SR_ERR;
553 return SR_OK;
01cf8814
DR
554}
555
697785d1 556static int hw_closedev(int device_index)
01cf8814 557{
a00ba012 558 struct sr_device_instance *sdi;
01cf8814 559
697785d1
UH
560 if (!(sdi = sr_get_device_instance(device_instances, device_index))) {
561 sr_err("mso19: %s: sdi was NULL", __func__);
562 return SR_ERR; /* TODO: SR_ERR_ARG? */
563 }
01cf8814 564
697785d1 565 /* TODO */
01cf8814
DR
566 if (sdi->serial->fd != -1) {
567 serial_close(sdi->serial->fd);
568 sdi->serial->fd = -1;
5a2326a7 569 sdi->status = SR_ST_INACTIVE;
01cf8814 570 }
697785d1
UH
571
572 return SR_OK;
01cf8814
DR
573}
574
575static void *hw_get_device_info(int device_index, int device_info_id)
576{
a00ba012 577 struct sr_device_instance *sdi;
01cf8814
DR
578 struct mso *mso;
579 void *info = NULL;
580
d32d961d 581 if (!(sdi = sr_get_device_instance(device_instances, device_index)))
01cf8814
DR
582 return NULL;
583 mso = sdi->priv;
584
585 switch (device_info_id) {
5a2326a7 586 case SR_DI_INSTANCE:
01cf8814
DR
587 info = sdi;
588 break;
5a2326a7 589 case SR_DI_NUM_PROBES: /* FIXME: How to report analog probe? */
464d12c7
KS
590 info = GINT_TO_POINTER(NUM_PROBES);
591 break;
592 case SR_DI_PROBE_NAMES:
593 info = probe_names;
01cf8814 594 break;
5a2326a7 595 case SR_DI_SAMPLERATES:
01cf8814
DR
596 info = &samplerates;
597 break;
5a2326a7 598 case SR_DI_TRIGGER_TYPES:
01cf8814
DR
599 info = "01"; /* FIXME */
600 break;
5a2326a7 601 case SR_DI_CUR_SAMPLERATE:
01cf8814
DR
602 info = &mso->cur_rate;
603 break;
604 }
605 return info;
606}
607
608static int hw_get_status(int device_index)
609{
a00ba012 610 struct sr_device_instance *sdi;
01cf8814 611
d32d961d 612 if (!(sdi = sr_get_device_instance(device_instances, device_index)))
5a2326a7 613 return SR_ST_NOT_FOUND;
01cf8814
DR
614
615 return sdi->status;
616}
617
618static int *hw_get_capabilities(void)
619{
620 return capabilities;
621}
622
623static int hw_set_configuration(int device_index, int capability, void *value)
624{
a00ba012 625 struct sr_device_instance *sdi;
01cf8814 626
d32d961d 627 if (!(sdi = sr_get_device_instance(device_instances, device_index)))
e46b8fb1 628 return SR_ERR;
01cf8814
DR
629
630 switch (capability) {
5a2326a7 631 case SR_HWCAP_SAMPLERATE:
01cf8814 632 return mso_configure_rate(sdi, *(uint64_t *) value);
5a2326a7
UH
633 case SR_HWCAP_PROBECONFIG:
634 case SR_HWCAP_LIMIT_SAMPLES:
01cf8814 635 default:
e46b8fb1 636 return SR_OK; /* FIXME */
01cf8814 637 }
01cf8814
DR
638}
639
640#define MSO_TRIGGER_UNKNOWN '!'
641#define MSO_TRIGGER_UNKNOWN1 '1'
642#define MSO_TRIGGER_UNKNOWN2 '2'
643#define MSO_TRIGGER_UNKNOWN3 '3'
644#define MSO_TRIGGER_WAIT '4'
645#define MSO_TRIGGER_FIRED '5'
646#define MSO_TRIGGER_DATAREADY '6'
647
648/* FIXME: Pass errors? */
649static int receive_data(int fd, int revents, void *user_data)
650{
a00ba012 651 struct sr_device_instance *sdi = user_data;
01cf8814 652 struct mso *mso = sdi->priv;
b9c735a2 653 struct sr_datafeed_packet packet;
01cf8814
DR
654 uint8_t in[1024], logic_out[1024];
655 double analog_out[1024];
656 size_t i, s;
657
658 revents = revents;
659
2119ab03 660 s = serial_read(fd, in, sizeof(in));
01cf8814
DR
661 if (s <= 0)
662 return FALSE;
663
664 /* No samples */
665 if (mso->trigger_state != MSO_TRIGGER_DATAREADY) {
666 mso->trigger_state = in[0];
667 if (mso->trigger_state == MSO_TRIGGER_DATAREADY) {
668 mso_read_buffer(sdi);
669 mso->buffer_n = 0;
670 } else {
671 mso_check_trigger(sdi, NULL);
672 }
673 return FALSE;
674 }
675
676 /* the hardware always dumps 1024 samples, 24bits each */
677 if (mso->buffer_n < 3072) {
678 memcpy(mso->buffer + mso->buffer_n, in, s);
679 mso->buffer_n += s;
680 }
681 if (mso->buffer_n < 3072)
682 return FALSE;
683
684 /* do the conversion */
685 for (i = 0; i < 1024; i++) {
686 /* FIXME: Need to do conversion to mV */
687 analog_out[i] = (mso->buffer[i * 3] & 0x3f) |
688 ((mso->buffer[i * 3 + 1] & 0xf) << 6);
689 logic_out[i] = ((mso->buffer[i * 3 + 1] & 0x30) >> 4) |
690 ((mso->buffer[i * 3 + 2] & 0x3f) << 2);
691 }
692
5a2326a7 693 packet.type = SR_DF_LOGIC;
01cf8814
DR
694 packet.length = 1024;
695 packet.unitsize = 1;
696 packet.payload = logic_out;
8a2efef2 697 sr_session_bus(mso->session_id, &packet);
01cf8814
DR
698
699
5a2326a7 700 packet.type = SR_DF_ANALOG;
01cf8814
DR
701 packet.length = 1024;
702 packet.unitsize = sizeof(double);
703 packet.payload = analog_out;
8a2efef2 704 sr_session_bus(mso->session_id, &packet);
01cf8814 705
5a2326a7 706 packet.type = SR_DF_END;
8a2efef2 707 sr_session_bus(mso->session_id, &packet);
01cf8814
DR
708
709 return TRUE;
710}
711
712static int hw_start_acquisition(int device_index, gpointer session_device_id)
713{
a00ba012 714 struct sr_device_instance *sdi;
01cf8814 715 struct mso *mso;
b9c735a2
UH
716 struct sr_datafeed_packet packet;
717 struct sr_datafeed_header header;
e46b8fb1 718 int ret = SR_ERR;
01cf8814 719
d32d961d 720 if (!(sdi = sr_get_device_instance(device_instances, device_index)))
01cf8814
DR
721 return ret;
722 mso = sdi->priv;
723
724 /* FIXME: No need to do full reconfigure every time */
725// ret = mso_reset_fsm(sdi);
e46b8fb1 726// if (ret != SR_OK)
01cf8814
DR
727// return ret;
728
729 /* FIXME: ACDC Mode */
730 mso->ctlbase &= 0x7f;
731// mso->ctlbase |= mso->acdcmode;
732
733 ret = mso_configure_rate(sdi, mso->cur_rate);
e46b8fb1 734 if (ret != SR_OK)
01cf8814
DR
735 return ret;
736
737 /* set dac offset */
738 ret = mso_dac_out(sdi, mso->dac_offset);
e46b8fb1 739 if (ret != SR_OK)
01cf8814
DR
740 return ret;
741
742 ret = mso_configure_threshold_level(sdi);
e46b8fb1 743 if (ret != SR_OK)
01cf8814
DR
744 return ret;
745
746 ret = mso_configure_trigger(sdi);
e46b8fb1 747 if (ret != SR_OK)
01cf8814
DR
748 return ret;
749
750 /* FIXME: trigger_position */
751
752
753 /* END of config hardware part */
754
755 /* with trigger */
756 ret = mso_arm(sdi);
e46b8fb1 757 if (ret != SR_OK)
01cf8814
DR
758 return ret;
759
760 /* without trigger */
761// ret = mso_force_capture(sdi);
e46b8fb1 762// if (ret != SR_OK)
01cf8814
DR
763// return ret;
764
765 mso_check_trigger(sdi, &mso->trigger_state);
766 ret = mso_check_trigger(sdi, NULL);
e46b8fb1 767 if (ret != SR_OK)
01cf8814
DR
768 return ret;
769
770 mso->session_id = session_device_id;
6f1be0a2 771 sr_source_add(sdi->serial->fd, G_IO_IN, -1, receive_data, sdi);
01cf8814 772
5a2326a7 773 packet.type = SR_DF_HEADER;
b9c735a2 774 packet.length = sizeof(struct sr_datafeed_header);
01cf8814
DR
775 packet.payload = (unsigned char *) &header;
776 header.feed_version = 1;
777 gettimeofday(&header.starttime, NULL);
778 header.samplerate = mso->cur_rate;
779 header.num_analog_probes = 1;
780 header.num_logic_probes = 8;
5a2326a7 781 header.protocol_id = SR_PROTO_RAW;
8a2efef2 782 sr_session_bus(session_device_id, &packet);
01cf8814
DR
783
784 return ret;
785}
786
787/* FIXME */
788static void hw_stop_acquisition(int device_index, gpointer session_device_id)
789{
b9c735a2 790 struct sr_datafeed_packet packet;
01cf8814
DR
791
792 device_index = device_index;
793
5a2326a7 794 packet.type = SR_DF_END;
8a2efef2 795 sr_session_bus(session_device_id, &packet);
01cf8814
DR
796}
797
5c2d46d1 798struct sr_device_plugin link_mso19_plugin_info = {
01cf8814 799 .name = "link-mso19",
9f8274a5 800 .longname = "Link Instruments MSO-19",
01cf8814
DR
801 .api_version = 1,
802 .init = hw_init,
803 .cleanup = hw_cleanup,
86f5e3d8
UH
804 .opendev = hw_opendev,
805 .closedev = hw_closedev,
01cf8814
DR
806 .get_device_info = hw_get_device_info,
807 .get_status = hw_get_status,
808 .get_capabilities = hw_get_capabilities,
809 .set_configuration = hw_set_configuration,
810 .start_acquisition = hw_start_acquisition,
811 .stop_acquisition = hw_stop_acquisition,
812};