X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=hardware%2Fsaleae-logic%2Fsaleae-logic.c;h=bde17d75201c2a281cd2c9361eaac6b7f8d6969d;hb=c73d2ea421c2b425c3f0ae33bce2bfd0c448ca5f;hp=fb434fa3707aeee1843cad2b6fe2dffdb093cedb;hpb=1a081ca67d63a0bd933a3d715792d85afd437296;p=libsigrok.git diff --git a/hardware/saleae-logic/saleae-logic.c b/hardware/saleae-logic/saleae-logic.c index fb434fa3..bde17d75 100644 --- a/hardware/saleae-logic/saleae-logic.c +++ b/hardware/saleae-logic/saleae-logic.c @@ -1,7 +1,7 @@ /* * This file is part of the sigrok project. * - * Copyright (C) 2012 Bert Vermeulen + * Copyright (C) 2010-2012 Bert Vermeulen * * 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 @@ -91,6 +91,8 @@ static struct sr_samplerates samplerates = { 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); @@ -130,20 +132,29 @@ static int check_conf_profile(libusb_device *dev) 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; } @@ -174,7 +185,7 @@ static int sl_open_device(int device_index) 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; } @@ -211,7 +222,7 @@ static int sl_open_device(int device_index) 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 */ @@ -320,7 +331,7 @@ static int hw_init(const char *deviceinfo) (void)deviceinfo; if (libusb_init(&usb_context) != 0) { - sr_warn("Failed to initialize USB."); + sr_err("Failed to initialize USB."); return 0; } @@ -331,7 +342,7 @@ static int hw_init(const char *deviceinfo) 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; } @@ -357,6 +368,8 @@ static int hw_init(const char *deviceinfo) 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]), @@ -366,7 +379,7 @@ static int hw_init(const char *deviceinfo) /* 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); } @@ -411,14 +424,14 @@ static int hw_opendev(int device_index) } 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; } @@ -520,6 +533,47 @@ static int *hw_get_capabilities(void) 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) { @@ -536,16 +590,20 @@ static int set_configuration_samplerate(struct sr_device_instance *sdi, 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; @@ -631,15 +689,14 @@ static void receive_transfer(struct libusb_transfer *transfer) /* 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) { @@ -783,7 +840,7 @@ static int hw_start_acquisition(int device_index, gpointer session_data) 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; @@ -791,7 +848,6 @@ static int hw_start_acquisition(int device_index, gpointer session_data) 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); @@ -815,7 +871,7 @@ static void hw_stop_acquisition(int device_index, gpointer session_data) /* 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,