fx2lafw: Add working glue layer for frontends
This commit is contained in:
parent
7e5ccff2ec
commit
7fb90f94d6
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue