diff options
Diffstat (limited to 'src/libosmo-fl2k.c')
-rw-r--r-- | src/libosmo-fl2k.c | 58 |
1 files changed, 36 insertions, 22 deletions
diff --git a/src/libosmo-fl2k.c b/src/libosmo-fl2k.c index c5959c3..3e166e0 100644 --- a/src/libosmo-fl2k.c +++ b/src/libosmo-fl2k.c @@ -2,7 +2,7 @@ * osmo-fl2k, turns FL2000-based USB 3.0 to VGA adapters into * low cost DACs * - * Copyright (C) 2016-2018 by Steve Markgraf <steve@steve-m.de> + * Copyright (C) 2016-2020 by Steve Markgraf <steve@steve-m.de> * * SPDX-License-Identifier: GPL-2.0+ * @@ -250,9 +250,9 @@ int fl2k_set_sample_rate(fl2k_dev_t *dev, uint32_t target_freq) error = sample_clock - (double)target_freq; /* Keep closest match */ - if (fabsf(error) < last_error) { + if (fabs(error) < last_error) { result_reg = reg; - last_error = fabsf(error); + last_error = fabs(error); } } } @@ -262,7 +262,7 @@ int fl2k_set_sample_rate(fl2k_dev_t *dev, uint32_t target_freq) error = sample_clock - (double)target_freq; dev->rate = sample_clock; - if (fabsf(error) > 1) + if (fabs(error) > 1) fprintf(stderr, "Requested sample rate %d not possible, using" " %f, error is %f\n", target_freq, sample_clock, error); @@ -444,11 +444,16 @@ int fl2k_open(fl2k_dev_t **out_dev, uint32_t index) fprintf(stderr, "usb_claim_interface 0 error %d\n", r); goto err; } - r = libusb_claim_interface(dev->devh, 1); + r = libusb_set_interface_alt_setting(dev->devh, 0, 1); if (r < 0) { - fprintf(stderr, "usb_claim_interface 1 error %d\n", r); - goto err; + fprintf(stderr, "Failed to switch interface 0 to " + "altsetting 1, trying to use interface 1\n"); + + r = libusb_claim_interface(dev->devh, 1); + if (r < 0) { + fprintf(stderr, "Could not claim interface 1: %d\n", r); + } } r = fl2k_init_device(dev); @@ -529,6 +534,7 @@ static void LIBUSB_CALL _libusb_callback(struct libusb_transfer *xfer) fl2k_xfer_info_t *next_xfer_info; fl2k_dev_t *dev = (fl2k_dev_t *)xfer_info->dev; struct libusb_transfer *next_xfer = NULL; + int r = 0; if (LIBUSB_TRANSFER_COMPLETED == xfer->status) { /* resubmit transfer */ @@ -541,8 +547,7 @@ static void LIBUSB_CALL _libusb_callback(struct libusb_transfer *xfer) /* Submit next filled transfer */ next_xfer_info->state = BUF_SUBMITTED; - libusb_submit_transfer(next_xfer); - + r = libusb_submit_transfer(next_xfer); xfer_info->state = BUF_EMPTY; pthread_cond_signal(&dev->buf_cond); } else { @@ -551,17 +556,21 @@ static void LIBUSB_CALL _libusb_callback(struct libusb_transfer *xfer) * stops to output data and hangs * (happens only in the hacked 'gapless' * mode without HSYNC and VSYNC) */ - libusb_submit_transfer(xfer); + r = libusb_submit_transfer(xfer); pthread_cond_signal(&dev->buf_cond); dev->underflow_cnt++; } } - } else if (LIBUSB_TRANSFER_CANCELLED != xfer->status) { + } + + if (((LIBUSB_TRANSFER_CANCELLED != xfer->status) && + (LIBUSB_TRANSFER_COMPLETED != xfer->status)) || + (r == LIBUSB_ERROR_NO_DEVICE)) { dev->dev_lost = 1; fl2k_stop_tx(dev); pthread_cond_signal(&dev->buf_cond); - fprintf(stderr, "cb transfer status: %d, " - "canceling...\n", xfer->status); + fprintf(stderr, "cb transfer status: %d, submit " + "transfer %d, canceling...\n", xfer->status, r); } } @@ -569,6 +578,10 @@ static int fl2k_alloc_submit_transfers(fl2k_dev_t *dev) { unsigned int i; int r = 0; + const char *incr_usbfs = "Please increase your allowed usbfs buffer" + " size with the following command:\n" + "echo 0 > /sys/module/usbcore/parameters/" + "usbfs_memory_mb\n"; if (!dev) return FL2K_ERROR_INVALID_PARAM; @@ -609,8 +622,9 @@ static int fl2k_alloc_submit_transfers(fl2k_dev_t *dev) } } else { fprintf(stderr, "Failed to allocate zero-copy " - "buffer for transfer %d\nFalling " - "back to buffers in userspace\n", i); + "buffer for transfer %d\n%sFalling " + "back to buffers in userspace\n", + i, incr_usbfs); dev->use_zerocopy = 0; break; } @@ -664,12 +678,8 @@ static int fl2k_alloc_submit_transfers(fl2k_dev_t *dev) dev->xfer_info[i].state = BUF_SUBMITTED; if (r < 0) { - fprintf(stderr, "Failed to submit transfer %i\n" - "Please increase your allowed " - "usbfs buffer size with the " - "following command:\n" - "echo 0 > /sys/module/usbcore" - "/parameters/usbfs_memory_mb\n", i); + fprintf(stderr, "Failed to submit transfer %i\n%s", + i, incr_usbfs); break; } } @@ -777,6 +787,11 @@ static void *fl2k_usb_worker(void *arg) } } + /* wake up sample worker */ + pthread_cond_signal(&dev->buf_cond); + + /* wait for sample worker thread to finish before freeing buffers */ + pthread_join(dev->sample_worker_thread, NULL); _fl2k_free_async_buffers(dev); dev->async_status = next_status; @@ -954,7 +969,6 @@ static void *fl2k_sample_worker(void *arg) if (dev->dev_lost && dev->cb) { data_info.device_error = 1; dev->cb(&data_info); - fl2k_stop_tx(dev); } pthread_exit(NULL); |