From 003bd51167d9680e9721c7296323fdffe4be5a09 Mon Sep 17 00:00:00 2001 From: Steve Markgraf Date: Sun, 5 Jan 2014 22:51:44 +0100 Subject: [PATCH] lib: check for validity of sample rates Thanks to Joris van Rantwijk for finding what seems to be a hardware limitation/bug (bit 28 of the rsamp register being forced to the value of bit 27). Signed-off-by: Steve Markgraf --- include/rtl-sdr.h | 12 +++++++++++- src/librtlsdr.c | 18 ++++++++++-------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/include/rtl-sdr.h b/include/rtl-sdr.h index ca89b77..a07fc60 100644 --- a/include/rtl-sdr.h +++ b/include/rtl-sdr.h @@ -243,7 +243,17 @@ RTLSDR_API int rtlsdr_set_tuner_if_gain(rtlsdr_dev_t *dev, int stage, int gain); */ RTLSDR_API int rtlsdr_set_tuner_gain_mode(rtlsdr_dev_t *dev, int manual); -/* this will select the baseband filters according to the requested sample rate */ +/*! + * Set the sample rate for the device, also selects the baseband filters + * according to the requested sample rate for tuners where this is possible. + * + * \param dev the device handle given by rtlsdr_open() + * \param samp_rate the sample rate to be set, possible values are: + * 225001 - 300000 Hz + * 900001 - 3200000 Hz + * sample loss is to be expected for rates > 2400000 + * \return 0 on success, -EINVAL on invalid rate + */ RTLSDR_API int rtlsdr_set_sample_rate(rtlsdr_dev_t *dev, uint32_t rate); /*! diff --git a/src/librtlsdr.c b/src/librtlsdr.c index ad60779..81f536f 100644 --- a/src/librtlsdr.c +++ b/src/librtlsdr.c @@ -337,8 +337,6 @@ static rtlsdr_dongle_t known_devices[] = { #define MIN_RTL_XTAL_FREQ (DEF_RTL_XTAL_FREQ - 1000) #define MAX_RTL_XTAL_FREQ (DEF_RTL_XTAL_FREQ + 1000) -#define MAX_SAMP_RATE 3200000 - #define CTRL_IN (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_IN) #define CTRL_OUT (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT) #define CTRL_TIMEOUT 300 @@ -1053,20 +1051,24 @@ int rtlsdr_set_sample_rate(rtlsdr_dev_t *dev, uint32_t samp_rate) { int r = 0; uint16_t tmp; - uint32_t rsamp_ratio; + uint32_t rsamp_ratio, real_rsamp_ratio; double real_rate; if (!dev) return -1; - /* check for the maximum rate the resampler supports */ - if (samp_rate > MAX_SAMP_RATE) - samp_rate = MAX_SAMP_RATE; + /* check if the rate is supported by the resampler */ + if ((samp_rate <= 225000) || (samp_rate > 3200000) || + ((samp_rate > 300000) && (samp_rate <= 900000))) { + fprintf(stderr, "Invalid sample rate: %u Hz\n", samp_rate); + return -EINVAL; + } rsamp_ratio = (dev->rtl_xtal * TWO_POW(22)) / samp_rate; - rsamp_ratio &= ~3; + rsamp_ratio &= 0x0ffffffc; - real_rate = (dev->rtl_xtal * TWO_POW(22)) / rsamp_ratio; + real_rsamp_ratio = rsamp_ratio | ((rsamp_ratio & 0x08000000) << 1); + real_rate = (dev->rtl_xtal * TWO_POW(22)) / real_rsamp_ratio; if ( ((double)samp_rate) != real_rate ) fprintf(stderr, "Exact sample rate is: %f Hz\n", real_rate);