aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Markgraf <steve@steve-m.de>2014-01-05 22:51:44 +0100
committerSteve Markgraf <steve@steve-m.de>2014-01-05 22:51:44 +0100
commit003bd51167d9680e9721c7296323fdffe4be5a09 (patch)
treea8e6fdab9185f73b08420f152630d03a1fcce6b1
parentd683b128f918778f666349fa511fb9be54b78598 (diff)
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 <steve@steve-m.de>
-rw-r--r--include/rtl-sdr.h12
-rw-r--r--src/librtlsdr.c18
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);