#include "sigrok.h"
#include "sigrok-internal.h"
#include "fx2lafw.h"
+#include "command.h"
static struct fx2lafw_profile supported_fx2[] = {
- /* USBee AX */
+ /* CWAV USBee AX
+ * EE Electronics ESLA201A
+ */
{ 0x08a9, 0x0014, "CWAV", "USBee AX", NULL, 8 },
{ 0, 0, 0, 0, 0, 0 }
};
static GSList *dev_insts = NULL;
static libusb_context *usb_context = NULL;
-static int hw_dev_acquisition_stop(int dev_index, gpointer session_dev_id);
+static int hw_dev_config_set(int dev_index, int hwcap, void *value);
+static int hw_dev_acquisition_stop(int dev_index, void *session_dev_id);
/**
* Check the USB configuration to determine if this is an fx2lafw device.
break;
intf_dsc = &(conf_dsc->interface[0].altsetting[0]);
- if (intf_dsc->bNumEndpoints != 3)
- /* Need exactly 3 end points. */
+ if (intf_dsc->bNumEndpoints != 2)
+ /* Need exactly 2 end points. */
break;
if ((intf_dsc->endpoint[0].bEndpointAddress & 0x8f) !=
- (1 | LIBUSB_ENDPOINT_OUT))
- /* The first endpoint should be 1 (outbound). */
- break;
-
- if ((intf_dsc->endpoint[1].bEndpointAddress & 0x8f) !=
- (2 | LIBUSB_ENDPOINT_IN))
- /* The second endpoint should be 2 (inbound). */
+ (2 | LIBUSB_ENDPOINT_IN)) // 0x82
+ /* The first endpoint should be 2 (inbound). */
break;
/* TODO: Check the debug channel... */
continue;
}
- if (des.idVendor != FIRMWARE_VID
- || des.idProduct != FIRMWARE_PID)
+ if (des.idVendor != ctx->profile->vid
+ || des.idProduct != ctx->profile->pid)
continue;
if (sdi->status == SR_ST_INITIALIZING) {
return SR_ERR;
}
+ if (ctx->cur_samplerate == 0) {
+ /* Samplerate hasn't been set; default to the slowest one. */
+ if (hw_dev_config_set(dev_index, SR_HWCAP_SAMPLERATE,
+ &fx2lafw_supported_samplerates[0]) == SR_ERR)
+ return SR_ERR;
+ }
+
return SR_OK;
}
if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) {
sr_err("fx2lafw: %s: sdi was NULL", __func__);
- return SR_ERR; /* TODO: SR_ERR_ARG? */
+ return SR_ERR_BUG;
}
/* TODO */
return &fx2lafw_samplerates;
case SR_DI_TRIGGER_TYPES:
return TRIGGER_TYPES;
+ case SR_DI_CUR_SAMPLERATE:
+ return &ctx->cur_samplerate;
}
return NULL;
return SR_ERR;
ctx = sdi->priv;
- if (hwcap == SR_HWCAP_LIMIT_SAMPLES) {
+ if (hwcap == SR_HWCAP_SAMPLERATE) {
+ ctx->cur_samplerate = *(uint64_t *)value;
+ ret = SR_OK;
+ } else if (hwcap == SR_HWCAP_PROBECONFIG) {
+ ret = SR_OK;
+ } else if (hwcap == SR_HWCAP_LIMIT_SAMPLES) {
ctx->limit_samples = *(uint64_t *)value;
ret = SR_OK;
} else {
return ret;
}
-static int receive_data(int fd, int revents, void *user_data)
+static int receive_data(int fd, int revents, void *cb_data)
{
struct timeval tv;
/* Avoid compiler warnings. */
(void)fd;
(void)revents;
- (void)user_data;
+ (void)cb_data;
tv.tv_sec = tv.tv_usec = 0;
libusb_handle_events_timeout(usb_context, &tv);
return TRUE;
}
+static void abort_acquisition(struct context *ctx)
+{
+ struct sr_datafeed_packet packet;
+
+ packet.type = SR_DF_END;
+ sr_session_send(ctx->session_dev_id, &packet);
+
+ ctx->num_samples = -1;
+
+ /* TODO: Need to cancel and free any queued up transfers. */
+}
+
static void receive_transfer(struct libusb_transfer *transfer)
{
/* TODO: These statics have to move to the ctx struct. */
- static int num_samples = 0;
static int empty_transfer_count = 0;
struct sr_datafeed_packet packet;
struct sr_datafeed_logic logic;
- struct context *ctx;
+ struct context *ctx = transfer->user_data;
int cur_buflen;
unsigned char *cur_buf, *new_buf;
- /* hw_dev_acquisition_stop() is telling us to stop. */
- if (transfer == NULL)
- num_samples = -1;
-
/*
* If acquisition has already ended, just free any queued up
* transfer that come in.
*/
- if (num_samples == -1) {
+ if (ctx->num_samples == -1) {
if (transfer)
libusb_free_transfer(transfer);
return;
* The FX2 gave up. End the acquisition, the frontend
* will work out that the samplecount is short.
*/
- hw_dev_acquisition_stop(-1, ctx->session_data);
+ abort_acquisition(ctx);
}
return;
} else {
logic.length = cur_buflen;
logic.unitsize = 1;
logic.data = cur_buf;
- sr_session_bus(ctx->session_data, &packet);
+ sr_session_send(ctx->session_dev_id, &packet);
g_free(cur_buf);
- num_samples += cur_buflen;
+ ctx->num_samples += cur_buflen;
if (ctx->limit_samples &&
- (unsigned int) num_samples > ctx->limit_samples) {
- hw_dev_acquisition_stop(-1, ctx->session_data);
+ (unsigned int) ctx->num_samples > ctx->limit_samples) {
+ abort_acquisition(ctx);
}
}
-static int hw_dev_acquisition_start(int dev_index, gpointer session_data)
+static int hw_dev_acquisition_start(int dev_index, void *cb_data)
{
struct sr_dev_inst *sdi;
struct sr_datafeed_packet *packet;
struct context *ctx;
struct libusb_transfer *transfer;
const struct libusb_pollfd **lupfd;
- int size, i;
+ int err, size, i;
unsigned char *buf;
if (!(sdi = sr_dev_inst_get(dev_insts, dev_index)))
return SR_ERR;
ctx = sdi->priv;
- ctx->session_data = session_data;
+ ctx->session_dev_id = cb_data;
+ ctx->num_samples = 0;
if (!(packet = g_try_malloc(sizeof(struct sr_datafeed_packet)))) {
sr_err("fx2lafw: %s: packet malloc failed", __func__);
packet->payload = header;
header->feed_version = 1;
gettimeofday(&header->starttime, NULL);
- header->samplerate = 24000000UL;
+ header->samplerate = ctx->cur_samplerate;
header->num_logic_probes = ctx->profile->num_probes;
- sr_session_bus(session_data, packet);
+ sr_session_send(cb_data, packet);
g_free(header);
g_free(packet);
+ if ((err = command_start_acquisition (ctx->usb->devhdl,
+ ctx->cur_samplerate)) != SR_OK) {
+ return err;
+ }
+
return SR_OK;
}
-/* This stops acquisition on ALL devices, ignoring dev_index. */
-static int hw_dev_acquisition_stop(int dev_index, gpointer session_data)
+/* TODO: This stops acquisition on ALL devices, ignoring dev_index. */
+static int hw_dev_acquisition_stop(int dev_index, void *cb_data)
{
- struct sr_datafeed_packet packet;
-
- /* Avoid compiler warnings. */
- (void)dev_index;
-
- packet.type = SR_DF_END;
- sr_session_bus(session_data, &packet);
+ struct sr_dev_inst *sdi;
- receive_transfer(NULL);
+ /* unused parameter */
+ (void)cb_data;
- /* TODO: Need to cancel and free any queued up transfers. */
+ if (!(sdi = sr_dev_inst_get(dev_insts, dev_index)))
+ return SR_ERR;
+
+ abort_acquisition(sdi->priv);
return SR_OK;
}