]> sigrok.org Git - libsigrok.git/blobdiff - hardware/saleae-logic/saleae-logic.c
sr/cli/gtk: Remove analog left-overs from API.
[libsigrok.git] / hardware / saleae-logic / saleae-logic.c
index 0940fab42b6cd33c5062c70776f8e7a97d604e6b..09a37cb29caa63dae0e0a98ae850c17c920f60ae 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the sigrok project.
  *
- * Copyright (C) 2010 Bert Vermeulen <bert@biot.com>
+ * Copyright (C) 2012 Bert Vermeulen <bert@biot.com>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "config.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/time.h>
 #include <inttypes.h>
 #include <glib.h>
 #include <libusb.h>
-#include <sigrok.h>
-#include <sigrok-internal.h>
+#include "config.h"
+#include "sigrok.h"
+#include "sigrok-internal.h"
 #include "saleae-logic.h"
 
 static struct fx2_profile supported_fx2[] = {
@@ -46,6 +46,26 @@ static int capabilities[] = {
        0,
 };
 
+static const char *probe_names[] = {
+       "0",
+       "1",
+       "2",
+       "3",
+       "4",
+       "5",
+       "6",
+       "7",
+       "8",
+       "9",
+       "10",
+       "11",
+       "12",
+       "13",
+       "14",
+       "15",
+       NULL,
+};
+
 static uint64_t supported_samplerates[] = {
        SR_KHZ(200),
        SR_KHZ(250),
@@ -172,24 +192,24 @@ static int sl_open_device(int device_index)
                         * This device is fully enumerated, so we need to find this
                         * device by vendor, product, bus and address.
                         */
-                       if (libusb_get_bus_number(devlist[i]) != sdi->usb->bus
-                               || libusb_get_device_address(devlist[i]) != sdi->usb->address)
+                       if (libusb_get_bus_number(devlist[i]) != fx2->usb->bus
+                               || libusb_get_device_address(devlist[i]) != fx2->usb->address)
                                /* this is not the one */
                                continue;
                }
 
-               if (!(err = libusb_open(devlist[i], &sdi->usb->devhdl))) {
-                       if (sdi->usb->address == 0xff)
+               if (!(err = libusb_open(devlist[i], &fx2->usb->devhdl))) {
+                       if (fx2->usb->address == 0xff)
                                /*
                                 * first time we touch this device after firmware upload,
                                 * so we don't know the address yet.
                                 */
-                               sdi->usb->address = libusb_get_device_address(devlist[i]);
+                               fx2->usb->address = libusb_get_device_address(devlist[i]);
 
                        sdi->status = SR_ST_ACTIVE;
                        sr_info("saleae: opened device %d on %d.%d interface %d",
-                                 sdi->index, sdi->usb->bus,
-                                 sdi->usb->address, USB_INTERFACE);
+                                 sdi->index, fx2->usb->bus,
+                                 fx2->usb->address, USB_INTERFACE);
                } else {
                        sr_warn("failed to open device: %d", err);
                }
@@ -207,14 +227,18 @@ static int sl_open_device(int device_index)
 
 static void close_device(struct sr_device_instance *sdi)
 {
-       if (sdi->usb->devhdl == NULL)
+       struct fx2_device *fx2;
+
+       fx2 = sdi->priv;
+
+       if (fx2->usb->devhdl == NULL)
                return;
 
        sr_info("saleae: closing device %d on %d.%d interface %d", sdi->index,
-               sdi->usb->bus, sdi->usb->address, USB_INTERFACE);
-       libusb_release_interface(sdi->usb->devhdl, USB_INTERFACE);
-       libusb_close(sdi->usb->devhdl);
-       sdi->usb->devhdl = NULL;
+               fx2->usb->bus, fx2->usb->address, USB_INTERFACE);
+       libusb_release_interface(fx2->usb->devhdl, USB_INTERFACE);
+       libusb_close(fx2->usb->devhdl);
+       fx2->usb->devhdl = NULL;
        sdi->status = SR_ST_INACTIVE;
 }
 
@@ -269,10 +293,11 @@ static struct fx2_device *fx2_device_new(void)
        struct fx2_device *fx2;
 
        if (!(fx2 = g_try_malloc0(sizeof(struct fx2_device)))) {
-               sr_err("saleae: %s: saleae malloc failed", __func__);
+               sr_err("saleae: %s: fx2 malloc failed", __func__);
                return NULL;
        }
        fx2->trigger_stage = TRIGGER_FIRED;
+       fx2->usb = NULL;
 
        return fx2;
 }
@@ -292,7 +317,7 @@ static int hw_init(const char *deviceinfo)
        int err, devcnt, i, j;
 
        /* Avoid compiler warnings. */
-       deviceinfo = deviceinfo;
+       (void)deviceinfo;
 
        if (libusb_init(&usb_context) != 0) {
                sr_warn("Failed to initialize USB.");
@@ -333,7 +358,7 @@ static int hw_init(const char *deviceinfo)
                if (check_conf_profile(devlist[i])) {
                        /* Already has the firmware, so fix the new address. */
                        sdi->status = SR_ST_INACTIVE;
-                       sdi->usb = sr_usb_device_instance_new
+                       fx2->usb = sr_usb_device_instance_new
                            (libusb_get_bus_number(devlist[i]),
                             libusb_get_device_address(devlist[i]), NULL);
                } else {
@@ -342,7 +367,7 @@ static int hw_init(const char *deviceinfo)
                                g_get_current_time(&fx2->fw_updated);
                        else
                                sr_warn("firmware upload failed for device %d", devcnt);
-                       sdi->usb = sr_usb_device_instance_new
+                       fx2->usb = sr_usb_device_instance_new
                                (libusb_get_bus_number(devlist[i]), 0xff, NULL);
                }
                devcnt++;
@@ -391,7 +416,7 @@ static int hw_opendev(int device_index)
        }
        fx2 = sdi->priv;
 
