mirror of https://github.com/drowe67/librtlsdr.git
bugfix for vco options, added rtlsdr_is_tuner_PLL_locked() to API
* bugfix for vco options: moved init of vco variables: parsed options got overwritten at r820t_init(). see https://github.com/librtlsdr/librtlsdr/issues/91 * added IS_TUNER_PLL_LOCKED (=0x55) command to rtl_tcp protocol * rtl_tcp is checking rtlsdr_is_tuner_PLL_locked() automatically every 3 seconds - when idle: https://github.com/librtlsdr/librtlsdr/issues/91#issuecomment-689830755 Signed-off-by: hayati ayguen <h_ayguen@web.de>development
parent
c7d071e17e
commit
1819a8db99
|
@ -172,6 +172,20 @@ RTLSDR_API int rtlsdr_read_eeprom(rtlsdr_dev_t *dev, uint8_t *data,
|
|||
*/
|
||||
RTLSDR_API int rtlsdr_set_center_freq(rtlsdr_dev_t *dev, uint32_t freq);
|
||||
|
||||
/*!
|
||||
* Check, if tuner PLL (frequency) is still locked.
|
||||
* Tuner/PLL might loose lock (at high frequencies),
|
||||
* e.g. for temperature reasons
|
||||
*
|
||||
* \param dev the device handle given by rtlsdr_open()
|
||||
* \return 1: PLL is NOT locked
|
||||
* \return 0: PLL HAS lock
|
||||
* \return < 0: if device handle is invalid or some other error
|
||||
* \return -2: not supported for devices' tuner
|
||||
*/
|
||||
RTLSDR_API int rtlsdr_is_tuner_PLL_locked(rtlsdr_dev_t *dev);
|
||||
|
||||
|
||||
/*!
|
||||
* Get actual frequency the device is tuned to.
|
||||
*
|
||||
|
@ -180,6 +194,7 @@ 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.
|
||||
*
|
||||
|
|
|
@ -75,7 +75,8 @@ enum RTL_TCP_COMMANDS {
|
|||
GPIO_WRITE_PIN = 0x52, /* rtlsdr_set_gpio_output() and rtlsdr_set_gpio_bit() */
|
||||
GPIO_READ_PIN = 0x53, /* rtlsdr_get_gpio_bit() */
|
||||
GPIO_GET_BYTE = 0x54, /* rtlsdr_get_gpio_byte() */
|
||||
|
||||
|
||||
IS_TUNER_PLL_LOCKED = 0x55, /* rtlsdr_is_tuner_PLL_locked() */
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -149,6 +149,7 @@ enum r82xx_delivery_system {
|
|||
int r82xx_standby(struct r82xx_priv *priv);
|
||||
int r82xx_init(struct r82xx_priv *priv);
|
||||
int r82xx_set_freq(struct r82xx_priv *priv, uint32_t freq);
|
||||
int r82xx_is_tuner_locked(struct r82xx_priv *priv);
|
||||
int r82xx_set_gain(struct r82xx_priv *priv, int set_manual_gain, int gain, int extended_mode, int lna_gain, int mixer_gain, int vga_gain, int *rtl_vga_control);
|
||||
int r82xx_get_rf_gain(struct r82xx_priv *priv);
|
||||
int r82xx_get_if_gain(struct r82xx_priv *priv);
|
||||
|
|
|
@ -381,10 +381,6 @@ int r820t_init(void *dev) {
|
|||
devt->r82xx_c.rafael_chip = CHIP_R820T;
|
||||
}
|
||||
|
||||
devt->r82xx_c.vco_curr_min = 0xff; /* VCO min/max current for R18/0x12 bits [7:5] in 0 .. 7. use 0xff for default */
|
||||
devt->r82xx_c.vco_curr_max = 0xff; /* value is inverted: programmed is 7-value, that 0 is lowest current */
|
||||
devt->r82xx_c.vco_algo = 0x00;
|
||||
|
||||
rtlsdr_get_xtal_freq(devt, NULL, &devt->r82xx_c.xtal);
|
||||
|
||||
devt->r82xx_c.max_i2c_msg_len = 8;
|
||||
|
@ -1457,6 +1453,29 @@ int rtlsdr_set_center_freq(rtlsdr_dev_t *dev, uint32_t freq)
|
|||
return r;
|
||||
}
|
||||
|
||||
|
||||
int rtlsdr_is_tuner_PLL_locked(rtlsdr_dev_t *dev)
|
||||
{
|
||||
int r = -1;
|
||||
|
||||
#if LOG_API_CALLS && LOG_API_SET_FREQ
|
||||
fprintf(stderr, "LOG: rtlsdr_is_tuner_PLL_locked()\n");
|
||||
#endif
|
||||
|
||||
if (!dev || !dev->tuner)
|
||||
return -1;
|
||||
|
||||
if (dev->tuner_type != RTLSDR_TUNER_R820T && dev->tuner_type != RTLSDR_TUNER_R828D )
|
||||
return -2;
|
||||
|
||||
rtlsdr_set_i2c_repeater(dev, 1);
|
||||
r = r82xx_is_tuner_locked(&dev->r82xx_p);
|
||||
rtlsdr_set_i2c_repeater(dev, 0);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
uint32_t rtlsdr_get_center_freq(rtlsdr_dev_t *dev)
|
||||
{
|
||||
#ifdef _ENABLE_RPC
|
||||
|
@ -3005,6 +3024,11 @@ int rtlsdr_open(rtlsdr_dev_t **out_dev, uint32_t index)
|
|||
dev->gpio_state = 0;
|
||||
dev->called_set_opt = 0;
|
||||
|
||||
/* fprintf(stderr, "\n*********************************\ninit/overwrite tuner VCO settings\n"); */
|
||||
dev->r82xx_c.vco_curr_min = 0xff; /* VCO min/max current for R18/0x12 bits [7:5] in 0 .. 7. use 0xff for default */
|
||||
dev->r82xx_c.vco_curr_max = 0xff; /* value is inverted: programmed is 7-value, that 0 is lowest current */
|
||||
dev->r82xx_c.vco_algo = 0x00;
|
||||
|
||||
/* dev->softagc.command_thread; */
|
||||
dev->softagc.agcState = SOFTSTATE_OFF;
|
||||
dev->softagc.softAgcMode = SOFTAGC_OFF; /* SOFTAGC_FREQ_CHANGE SOFTAGC_ATTEN SOFTAGC_ALL */
|
||||
|
|
|
@ -310,6 +310,30 @@ static int set_gain_by_index(rtlsdr_dev_t *_dev, unsigned int index)
|
|||
return res;
|
||||
}
|
||||
|
||||
static void check_tuner_pll(rtlsdr_dev_t *dev, int *tuner_unsupported)
|
||||
{
|
||||
int r = rtlsdr_is_tuner_PLL_locked(dev);
|
||||
/* printf("performed lock check:\n"); */
|
||||
if (r == 1)
|
||||
printf("tuner PLL is unlocked!\n");
|
||||
#if 0
|
||||
else if (r == 0)
|
||||
printf("tuner PLL is locked.\n");
|
||||
#endif
|
||||
else if (r == -2) {
|
||||
printf("error at PLL-locked check: tuner not supported! No further tests.\n");
|
||||
*tuner_unsupported = 1;
|
||||
}
|
||||
else if (r < 0)
|
||||
printf("error checking tuner PLL!\n");
|
||||
else
|
||||
printf("unknown error at tuner PLL check!\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
#define __attribute__(x)
|
||||
#pragma pack(push, 1)
|
||||
|
@ -327,6 +351,8 @@ static void *command_worker(void *arg)
|
|||
fd_set readfds;
|
||||
struct command cmd={0, 0};
|
||||
struct timeval tv= {1, 0};
|
||||
unsigned tuner_check_timeout = 0;
|
||||
int tuner_unsupported = 0;
|
||||
int r = 0;
|
||||
uint32_t tmp;
|
||||
int32_t itmp;
|
||||
|
@ -344,6 +370,19 @@ static void *command_worker(void *arg)
|
|||
if(r) {
|
||||
received = recv(s, (char*)&cmd+(sizeof(cmd)-left), left, 0);
|
||||
left -= received;
|
||||
/* printf("received %d bytes\n", received); */
|
||||
}
|
||||
else if (!tuner_unsupported)
|
||||
{
|
||||
/* timeout: nothing happend */
|
||||
++tuner_check_timeout;
|
||||
if (tuner_check_timeout >= 3)
|
||||
{
|
||||
/* automatic check every 3 seconds */
|
||||
check_tuner_pll(dev, &tuner_unsupported);
|
||||
tuner_check_timeout = 0;
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
if(received == SOCKET_ERROR || do_exit) {
|
||||
printf("comm recv bye\n");
|
||||
|
@ -572,6 +611,10 @@ static void *command_worker(void *arg)
|
|||
(iitmp >>7) & 1, (iitmp >>6) & 1, (iitmp >>5) & 1, (iitmp >>4) & 1,
|
||||
(iitmp >>3) & 1, (iitmp >>2) & 1, (iitmp >>1) & 1, iitmp & 1 );
|
||||
break;
|
||||
case IS_TUNER_PLL_LOCKED:
|
||||
check_tuner_pll(dev, &tuner_unsupported);
|
||||
tuner_check_timeout = 0;
|
||||
break;
|
||||
default:
|
||||
printf("unknown command 0x%02x\n", cmd.cmd);
|
||||
break;
|
||||
|
|
|
@ -891,6 +891,11 @@ static int r82xx_set_pll(struct r82xx_priv *priv, uint32_t freq)
|
|||
priv->last_vco_curr = vco_curr_min;
|
||||
}
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "vco_last = 0x%02x; vcocmin << 5 = 0x%02x; vcocmax << 5 = 0x%02x\n",
|
||||
(unsigned)priv->last_vco_curr, (unsigned)vco_curr_min, (unsigned)vco_curr_max);
|
||||
#endif
|
||||
|
||||
/* Calculate divider */
|
||||
while (mix_div <= 64) {
|
||||
if (((freq_khz * mix_div) >= vco_min) &&
|
||||
|
@ -1029,6 +1034,25 @@ static int r82xx_set_pll(struct r82xx_priv *priv, uint32_t freq)
|
|||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int r82xx_is_tuner_locked(struct r82xx_priv *priv)
|
||||
{
|
||||
uint8_t data[5];
|
||||
|
||||
/* Check if PLL has locked */
|
||||
int rc = r82xx_read(priv, 0x00, data, 3);
|
||||
if (rc < 0)
|
||||
return -3;
|
||||
if (!(data[2] & 0x40)) {
|
||||
#if PRINT_PLL_ERRORS
|
||||
fprintf(stderr, "[R82XX] PLL not locked at check!\n");
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int r82xx_sysfreq_sel(struct r82xx_priv *priv,
|
||||
enum r82xx_tuner_type type)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue