implement setting the sample rate
This commit is contained in:
parent
323af344fa
commit
a630fc0810
|
@ -54,30 +54,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.
|
||||
*
|
||||
|
@ -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
|
||||
|
|
|
@ -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,29 +386,63 @@ int osmosdr_set_tuner_if_gain(osmosdr_dev_t *dev, int stage, int gain)
|
|||
buffer, 5, CTRL_TIMEOUT);
|
||||
}
|
||||
|
||||
int osmosdr_set_sample_rate(osmosdr_dev_t *dev, uint32_t samp_rate)
|
||||
/* 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)
|
||||
{
|
||||
uint16_t r = 0;
|
||||
int n;
|
||||
|
||||
if (!dev)
|
||||
return -1;
|
||||
|
||||
/* check for the maximum rate the resampler supports */
|
||||
if (samp_rate > MAX_SAMP_RATE)
|
||||
samp_rate = MAX_SAMP_RATE;
|
||||
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);
|
||||
|
||||
if (dev->tuner && dev->tuner->set_bw) {
|
||||
dev->tuner->set_bw(dev, samp_rate);
|
||||
return 5;
|
||||
}
|
||||
|
||||
if (!r)
|
||||
dev->rate = samp_rate;
|
||||
else
|
||||
dev->rate = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int osmosdr_set_sample_rate(osmosdr_dev_t *dev, uint32_t samp_rate)
|
||||
{
|
||||
int n, decim = 3;
|
||||
int r = 0;
|
||||
unsigned int req_decim = 0;
|
||||
|
||||
if (!dev)
|
||||
return -1;
|
||||
|
||||
/* TODO: implement arbitrary rates by steering the master clock */
|
||||
|
||||
req_decim = dev->adc_clock / samp_rate;
|
||||
|
||||
for (n = 2; n <= 6; n++) { /* 4 to 64 */
|
||||
if (TWO_POW(n) == req_decim) {
|
||||
decim = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
dev->rate = 0;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
uint32_t osmosdr_get_sample_rate(osmosdr_dev_t *dev)
|
||||
{
|
||||
if (!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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Reference in New Issue