/*
* This file is part of the sigrok project.
*
- * Copyright (C) 2012 Bert Vermeulen <bert@biot.com>
+ * Copyright (C) 2010-2012 Bert Vermeulen <bert@biot.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
static GSList *device_instances = NULL;
static libusb_context *usb_context = NULL;
+static int new_saleae_logic_firmware = 0;
+
static int hw_set_configuration(int device_index, int capability, void *value);
static void hw_stop_acquisition(int device_index, gpointer session_device_id);
break;
intf_dsc = &(conf_dsc->interface[0].altsetting[0]);
- if (intf_dsc->bNumEndpoints != 2)
- /* Need 2 endpoints. */
+ if (intf_dsc->bNumEndpoints == 4) {
+ /* The new Saleae Logic firmware has 4 endpoints. */
+ new_saleae_logic_firmware = 1;
+ } else if (intf_dsc->bNumEndpoints == 2) {
+ /* The old Saleae Logic firmware has 2 endpoints. */
+ new_saleae_logic_firmware = 0;
+ } else {
+ /* Other number of endpoints -> not a Saleae Logic. */
break;
+ }
if ((intf_dsc->endpoint[0].bEndpointAddress & 0x8f) !=
(1 | LIBUSB_ENDPOINT_OUT))
- /* First endpoint should be 1 (outbound). */
+ /* The first endpoint should be 1 (outbound). */
break;
if ((intf_dsc->endpoint[1].bEndpointAddress & 0x8f) !=
(2 | LIBUSB_ENDPOINT_IN))
- /* First endpoint should be 2 (inbound). */
+ /* The second endpoint should be 2 (inbound). */
break;
+ /* TODO: The new firmware has 4 endpoints... */
+
/* If we made it here, it must be a Saleae Logic. */
ret = 1;
}
libusb_get_device_list(usb_context, &devlist);
for (i = 0; devlist[i]; i++) {
if ((err = libusb_get_device_descriptor(devlist[i], &des))) {
- sr_warn("failed to get device descriptor: %d", err);
+ sr_err("failed to get device descriptor: %d", err);
continue;
}
sdi->index, fx2->usb->bus,
fx2->usb->address, USB_INTERFACE);
} else {
- sr_warn("failed to open device: %d", err);
+ sr_err("failed to open device: %d", err);
}
/* if we made it here, we handled the device one way or another */
(void)deviceinfo;
if (libusb_init(&usb_context) != 0) {
- sr_warn("Failed to initialize USB.");
+ sr_err("Failed to initialize USB.");
return 0;
}
fx2_prof = NULL;
err = libusb_get_device_descriptor(devlist[i], &des);
if (err != 0) {
- sr_warn("failed to get device descriptor: %d", err);
+ sr_err("failed to get device descriptor: %d", err);
continue;
}
if (check_conf_profile(devlist[i])) {
/* Already has the firmware, so fix the new address. */
+ sr_dbg("Found a Saleae Logic with %s firmware.",
+ new_saleae_logic_firmware ? "new" : "old");
sdi->status = SR_ST_INACTIVE;
fx2->usb = sr_usb_device_instance_new
(libusb_get_bus_number(devlist[i]),
/* Remember when the firmware on this device was updated */
g_get_current_time(&fx2->fw_updated);
else
- sr_warn("firmware upload failed for device %d", devcnt);
+ sr_err("firmware upload failed for device %d", devcnt);
fx2->usb = sr_usb_device_instance_new
(libusb_get_bus_number(devlist[i]), 0xff, NULL);
}
}
if (err != SR_OK) {
- sr_warn("unable to open device");
+ sr_err("unable to open device");
return SR_ERR;
}
fx2 = sdi->priv;
err = libusb_claim_interface(fx2->usb->devhdl, USB_INTERFACE);
if (err != 0) {
- sr_warn("Unable to claim interface: %d", err);
+ sr_err("Unable to claim interface: %d", err);
return SR_ERR;
}
return capabilities;
}
+static uint8_t new_firmware_divider_value(uint64_t samplerate)
+{
+ switch (samplerate) {
+ case SR_MHZ(24):
+ return 0xe0;
+ break;
+ case SR_MHZ(16):
+ return 0xd5;
+ break;
+ case SR_MHZ(12):
+ return 0xe2;
+ break;
+ case SR_MHZ(8):
+ return 0xd4;
+ break;
+ case SR_MHZ(4):
+ return 0xda;
+ break;
+ case SR_MHZ(2):
+ return 0xe6;
+ break;
+ case SR_MHZ(1):
+ return 0x8e;
+ break;
+ case SR_KHZ(500):
+ return 0xfe;
+ break;
+ case SR_KHZ(250):
+ return 0x9e;
+ break;
+ case SR_KHZ(200):
+ return 0x4e;
+ break;
+ }
+
+ /* Shouldn't happen. */
+ sr_err("saleae: %s: Invalid samplerate %" PRIu64 "",
+ __func__, samplerate);
+ return 0;
+}
+
static int set_configuration_samplerate(struct sr_device_instance *sdi,
uint64_t samplerate)
{
if (supported_samplerates[i] == 0)
return SR_ERR_SAMPLERATE;
- divider = (uint8_t) (48 / (samplerate / 1000000.0)) - 1;
+ if (new_saleae_logic_firmware)
+ divider = new_firmware_divider_value(samplerate);
+ else
+ divider = (uint8_t) (48 / (samplerate / 1000000.0)) - 1;
sr_info("saleae: setting samplerate to %" PRIu64 " Hz (divider %d)",
samplerate, divider);
- buf[0] = 0x01;
+
+ buf[0] = (new_saleae_logic_firmware) ? 0xd5 : 0x01;
buf[1] = divider;
ret = libusb_bulk_transfer(fx2->usb->devhdl, 1 | LIBUSB_ENDPOINT_OUT,
buf, 2, &result, 500);
if (ret != 0) {
- sr_warn("failed to set samplerate: %d", ret);
+ sr_err("failed to set samplerate: %d", ret);
return SR_ERR;
}
fx2->cur_samplerate = samplerate;
/* Fire off a new request. */
if (!(new_buf = g_try_malloc(4096))) {
sr_err("saleae: %s: new_buf malloc failed", __func__);
- // return SR_ERR_MALLOC;
- return; /* FIXME */
+ return; /* TODO: SR_ERR_MALLOC */
}
transfer->buffer = new_buf;
transfer->length = 4096;
if (libusb_submit_transfer(transfer) != 0) {
/* TODO: Stop session? */
- sr_warn("eek");
+ sr_err("eek");
}
if (cur_buflen == 0) {
for (i = 0; lupfd[i]; i++)
sr_source_add(lupfd[i]->fd, lupfd[i]->events, 40, receive_data,
NULL);
- free(lupfd);
+ free(lupfd); /* NOT g_free()! */
packet->type = SR_DF_HEADER;
packet->payload = header;
gettimeofday(&header->starttime, NULL);
header->samplerate = fx2->cur_samplerate;
header->num_logic_probes = fx2->profile->num_probes;
- header->num_analog_probes = 0;
sr_session_bus(session_data, packet);
g_free(header);
g_free(packet);
/* TODO: Need to cancel and free any queued up transfers. */
}
-struct sr_device_plugin saleae_logic_plugin_info = {
+SR_PRIV struct sr_device_plugin saleae_logic_plugin_info = {
.name = "saleae-logic",
.longname = "Saleae Logic",
.api_version = 1,