]> sigrok.org Git - libsigrok.git/commitdiff
fx2lafw: Moved all protocol handling to protocol.c
authorJoel Holdsworth <redacted>
Thu, 15 Jun 2017 17:34:52 +0000 (11:34 -0600)
committerUwe Hermann <redacted>
Mon, 19 Jun 2017 22:18:16 +0000 (00:18 +0200)
Previously the USB communication code was split between api.c
and protocol.c, with protocol internals split between both. This
patch puts all the protocol handling code into one source file
reducing the number of internal interfaces and making the code
more readable.

src/hardware/fx2lafw/api.c
src/hardware/fx2lafw/protocol.c
src/hardware/fx2lafw/protocol.h

index b6e708b98ab11bd689cdd7a21d897a258fcc6c87..6c7d776f8e9109c2bb1a5b3b11e044d8cee47978 100644 (file)
@@ -581,180 +581,6 @@ static int config_list(uint32_t key, GVariant **data,
        return SR_OK;
 }
 
-static int receive_data(int fd, int revents, void *cb_data)
-{
-       struct timeval tv;
-       struct drv_context *drvc;
-
-       (void)fd;
-       (void)revents;
-
-       drvc = (struct drv_context *)cb_data;
-
-       tv.tv_sec = tv.tv_usec = 0;
-       libusb_handle_events_timeout(drvc->sr_ctx->libusb_ctx, &tv);
-
-       return TRUE;
-}
-
-static int start_transfers(const struct sr_dev_inst *sdi)
-{
-       struct dev_context *devc;
-       struct sr_usb_dev_inst *usb;
-       struct sr_trigger *trigger;
-       struct libusb_transfer *transfer;
-       unsigned int i, num_transfers;
-       int timeout, ret;
-       unsigned char *buf;
-       size_t size;
-
-       devc = sdi->priv;
-       usb = sdi->conn;
-
-       devc->sent_samples = 0;
-       devc->acq_aborted = FALSE;
-       devc->empty_transfer_count = 0;
-
-       if ((trigger = sr_session_trigger_get(sdi->session))) {
-               int pre_trigger_samples = 0;
-               if (devc->limit_samples > 0)
-                       pre_trigger_samples = devc->capture_ratio * devc->limit_samples/100;
-               devc->stl = soft_trigger_logic_new(sdi, trigger, pre_trigger_samples);
-               if (!devc->stl)
-                       return SR_ERR_MALLOC;
-               devc->trigger_fired = FALSE;
-       } else
-               devc->trigger_fired = TRUE;
-
-       num_transfers = fx2lafw_get_number_of_transfers(devc);
-
-       size = fx2lafw_get_buffer_size(devc);
-       devc->submitted_transfers = 0;
-
-       devc->transfers = g_try_malloc0(sizeof(*devc->transfers) * num_transfers);
-       if (!devc->transfers) {
-               sr_err("USB transfers malloc failed.");
-               return SR_ERR_MALLOC;
-       }
-
-       timeout = fx2lafw_get_timeout(devc);
-       devc->num_transfers = num_transfers;
-       for (i = 0; i < num_transfers; i++) {
-               if (!(buf = g_try_malloc(size))) {
-                       sr_err("USB transfer buffer malloc failed.");
-                       return SR_ERR_MALLOC;
-               }
-               transfer = libusb_alloc_transfer(0);
-               libusb_fill_bulk_transfer(transfer, usb->devhdl,
-                               2 | LIBUSB_ENDPOINT_IN, buf, size,
-                               fx2lafw_receive_transfer, (void *)sdi, timeout);
-               sr_info("submitting transfer: %d", i);
-               if ((ret = libusb_submit_transfer(transfer)) != 0) {
-                       sr_err("Failed to submit transfer: %s.",
-                              libusb_error_name(ret));
-                       libusb_free_transfer(transfer);
-                       g_free(buf);
-                       fx2lafw_abort_acquisition(devc);
-                       return SR_ERR;
-               }
-               devc->transfers[i] = transfer;
-               devc->submitted_transfers++;
-       }
-
-       /*
-        * If this device has analog channels and at least one of them is
-        * enabled, use mso_send_data_proc() to properly handle the analog
-        * data. Otherwise use la_send_data_proc().
-        */
-       if (g_slist_length(devc->enabled_analog_channels) > 0)
-               devc->send_data_proc = mso_send_data_proc;
-       else
-               devc->send_data_proc = la_send_data_proc;
-
-       std_session_send_df_header(sdi);
-
-       return SR_OK;
-}
-
-static int configure_channels(const struct sr_dev_inst *sdi)
-{
-       struct dev_context *devc;
-       const GSList *l;
-       int p;
-       struct sr_channel *ch;
-       uint32_t channel_mask = 0, num_analog = 0;
-
-       devc = sdi->priv;
-
-       g_slist_free(devc->enabled_analog_channels);
-       devc->enabled_analog_channels = NULL;
-
-       for (l = sdi->channels, p = 0; l; l = l->next, p++) {
-               ch = l->data;
-               if ((p <= NUM_CHANNELS) && (ch->type == SR_CHANNEL_ANALOG)
-                               && (ch->enabled)) {
-                       num_analog++;
-                       devc->enabled_analog_channels =
-                           g_slist_append(devc->enabled_analog_channels, ch);
-               } else {
-                       channel_mask |= ch->enabled << p;
-               }
-       }
-
-       /*
-        * Use wide sampling if either any of the LA channels 8..15 is enabled,
-        * and/or at least one analog channel is enabled.
-        */
-       devc->sample_wide = channel_mask > 0xff || num_analog > 0;
-
-       return SR_OK;
-}
-
-static int dev_acquisition_start(const struct sr_dev_inst *sdi)
-{
-       struct sr_dev_driver *di;
-       struct drv_context *drvc;
-       struct dev_context *devc;
-       int timeout, ret;
-       size_t size;
-
-       if (sdi->status != SR_ST_ACTIVE)
-               return SR_ERR_DEV_CLOSED;
-
-       di = sdi->driver;
-       drvc = di->context;
-       devc = sdi->priv;
-
-       devc->ctx = drvc->sr_ctx;
-       devc->sent_samples = 0;
-       devc->empty_transfer_count = 0;
-       devc->acq_aborted = FALSE;
-
-       if (configure_channels(sdi) != SR_OK) {
-               sr_err("Failed to configure channels.");
-               return SR_ERR;
-       }
-
-       timeout = fx2lafw_get_timeout(devc);
-       usb_source_add(sdi->session, devc->ctx, timeout, receive_data, drvc);
-
-       size = fx2lafw_get_buffer_size(devc);
-       /* Prepare for analog sampling. */
-       if (g_slist_length(devc->enabled_analog_channels) > 0) {
-               /* We need a buffer half the size of a transfer. */
-               devc->logic_buffer = g_try_malloc(size / 2);
-               devc->analog_buffer = g_try_malloc(
-                       sizeof(float) * size / 2);
-       }
-       start_transfers(sdi);
-       if ((ret = fx2lafw_command_start_acquisition(sdi)) != SR_OK) {
-               fx2lafw_abort_acquisition(devc);
-               return ret;
-       }
-
-       return SR_OK;
-}
-
 static int dev_acquisition_stop(struct sr_dev_inst *sdi)
 {
        fx2lafw_abort_acquisition(sdi->priv);
@@ -776,7 +602,7 @@ static struct sr_dev_driver fx2lafw_driver_info = {
        .config_list = config_list,
        .dev_open = dev_open,
        .dev_close = dev_close,
-       .dev_acquisition_start = dev_acquisition_start,
+       .dev_acquisition_start = fx2lafw_start_acquisition,
        .dev_acquisition_stop = dev_acquisition_stop,
        .context = NULL,
 };
index 9ca749a50bd6f3fea41b254e87121f55bb9a1ffd..95ce4bd3bd581e18459294b0e5ed011c3fa3a52d 100644 (file)
@@ -76,7 +76,7 @@ static int command_get_revid_version(struct sr_dev_inst *sdi, uint8_t *revid)
        return SR_OK;
 }
 
