libsigrok
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines
link-mso19.c
Go to the documentation of this file.
00001 /*
00002  * This file is part of the sigrok project.
00003  *
00004  * Copyright (C) 2011 Daniel Ribeiro <drwyrm@gmail.com>
00005  * Copyright (C) 2012 Renato Caldas <rmsc@fe.up.pt>
00006  *
00007  * This program is free software: you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation, either version 3 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00019  */
00020 
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include <string.h>
00024 #include <unistd.h>
00025 #include <fcntl.h>
00026 #include <sys/time.h>
00027 #include <inttypes.h>
00028 #include <glib.h>
00029 #include <libudev.h>
00030 #include <arpa/inet.h>
00031 #include "sigrok.h"
00032 #include "sigrok-internal.h"
00033 #include "link-mso19.h"
00034 
00035 #define USB_VENDOR "3195"
00036 #define USB_PRODUCT "f190"
00037 
00038 #define NUM_PROBES 8
00039 
00040 static int hwcaps[] = {
00041         SR_HWCAP_LOGIC_ANALYZER,
00042 //      SR_HWCAP_OSCILLOSCOPE,
00043 //      SR_HWCAP_PAT_GENERATOR,
00044 
00045         SR_HWCAP_SAMPLERATE,
00046 //      SR_HWCAP_CAPTURE_RATIO,
00047         SR_HWCAP_LIMIT_SAMPLES,
00048         0,
00049 };
00050 
00051 /*
00052  * Probes are numbered 0 to 7.
00053  *
00054  * See also: http://www.linkinstruments.com/images/mso19_1113.gif
00055  */
00056 static const char *probe_names[NUM_PROBES + 1] = {
00057         "0",
00058         "1",
00059         "2",
00060         "3",
00061         "4",
00062         "5",
00063         "6",
00064         "7",
00065         NULL,
00066 };
00067 
00068 static uint64_t supported_samplerates[] = {
00069         SR_HZ(100),
00070         SR_HZ(200),
00071         SR_HZ(500),
00072         SR_KHZ(1),
00073         SR_KHZ(2),
00074         SR_KHZ(5),
00075         SR_KHZ(10),
00076         SR_KHZ(20),
00077         SR_KHZ(50),
00078         SR_KHZ(100),
00079         SR_KHZ(200),
00080         SR_KHZ(500),
00081         SR_MHZ(1),
00082         SR_MHZ(2),
00083         SR_MHZ(5),
00084         SR_MHZ(10),
00085         SR_MHZ(20),
00086         SR_MHZ(50),
00087         SR_MHZ(100),
00088         SR_MHZ(200),
00089         0,
00090 };
00091 
00092 static struct sr_samplerates samplerates = {
00093         0,
00094         0,
00095         0,
00096         supported_samplerates,
00097 };
00098 
00099 static GSList *dev_insts = NULL;
00100 
00101 static int mso_send_control_message(struct sr_dev_inst *sdi,
00102                                     uint16_t payload[], int n)
00103 {
00104         int fd = sdi->serial->fd;
00105         int i, w, ret, s = n * 2 + sizeof(mso_head) + sizeof(mso_foot);
00106         char *p, *buf;
00107 
00108         ret = SR_ERR;
00109 
00110         if (fd < 0)
00111                 goto ret;
00112 
00113         if (!(buf = g_try_malloc(s))) {
00114                 sr_err("mso19: %s: buf malloc failed", __func__);
00115                 ret = SR_ERR_MALLOC;
00116                 goto ret;
00117         }
00118 
00119         p = buf;
00120         memcpy(p, mso_head, sizeof(mso_head));
00121         p += sizeof(mso_head);
00122 
00123         for (i = 0; i < n; i++) {
00124                 *(uint16_t *) p = htons(payload[i]);
00125                 p += 2;
00126         }
00127         memcpy(p, mso_foot, sizeof(mso_foot));
00128 
00129         w = 0;
00130         while (w < s) {
00131                 ret = serial_write(fd, buf + w, s - w);
00132                 if (ret < 0) {
00133                         ret = SR_ERR;
00134                         goto free;
00135                 }
00136                 w += ret;
00137         }
00138         ret = SR_OK;
00139 free:
00140         g_free(buf);
00141 ret:
00142         return ret;
00143 }
00144 
00145 static int mso_reset_adc(struct sr_dev_inst *sdi)
00146 {
00147         struct context *ctx = sdi->priv;
00148         uint16_t ops[2];
00149 
00150         ops[0] = mso_trans(REG_CTL1, (ctx->ctlbase1 | BIT_CTL1_RESETADC));
00151         ops[1] = mso_trans(REG_CTL1, ctx->ctlbase1);
00152         ctx->ctlbase1 |= BIT_CTL1_ADC_UNKNOWN4;
00153 
00154         sr_dbg("mso19: Requesting ADC reset");
00155         return mso_send_control_message(sdi, ARRAY_AND_SIZE(ops));
00156 }
00157 
00158 static int mso_reset_fsm(struct sr_dev_inst *sdi)
00159 {
00160         struct context *ctx = sdi->priv;
00161         uint16_t ops[1];
00162 
00163         ctx->ctlbase1 |= BIT_CTL1_RESETFSM;
00164         ops[0] = mso_trans(REG_CTL1, ctx->ctlbase1);
00165 
00166         sr_dbg("mso19: Requesting ADC reset");
00167         return mso_send_control_message(sdi, ARRAY_AND_SIZE(ops));
00168 }
00169 
00170 static int mso_toggle_led(struct sr_dev_inst *sdi, int state)
00171 {
00172         struct context *ctx = sdi->priv;
00173         uint16_t ops[1];
00174 
00175         ctx->ctlbase1 &= ~BIT_CTL1_LED;
00176         if (state)
00177                 ctx->ctlbase1 |= BIT_CTL1_LED;
00178         ops[0] = mso_trans(REG_CTL1, ctx->ctlbase1);
00179 
00180         sr_dbg("mso19: Requesting LED toggle");
00181         return mso_send_control_message(sdi, ARRAY_AND_SIZE(ops));
00182 }
00183 
00184 static int mso_check_trigger(struct sr_dev_inst *sdi, uint8_t *info)
00185 {
00186         uint16_t ops[] = { mso_trans(REG_TRIGGER, 0) };
00187         char buf[1];
00188         int ret;
00189 
00190         sr_dbg("mso19: Requesting trigger state");
00191         ret = mso_send_control_message(sdi, ARRAY_AND_SIZE(ops));
00192         if (info == NULL || ret != SR_OK)
00193                 return ret;
00194 
00195         buf[0] = 0;
00196         if (serial_read(sdi->serial->fd, buf, 1) != 1) /* FIXME: Need timeout */
00197                 ret = SR_ERR;
00198         *info = buf[0];
00199 
00200         sr_dbg("mso19: Trigger state is: 0x%x", *info);
00201         return ret;
00202 }
00203 
00204 static int mso_read_buffer(struct sr_dev_inst *sdi)
00205 {
00206         uint16_t ops[] = { mso_trans(REG_BUFFER, 0) };
00207 
00208         sr_dbg("mso19: Requesting buffer dump");
00209         return mso_send_control_message(sdi, ARRAY_AND_SIZE(ops));
00210 }
00211 
00212 static int mso_arm(struct sr_dev_inst *sdi)
00213 {
00214         struct context *ctx = sdi->priv;
00215         uint16_t ops[] = {
00216                 mso_trans(REG_CTL1, ctx->ctlbase1 | BIT_CTL1_RESETFSM),
00217                 mso_trans(REG_CTL1, ctx->ctlbase1 | BIT_CTL1_ARM),
00218                 mso_trans(REG_CTL1, ctx->ctlbase1),
00219         };
00220 
00221         sr_dbg("mso19: Requesting trigger arm");
00222         return mso_send_control_message(sdi, ARRAY_AND_SIZE(ops));
00223 }
00224 
00225 static int mso_force_capture(struct sr_dev_inst *sdi)
00226 {
00227         struct context *ctx = sdi->priv;
00228         uint16_t ops[] = {
00229                 mso_trans(REG_CTL1, ctx->ctlbase1 | 8),
00230                 mso_trans(REG_CTL1, ctx->ctlbase1),
00231         };
00232 
00233         sr_dbg("mso19: Requesting forced capture");
00234         return mso_send_control_message(sdi, ARRAY_AND_SIZE(ops));
00235 }
00236 
00237 static int mso_dac_out(struct sr_dev_inst *sdi, uint16_t val)
00238 {
00239         struct context *ctx = sdi->priv;
00240         uint16_t ops[] = {
00241                 mso_trans(REG_DAC1, (val >> 8) & 0xff),
00242                 mso_trans(REG_DAC2, val & 0xff),
00243                 mso_trans(REG_CTL1, ctx->ctlbase1 | BIT_CTL1_RESETADC),
00244         };
00245 
00246         sr_dbg("mso19: Setting dac word to 0x%x", val);
00247         return mso_send_control_message(sdi, ARRAY_AND_SIZE(ops));
00248 }
00249 
00250 static int mso_clkrate_out(struct sr_dev_inst *sdi, uint16_t val)
00251 {
00252         uint16_t ops[] = {
00253                 mso_trans(REG_CLKRATE1, (val >> 8) & 0xff),
00254                 mso_trans(REG_CLKRATE2, val & 0xff),
00255         };
00256 
00257         sr_dbg("mso19: Setting clkrate word to 0x%x", val);
00258         return mso_send_control_message(sdi, ARRAY_AND_SIZE(ops));
00259 }
00260 
00261 static int mso_configure_rate(struct sr_dev_inst *sdi, uint32_t rate)
00262 {
00263         struct context *ctx = sdi->priv;
00264         unsigned int i;
00265         int ret = SR_ERR;
00266 
00267         for (i = 0; i < ARRAY_SIZE(rate_map); i++) {
00268                 if (rate_map[i].rate == rate) {
00269                         ctx->ctlbase2 = rate_map[i].slowmode;
00270                         ret = mso_clkrate_out(sdi, rate_map[i].val);
00271                         if (ret == SR_OK)
00272                                 ctx->cur_rate = rate;
00273                         return ret;
00274                 }
00275         }
00276         return ret;
00277 }
00278 
00279 static inline uint16_t mso_calc_raw_from_mv(struct context *ctx)
00280 {
00281         return (uint16_t) (0x200 -
00282                         ((ctx->dso_trigger_voltage / ctx->dso_probe_attn) /
00283                          ctx->vbit));
00284 }
00285 
00286 static int mso_configure_trigger(struct sr_dev_inst *sdi)
00287 {
00288         struct context *ctx = sdi->priv;
00289         uint16_t ops[16];
00290         uint16_t dso_trigger = mso_calc_raw_from_mv(ctx);
00291 
00292         dso_trigger &= 0x3ff;
00293         if ((!ctx->trigger_slope && ctx->trigger_chan == 1) ||
00294                         (ctx->trigger_slope &&
00295                          (ctx->trigger_chan == 0 ||
00296                           ctx->trigger_chan == 2 ||
00297                           ctx->trigger_chan == 3)))
00298                 dso_trigger |= 0x400;
00299 
00300         switch (ctx->trigger_chan) {
00301         case 1:
00302                 dso_trigger |= 0xe000;
00303         case 2:
00304                 dso_trigger |= 0x4000;
00305                 break;
00306         case 3:
00307                 dso_trigger |= 0x2000;
00308                 break;
00309         case 4:
00310                 dso_trigger |= 0xa000;
00311                 break;
00312         case 5:
00313                 dso_trigger |= 0x8000;
00314                 break;
00315         default:
00316         case 0:
00317                 break;
00318         }
00319 
00320         switch (ctx->trigger_outsrc) {
00321         case 1:
00322                 dso_trigger |= 0x800;
00323                 break;
00324         case 2:
00325                 dso_trigger |= 0x1000;
00326                 break;
00327         case 3:
00328                 dso_trigger |= 0x1800;
00329                 break;
00330 
00331         }
00332 
00333         ops[0] = mso_trans(5, ctx->la_trigger);
00334         ops[1] = mso_trans(6, ctx->la_trigger_mask);
00335         ops[2] = mso_trans(3, dso_trigger & 0xff);
00336         ops[3] = mso_trans(4, (dso_trigger >> 8) & 0xff);
00337         ops[4] = mso_trans(11,
00338                         ctx->dso_trigger_width / SR_HZ_TO_NS(ctx->cur_rate));
00339 
00340         /* Select the SPI/I2C trigger config bank */
00341         ops[5] = mso_trans(REG_CTL2, (ctx->ctlbase2 | BITS_CTL2_BANK(2)));
00342         /* Configure the SPI/I2C protocol trigger */
00343         ops[6] = mso_trans(REG_PT_WORD(0), ctx->protocol_trigger.word[0]);
00344         ops[7] = mso_trans(REG_PT_WORD(1), ctx->protocol_trigger.word[1]);
00345         ops[8] = mso_trans(REG_PT_WORD(2), ctx->protocol_trigger.word[2]);
00346         ops[9] = mso_trans(REG_PT_WORD(3), ctx->protocol_trigger.word[3]);
00347         ops[10] = mso_trans(REG_PT_MASK(0), ctx->protocol_trigger.mask[0]);
00348         ops[11] = mso_trans(REG_PT_MASK(1), ctx->protocol_trigger.mask[1]);
00349         ops[12] = mso_trans(REG_PT_MASK(2), ctx->protocol_trigger.mask[2]);
00350         ops[13] = mso_trans(REG_PT_MASK(3), ctx->protocol_trigger.mask[3]);
00351         ops[14] = mso_trans(REG_PT_SPIMODE, ctx->protocol_trigger.spimode);
00352         /* Select the default config bank */
00353         ops[15] = mso_trans(REG_CTL2, ctx->ctlbase2);
00354 
00355         return mso_send_control_message(sdi, ARRAY_AND_SIZE(ops));
00356 }
00357 
00358 static int mso_configure_threshold_level(struct sr_dev_inst *sdi)
00359 {
00360         struct context *ctx = sdi->priv;
00361 
00362         return mso_dac_out(sdi, la_threshold_map[ctx->la_threshold]);
00363 }
00364 
00365 static int mso_parse_serial(const char *iSerial, const char *iProduct,
00366                             struct context *ctx)
00367 {
00368         unsigned int u1, u2, u3, u4, u5, u6;
00369 
00370         iProduct = iProduct;
00371         /* FIXME: This code is in the original app, but I think its
00372          * used only for the GUI */
00373 /*      if (strstr(iProduct, "REV_02") || strstr(iProduct, "REV_03"))
00374                 ctx->num_sample_rates = 0x16;
00375         else
00376                 ctx->num_sample_rates = 0x10; */
00377 
00378         /* parse iSerial */
00379         if (iSerial[0] != '4' || sscanf(iSerial, "%5u%3u%3u%1u%1u%6u",
00380                                 &u1, &u2, &u3, &u4, &u5, &u6) != 6)
00381                 return SR_ERR;
00382         ctx->hwmodel = u4;
00383         ctx->hwrev = u5;
00384         ctx->serial = u6;
00385         ctx->vbit = u1 / 10000;
00386         if (ctx->vbit == 0)
00387                 ctx->vbit = 4.19195;
00388         ctx->dac_offset = u2;
00389         if (ctx->dac_offset == 0)
00390                 ctx->dac_offset = 0x1ff;
00391         ctx->offset_range = u3;
00392         if (ctx->offset_range == 0)
00393                 ctx->offset_range = 0x17d;
00394 
00395         /*
00396          * FIXME: There is more code on the original software to handle
00397          * bigger iSerial strings, but as I can't test on my device
00398          * I will not implement it yet
00399          */
00400 
00401         return SR_OK;
00402 }
00403 
00404 static int hw_init(const char *devinfo)
00405 {
00406         struct sr_dev_inst *sdi;
00407         int devcnt = 0;
00408         struct udev *udev;
00409         struct udev_enumerate *enumerate;
00410         struct udev_list_entry *devs, *dev_list_entry;
00411         struct context *ctx;
00412 
00413         devinfo = devinfo;
00414 
00415         /* It's easier to map usb<->serial using udev */
00416         /*
00417          * FIXME: On windows we can get the same information from the
00418          * registry, add an #ifdef here later
00419          */
00420         udev = udev_new();
00421         if (!udev) {
00422                 sr_err("mso19: Failed to initialize udev.");
00423                 goto ret;
00424         }
00425         enumerate = udev_enumerate_new(udev);
00426         udev_enumerate_add_match_subsystem(enumerate, "usb-serial");
00427         udev_enumerate_scan_devices(enumerate);
00428         devs = udev_enumerate_get_list_entry(enumerate);
00429         udev_list_entry_foreach(dev_list_entry, devs) {
00430                 const char *syspath, *sysname, *idVendor, *idProduct,
00431                         *iSerial, *iProduct;
00432                 char path[32], manufacturer[32], product[32], hwrev[32];
00433                 struct udev_device *dev, *parent;
00434                 size_t s;
00435 
00436                 syspath = udev_list_entry_get_name(dev_list_entry);
00437                 dev = udev_device_new_from_syspath(udev, syspath);
00438                 sysname = udev_device_get_sysname(dev);
00439                 parent = udev_device_get_parent_with_subsystem_devtype(
00440                                 dev, "usb", "usb_device");
00441                 if (!parent) {
00442                         sr_err("mso19: Unable to find parent usb device for %s",
00443                                sysname);
00444                         continue;
00445                 }
00446 
00447                 idVendor = udev_device_get_sysattr_value(parent, "idVendor");
00448                 idProduct = udev_device_get_sysattr_value(parent, "idProduct");
00449                 if (strcmp(USB_VENDOR, idVendor)
00450                                 || strcmp(USB_PRODUCT, idProduct))
00451                         continue;
00452 
00453                 iSerial = udev_device_get_sysattr_value(parent, "serial");
00454                 iProduct = udev_device_get_sysattr_value(parent, "product");
00455 
00456                 snprintf(path, sizeof(path), "/dev/%s", sysname);
00457 
00458                 s = strcspn(iProduct, " ");
00459                 if (s > sizeof(product) ||
00460                                 strlen(iProduct) - s > sizeof(manufacturer)) {
00461                         sr_err("mso19: Could not parse iProduct: %s", iProduct);
00462                         continue;
00463                 }
00464                 strncpy(product, iProduct, s);
00465                 product[s] = 0;
00466                 strcpy(manufacturer, iProduct + s);
00467 
00468                 if (!(ctx = g_try_malloc0(sizeof(struct context)))) {
00469                         sr_err("mso19: %s: ctx malloc failed", __func__);
00470                         continue; /* TODO: Errors handled correctly? */
00471                 }
00472 
00473                 if (mso_parse_serial(iSerial, iProduct, ctx) != SR_OK) {
00474                         sr_err("mso19: Invalid iSerial: %s", iSerial);
00475                         goto err_free_ctx;
00476                 }
00477                 sprintf(hwrev, "r%d", ctx->hwrev);
00478 
00479                 /* hardware initial state */
00480                 ctx->ctlbase1 = 0;
00481                 {
00482                         /* Initialize the protocol trigger configuration */
00483                         int i;
00484                         for (i = 0; i < 4; i++) {
00485                                 ctx->protocol_trigger.word[i] = 0;
00486                                 ctx->protocol_trigger.mask[i] = 0xff;
00487                         }
00488                         ctx->protocol_trigger.spimode = 0;
00489                 }
00490 
00491                 sdi = sr_dev_inst_new(devcnt, SR_ST_INITIALIZING,
00492                                       manufacturer, product, hwrev);
00493                 if (!sdi) {
00494                         sr_err("mso19: Unable to create device instance for %s",
00495                                sysname);
00496                         goto err_free_ctx;
00497                 }
00498 
00499                 /* save a pointer to our private instance data */
00500                 sdi->priv = ctx;
00501 
00502                 sdi->serial = sr_serial_dev_inst_new(path, -1);
00503                 if (!sdi->serial)
00504                         goto err_dev_inst_free;
00505 
00506                 dev_insts = g_slist_append(dev_insts, sdi);
00507                 devcnt++;
00508                 continue;
00509 
00510 err_dev_inst_free:
00511                 sr_dev_inst_free(sdi);
00512 err_free_ctx:
00513                 g_free(ctx);
00514         }
00515 
00516         udev_enumerate_unref(enumerate);
00517         udev_unref(udev);
00518 
00519 ret:
00520         return devcnt;
00521 }
00522 
00523 static int hw_cleanup(void)
00524 {
00525         GSList *l;
00526         struct sr_dev_inst *sdi;
00527         int ret;
00528 
00529         ret = SR_OK;
00530         /* Properly close all devices. */
00531         for (l = dev_insts; l; l = l->next) {
00532                 if (!(sdi = l->data)) {
00533                         /* Log error, but continue cleaning up the rest. */
00534                         sr_err("mso19: %s: sdi was NULL, continuing", __func__);
00535                         ret = SR_ERR_BUG;
00536                         continue;
00537                 }
00538                 if (sdi->serial->fd != -1)
00539                         serial_close(sdi->serial->fd);
00540                 sr_dev_inst_free(sdi);
00541         }
00542         g_slist_free(dev_insts);
00543         dev_insts = NULL;
00544 
00545         return ret;
00546 }
00547 
00548 static int hw_dev_open(int dev_index)
00549 {
00550         struct sr_dev_inst *sdi;
00551         struct context *ctx;
00552         int ret = SR_ERR;
00553 
00554         if (!(sdi = sr_dev_inst_get(dev_insts, dev_index)))
00555                 return ret;
00556 
00557         ctx = sdi->priv;
00558         sdi->serial->fd = serial_open(sdi->serial->port, O_RDWR);
00559         if (sdi->serial->fd == -1)
00560                 return ret;
00561 
00562         ret = serial_set_params(sdi->serial->fd, 460800, 8, 0, 1, 2);
00563         if (ret != SR_OK)
00564                 return ret;
00565 
00566         sdi->status = SR_ST_ACTIVE;
00567 
00568         /* FIXME: discard serial buffer */
00569 
00570         mso_check_trigger(sdi, &ctx->trigger_state);
00571         sr_dbg("mso19: trigger state: 0x%x", ctx->trigger_state);
00572 
00573         ret = mso_reset_adc(sdi);
00574         if (ret != SR_OK)
00575                 return ret;
00576 
00577         mso_check_trigger(sdi, &ctx->trigger_state);
00578         sr_dbg("mso19: trigger state: 0x%x", ctx->trigger_state);
00579 
00580 //      ret = mso_reset_fsm(sdi);
00581 //      if (ret != SR_OK)
00582 //              return ret;
00583 
00584         sr_dbg("mso19: Finished %s", __func__);
00585 
00586 //      return SR_ERR;
00587         return SR_OK;
00588 }
00589 
00590 static int hw_dev_close(int dev_index)
00591 {
00592         struct sr_dev_inst *sdi;
00593 
00594         if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) {
00595                 sr_err("mso19: %s: sdi was NULL", __func__);
00596                 return SR_ERR_BUG;
00597         }
00598 
00599         /* TODO */
00600         if (sdi->serial->fd != -1) {
00601                 serial_close(sdi->serial->fd);
00602                 sdi->serial->fd = -1;
00603                 sdi->status = SR_ST_INACTIVE;
00604         }
00605 
00606         sr_dbg("mso19: finished %s", __func__);
00607         return SR_OK;
00608 }
00609 
00610 static void *hw_dev_info_get(int dev_index, int dev_info_id)
00611 {
00612         struct sr_dev_inst *sdi;
00613         struct context *ctx;
00614         void *info = NULL;
00615 
00616         if (!(sdi = sr_dev_inst_get(dev_insts, dev_index)))
00617                 return NULL;
00618         ctx = sdi->priv;
00619 
00620         switch (dev_info_id) {
00621         case SR_DI_INST:
00622                 info = sdi;
00623                 break;
00624         case SR_DI_NUM_PROBES: /* FIXME: How to report analog probe? */
00625                 info = GINT_TO_POINTER(NUM_PROBES);
00626                 break;
00627         case SR_DI_PROBE_NAMES: 
00628                 info = probe_names;
00629                 break;
00630         case SR_DI_SAMPLERATES:
00631                 info = &samplerates;
00632                 break;
00633         case SR_DI_TRIGGER_TYPES:
00634                 info = "01"; /* FIXME */
00635                 break;
00636         case SR_DI_CUR_SAMPLERATE:
00637                 info = &ctx->cur_rate;
00638                 break;
00639         }
00640         return info;
00641 }
00642 
00643 static int hw_dev_status_get(int dev_index)
00644 {
00645         struct sr_dev_inst *sdi;
00646 
00647         if (!(sdi = sr_dev_inst_get(dev_insts, dev_index)))
00648                 return SR_ST_NOT_FOUND;
00649 
00650         return sdi->status;
00651 }
00652 
00653 static int *hw_hwcap_get_all(void)
00654 {
00655         return hwcaps;
00656 }
00657 
00658 static int hw_dev_config_set(int dev_index, int hwcap, void *value)
00659 {
00660         struct sr_dev_inst *sdi;
00661 
00662         if (!(sdi = sr_dev_inst_get(dev_insts, dev_index)))
00663                 return SR_ERR;
00664 
00665         switch (hwcap) {
00666         case SR_HWCAP_SAMPLERATE:
00667                 return mso_configure_rate(sdi, *(uint64_t *) value);
00668         case SR_HWCAP_PROBECONFIG:
00669         case SR_HWCAP_LIMIT_SAMPLES:
00670         default:
00671                 return SR_OK; /* FIXME */
00672         }
00673 }
00674 
00675 #define MSO_TRIGGER_UNKNOWN     '!'
00676 #define MSO_TRIGGER_UNKNOWN1    '1'
00677 #define MSO_TRIGGER_UNKNOWN2    '2'
00678 #define MSO_TRIGGER_UNKNOWN3    '3'
00679 #define MSO_TRIGGER_WAIT        '4'
00680 #define MSO_TRIGGER_FIRED       '5'
00681 #define MSO_TRIGGER_DATAREADY   '6'
00682 
00683 /* FIXME: Pass errors? */
00684 static int receive_data(int fd, int revents, void *cb_data)
00685 {
00686         struct sr_dev_inst *sdi = cb_data;
00687         struct context *ctx = sdi->priv;
00688         struct sr_datafeed_packet packet;
00689         struct sr_datafeed_logic logic;
00690         uint8_t in[1024], logic_out[1024];
00691         double analog_out[1024];
00692         size_t i, s;
00693 
00694         /* Avoid compiler warnings. */
00695         (void)revents;
00696 
00697         s = serial_read(fd, in, sizeof(in));
00698         if (s <= 0)
00699                 return FALSE;
00700 
00701         /* No samples */
00702         if (ctx->trigger_state != MSO_TRIGGER_DATAREADY) {
00703                 ctx->trigger_state = in[0];
00704                 if (ctx->trigger_state == MSO_TRIGGER_DATAREADY) {
00705                         mso_read_buffer(sdi);
00706                         ctx->buffer_n = 0;
00707                 } else {
00708                         mso_check_trigger(sdi, NULL);
00709                 }
00710                 return FALSE;
00711         }
00712 
00713         /* the hardware always dumps 1024 samples, 24bits each */
00714         if (ctx->buffer_n < 3072) {
00715                 memcpy(ctx->buffer + ctx->buffer_n, in, s);
00716                 ctx->buffer_n += s;
00717         }
00718         if (ctx->buffer_n < 3072)
00719                 return FALSE;
00720 
00721         /* do the conversion */
00722         for (i = 0; i < 1024; i++) {
00723                 /* FIXME: Need to do conversion to mV */
00724                 analog_out[i] = (ctx->buffer[i * 3] & 0x3f) |
00725                         ((ctx->buffer[i * 3 + 1] & 0xf) << 6);
00726                 logic_out[i] = ((ctx->buffer[i * 3 + 1] & 0x30) >> 4) |
00727                         ((ctx->buffer[i * 3 + 2] & 0x3f) << 2);
00728         }
00729 
00730         packet.type = SR_DF_LOGIC;
00731         packet.payload = &logic;
00732         logic.length = 1024;
00733         logic.unitsize = 1;
00734         logic.data = logic_out;
00735         sr_session_send(ctx->session_dev_id, &packet);
00736 
00737         // Dont bother fixing this yet, keep it "old style"
00738         /*
00739         packet.type = SR_DF_ANALOG;
00740         packet.length = 1024;
00741         packet.unitsize = sizeof(double);
00742         packet.payload = analog_out;
00743         sr_session_send(ctx->session_dev_id, &packet);
00744         */
00745 
00746         packet.type = SR_DF_END;
00747         sr_session_send(ctx->session_dev_id, &packet);
00748 
00749         return TRUE;
00750 }
00751 
00752 static int hw_dev_acquisition_start(int dev_index, void *cb_data)
00753 {
00754         struct sr_dev_inst *sdi;
00755         struct context *ctx;
00756         struct sr_datafeed_packet packet;
00757         struct sr_datafeed_header header;
00758         int ret = SR_ERR;
00759 
00760         if (!(sdi = sr_dev_inst_get(dev_insts, dev_index)))
00761                 return ret;
00762         ctx = sdi->priv;
00763 
00764         /* FIXME: No need to do full reconfigure every time */
00765 //      ret = mso_reset_fsm(sdi);
00766 //      if (ret != SR_OK)
00767 //              return ret;
00768 
00769         /* FIXME: ACDC Mode */
00770         ctx->ctlbase1 &= 0x7f;
00771 //      ctx->ctlbase1 |= ctx->acdcmode;
00772 
00773         ret = mso_configure_rate(sdi, ctx->cur_rate);
00774         if (ret != SR_OK)
00775                 return ret;
00776 
00777         /* set dac offset */
00778         ret = mso_dac_out(sdi, ctx->dac_offset);
00779         if (ret != SR_OK)
00780                 return ret;
00781 
00782         ret = mso_configure_threshold_level(sdi);
00783         if (ret != SR_OK)
00784                 return ret;
00785 
00786         ret = mso_configure_trigger(sdi);
00787         if (ret != SR_OK)
00788                 return ret;
00789 
00790         /* FIXME: trigger_position */
00791 
00792 
00793         /* END of config hardware part */
00794 
00795         /* with trigger */
00796         ret = mso_arm(sdi);
00797         if (ret != SR_OK)
00798                 return ret;
00799 
00800         /* without trigger */
00801 //      ret = mso_force_capture(sdi);
00802 //      if (ret != SR_OK)
00803 //              return ret;
00804 
00805         mso_check_trigger(sdi, &ctx->trigger_state);
00806         ret = mso_check_trigger(sdi, NULL);
00807         if (ret != SR_OK)
00808                 return ret;
00809 
00810         ctx->session_dev_id = cb_data;
00811         sr_source_add(sdi->serial->fd, G_IO_IN, -1, receive_data, sdi);
00812 
00813         packet.type = SR_DF_HEADER;
00814         packet.payload = (unsigned char *) &header;
00815         header.feed_version = 1;
00816         gettimeofday(&header.starttime, NULL);
00817         header.samplerate = ctx->cur_rate;
00818         // header.num_analog_probes = 1;
00819         header.num_logic_probes = 8;
00820         sr_session_send(ctx->session_dev_id, &packet);
00821 
00822         return ret;
00823 }
00824 
00825 /* TODO: This stops acquisition on ALL devices, ignoring dev_index. */
00826 static int hw_dev_acquisition_stop(int dev_index, void *cb_data)
00827 {
00828         struct sr_datafeed_packet packet;
00829 
00830         /* Avoid compiler warnings. */
00831         (void)dev_index;
00832 
00833         packet.type = SR_DF_END;
00834         sr_session_send(cb_data, &packet);
00835 
00836         return SR_OK;
00837 }
00838 
00839 SR_PRIV struct sr_dev_driver link_mso19_driver_info = {
00840         .name = "link-mso19",
00841         .longname = "Link Instruments MSO-19",
00842         .api_version = 1,
00843         .init = hw_init,
00844         .cleanup = hw_cleanup,
00845         .dev_open = hw_dev_open,
00846         .dev_close = hw_dev_close,
00847         .dev_info_get = hw_dev_info_get,
00848         .dev_status_get = hw_dev_status_get,
00849         .hwcap_get_all = hw_hwcap_get_all,
00850         .dev_config_set = hw_dev_config_set,
00851         .dev_acquisition_start = hw_dev_acquisition_start,
00852         .dev_acquisition_stop = hw_dev_acquisition_stop,
00853 };
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines