kopia lustrzana https://github.com/keenerd/rtl-sdr
apply frequency correction value on the xtal clock directly
by using this approach both, the tuning frequency and the sample rate should be corrected at the same time.pull/1/merge
rodzic
7dc15d9fd7
commit
f9b5d7b0a6
|
@ -60,9 +60,9 @@ RTLSDR_API int rtlsdr_close(rtlsdr_dev_t *dev);
|
|||
*
|
||||
* Usually both ICs use the same clock. Changing the clock may make sense if
|
||||
* you are applying an external clock to the tuner or to compensate the
|
||||
* frequency (and samplerate) error caused by the original cheap crystal.
|
||||
* frequency (and samplerate) error caused by the original (cheap) crystal.
|
||||
*
|
||||
* NOTE: Call this function only if you know what you are doing.
|
||||
* NOTE: Call this function only if you fully understand the implications.
|
||||
*
|
||||
* \param dev the device handle given by rtlsdr_open()
|
||||
* \param rtl_freq frequency value used to clock the RTL2832 in Hz
|
||||
|
@ -109,8 +109,21 @@ RTLSDR_API int rtlsdr_set_center_freq(rtlsdr_dev_t *dev, uint32_t freq);
|
|||
*/
|
||||
RTLSDR_API uint32_t rtlsdr_get_center_freq(rtlsdr_dev_t *dev);
|
||||
|
||||
/*!
|
||||
* Set the frequency correction value for the device.
|
||||
*
|
||||
* \param dev the device handle given by rtlsdr_open()
|
||||
* \param ppm correction value in parts per million (ppm)
|
||||
* \return 0 on success
|
||||
*/
|
||||
RTLSDR_API int rtlsdr_set_freq_correction(rtlsdr_dev_t *dev, int ppm);
|
||||
|
||||
/*!
|
||||
* Get actual frequency correction value of the device.
|
||||
*
|
||||
* \param dev the device handle given by rtlsdr_open()
|
||||
* \return correction value in parts per million (ppm)
|
||||
*/
|
||||
RTLSDR_API int rtlsdr_get_freq_correction(rtlsdr_dev_t *dev);
|
||||
|
||||
enum rtlsdr_tuner {
|
||||
|
|
|
@ -91,7 +91,7 @@ void rtlsdr_set_gpio_bit(rtlsdr_dev_t *dev, uint8_t gpio, int val);
|
|||
int e4000_init(void *dev) {
|
||||
rtlsdr_dev_t* devt = (rtlsdr_dev_t*)dev;
|
||||
devt->e4k_s.i2c_addr = E4K_I2C_ADDR;
|
||||
devt->e4k_s.vco.fosc = devt->tun_xtal;
|
||||
devt->e4k_s.vco.fosc = devt->tun_xtal; /* no need to correct it here */
|
||||
devt->e4k_s.rtl_dev = dev;
|
||||
return e4k_init(&devt->e4k_s);
|
||||
}
|
||||
|
@ -540,10 +540,7 @@ int rtlsdr_set_xtal_freq(rtlsdr_dev_t *dev, uint32_t rtl_freq, uint32_t tuner_fr
|
|||
(rtl_freq < MIN_RTL_XTAL_FREQ || rtl_freq > MAX_RTL_XTAL_FREQ))
|
||||
return -2;
|
||||
|
||||
if (dev->rtl_xtal != rtl_freq) {
|
||||
if (0 == rtl_freq)
|
||||
rtl_freq = DEF_RTL_XTAL_FREQ;
|
||||
|
||||
if (rtl_freq > 0 && dev->rtl_xtal != rtl_freq) {
|
||||
dev->rtl_xtal = rtl_freq;
|
||||
|
||||
/* update xtal-dependent settings */
|
||||
|
@ -553,9 +550,13 @@ int rtlsdr_set_xtal_freq(rtlsdr_dev_t *dev, uint32_t rtl_freq, uint32_t tuner_fr
|
|||
|
||||
if (dev->tun_xtal != tuner_freq) {
|
||||
if (0 == tuner_freq)
|
||||
tuner_freq = dev->rtl_xtal;
|
||||
dev->tun_xtal = dev->rtl_xtal;
|
||||
else
|
||||
dev->tun_xtal = tuner_freq;
|
||||
|
||||
dev->tun_xtal = tuner_freq;
|
||||
/* read corrected clock value into e4k structure */
|
||||
if (rtlsdr_get_xtal_freq(dev, NULL, &dev->e4k_s.vco.fosc))
|
||||
return -3;
|
||||
|
||||
/* update xtal-dependent settings */
|
||||
if (dev->freq)
|
||||
|
@ -570,12 +571,13 @@ int rtlsdr_get_xtal_freq(rtlsdr_dev_t *dev, uint32_t *rtl_freq, uint32_t *tuner_
|
|||
if (!dev)
|
||||
return -1;
|
||||
|
||||
*rtl_freq = dev->rtl_xtal;
|
||||
#define APPLY_PPM_CORR(val,ppm) (((val) * (1.0 + (ppm) / 1e6)))
|
||||
|
||||
if (!dev->tuner)
|
||||
return -2;
|
||||
if (rtl_freq)
|
||||
*rtl_freq = (uint32_t) APPLY_PPM_CORR(dev->rtl_xtal, dev->corr);
|
||||
|
||||
*tuner_freq = dev->tun_xtal;
|
||||
if (tuner_freq)
|
||||
*tuner_freq = (uint32_t) APPLY_PPM_CORR(dev->tun_xtal, dev->corr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -624,16 +626,13 @@ int rtlsdr_get_usb_strings(rtlsdr_dev_t *dev, char *manufact, char *product,
|
|||
int rtlsdr_set_center_freq(rtlsdr_dev_t *dev, uint32_t freq)
|
||||
{
|
||||
int r = -1;
|
||||
double f = (double) freq;
|
||||
|
||||
if (!dev || !dev->tuner)
|
||||
return -1;
|
||||
|
||||
if (dev->tuner->set_freq) {
|
||||
f *= 1.0 + dev->corr / 1e6;
|
||||
|
||||
rtlsdr_set_i2c_repeater(dev, 1);
|
||||
r = dev->tuner->set_freq(dev, (uint32_t) f);
|
||||
r = dev->tuner->set_freq(dev, freq);
|
||||
rtlsdr_set_i2c_repeater(dev, 0);
|
||||
|
||||
if (!r)
|
||||
|
@ -647,7 +646,7 @@ int rtlsdr_set_center_freq(rtlsdr_dev_t *dev, uint32_t freq)
|
|||
|
||||
uint32_t rtlsdr_get_center_freq(rtlsdr_dev_t *dev)
|
||||
{
|
||||
if (!dev || !dev->tuner)
|
||||
if (!dev)
|
||||
return 0;
|
||||
|
||||
return dev->freq;
|
||||
|
@ -655,25 +654,32 @@ uint32_t rtlsdr_get_center_freq(rtlsdr_dev_t *dev)
|
|||
|
||||
int rtlsdr_set_freq_correction(rtlsdr_dev_t *dev, int ppm)
|
||||
{
|
||||
int r;
|
||||
int r = 0;
|
||||
|
||||
if (!dev || !dev->tuner)
|
||||
if (!dev)
|
||||
return -1;
|
||||
|
||||
if (dev->corr == ppm)
|
||||
return -1;
|
||||
return -2;
|
||||
|
||||
dev->corr = ppm;
|
||||
|
||||
/* retune to apply new correction value */
|
||||
r = rtlsdr_set_center_freq(dev, dev->freq);
|
||||
/* read corrected clock value into e4k structure */
|
||||
if (rtlsdr_get_xtal_freq(dev, NULL, &dev->e4k_s.vco.fosc))
|
||||
return -3;
|
||||
|
||||
if (dev->rate) /* reset sample rate to apply new correction value */
|
||||
r |= rtlsdr_set_sample_rate(dev, dev->rate);
|
||||
|
||||
if (dev->freq) /* retune to apply new correction value */
|
||||
r |= rtlsdr_set_center_freq(dev, dev->freq);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int rtlsdr_get_freq_correction(rtlsdr_dev_t *dev)
|
||||
{
|
||||
if (!dev || !dev->tuner)
|
||||
if (!dev)
|
||||
return 0;
|
||||
|
||||
return dev->corr;
|
||||
|
@ -752,7 +758,7 @@ int rtlsdr_set_tuner_gain(rtlsdr_dev_t *dev, int gain)
|
|||
|
||||
int rtlsdr_get_tuner_gain(rtlsdr_dev_t *dev)
|
||||
{
|
||||
if (!dev || !dev->tuner)
|
||||
if (!dev)
|
||||
return 0;
|
||||
|
||||
return dev->gain;
|
||||
|
@ -796,6 +802,7 @@ int rtlsdr_set_sample_rate(rtlsdr_dev_t *dev, uint32_t samp_rate)
|
|||
uint16_t tmp;
|
||||
uint32_t rsamp_ratio;
|
||||
double real_rate;
|
||||
uint32_t rtl_freq;
|
||||
|
||||
if (!dev)
|
||||
return -1;
|
||||
|
@ -804,10 +811,14 @@ int rtlsdr_set_sample_rate(rtlsdr_dev_t *dev, uint32_t samp_rate)
|
|||
if (samp_rate > MAX_SAMP_RATE)
|
||||
samp_rate = MAX_SAMP_RATE;
|
||||
|
||||
rsamp_ratio = (dev->rtl_xtal * TWO_POW(22)) / samp_rate;
|
||||
/* read corrected clock value */
|
||||
if (rtlsdr_get_xtal_freq(dev, &rtl_freq, NULL))
|
||||
return -2;
|
||||
|
||||
rsamp_ratio = (rtl_freq * TWO_POW(22)) / samp_rate;
|
||||
rsamp_ratio &= ~3;
|
||||
|
||||
real_rate = (dev->rtl_xtal * TWO_POW(22)) / rsamp_ratio;
|
||||
real_rate = (rtl_freq * TWO_POW(22)) / rsamp_ratio;
|
||||
|
||||
if ( ((double)samp_rate) != real_rate )
|
||||
fprintf(stderr, "Exact sample rate is: %f Hz\n", real_rate);
|
||||
|
@ -1089,7 +1100,7 @@ found:
|
|||
}
|
||||
|
||||
dev->tuner = &tuners[dev->tuner_type];
|
||||
dev->tun_xtal = dev->rtl_xtal;
|
||||
dev->tun_xtal = dev->rtl_xtal; /* use the rtl clock value by default */
|
||||
|
||||
if (dev->tuner->init)
|
||||
r = dev->tuner->init(dev);
|
||||
|
@ -1313,10 +1324,16 @@ int rtlsdr_cancel_async(rtlsdr_dev_t *dev)
|
|||
|
||||
uint32_t rtlsdr_get_tuner_clock(void *dev)
|
||||
{
|
||||
uint32_t tuner_freq;
|
||||
|
||||
if (!dev)
|
||||
return 0;
|
||||
|
||||
return ((rtlsdr_dev_t *)dev)->tun_xtal;
|
||||
/* read corrected clock value */
|
||||
if (rtlsdr_get_xtal_freq((rtlsdr_dev_t *)dev, NULL, &tuner_freq))
|
||||
return 0;
|
||||
|
||||
return tuner_freq;
|
||||
}
|
||||
|
||||
int rtlsdr_i2c_write_fn(void *dev, uint8_t addr, uint8_t *buf, int len)
|
||||
|
|
Ładowanie…
Reference in New Issue