various changes

tidy up code, add manufacturer/model test for r828d, tuner hack testing
This commit is contained in:
rtlsdrblog 2023-05-19 00:38:05 +12:00
parent 2a568c7948
commit 7700ec324d
3 changed files with 153 additions and 117 deletions

View File

@ -82,6 +82,9 @@ struct r82xx_priv {
uint32_t int_freq;
uint8_t fil_cal_code;
uint8_t input;
int gain;
int gain_manual_mode;
int gain_sensitivity_mode;
int has_lock;
int init_done;

View File

@ -165,6 +165,8 @@ struct rtlsdr_dev {
unsigned int xfer_errors;
int force_bt;
int force_ds;
char manufact[256];
char product[256];
};
void rtlsdr_set_gpio_bit(rtlsdr_dev_t *dev, uint8_t gpio, int val);
@ -1204,7 +1206,16 @@ int rtlsdr_set_agc_mode(rtlsdr_dev_t *dev, int on)
if (!dev)
return -1;
return rtlsdr_demod_write_reg(dev, 0, 0x19, on ? 0x25 : 0x05, 1);
/* testing:
* replaceme the useless RTL AGC function with a function that
implements max LNA gain for sensitivity when on */
rtlsdr_set_i2c_repeater(dev, 1);
sensitivity_mode_toggle(&dev->r82xx_p, on);
rtlsdr_set_i2c_repeater(dev, 0);
return 0;
//return rtlsdr_demod_write_reg(dev, 0, 0x19, on ? 0x25 : 0x05, 1);
}
int rtlsdr_set_direct_sampling(rtlsdr_dev_t *dev, int on)
@ -1483,6 +1494,16 @@ int rtlsdr_get_index_by_serial(const char *serial)
return -3;
}
/* Returns true if the manufact_check and product_check strings match what is in the dongles EEPROM */
int rtlsdr_check_dongle_model(rtlsdr_dev_t *dev, char* manufact_check, char* product_check) {
if ((strcmp(dev->manufact, manufact_check) == 0 && strcmp(dev->product, product_check) == 0))
{
return 1;
}
return 0;
}
int rtlsdr_open(rtlsdr_dev_t **out_dev, uint32_t index)
{
int r;
@ -1609,6 +1630,12 @@ int rtlsdr_open(rtlsdr_dev_t **out_dev, uint32_t index)
reg = rtlsdr_i2c_read_reg(dev, R828D_I2C_ADDR, R82XX_CHECK_ADDR);
if (reg == R82XX_CHECK_VAL) {
fprintf(stderr, "Found Rafael Micro R828D tuner\n");
if (rtlsdr_check_dongle_model(dev, "RTLSDRBlog", "Blog V4"))
{
fprintf(stderr, "RTL-SDR Blog V4 Detected\n");
}
dev->tuner_type = RTLSDR_TUNER_R828D;
goto found;
}
@ -1642,7 +1669,11 @@ found:
switch (dev->tuner_type) {
case RTLSDR_TUNER_R828D:
// If NOT an RTL-SDR Blog V4, set typical R828D 16 MHz freq. Otherwise, keep at 28.8 MHz.
if (!(rtlsdr_check_dongle_model(dev, "RTLSDRBlog", "Blog V4")))
{
dev->tun_xtal = R828D_XTAL_FREQ;
}
/* fall-through */
case RTLSDR_TUNER_R820T:
/* disable Zero-IF mode */

View File

@ -33,9 +33,12 @@
#define MHZ(x) ((x)*1000*1000)
#define KHZ(x) ((x)*1000)
#define HF 0x10
#define VHF 0x20
#define UHF 0x30
#define HF 1
#define VHF 2
#define UHF 3
#define NOTCH_FILTERS_OFF 100
#define NOTCH_FILTERS_ON 200
/*
* Static constants
@ -959,10 +962,12 @@ static const int r82xx_mixer_gain_steps[] = {
int r82xx_set_gain(struct r82xx_priv *priv, int set_manual_gain, int gain)
{
int rc;
priv->gain = gain;
priv->gain_manual_mode = set_manual_gain;
if (set_manual_gain) {
int i, total_gain = 0;
uint8_t mix_index = 0, lna_index = 0;
uint8_t mix_index = 0, lna_index = 0, vga_index = 0;
uint8_t data[4];
/* LNA auto off */
@ -980,24 +985,40 @@ int r82xx_set_gain(struct r82xx_priv *priv, int set_manual_gain, int gain)
return rc;
/* set fixed VGA gain for now (16.3 dB) */
//rc = r82xx_write_reg_mask(priv, 0x0c, 0x08, 0x9f);
rc = r82xx_write_reg_mask(priv, 0x0c, 0x08, 0x9f); //init val 0x08 0x0c works well at 1.7
if (rc < 0)
return rc;
if (priv->gain_sensitivity_mode)
{
mix_index = (int)(gain / 33);
lna_index = 15;
}
else
{
for (i = 0; i < 15; i++) {
if (total_gain >= gain)
break;
total_gain += r82xx_lna_gain_steps[++lna_index];
//total_gain += r82xx_vga_gain_steps[++vga_index];
if (total_gain >= gain)
break;
total_gain += r82xx_mixer_gain_steps[++mix_index];
}
}
fprintf(stdout, "Gain: %i", gain);
fprintf(stdout, "Mix Index: %i", mix_index);
fprintf(stdout, "LNA Index: %i", lna_index);
/* set LNA gain */
rc = r82xx_write_reg_mask(priv, 0x05, lna_index, 0x0f);
//rc = r82xx_write_reg_mask(priv, 0x05, 0x0f, 0x0f);
if (rc < 0)
return rc;
@ -1005,7 +1026,8 @@ int r82xx_set_gain(struct r82xx_priv *priv, int set_manual_gain, int gain)
rc = r82xx_write_reg_mask(priv, 0x07, mix_index, 0x0f);
if (rc < 0)
return rc;
} else {
}
else {
/* LNA */
rc = r82xx_write_reg_mask(priv, 0x05, 0, 0x10);
if (rc < 0)
@ -1101,21 +1123,39 @@ int r82xx_set_bandwidth(struct r82xx_priv *priv, int bw, uint32_t rate)
#undef FILT_HP_BW1
#undef FILT_HP_BW2
// Changes to support new r828d dongle versions
int sensitivity_mode_toggle(struct r82xx_priv *priv, int toggle)
{
int rc;
if (toggle)
{
//fprintf(stdout, "TOGGLE ON");
priv->gain_sensitivity_mode = 1;
r82xx_set_gain(priv, priv->gain_manual_mode, priv->gain);
//rc = r82xx_write_reg_mask(priv, 0x06, 0x10, 0x10);
}
else
{
priv->gain_sensitivity_mode = 0;
//fprintf(stdout, "TOGGLE OFF");
r82xx_set_gain(priv, priv->gain_manual_mode, priv->gain);
//rc = r82xx_write_reg_mask(priv, 0x06, 0x00, 0x10);
}
return rc;
}
int r82xx_set_freq(struct r82xx_priv *priv, uint32_t freq)
{
int rc = -1;
int is_rtlsdr_blog_v4 = rtlsdr_check_dongle_model(priv->rtl_dev, "RTLSDRBlog", "Blog V4");
// Automatically upconvert to 28.8 MHz if we tune to HF so we don't need to set any upconvert offset in the SDR software
uint32_t upconvert_freq = freq;
if (freq < MHZ(28.8))
{
upconvert_freq = upconvert_freq + MHZ(28.8);
}
/* if it's an RTL-SDR Blog V4, automatically upconvert by 28.8 MHz if we tune to HF
* so that we don't need to manually set any upconvert offset in the SDR software */
uint32_t upconvert_freq = is_rtlsdr_blog_v4 ? ((freq < MHZ(28.8)) ? (freq + MHZ(28.8)) : freq) : freq;
uint32_t lo_freq = upconvert_freq + priv->int_freq;
uint8_t air_cable1_in;
uint8_t cable2_in;
rc = r82xx_set_mux(priv, lo_freq);
if (rc < 0)
@ -1125,101 +1165,63 @@ int r82xx_set_freq(struct r82xx_priv *priv, uint32_t freq)
if (rc < 0 || !priv->has_lock)
goto err;
if (is_rtlsdr_blog_v4)
{
/* determine if notch filters should be on or off
* notches are turned OFF when tuned within the notch band
* and ON when tuned outside the notch band.
*/
uint8_t open_d = (freq <= MHZ(2.2) || (freq >= MHZ(85) && freq <= MHZ(112)) || (freq >= MHZ(172) && freq <= MHZ(242))) ? 0x00 : 0x08;
rc = r82xx_write_reg_mask(priv, 0x17, open_d, 0x08);
// Set open_d notches automatically
if (freq <= MHZ(2.2)
|| (freq >= MHZ(85) && freq <= MHZ(112)) // Notch off until 112 because of roll off
|| (freq >= MHZ(172) && freq <= MHZ(242)))
{
rc = r82xx_write_reg_mask(priv, 0x17, 0x00, 0x08); // open_d hi_z (notches off)
}
else
{
rc = r82xx_write_reg_mask(priv, 0x17, 0x08, 0x08); // open_d low_z (notches on)
}
if (rc < 0)
goto err;
return rc;
// HF -> Cable_2
// VHF -> Cable_1
// UHF -> Air_in
/* select tuner band based on frequency
* and only switch if there is a band change
*(to avoid excessive register writes when tuning rapidly) */
uint8_t band = (freq <= MHZ(28.8)) ? HF : ((freq > MHZ(28.8) && freq < MHZ(300)) ? VHF : UHF);
/* switch between 'Cable1' and 'Air-In' inputs on sticks with
* R828D tuner. We switch at 345 MHz, because that's where the
* noise-floor has about the same level with identical LNA
* settings. The original driver used 320 MHz. - Modded to switch at 300 MHz */
// Only switch if there is a band change (to avoid excessive register writes when tuning rapidly)
int band = 0x00;
if (freq <= MHZ(28.8))
{
band = HF; // HF
}
else if (freq > MHZ(28.8) && freq < MHZ(300)) // VHF Tuner Input
{
band = VHF;
}
else // UHF Tuner Input
{
band = UHF;
}
if ((priv->cfg->rafael_chip == CHIP_R828D) && (band != priv->input))
/* switch between tuner inputs on the RTL-SDR Blog V4 */
if (band != priv->input)
{
priv->input = band;
// Turn LT OFF to save power
rc = r82xx_write_reg_mask(priv, 0x05, 0x80, 0x80);
if (rc < 0)
goto err;
/* activate cable 2 (HF input) */
uint8_t cable_2_in = (band == HF) ? 0x08 : 0x00;
rc = r82xx_write_reg_mask(priv, 0x06, cable_2_in, 0x08);
// Turn open_d off
//rc = r82xx_write_reg_mask(priv, 0x17, 0x00, 0x08);
/* activate cable 1 (VHF input) */
uint8_t cable_1_in = (band == VHF) ? 0x40 : 0x00;
rc = r82xx_write_reg_mask(priv, 0x05, cable_1_in, 0x40);
/* this register appears to boost cable 1 SNR slightly */
//uint8_t cable_1_enhance = (band == VHF) ? 0x04 : 0x00;
//rc = r82xx_write_reg_mask(priv, 0x06, cable_1_enhance, 0x04);
//HF
if (band == HF) //(freq < MHZ(28.8))
{
// Switch in Cable 2
rc = r82xx_write_reg_mask(priv, 0x06, 0x08, 0x08);
}
else
{
// Switch out Cable 2
rc = r82xx_write_reg_mask(priv, 0x06, 0x00, 0x08);
}
// VHF
// Activate Cable_1 input between 28.8 -> 400 MHz.
if (band == VHF)
{
rc = r82xx_write_reg_mask(priv, 0x05, 0x40, 0x40);
// This register setting appears to enhance Cable 1 input by 2dB
rc = r82xx_write_reg_mask(priv, 0x06, 0x04, 0x04);
}
else
{
rc = r82xx_write_reg_mask(priv, 0x05, 0x00, 0x40);
// Turn off the Cable_1 enhancement (off)
rc = r82xx_write_reg_mask(priv, 0x06, 0x00, 0x04);
}
if (band == UHF)
{
//Turn air_in LNA ON
rc = r82xx_write_reg_mask(priv, 0x05, 0x00, 0x20);
}
else
{
// Otherwise turn it off to save power (as it uses a lot of power)
rc = r82xx_write_reg_mask(priv, 0x05, 0x20, 0x20);
}
/* activate air_in (UHF input) */
uint8_t air_in = (band == UHF) ? 0x00 : 0x20;
rc = r82xx_write_reg_mask(priv, 0x05, air_in, 0x20);
if (rc < 0)
goto err;
}
}
else /* Standard R828D dongle*/
{
/* switch between 'Cable1' and 'Air-In' inputs on sticks with
* R828D tuner. We switch at 345 MHz, because that's where the
* noise-floor has about the same level with identical LNA
* settings. The original driver used 320 MHz. */
air_cable1_in = (freq > MHZ(345)) ? 0x00 : 0x60;
if ((priv->cfg->rafael_chip == CHIP_R828D) &&
(air_cable1_in != priv->input)) {
priv->input = air_cable1_in;
rc = r82xx_write_reg_mask(priv, 0x05, air_cable1_in, 0x60);
}
}
err:
if (rc < 0)