-       err = libusb_claim_interface(sdi->usb->devhdl, USB_INTERFACE);
+       err = libusb_claim_interface(fx2->usb->devhdl, USB_INTERFACE);
        if (err != 0) {
                sr_warn("Unable to claim interface: %d", err);
                return SR_ERR;
@@ -425,14 +450,18 @@ static int hw_closedev(int device_index)
 static void hw_cleanup(void)
 {
        GSList *l;
+       struct sr_device_instance *sdi;
+       struct fx2_device *fx2;
 
-       /* Properly close all devices... */
-       for (l = device_instances; l; l = l->next)
-               close_device((struct sr_device_instance *)l->data);
+       /* Properly close and free all devices. */
+       for (l = device_instances; l; l = l->next) {
+               sdi = l->data;
+               fx2 = sdi->priv;
+               close_device(sdi);
+               sr_usb_device_instance_free(fx2->usb);
+               sr_device_instance_free(sdi);
+       }
 
-       /* ...and free all their memory. */
-       for (l = device_instances; l; l = l->next)
-               g_free(l->data);
        g_slist_free(device_instances);
        device_instances = NULL;
 
@@ -458,6 +487,9 @@ static void *hw_get_device_info(int device_index, int device_info_id)
        case SR_DI_NUM_PROBES:
                info = GINT_TO_POINTER(fx2->profile->num_probes);
                break;
+       case SR_DI_PROBE_NAMES:
+               info = probe_names;
+               break;
        case SR_DI_SAMPLERATES:
                info = &samplerates;
                break;
@@ -510,7 +542,7 @@ static int set_configuration_samplerate(struct sr_device_instance *sdi,
                samplerate, divider);
        buf[0] = 0x01;
        buf[1] = divider;
-       ret = libusb_bulk_transfer(sdi->usb->devhdl, 1 | LIBUSB_ENDPOINT_OUT,
+       ret = libusb_bulk_transfer(fx2->usb->devhdl, 1 | LIBUSB_ENDPOINT_OUT,
                                   buf, 2, &result, 500);
        if (ret != 0) {
                sr_warn("failed to set samplerate: %d", ret);
@@ -553,9 +585,9 @@ static int receive_data(int fd, int revents, void *user_data)
        struct timeval tv;
 
        /* Avoid compiler warnings. */
-       fd = fd;
-       revents = revents;
-       user_data = user_data;
+       (void)fd;
+       (void)revents;
+       (void)user_data;
 
        tv.tv_sec = tv.tv_usec = 0;
        libusb_handle_events_timeout(usb_context, &tv);
@@ -563,11 +595,13 @@ static int receive_data(int fd, int revents, void *user_data)
        return TRUE;
 }
 
-void receive_transfer(struct libusb_transfer *transfer)
+static void receive_transfer(struct libusb_transfer *transfer)
 {
+       /* TODO: these statics have to move to fx2_device struct */
        static int num_samples = 0;
        static int empty_transfer_count = 0;
        struct sr_datafeed_packet packet;
+       struct sr_datafeed_logic logic;
        struct fx2_device *fx2;
        int cur_buflen, trigger_offset, i;
        unsigned char *cur_buf, *new_buf;
@@ -630,6 +664,7 @@ void receive_transfer(struct libusb_transfer *transfer)
                                /* Match on this trigger stage. */
                                fx2->trigger_buffer[fx2->trigger_stage] = cur_buf[i];
                                fx2->trigger_stage++;
+
                                if (fx2->trigger_stage == NUM_TRIGGER_STAGES || fx2->trigger_mask[fx2->trigger_stage] == 0) {
                                        /* Match on all trigger stages, we're done. */
                                        trigger_offset = i + 1;
@@ -639,7 +674,7 @@ void receive_transfer(struct libusb_transfer *transfer)
                                         * Tell the frontend we hit the trigger here.
                                         */
                                        packet.type = SR_DF_TRIGGER;
-                                       packet.length = 0;
+                                       packet.payload = NULL;
                                        sr_session_bus(fx2->session_data, &packet);
 
                                        /*
@@ -647,9 +682,10 @@ void receive_transfer(struct libusb_transfer *transfer)
                                         * skipping past them.
                                         */
                                        packet.type = SR_DF_LOGIC;
-                                       packet.length = fx2->trigger_stage;
-                                       packet.unitsize = 1;
-                                       packet.payload = fx2->trigger_buffer;
+                                       packet.payload = &logic;
+                                       logic.length = fx2->trigger_stage;
+                                       logic.unitsize = 1;
+                                       logic.data = fx2->trigger_buffer;
                                        sr_session_bus(fx2->session_data, &packet);
 
                                        fx2->trigger_stage = TRIGGER_FIRED;
@@ -678,9 +714,10 @@ void receive_transfer(struct libusb_transfer *transfer)
        if (fx2->trigger_stage == TRIGGER_FIRED) {
                /* Send the incoming transfer to the session bus. */
                packet.type = SR_DF_LOGIC;
-               packet.length = cur_buflen - trigger_offset;
-               packet.unitsize = 1;
-               packet.payload = cur_buf + trigger_offset;
+               packet.payload = &logic;
+               logic.length = cur_buflen - trigger_offset;
+               logic.unitsize = 1;
+               logic.data = cur_buf + trigger_offset;
                sr_session_bus(fx2->session_data, &packet);
                g_free(cur_buf);
 
@@ -716,7 +753,7 @@ static int hw_start_acquisition(int device_index, gpointer session_data)
                sr_err("saleae: %s: packet malloc failed", __func__);
                return SR_ERR_MALLOC;
        }
-       
+
        if (!(header = g_try_malloc(sizeof(struct sr_datafeed_header)))) {
                sr_err("saleae: %s: header malloc failed", __func__);
                return SR_ERR_MALLOC;
@@ -730,7 +767,7 @@ static int hw_start_acquisition(int device_index, gpointer session_data)
                        return SR_ERR_MALLOC;
                }
                transfer = libusb_alloc_transfer(0);
-               libusb_fill_bulk_transfer(transfer, sdi->usb->devhdl,
+               libusb_fill_bulk_transfer(transfer, fx2->usb->devhdl,
                                2 | LIBUSB_ENDPOINT_IN, buf, size,
                                receive_transfer, fx2, 40);
                if (libusb_submit_transfer(transfer) != 0) {
@@ -749,14 +786,11 @@ static int hw_start_acquisition(int device_index, gpointer session_data)
        free(lupfd);
 
        packet->type = SR_DF_HEADER;
-       packet->length = sizeof(struct sr_datafeed_header);
-       packet->payload = (unsigned char *)header;
+       packet->payload = header;
        header->feed_version = 1;
        gettimeofday(&header->starttime, NULL);
        header->samplerate = fx2->cur_samplerate;
-       header->protocol_id = SR_PROTO_RAW;
        header->num_logic_probes = fx2->profile->num_probes;
-       header->num_analog_probes = 0;
        sr_session_bus(session_data, packet);
        g_free(header);
        g_free(packet);
@@ -770,7 +804,7 @@ static void hw_stop_acquisition(int device_index, gpointer session_data)
        struct sr_datafeed_packet packet;
 
        /* Avoid compiler warnings. */
-       device_index = device_index;
+       (void)device_index;
 
        packet.type = SR_DF_END;
        sr_session_bus(session_data, &packet);
@@ -780,7 +814,7 @@ static void hw_stop_acquisition(int device_index, gpointer session_data)
        /* TODO: Need to cancel and free any queued up transfers. */
 }
 
-struct sr_device_plugin saleae_logic_plugin_info = {
+SR_PRIV struct sr_device_plugin saleae_logic_plugin_info = {
        .name = "saleae-logic",
        .longname = "Saleae Logic",
        .api_version = 1,