]> sigrok.org Git - libsigrok.git/blobdiff - src/hardware/pipistrello-ols/protocol.c
uni-t-ut181a: silence compiler warning, use of uninitialized variable
[libsigrok.git] / src / hardware / pipistrello-ols / protocol.c
index 45ffad009a6fe53af6dad39ce1de1ae207cc29f6..f0ef680527abc48d925f9dae6b9bbcb1adeb5add 100644 (file)
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <config.h>
 #include "protocol.h"
 
-extern SR_PRIV struct sr_dev_driver p_ols_driver_info;
-static struct sr_dev_driver *di = &p_ols_driver_info;
-
 SR_PRIV int write_shortcommand(struct dev_context *devc, uint8_t command)
 {
        uint8_t buf[1];
@@ -75,16 +73,13 @@ SR_PRIV int p_ols_open(struct dev_context *devc)
 
        /* Note: Caller checks devc and devc->ftdic. */
 
-       /* Select interface B, otherwise communication will fail. */
        ret = ftdi_set_interface(devc->ftdic, INTERFACE_B);
        if (ret < 0) {
                sr_err("Failed to set FTDI interface B (%d): %s", ret,
                       ftdi_get_error_string(devc->ftdic));
                return SR_ERR;
        }
-       sr_dbg("FTDI chip interface B set successfully.");
 
-       /* Check for the device and temporarily open it. */
        ret = ftdi_usb_open_desc(devc->ftdic, USB_VENDOR_ID, USB_DEVICE_ID,
                                 USB_IPRODUCT, NULL);
        if (ret < 0) {
@@ -94,47 +89,39 @@ SR_PRIV int p_ols_open(struct dev_context *devc)
                               ftdi_get_error_string(devc->ftdic));
                return SR_ERR;
        }
-       sr_dbg("FTDI device opened successfully.");
 
-       /* Purge RX/TX buffers in the FTDI chip. */
        if ((ret = ftdi_usb_purge_buffers(devc->ftdic)) < 0) {
                sr_err("Failed to purge FTDI RX/TX buffers (%d): %s.",
                       ret, ftdi_get_error_string(devc->ftdic));
                goto err_open_close_ftdic;
        }
-       sr_dbg("FTDI chip buffers purged successfully.");
 
-       /* Reset the FTDI bitmode. */
        ret = ftdi_set_bitmode(devc->ftdic, 0xff, BITMODE_RESET);
        if (ret < 0) {
                sr_err("Failed to reset the FTDI chip bitmode (%d): %s.",
                       ret, ftdi_get_error_string(devc->ftdic));
                goto err_open_close_ftdic;
        }
-       sr_dbg("FTDI chip bitmode reset successfully.");
 
-       /* Set the FTDI latency timer to 16. */
        ret = ftdi_set_latency_timer(devc->ftdic, 16);
        if (ret < 0) {
                sr_err("Failed to set FTDI latency timer (%d): %s.",
                       ret, ftdi_get_error_string(devc->ftdic));
                goto err_open_close_ftdic;
        }
-       sr_dbg("FTDI chip latency timer set successfully.");
 
-       /* Set the FTDI read data chunk size to 64kB. */
        ret = ftdi_read_data_set_chunksize(devc->ftdic, 64 * 1024);
        if (ret < 0) {
                sr_err("Failed to set FTDI read data chunk size (%d): %s.",
                       ret, ftdi_get_error_string(devc->ftdic));
                goto err_open_close_ftdic;
        }
-       sr_dbg("FTDI chip read data chunk size set successfully.");
-       
+
        return SR_OK;
 
 err_open_close_ftdic:
        ftdi_usb_close(devc->ftdic);
+
        return SR_ERR;
 }
 
@@ -153,59 +140,64 @@ SR_PRIV int p_ols_close(struct dev_context *devc)
        return SR_OK;
 }
 
