fx2lafw: Add working glue layer for frontends

This commit is contained in:
Benjamin Larsson 2016-04-25 23:46:19 +02:00 committed by Uwe Hermann
parent 7e5ccff2ec
commit 7fb90f94d6
3 changed files with 82 additions and 24 deletions

View File

@ -133,15 +133,6 @@ static const uint32_t devopts[] = {
SR_CONF_CAPTURE_RATIO | SR_CONF_GET | SR_CONF_SET, SR_CONF_CAPTURE_RATIO | SR_CONF_GET | SR_CONF_SET,
}; };
static const char *channel_names[] = {
"0", "1", "2", "3", "4", "5", "6", "7",
"8", "9", "10", "11", "12", "13", "14", "15",
};
static const char *ax_channel_names[] = {
"A0",
};
static const int32_t soft_trigger_matches[] = { static const int32_t soft_trigger_matches[] = {
SR_TRIGGER_ZERO, SR_TRIGGER_ZERO,
SR_TRIGGER_ONE, SR_TRIGGER_ONE,
@ -201,6 +192,8 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options)
struct dev_context *devc; struct dev_context *devc;
struct sr_dev_inst *sdi; struct sr_dev_inst *sdi;
struct sr_usb_dev_inst *usb; struct sr_usb_dev_inst *usb;
struct sr_channel *ch;
struct sr_channel_group *cg;
struct sr_config *src; struct sr_config *src;
const struct fx2lafw_profile *prof; const struct fx2lafw_profile *prof;
GSList *l, *devices, *conn_devices; GSList *l, *devices, *conn_devices;
@ -212,6 +205,7 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options)
int num_logic_channels = 0, num_analog_channels = 0; int num_logic_channels = 0, num_analog_channels = 0;
const char *conn; const char *conn;
char manufacturer[64], product[64], serial_num[64], connection_id[64]; char manufacturer[64], product[64], serial_num[64], connection_id[64];
char channel_name[16];
drvc = di->context; drvc = di->context;
@ -316,17 +310,33 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options)
num_logic_channels = prof->dev_caps & DEV_CAPS_16BIT ? 16 : 8; num_logic_channels = prof->dev_caps & DEV_CAPS_16BIT ? 16 : 8;
num_analog_channels = prof->dev_caps & DEV_CAPS_AX_ANALOG ? 1 : 0; num_analog_channels = prof->dev_caps & DEV_CAPS_AX_ANALOG ? 1 : 0;
for (j = 0; j < num_logic_channels; j++) /* Logic channels, all in one channel group. */
sr_channel_new(sdi, j, SR_CHANNEL_LOGIC, TRUE, cg = g_malloc0(sizeof(struct sr_channel_group));
channel_names[j]); cg->name = g_strdup("Logic");
for (j = 0; j < num_logic_channels; j++) {
sprintf(channel_name, "D%d", j);
ch = sr_channel_new(sdi, j, SR_CHANNEL_LOGIC,
TRUE, channel_name);
cg->channels = g_slist_append(cg->channels, ch);
}
sdi->channel_groups = g_slist_append(NULL, cg);
for (j = 0; j < num_analog_channels; j++) for (j = 0; j < num_analog_channels; j++) {
sr_channel_new(sdi, j, SR_CHANNEL_ANALOG, TRUE, snprintf(channel_name, 16, "A%d", j);
ax_channel_names[j]); ch = sr_channel_new(sdi, j + num_logic_channels,
SR_CHANNEL_ANALOG, TRUE, channel_name);
/* Every analog channel gets its own channel group. */
cg = g_malloc0(sizeof(struct sr_channel_group));
cg->name = g_strdup(channel_name);
cg->channels = g_slist_append(NULL, ch);
sdi->channel_groups = g_slist_append(sdi->channel_groups, cg);
}
devc = fx2lafw_dev_new(); devc = fx2lafw_dev_new();
devc->profile = prof; devc->profile = prof;
devc->sample_wide = (prof->dev_caps & DEV_CAPS_16BIT) != 0; if ((prof->dev_caps & DEV_CAPS_16BIT) || (prof->dev_caps & DEV_CAPS_AX_ANALOG))
devc->sample_wide = TRUE;
sdi->priv = devc; sdi->priv = devc;
drvc->instances = g_slist_append(drvc->instances, sdi); drvc->instances = g_slist_append(drvc->instances, sdi);
devices = g_slist_append(devices, sdi); devices = g_slist_append(devices, sdi);
@ -375,6 +385,20 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options)
return devices; return devices;
} }
static void clear_dev_context(void *priv)
{
struct dev_context *devc;
devc = priv;
g_slist_free(devc->enabled_analog_channels);
g_free(devc);
}
static int dev_clear(const struct sr_dev_driver *di)
{
return std_dev_clear(di, clear_dev_context);
}
static GSList *dev_list(const struct sr_dev_driver *di) static GSList *dev_list(const struct sr_dev_driver *di)
{ {
return ((struct drv_context *)(di->context))->instances; return ((struct drv_context *)(di->context))->instances;
@ -799,6 +823,31 @@ static int dslogic_trigger_request(const struct sr_dev_inst *sdi)
return ret; return ret;
} }
static int configure_channels(const struct sr_dev_inst *sdi)
{
struct dev_context *devc;
const GSList *l;
int p;
struct sr_channel *ch;
devc = sdi->priv;
g_slist_free(devc->enabled_analog_channels);
devc->enabled_analog_channels = NULL;
memset(devc->ch_enabled, 0, sizeof(devc->ch_enabled));
for (l = sdi->channels, p = 0; l; l = l->next, p++) {
ch = l->data;
if ((p <= NUM_CHANNELS) && (ch->type == SR_CHANNEL_ANALOG)) {
devc->ch_enabled[p] = ch->enabled;
devc->enabled_analog_channels =
g_slist_append(devc->enabled_analog_channels, ch);
}
}
return SR_OK;
}
static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data) static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
{ {
struct sr_dev_driver *di; struct sr_dev_driver *di;
@ -820,6 +869,11 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
devc->empty_transfer_count = 0; devc->empty_transfer_count = 0;
devc->acq_aborted = FALSE; devc->acq_aborted = FALSE;
if (configure_channels(sdi) != SR_OK) {
sr_err("Failed to configure channels.");
return SR_ERR;
}
timeout = fx2lafw_get_timeout(devc); timeout = fx2lafw_get_timeout(devc);
usb_source_add(sdi->session, devc->ctx, timeout, receive_data, drvc); usb_source_add(sdi->session, devc->ctx, timeout, receive_data, drvc);
@ -868,7 +922,7 @@ SR_PRIV struct sr_dev_driver fx2lafw_driver_info = {
.cleanup = cleanup, .cleanup = cleanup,
.scan = scan, .scan = scan,
.dev_list = dev_list, .dev_list = dev_list,
.dev_clear = NULL, .dev_clear = dev_clear,
.config_get = config_get, .config_get = config_get,
.config_set = config_set, .config_set = config_set,
.config_list = config_list, .config_list = config_list,

View File

@ -125,6 +125,8 @@ SR_PRIV int fx2lafw_command_start_acquisition(const struct sr_dev_inst *sdi)
/* Select the sampling width. */ /* Select the sampling width. */
cmd.flags |= devc->sample_wide ? CMD_START_FLAGS_SAMPLE_16BIT : cmd.flags |= devc->sample_wide ? CMD_START_FLAGS_SAMPLE_16BIT :
CMD_START_FLAGS_SAMPLE_8BIT; CMD_START_FLAGS_SAMPLE_8BIT;
/* Enable CTL2 clock. */
cmd.flags |= (devc->profile->dev_caps & DEV_CAPS_AX_ANALOG) ? CMD_START_FLAGS_CLK_CTL2 : 0;
/* Send the control message. */ /* Send the control message. */
ret = libusb_control_transfer(usb->devhdl, LIBUSB_REQUEST_TYPE_VENDOR | ret = libusb_control_transfer(usb->devhdl, LIBUSB_REQUEST_TYPE_VENDOR |
@ -393,12 +395,11 @@ SR_PRIV void mso_send_data_proc(struct dev_context *devc,
sample_width = sample_width; sample_width = sample_width;
length /= 2; length /= 2;
sr_dbg("mso_send_data_proc length = %d", length);
/* Send the logic */ /* Send the logic */
for(i = 0; i < length; i++) { for(i = 0; i < length; i++) {
devc->logic_buffer[i] = data[i * 2]; devc->logic_buffer[i] = data[i * 2];
devc->analog_buffer[i] = data[i * 2 + 1] - 128.0f; /* Rescale to -10V - +10V from 0-255. */
devc->analog_buffer[i] = data[i * 2 + 1] - 128.0f / 12.8f;
}; };
const struct sr_datafeed_logic logic = { const struct sr_datafeed_logic logic = {
@ -414,10 +415,11 @@ SR_PRIV void mso_send_data_proc(struct dev_context *devc,
sr_session_send(devc->cb_data, &logic_packet); sr_session_send(devc->cb_data, &logic_packet);
const struct sr_datafeed_analog_old analog = { const struct sr_datafeed_analog_old analog = {
.channels = devc->enabled_analog_channels,
.num_samples = length, .num_samples = length,
.mq = SR_MQ_VOLTAGE, .mq = SR_MQ_VOLTAGE,
.unit = SR_UNIT_VOLT, .unit = SR_UNIT_VOLT,
.mqflags = SR_MQFLAG_DC, .mqflags = 0 /*SR_MQFLAG_DC*/,
.data = devc->analog_buffer .data = devc->analog_buffer
}; };
@ -425,8 +427,6 @@ SR_PRIV void mso_send_data_proc(struct dev_context *devc,
.type = SR_DF_ANALOG_OLD, .type = SR_DF_ANALOG_OLD,
.payload = &analog .payload = &analog
}; };
sr_dbg("mso_send_data_proc length = %d", length);
sr_session_send(devc->cb_data, &analog_packet); sr_session_send(devc->cb_data, &analog_packet);
} }

View File

@ -39,6 +39,8 @@
#define NUM_SIMUL_TRANSFERS 32 #define NUM_SIMUL_TRANSFERS 32
#define MAX_EMPTY_TRANSFERS (NUM_SIMUL_TRANSFERS * 2) #define MAX_EMPTY_TRANSFERS (NUM_SIMUL_TRANSFERS * 2)
#define NUM_CHANNELS 16
#define FX2LAFW_REQUIRED_VERSION_MAJOR 1 #define FX2LAFW_REQUIRED_VERSION_MAJOR 1
#define MAX_8BIT_SAMPLE_RATE SR_MHZ(24) #define MAX_8BIT_SAMPLE_RATE SR_MHZ(24)
@ -66,7 +68,7 @@
#define CMD_START_FLAGS_WIDE_POS 5 #define CMD_START_FLAGS_WIDE_POS 5
#define CMD_START_FLAGS_CLK_SRC_POS 6 #define CMD_START_FLAGS_CLK_SRC_POS 6
#define CMD_START_FLAGS_CLK_CTL2 (1 << CMD_START_FLAGS_CLK_CTL2) #define CMD_START_FLAGS_CLK_CTL2 (1 << CMD_START_FLAGS_CLK_CTL2_POS)
#define CMD_START_FLAGS_SAMPLE_8BIT (0 << CMD_START_FLAGS_WIDE_POS) #define CMD_START_FLAGS_SAMPLE_8BIT (0 << CMD_START_FLAGS_WIDE_POS)
#define CMD_START_FLAGS_SAMPLE_16BIT (1 << CMD_START_FLAGS_WIDE_POS) #define CMD_START_FLAGS_SAMPLE_16BIT (1 << CMD_START_FLAGS_WIDE_POS)
@ -91,6 +93,8 @@ struct fx2lafw_profile {
struct dev_context { struct dev_context {
const struct fx2lafw_profile *profile; const struct fx2lafw_profile *profile;
GSList *enabled_analog_channels;
gboolean ch_enabled[NUM_CHANNELS];
/* /*
* Since we can't keep track of an fx2lafw device after upgrading * Since we can't keep track of an fx2lafw device after upgrading
* the firmware (it renumerates into a different device address * the firmware (it renumerates into a different device address