X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fhardware%2Fpipistrello-ols%2Fprotocol.c;h=62515050511b67ead751998e9f7bdd44ee100cc0;hb=a9ed2eb06953eb34fb019ae9a80e213c75790fab;hp=5e8d721ff0c4b89628be16aaa5dc9a3c12830ee7;hpb=1f9bcd0f946a0a55275357143e259ff402619444;p=libsigrok.git
diff --git a/src/hardware/pipistrello-ols/protocol.c b/src/hardware/pipistrello-ols/protocol.c
index 5e8d721f..62515050 100644
--- a/src/hardware/pipistrello-ols/protocol.c
+++ b/src/hardware/pipistrello-ols/protocol.c
@@ -17,11 +17,9 @@
* along with this program. If not, see .
*/
+#include
#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,56 +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')
- devc->trigger_value[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;
@@ -211,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("");
@@ -270,32 +264,27 @@ 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) */
- devc->max_samples = tmp_int;
+ devc->max_samplebytes = tmp_int;
break;
case 0x02:
/* Amount of dynamic memory available (bytes) */
/* what is this for? */
break;
case 0x03:
- /* Maximum sample rate (hz) */
+ /* Maximum sample rate (Hz) */
devc->max_samplerate = tmp_int;
break;
case 0x04:
@@ -316,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 */
@@ -383,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;
@@ -412,7 +397,7 @@ SR_PRIV int p_ols_receive_data(int fd, int revents, void *cb_data)
memset(devc->raw_sample_buf, 0x82, devc->limit_samples * 4);
}
- if (devc->num_samples < devc->limit_samples) {
+ if ((devc->num_samples < devc->limit_samples) && (devc->cnt_samples < devc->max_samples)) {
num_channels = 0;
for (i = NUM_CHANNELS; i > 0x02; i /= 2) {
@@ -426,7 +411,7 @@ SR_PRIV int p_ols_receive_data(int fd, int revents, void *cb_data)
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) {
@@ -443,40 +428,44 @@ SR_PRIV int p_ols_receive_data(int fd, int revents, void *cb_data)
devc->sample[devc->num_bytes++] = byte;
sr_spew("Received byte 0x%.2x.", byte);
- if (devc->num_bytes == num_channels) {
- devc->cnt_samples++;
- devc->cnt_samples_rle++;
- /*
- * Got a full sample. Convert from the OLS's little-endian
- * sample to the local format.
- */
- sample = devc->sample[0] | (devc->sample[1] << 8) \
- | (devc->sample[2] << 16) | (devc->sample[3] << 24);
- sr_spew("Received sample 0x%.*x.", devc->num_bytes * 2, sample);
- if (devc->flag_reg & FLAG_RLE) {
+
+ if ((devc->flag_reg & FLAG_DEMUX) && (devc->flag_reg & FLAG_RLE)) {
+ /* 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) {
+ devc->cnt_samples += 2;
+ devc->cnt_samples_rle += 2;
+ /*
+ * Got a sample pair. Convert from the OLS's little-endian
+ * sample to the local format.
+ */
+ sample = devc->sample[0] | (devc->sample[1] << 8) \
+ | (devc->sample[2] << 16) | (devc->sample[3] << 24);
+ sr_spew("Received sample pair 0x%.*x.", devc->num_bytes * 2, sample);
+
/*
- * In RLE mode the high bit of the sample is the
- * "count" flag, meaning this sample is the number
- * of times the previous sample occurred.
+ * In RLE mode the high bit of the sample pair is the
+ * "count" flag, meaning this sample pair is the number
+ * of times the previous sample pair occurred.
*/
if (devc->sample[devc->num_bytes - 1] & 0x80) {
/* Clear the high bit. */
sample &= ~(0x80 << (devc->num_bytes - 1) * 8);
devc->rle_count = sample;
- devc->cnt_samples_rle += devc->rle_count;
- sr_dbg("RLE count: %u.", devc->rle_count);
+ devc->cnt_samples_rle += devc->rle_count * 2;
+ sr_dbg("RLE count: %u.", devc->rle_count * 2);
devc->num_bytes = 0;
continue;
}
- }
- devc->num_samples += devc->rle_count + 1;
- if (devc->num_samples > devc->limit_samples) {
- /* Save us from overrunning the buffer. */
- devc->rle_count -= devc->num_samples - devc->limit_samples;
- devc->num_samples = devc->limit_samples;
- }
+ devc->num_samples += (devc->rle_count + 1) * 2;
+ if (devc->num_samples > devc->limit_samples) {
+ /* Save us from overrunning the buffer. */
+ devc->rle_count -= (devc->num_samples - devc->limit_samples) / 2;
+ devc->num_samples = devc->limit_samples;
+ index = bytes_read;
+ }
- if (num_channels < 4) {
/*
* Some channel groups may have been turned
* off, to speed up transfer between the
@@ -487,8 +476,9 @@ SR_PRIV int p_ols_receive_data(int fd, int revents, void *cb_data)
* the number of channels.
*/
j = 0;
+ /* expand first sample */
memset(devc->tmp_sample, 0, 4);
- for (i = 0; i < 4; i++) {
+ for (i = 0; i < 2; i++) {
if (((devc->flag_reg >> 2) & (1 << i)) == 0) {
/*
* This channel group was
@@ -496,32 +486,132 @@ SR_PRIV int p_ols_receive_data(int fd, int revents, void *cb_data)
* sample.
*/
devc->tmp_sample[i] = devc->sample[j++];
- } else if (devc->flag_reg & FLAG_DEMUX && (i > 2)) {
- /* group 2 & 3 get added to 0 & 1 */
- devc->tmp_sample[i - 2] = devc->sample[j++];
}
}
- memcpy(devc->sample, devc->tmp_sample, 4);
- sr_spew("Expanded sample: 0x%.8x.", sample);
+ /* Clear out the most significant bit of the sample */
+ devc->tmp_sample[devc->num_bytes - 1] &= 0x7f;
+ 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);
+ for (i = 0; i < 2; i++) {
+ if (((devc->flag_reg >> 2) & (1 << i)) == 0) {
+ /*
+ * This channel group was
+ * enabled, copy from received
+ * 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%.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.
+ * store it in reverse order here, so we can dump
+ * this on the session bus later.
+ */
+ offset = (devc->limit_samples - devc->num_samples) * 4;
+ for (i = 0; i <= devc->rle_count; i++) {
+ memcpy(devc->raw_sample_buf + offset + (i * 8),
+ devc->tmp_sample2, 4);
+ memcpy(devc->raw_sample_buf + offset + (4 + (i * 8)),
+ devc->tmp_sample, 4);
+ }
+ memset(devc->sample, 0, 4);
+ devc->num_bytes = 0;
+ devc->rle_count = 0;
}
+ }
+ else {
+ if (devc->num_bytes == num_channels) {
+ devc->cnt_samples++;
+ devc->cnt_samples_rle++;
+ /*
+ * Got a full sample. Convert from the OLS's little-endian
+ * sample to the local format.
+ */
+ sample = devc->sample[0] | (devc->sample[1] << 8) \
+ | (devc->sample[2] << 16) | (devc->sample[3] << 24);
+ sr_spew("Received sample 0x%.*x.", devc->num_bytes * 2, sample);
+ if (devc->flag_reg & FLAG_RLE) {
+ /*
+ * In RLE mode the high bit of the sample is the
+ * "count" flag, meaning this sample is the number
+ * of times the previous sample occurred.
+ */
+ if (devc->sample[devc->num_bytes - 1] & 0x80) {
+ /* Clear the high bit. */
+ sample &= ~(0x80 << (devc->num_bytes - 1) * 8);
+ devc->rle_count = sample;
+ devc->cnt_samples_rle += devc->rle_count;
+ sr_dbg("RLE count: %u.", devc->rle_count);
+ devc->num_bytes = 0;
+ continue;
+ }
+ }
+ devc->num_samples += devc->rle_count + 1;
+ if (devc->num_samples > devc->limit_samples) {
+ /* Save us from overrunning the buffer. */
+ devc->rle_count -= devc->num_samples - devc->limit_samples;
+ devc->num_samples = devc->limit_samples;
+ index = bytes_read;
+ }
- /*
- * Pipistrello OLS sends its sample buffer backwards.
- * store it in reverse order here, so we can dump
- * this on the session bus later.
- */
- offset = (devc->limit_samples - devc->num_samples) * 4;
- for (i = 0; i <= devc->rle_count; i++) {
- memcpy(devc->raw_sample_buf + offset + (i * 4),
- devc->sample, 4);
+ if (num_channels < 4) {
+ /*
+ * Some channel groups may have been turned
+ * off, to speed up transfer between the
+ * hardware and the PC. Expand that here before
+ * submitting it over the session bus --
+ * whatever is listening on the bus will be
+ * expecting a full 32-bit sample, based on
+ * the number of channels.
+ */
+ j = 0;
+ memset(devc->tmp_sample, 0, 4);
+ for (i = 0; i < 4; i++) {
+ if (((devc->flag_reg >> 2) & (1 << i)) == 0) {
+ /*
+ * This channel group was
+ * enabled, copy from received
+ * sample.
+ */
+ devc->tmp_sample[i] = devc->sample[j++];
+ }
+ }
+ memcpy(devc->sample, devc->tmp_sample, 4);
+ sr_spew("Expanded sample: 0x%.8x.", sample);
+ }
+
+ /*
+ * Pipistrello OLS sends its sample buffer backwards.
+ * store it in reverse order here, so we can dump
+ * this on the session bus later.
+ */
+ offset = (devc->limit_samples - devc->num_samples) * 4;
+ for (i = 0; i <= devc->rle_count; i++) {
+ memcpy(devc->raw_sample_buf + offset + (i * 4),
+ devc->sample, 4);
+ }
+ memset(devc->sample, 0, 4);
+ devc->num_bytes = 0;
+ devc->rle_count = 0;
}
- memset(devc->sample, 0, 4);
- devc->num_bytes = 0;
- devc->rle_count = 0;
}
}
return TRUE;
} else {
+ 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.
* Send the (properly-ordered) buffer to the frontend.
@@ -542,12 +632,12 @@ 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);
+ sr_session_send(sdi, &packet);
/* Send post-trigger samples. */
packet.type = SR_DF_LOGIC;
@@ -556,7 +646,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;
@@ -565,11 +655,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;