-SR_PRIV int fx2lafw_command_start_acquisition(const struct sr_dev_inst *sdi)
+static int command_start_acquisition(const struct sr_dev_inst *sdi)
 {
        struct dev_context *devc;
        struct sr_usb_dev_inst *usb;
@@ -340,7 +340,7 @@ static void resubmit_transfer(struct libusb_transfer *transfer)
 
 }
 
-SR_PRIV void mso_send_data_proc(struct sr_dev_inst *sdi,
+static void mso_send_data_proc(struct sr_dev_inst *sdi,
        uint8_t *data, size_t length, size_t sample_width)
 {
        size_t i;
@@ -392,7 +392,7 @@ SR_PRIV void mso_send_data_proc(struct sr_dev_inst *sdi,
        sr_session_send(sdi, &analog_packet);
 }
 
-SR_PRIV void la_send_data_proc(struct sr_dev_inst *sdi,
+static void la_send_data_proc(struct sr_dev_inst *sdi,
        uint8_t *data, size_t length, size_t sample_width)
 {
        const struct sr_datafeed_logic logic = {
@@ -409,7 +409,7 @@ SR_PRIV void la_send_data_proc(struct sr_dev_inst *sdi,
        sr_session_send(sdi, &packet);
 }
 
-SR_PRIV void LIBUSB_CALL fx2lafw_receive_transfer(struct libusb_transfer *transfer)
+static void LIBUSB_CALL receive_transfer(struct libusb_transfer *transfer)
 {
        struct sr_dev_inst *sdi;
        struct dev_context *devc;
@@ -504,12 +504,46 @@ SR_PRIV void LIBUSB_CALL fx2lafw_receive_transfer(struct libusb_transfer *transf
                resubmit_transfer(transfer);
 }
 
+static int configure_channels(const struct sr_dev_inst *sdi)
+{
+       struct dev_context *devc;
+       const GSList *l;
+       int p;
+       struct sr_channel *ch;
+       uint32_t channel_mask = 0, num_analog = 0;
+
+       devc = sdi->priv;
+
+       g_slist_free(devc->enabled_analog_channels);
+       devc->enabled_analog_channels = NULL;
+
+       for (l = sdi->channels, p = 0; l; l = l->next, p++) {
+               ch = l->data;
+               if ((p <= NUM_CHANNELS) && (ch->type == SR_CHANNEL_ANALOG)
+                               && (ch->enabled)) {
+                       num_analog++;
+                       devc->enabled_analog_channels =
+                           g_slist_append(devc->enabled_analog_channels, ch);
+               } else {
+                       channel_mask |= ch->enabled << p;
+               }
+       }
+
+       /*
+        * Use wide sampling if either any of the LA channels 8..15 is enabled,
+        * and/or at least one analog channel is enabled.
+        */
+       devc->sample_wide = channel_mask > 0xff || num_analog > 0;
+
+       return SR_OK;
+}
+
 static unsigned int to_bytes_per_ms(unsigned int samplerate)
 {
        return samplerate / 1000;
 }
 
-SR_PRIV size_t fx2lafw_get_buffer_size(struct dev_context *devc)
+static size_t get_buffer_size(struct dev_context *devc)
 {
        size_t s;
 
@@ -521,13 +555,13 @@ SR_PRIV size_t fx2lafw_get_buffer_size(struct dev_context *devc)
        return (s + 511) & ~511;
 }
 
-SR_PRIV unsigned int fx2lafw_get_number_of_transfers(struct dev_context *devc)
+static unsigned int get_number_of_transfers(struct dev_context *devc)
 {
        unsigned int n;
 
        /* Total buffer size should be able to hold about 500ms of data. */
        n = (500 * to_bytes_per_ms(devc->cur_samplerate) /
-               fx2lafw_get_buffer_size(devc));
+               get_buffer_size(devc));
 
        if (n > NUM_SIMUL_TRANSFERS)
                return NUM_SIMUL_TRANSFERS;
@@ -535,13 +569,153 @@ SR_PRIV unsigned int fx2lafw_get_number_of_transfers(struct dev_context *devc)
        return n;
 }
 
-SR_PRIV unsigned int fx2lafw_get_timeout(struct dev_context *devc)
+static unsigned int get_timeout(struct dev_context *devc)
 {
        size_t total_size;
        unsigned int timeout;
 
-       total_size = fx2lafw_get_buffer_size(devc) *
-                       fx2lafw_get_number_of_transfers(devc);
+       total_size = get_buffer_size(devc) *
+                       get_number_of_transfers(devc);
        timeout = total_size / to_bytes_per_ms(devc->cur_samplerate);
        return timeout + timeout / 4; /* Leave a headroom of 25% percent. */
 }
+
+static int receive_data(int fd, int revents, void *cb_data)
+{
+       struct timeval tv;
+       struct drv_context *drvc;
+
+       (void)fd;
+       (void)revents;
+
+       drvc = (struct drv_context *)cb_data;
+
+       tv.tv_sec = tv.tv_usec = 0;
+       libusb_handle_events_timeout(drvc->sr_ctx->libusb_ctx, &tv);
+
+       return TRUE;
+}
+
+static int start_transfers(const struct sr_dev_inst *sdi)
+{
+       struct dev_context *devc;
+       struct sr_usb_dev_inst *usb;
+       struct sr_trigger *trigger;
+       struct libusb_transfer *transfer;
+       unsigned int i, num_transfers;
+       int timeout, ret;
+       unsigned char *buf;
+       size_t size;
+
+       devc = sdi->priv;
+       usb = sdi->conn;
+
+       devc->sent_samples = 0;
+       devc->acq_aborted = FALSE;
+       devc->empty_transfer_count = 0;
+
+       if ((trigger = sr_session_trigger_get(sdi->session))) {
+               int pre_trigger_samples = 0;
+               if (devc->limit_samples > 0)
+                       pre_trigger_samples = devc->capture_ratio * devc->limit_samples/100;
+               devc->stl = soft_trigger_logic_new(sdi, trigger, pre_trigger_samples);
+               if (!devc->stl)
+                       return SR_ERR_MALLOC;
+               devc->trigger_fired = FALSE;
+       } else
+               devc->trigger_fired = TRUE;
+
+       num_transfers = get_number_of_transfers(devc);
+
+       size = get_buffer_size(devc);
+       devc->submitted_transfers = 0;
+
+       devc->transfers = g_try_malloc0(sizeof(*devc->transfers) * num_transfers);
+       if (!devc->transfers) {
+               sr_err("USB transfers malloc failed.");
+               return SR_ERR_MALLOC;
+       }
+
+       timeout = get_timeout(devc);
+       devc->num_transfers = num_transfers;
+       for (i = 0; i < num_transfers; i++) {
+               if (!(buf = g_try_malloc(size))) {
+                       sr_err("USB transfer buffer malloc failed.");
+                       return SR_ERR_MALLOC;
+               }
+               transfer = libusb_alloc_transfer(0);
+               libusb_fill_bulk_transfer(transfer, usb->devhdl,
+                               2 | LIBUSB_ENDPOINT_IN, buf, size,
+                               receive_transfer, (void *)sdi, timeout);
+               sr_info("submitting transfer: %d", i);
+               if ((ret = libusb_submit_transfer(transfer)) != 0) {
+                       sr_err("Failed to submit transfer: %s.",
+                              libusb_error_name(ret));
+                       libusb_free_transfer(transfer);
+                       g_free(buf);
+                       fx2lafw_abort_acquisition(devc);
+                       return SR_ERR;
+               }
+               devc->transfers[i] = transfer;
+               devc->submitted_transfers++;
+       }
+
+       /*
+        * If this device has analog channels and at least one of them is
+        * enabled, use mso_send_data_proc() to properly handle the analog
+        * data. Otherwise use la_send_data_proc().
+        */
+       if (g_slist_length(devc->enabled_analog_channels) > 0)
+               devc->send_data_proc = mso_send_data_proc;
+       else
+               devc->send_data_proc = la_send_data_proc;
+
+       std_session_send_df_header(sdi);
+
+       return SR_OK;
+}
+
+SR_PRIV int fx2lafw_start_acquisition(const struct sr_dev_inst *sdi)
+{
+       struct sr_dev_driver *di;
+       struct drv_context *drvc;
+       struct dev_context *devc;
+       int timeout, ret;
+       size_t size;
+
+       if (sdi->status != SR_ST_ACTIVE)
+               return SR_ERR_DEV_CLOSED;
+
+       di = sdi->driver;
+       drvc = di->context;
+       devc = sdi->priv;
+
+       devc->ctx = drvc->sr_ctx;
+       devc->sent_samples = 0;
+       devc->empty_transfer_count = 0;
+       devc->acq_aborted = FALSE;
+
+       if (configure_channels(sdi) != SR_OK) {
+               sr_err("Failed to configure channels.");
+               return SR_ERR;
+       }
+
+       timeout = get_timeout(devc);
+       usb_source_add(sdi->session, devc->ctx, timeout, receive_data, drvc);
+
+       size = get_buffer_size(devc);
+       /* Prepare for analog sampling. */
+       if (g_slist_length(devc->enabled_analog_channels) > 0) {
+               /* We need a buffer half the size of a transfer. */
+               devc->logic_buffer = g_try_malloc(size / 2);
+               devc->analog_buffer = g_try_malloc(
+                       sizeof(float) * size / 2);
+       }
+       start_transfers(sdi);
+       if ((ret = command_start_acquisition(sdi)) != SR_OK) {
+               fx2lafw_abort_acquisition(devc);
+               return ret;
+       }
+
+       return SR_OK;
+}
index a18696c6055efe3b0a9862b31edede56a61757ef..f5ef67c99bbb3fa2cd8225554bf9d0beb4997561 100644 (file)
@@ -126,17 +126,9 @@ struct dev_context {
        float *analog_buffer;
 };
 
-SR_PRIV int fx2lafw_command_start_acquisition(const struct sr_dev_inst *sdi);
 SR_PRIV int fx2lafw_dev_open(struct sr_dev_inst *sdi, struct sr_dev_driver *di);
 SR_PRIV struct dev_context *fx2lafw_dev_new(void);
+SR_PRIV int fx2lafw_start_acquisition(const struct sr_dev_inst *sdi);
 SR_PRIV void fx2lafw_abort_acquisition(struct dev_context *devc);
-SR_PRIV void LIBUSB_CALL fx2lafw_receive_transfer(struct libusb_transfer *transfer);
-SR_PRIV size_t fx2lafw_get_buffer_size(struct dev_context *devc);
-SR_PRIV unsigned int fx2lafw_get_number_of_transfers(struct dev_context *devc);
-SR_PRIV unsigned int fx2lafw_get_timeout(struct dev_context *devc);
-SR_PRIV void la_send_data_proc(struct sr_dev_inst *sdi, uint8_t *data,
-               size_t length, size_t sample_width);
-SR_PRIV void mso_send_data_proc(struct sr_dev_inst *sdi, uint8_t *data,
-               size_t length, size_t sample_width);
 
 #endif