-SR_PRIV int p_ols_configure_channels(const struct sr_dev_inst *sdi)
+/* Configures the channel mask based on which channels are enabled. */
+SR_PRIV void pols_channel_mask(const struct sr_dev_inst *sdi)
 {
        struct dev_context *devc;
-       const struct sr_channel *ch;
+       struct sr_channel *channel;
        const GSList *l;
-       int channel_bit, stage, i;
-       char *tc;
 
        devc = sdi->priv;
 
        devc->channel_mask = 0;
+       for (l = sdi->channels; l; l = l->next) {
+               channel = l->data;
+               if (channel->enabled)
+                       devc->channel_mask |= 1 << channel->index;
+       }
+}
+
+SR_PRIV int pols_convert_trigger(const struct sr_dev_inst *sdi)
+{
+       struct dev_context *devc;
+       struct sr_trigger *trigger;
+       struct sr_trigger_stage *stage;
+       struct sr_trigger_match *match;
+       const GSList *l, *m;
+       int i;
+
+       devc = sdi->priv;
+
+       devc->num_stages = 0;
        for (i = 0; i < NUM_TRIGGER_STAGES; i++) {
                devc->trigger_mask[i] = 0;
                devc->trigger_value[i] = 0;
                devc->trigger_edge[i] = 0;
        }
 
-       devc->num_stages = 0;
-       for (l = sdi->channels; l; l = l->next) {
-               ch = (const struct sr_channel *)l->data;
-               if (!ch->enabled)
-                       continue;
+       if (!(trigger = sr_session_trigger_get(sdi->session)))
+               return SR_OK;
 
-               if (ch->index >= devc->max_channels) {
-                       sr_err("Channels over the limit of %d\n", devc->max_channels);
-                       return SR_ERR;
-               }
+       devc->num_stages = g_slist_length(trigger->stages);
+       if (devc->num_stages > NUM_TRIGGER_STAGES) {
+               sr_err("This device only supports %d trigger stages.",
+                               NUM_TRIGGER_STAGES);
+               return SR_ERR;
+       }
 
-               /*
-                * Set up the channel mask for later configuration into the
-                * flag register.
-                */
-               channel_bit = 1 << (ch->index);
-               devc->channel_mask |= channel_bit;
-
-               if (!ch->trigger)
-                       continue;
-
-               /* Configure trigger mask and value. */
-               stage = 0;
-               for (tc = ch->trigger; tc && *tc; tc++) {
-                       devc->trigger_mask[stage] |= channel_bit;
-                       if ((*tc == '1') || (*tc == 'r'))
-                               devc->trigger_value[stage] |= channel_bit;
-                       if ((*tc == 'r') || (*tc == 'f'))
-                               devc->trigger_edge[stage] |= channel_bit;
-                       stage++;
-                       /* Only supporting parallel mode, with up to 4 stages. */
-                       if (stage > 3)
-                               return SR_ERR;
+       for (l = trigger->stages; l; l = l->next) {
+               stage = l->data;
+               for (m = stage->matches; m; m = m->next) {
+                       match = m->data;
+                       if (!match->channel->enabled)
+                               /* Ignore disabled channels with a trigger. */
+                               continue;
+                       devc->trigger_mask[stage->stage] |= 1 << match->channel->index;
+                       if (match->match == SR_TRIGGER_ONE || match->match == SR_TRIGGER_RISING)
+                               devc->trigger_value[stage->stage] |= 1 << match->channel->index;
+                       if (match->match == SR_TRIGGER_RISING || match->match == SR_TRIGGER_FALLING)
+                               devc->trigger_edge[stage->stage] |= 1 << match->channel->index;
                }
-               if (stage > devc->num_stages)
-                       devc->num_stages = stage - 1;
        }
 
        return SR_OK;
@@ -214,15 +206,14 @@ SR_PRIV int p_ols_configure_channels(const struct sr_dev_inst *sdi)
 SR_PRIV struct sr_dev_inst *p_ols_get_metadata(uint8_t *buf, int bytes_read, struct dev_context *devc)
 {
        struct sr_dev_inst *sdi;
-       struct sr_channel *ch;
        uint32_t tmp_int, ui;
        uint8_t key, type, token;
        GString *tmp_str, *devname, *version;
        guchar tmp_c;
-       int index, i;
+       int index;
 
-       sdi = sr_dev_inst_new(0, SR_ST_INACTIVE, NULL, NULL, NULL);
-       sdi->driver = di;
+       sdi = g_malloc0(sizeof(struct sr_dev_inst));
+       sdi->status = SR_ST_INACTIVE;
        sdi->priv = devc;
 
        devname = g_string_new("");
@@ -273,21 +264,16 @@ SR_PRIV struct sr_dev_inst *p_ols_get_metadata(uint8_t *buf, int bytes_read, str
                        break;
                case 1:
                        /* 32-bit unsigned integer */
-                       tmp_int = 0;
-                       for (i = 0; i < 4; i++) {
-                               tmp_int = (tmp_int << 8) | buf[index++];
-                       }
+                       tmp_int = RB32(&buf[index]);
+                       index += sizeof(uint32_t);
                        sr_dbg("Got metadata key 0x%.2x value 0x%.8x.",
                               key, tmp_int);
                        switch (token) {
                        case 0x00:
                                /* Number of usable channels */
-                               for (ui = 0; ui < tmp_int; ui++) {
-                                       if (!(ch = sr_channel_new(ui, SR_CHANNEL_LOGIC, TRUE,
-                                                       p_ols_channel_names[ui])))
-                                               return 0;
-                                       sdi->channels = g_slist_append(sdi->channels, ch);
-                               }
+                               for (ui = 0; ui < tmp_int; ui++)
+                                       sr_channel_new(sdi, ui, SR_CHANNEL_LOGIC, TRUE,
+                                                       p_ols_channel_names[ui]);
                                break;
                        case 0x01:
                                /* Amount of sample memory available (bytes) */
@@ -298,7 +284,7 @@ SR_PRIV struct sr_dev_inst *p_ols_get_metadata(uint8_t *buf, int bytes_read, str
                                /* what is this for? */
                                break;
                        case 0x03:
-                               /* Maximum sample rate (hz) */
+                               /* Maximum sample rate (Hz) */
                                devc->max_samplerate = tmp_int;
                                break;
                        case 0x04:
@@ -319,12 +305,9 @@ SR_PRIV struct sr_dev_inst *p_ols_get_metadata(uint8_t *buf, int bytes_read, str
                        switch (token) {
                        case 0x00:
                                /* Number of usable channels */
-                               for (ui = 0; ui < tmp_c; ui++) {
-                                       if (!(ch = sr_channel_new(ui, SR_CHANNEL_LOGIC, TRUE,
-                                                       p_ols_channel_names[ui])))
-                                               return 0;
-                                       sdi->channels = g_slist_append(sdi->channels, ch);
-                               }
+                               for (ui = 0; ui < tmp_c; ui++)
+                                       sr_channel_new(sdi, ui, SR_CHANNEL_LOGIC, TRUE,
+                                                       p_ols_channel_names[ui]);
                                break;
                        case 0x01:
                                /* protocol version */
@@ -386,7 +369,6 @@ SR_PRIV int p_ols_set_samplerate(const struct sr_dev_inst *sdi,
        return SR_OK;
 }
 
-
 SR_PRIV int p_ols_receive_data(int fd, int revents, void *cb_data)
 {
        struct dev_context *devc;
@@ -423,14 +405,13 @@ SR_PRIV int p_ols_receive_data(int fd, int revents, void *cb_data)
                                num_channels++;
                        }
                }
-               sr_dbg("num_channels = %d", num_channels);
 
                /* Get a block of data. */
                bytes_read = ftdi_read_data(devc->ftdic, devc->ftdi_buf, FTDI_BUF_SIZE);
                if (bytes_read < 0) {
                        sr_err("Failed to read FTDI data (%d): %s.",
                               bytes_read, ftdi_get_error_string(devc->ftdic));
-                       sdi->driver->dev_acquisition_stop(sdi, sdi);
+                       sr_dev_acquisition_stop(sdi);
                        return FALSE;
                }
                if (bytes_read == 0) {
@@ -449,7 +430,7 @@ SR_PRIV int p_ols_receive_data(int fd, int revents, void *cb_data)
                        sr_spew("Received byte 0x%.2x.", byte);
 
                        if ((devc->flag_reg & FLAG_DEMUX) && (devc->flag_reg & FLAG_RLE)) {
-                               /* RLE in demux mode must be processed differently 
+                               /* RLE in demux mode must be processed differently
                                * since in this case the RLE encoder is operating on pairs of samples.
                                */
                                if (devc->num_bytes == num_channels * 2) {
@@ -505,11 +486,13 @@ SR_PRIV int p_ols_receive_data(int fd, int revents, void *cb_data)
                                                         * sample.
                                                         */
                                                        devc->tmp_sample[i] = devc->sample[j++];
-                                               } 
+                                               }
                                        }
                                        /* Clear out the most significant bit of the sample */
                                        devc->tmp_sample[devc->num_bytes - 1] &= 0x7f;
-                                       sr_spew("Expanded sample 1: 0x%.8x.", devc->tmp_sample);
+                                       sr_spew("Expanded sample 1: 0x%.2x%.2x%.2x%.2x.",
+                                               devc->tmp_sample[3], devc->tmp_sample[2],
+                                               devc->tmp_sample[1], devc->tmp_sample[0]);
 
                                        /* expand second sample */
                                        memset(devc->tmp_sample2, 0, 4);
@@ -521,11 +504,13 @@ SR_PRIV int p_ols_receive_data(int fd, int revents, void *cb_data)
                                                         * sample.
                                                         */
                                                        devc->tmp_sample2[i] = devc->sample[j++];
-                                               } 
+                                               }
                                        }
                                        /* Clear out the most significant bit of the sample */
                                        devc->tmp_sample2[devc->num_bytes - 1] &= 0x7f;
-                                       sr_spew("Expanded sample 2: 0x%.8x.", devc->tmp_sample2);
+                                       sr_spew("Expanded sample 2: 0x%.2x%.2x%.2x%.2x.",
+                                               devc->tmp_sample2[3], devc->tmp_sample2[2],
+                                               devc->tmp_sample2[1], devc->tmp_sample2[0]);
 
                                        /*
                                         * OLS sends its sample buffer backwards.
@@ -599,7 +584,7 @@ SR_PRIV int p_ols_receive_data(int fd, int revents, void *cb_data)
                                                                 * sample.
                                                                 */
                                                                devc->tmp_sample[i] = devc->sample[j++];
-                                                       } 
+                                                       }
                                                }
                                                memcpy(devc->sample, devc->tmp_sample, 4);
                                                sr_spew("Expanded sample: 0x%.8x.", sample);
@@ -623,8 +608,9 @@ SR_PRIV int p_ols_receive_data(int fd, int revents, void *cb_data)
                }
                return TRUE;
        } else {
-               do bytes_read = ftdi_read_data(devc->ftdic, devc->ftdi_buf, FTDI_BUF_SIZE);
-               while (bytes_read > 0);
+               do {
+                       bytes_read = ftdi_read_data(devc->ftdic, devc->ftdi_buf, FTDI_BUF_SIZE);
+               } while (bytes_read > 0);
 
                /*
                 * We've acquired all the samples we asked for -- we're done.
@@ -646,12 +632,11 @@ SR_PRIV int p_ols_receive_data(int fd, int revents, void *cb_data)
                                logic.unitsize = 4;
                                logic.data = devc->raw_sample_buf +
                                        (devc->limit_samples - devc->num_samples) * 4;
-                               sr_session_send(cb_data, &packet);
+                               sr_session_send(sdi, &packet);
                        }
 
                        /* Send the trigger. */
-                       packet.type = SR_DF_TRIGGER;
-                       sr_session_send(cb_data, &packet);
+                       std_session_send_df_trigger(sdi);
 
                        /* Send post-trigger samples. */
                        packet.type = SR_DF_LOGIC;
@@ -660,7 +645,7 @@ SR_PRIV int p_ols_receive_data(int fd, int revents, void *cb_data)
                        logic.unitsize = 4;
                        logic.data = devc->raw_sample_buf + devc->trigger_at * 4 +
                                (devc->limit_samples - devc->num_samples) * 4;
-                       sr_session_send(cb_data, &packet);
+                       sr_session_send(sdi, &packet);
                } else {
                        /* no trigger was used */
                        packet.type = SR_DF_LOGIC;
@@ -669,11 +654,11 @@ SR_PRIV int p_ols_receive_data(int fd, int revents, void *cb_data)
                        logic.unitsize = 4;
                        logic.data = devc->raw_sample_buf +
                                (devc->limit_samples - devc->num_samples) * 4;
-                       sr_session_send(cb_data, &packet);
+                       sr_session_send(sdi, &packet);
                }
                g_free(devc->raw_sample_buf);
 
-               sdi->driver->dev_acquisition_stop(sdi, cb_data);
+               sr_dev_acquisition_stop(sdi);
        }
 
        return TRUE;