summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDimitri Stolnikov <horiz0n@gmx.net>2012-06-06 00:44:04 +0200
committerDimitri Stolnikov <horiz0n@gmx.net>2012-06-06 00:44:04 +0200
commita630fc081020b261b86b2da08e54b2c64be35f89 (patch)
tree8c60f15da713b9fd4654e7d02713eb0d83b3e026
parent323af344fad23e29c7bfe032034f86ce94461d09 (diff)
implement setting the sample rate
-rw-r--r--software/libosmosdr/include/osmosdr.h46
-rw-r--r--software/libosmosdr/src/libosmosdr.c131
-rw-r--r--software/libosmosdr/src/osmo_sdr.c13
3 files changed, 80 insertions, 110 deletions
diff --git a/software/libosmosdr/include/osmosdr.h b/software/libosmosdr/include/osmosdr.h
index e80a2f8..f28359c 100644
--- a/software/libosmosdr/include/osmosdr.h
+++ b/software/libosmosdr/include/osmosdr.h
@@ -55,30 +55,6 @@ OSMOSDR_API int osmosdr_close(osmosdr_dev_t *dev);
/* configuration functions */
/*!
- * Set clock frequencies used for the ADC and the tuner ICs.
- *
- * NOTE: Call this function only if you know what you are doing.
- *
- * \param dev the device handle given by osmosdr_open()
- * \param adc_clock frequency value used to clock the ADC in Hz
- * \param tun_clock frequency value used to clock the tuner IC in Hz
- * \return 0 on success
- */
-OSMOSDR_API int osmosdr_set_clock_freq(osmosdr_dev_t *dev, uint32_t adc_clock,
- uint32_t tun_clock);
-
-/*!
- * Get clock frequencies used for the ADC and the tuner IC.
- *
- * \param dev the device handle given by osmosdr_open()
- * \param adc_clock frequency value used to clock the ADC in Hz
- * \param tun_clock frequency value used to clock the tuner IC in Hz
- * \return 0 on success
- */
-OSMOSDR_API int osmosdr_get_clock_freq(osmosdr_dev_t *dev, uint32_t *adc_clock,
- uint32_t *tun_clock);
-
-/*!
* Get USB device strings.
*
* NOTE: The string arguments must provide space for up to 256 bytes.
@@ -164,11 +140,29 @@ OSMOSDR_API int osmosdr_set_tuner_mixer_enh(osmosdr_dev_t *dev, int enh);
/* set IF stages gain */
OSMOSDR_API int osmosdr_set_tuner_if_gain(osmosdr_dev_t *dev, int stage, int gain);
-/* this will select the baseband filters according to the requested sample rate */
+/*!
+ * Get a list of sample rates supported by the device.
+ *
+ * NOTE: The rates argument must be preallocated by the caller. If NULL is
+ * being given instead, the number of available rate values will be returned.
+ *
+ * \param dev the device handle given by osmosdr_open()
+ * \param rates array of rate values in Hz
+ * \return <= 0 on error, number of available (returned) rate values otherwise
+ */
+OSMOSDR_API uint32_t osmosdr_get_sample_rates(osmosdr_dev_t *dev, uint32_t *rates);
+
+/*!
+ * Set the sample rate for the device.
+ *
+ * \param dev the device handle given by osmosdr_open()
+ * \param rate the sample rate in Hz
+ * \return 0 on success
+ */
OSMOSDR_API int osmosdr_set_sample_rate(osmosdr_dev_t *dev, uint32_t rate);
/*!
- * Get actual sample rate the device is configured to.
+ * Get the sample rate the device is configured to.
*
* \param dev the device handle given by osmosdr_open()
* \return 0 on error, sample rate in Hz otherwise
diff --git a/software/libosmosdr/src/libosmosdr.c b/software/libosmosdr/src/libosmosdr.c
index 485e5a0..1c5a22f 100644
--- a/software/libosmosdr/src/libosmosdr.c
+++ b/software/libosmosdr/src/libosmosdr.c
@@ -72,7 +72,6 @@ struct osmosdr_dev {
uint32_t adc_clock; /* Hz */
/* tuner context */
osmosdr_tuner_t *tuner;
- uint32_t tun_clock; /* Hz */
uint32_t freq; /* Hz */
int gain; /* dB */
};
@@ -91,17 +90,7 @@ static osmosdr_dongle_t known_devices[] = {
#define DEFAULT_BUF_NUMBER 32
#define DEFAULT_BUF_LENGTH (16 * 32 * 512)
-// TODO: change the constants according to the limits imposed by the hardware
-
-#define DEF_ADC_FREQ 28800000
-#define MIN_ADC_FREQ (DEF_ADC_FREQ - 1000)
-#define MAX_ADC_FREQ (DEF_ADC_FREQ + 1000)
-
-#define DEF_E4K_FREQ 28800000
-#define MIN_E4K_FREQ (DEF_E4K_FREQ - 1000)
-#define MAX_E4K_FREQ (DEF_E4K_FREQ + 1000)
-
-#define MAX_SAMP_RATE 3200000
+#define DEF_ADC_FREQ 4000000
#define CTRL_IN (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_IN)
#define CTRL_OUT (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT)
@@ -212,57 +201,6 @@ static osmosdr_tuner_t tuner = {
e4k_set_bw, e4k_set_gain, e4k_set_gain_mode
};
-int osmosdr_set_xtal_freq(osmosdr_dev_t *dev, uint32_t adc_clock, uint32_t tun_clock)
-{
- int r = 0;
-
- if (!dev)
- return -1;
-
- if (adc_clock > 0 &&
- (adc_clock < MIN_ADC_FREQ || adc_clock > MAX_ADC_FREQ))
- return -2;
-
- if (dev->adc_clock != adc_clock) {
- if (0 == adc_clock)
- adc_clock = DEF_ADC_FREQ;
-
- dev->adc_clock = adc_clock;
-
- /* update xtal-dependent settings */
- if (dev->rate)
- r = osmosdr_set_sample_rate(dev, dev->rate);
- }
-
- if (dev->tun_clock != tun_clock) {
- if (0 == tun_clock)
- tun_clock = dev->adc_clock;
-
- dev->tun_clock = tun_clock;
-
- /* update xtal-dependent settings */
- if (dev->freq)
- r = osmosdr_set_center_freq(dev, dev->freq);
- }
-
- return r;
-}
-
-int osmosdr_get_xtal_freq(osmosdr_dev_t *dev, uint32_t *adc_clock, uint32_t *tun_clock)
-{
- if (!dev)
- return -1;
-
- *adc_clock = dev->adc_clock;
-
- if (!dev->tuner)
- return -2;
-
- *tun_clock = dev->tun_clock;
-
- return 0;
-}
-
int osmosdr_get_usb_strings(osmosdr_dev_t *dev, char *manufact, char *product,
char *serial)
{
@@ -312,9 +250,8 @@ int osmosdr_set_center_freq(osmosdr_dev_t *dev, uint32_t freq)
if (!dev || !dev->tuner)
return -1;
- if (dev->tuner->set_freq) {
+ if (dev->tuner->set_freq)
r = dev->tuner->set_freq(dev, freq);
- }
if (!r)
dev->freq = freq;
@@ -358,9 +295,8 @@ int osmosdr_set_tuner_gain(osmosdr_dev_t *dev, int gain)
if (!dev || !dev->tuner)
return -1;
- if (dev->tuner->set_gain) {
+ if (dev->tuner->set_gain)
r = dev->tuner->set_gain((void *)dev, gain);
- }
if (!r)
dev->gain = gain;
@@ -385,9 +321,8 @@ int osmosdr_set_tuner_gain_mode(osmosdr_dev_t *dev, int mode)
if (!dev || !dev->tuner)
return -1;
- if (dev->tuner->set_gain_mode) {
+ if (dev->tuner->set_gain_mode)
r = dev->tuner->set_gain_mode((void *)dev, mode);
- }
return r;
}
@@ -451,27 +386,61 @@ int osmosdr_set_tuner_if_gain(osmosdr_dev_t *dev, int stage, int gain)
buffer, 5, CTRL_TIMEOUT);
}
+/* two raised to the power of n */
+#define TWO_POW(n) (1ULL<<(n))
+
+uint32_t osmosdr_get_sample_rates(osmosdr_dev_t *dev, uint32_t *rates)
+{
+ int n;
+
+ if (!dev)
+ return -1;
+
+ if (!rates) { /* no buffer provided, just return the count */
+ return 5;
+ } else {
+ for (n = 6; n > 1; n--) /* 64 to 4 */
+ *(rates++) = dev->adc_clock / TWO_POW(n);
+
+ return 5;
+ }
+
+ return 0;
+}
+
int osmosdr_set_sample_rate(osmosdr_dev_t *dev, uint32_t samp_rate)
{
- uint16_t r = 0;
+ int n, decim = 3;
+ int r = 0;
+ unsigned int req_decim = 0;
if (!dev)
return -1;
- /* check for the maximum rate the resampler supports */
- if (samp_rate > MAX_SAMP_RATE)
- samp_rate = MAX_SAMP_RATE;
+ /* TODO: implement arbitrary rates by steering the master clock */
+
+ req_decim = dev->adc_clock / samp_rate;
- if (dev->tuner && dev->tuner->set_bw) {
- dev->tuner->set_bw(dev, samp_rate);
+ for (n = 2; n <= 6; n++) { /* 4 to 64 */
+ if (TWO_POW(n) == req_decim) {
+ decim = n;
+ break;
+ }
}
- if (!r)
+ samp_rate = dev->adc_clock / TWO_POW(decim);
+
+ r = osmosdr_set_fpga_decimation(dev, decim);
+ if (!r) {
+ if (dev->tuner && dev->tuner->set_bw)
+ dev->tuner->set_bw(dev, samp_rate);
+
dev->rate = samp_rate;
- else
+ } else {
dev->rate = 0;
+ }
- return 0;
+ return r;
}
uint32_t osmosdr_get_sample_rate(osmosdr_dev_t *dev)
@@ -739,14 +708,10 @@ int osmosdr_open(osmosdr_dev_t **out_dev, uint32_t index)
dev->adc_clock = DEF_ADC_FREQ;
- /* TODO: osmosdr_init_baseband(dev); */
-
dev->tuner = &tuner; /* so far we support only one tuner */
found:
if (dev->tuner) {
- dev->tun_clock = dev->adc_clock;
-
if (dev->tuner->init) {
r = dev->tuner->init(dev);
}
@@ -771,8 +736,6 @@ int osmosdr_close(osmosdr_dev_t *dev)
if (!dev)
return -1;
- /* TODO: osmosdr_deinit_baseband(dev); */
-
libusb_release_interface(dev->devh, 0);
libusb_close(dev->devh);
diff --git a/software/libosmosdr/src/osmo_sdr.c b/software/libosmosdr/src/osmo_sdr.c
index f3eb8f6..c9cdd4d 100644
--- a/software/libosmosdr/src/osmo_sdr.c
+++ b/software/libosmosdr/src/osmo_sdr.c
@@ -110,6 +110,7 @@ int main(int argc, char **argv)
char vendor[256] = { 0 }, product[256] = { 0 }, serial[256] = { 0 };
int count;
int gains[100];
+ uint32_t rates[100];
#ifndef _WIN32
while ((opt = getopt(argc, argv, "d:f:g:s:b:S::")) != -1) {
@@ -205,6 +206,14 @@ int main(int argc, char **argv)
fprintf(stderr, "%.1f ", gains[i] / 10.0);
fprintf(stderr, "\n");
+ count = osmosdr_get_sample_rates(dev, NULL);
+ fprintf(stderr, "Supported sample rates (%d): ", count);
+
+ count = osmosdr_get_sample_rates(dev, rates);
+ for (i = 0; i < count; i++)
+ fprintf(stderr, "%u ", rates[i]);
+ fprintf(stderr, "\n");
+
r = osmosdr_get_usb_strings(dev, vendor, product, serial);
if (r < 0)
fprintf(stderr, "WARNING: Failed to read usb strings.\n");
@@ -215,6 +224,10 @@ int main(int argc, char **argv)
r = osmosdr_set_sample_rate(dev, samp_rate);
if (r < 0)
fprintf(stderr, "WARNING: Failed to set sample rate.\n");
+ else {
+ samp_rate = osmosdr_get_sample_rate(dev);
+ fprintf(stderr, "Sample rate is set to %u Hz.\n", samp_rate);
+ }
/* Set the frequency */
r = osmosdr_set_center_freq(dev, frequency);