summaryrefslogtreecommitdiffstats
path: root/software/libosmosdr/src/libosmosdr.c
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 /software/libosmosdr/src/libosmosdr.c
parent323af344fad23e29c7bfe032034f86ce94461d09 (diff)
implement setting the sample rate
Diffstat (limited to 'software/libosmosdr/src/libosmosdr.c')
-rw-r--r--software/libosmosdr/src/libosmosdr.c131
1 files changed, 47 insertions, 84 deletions
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);