After playing around with the E4000 tuner gain settings, I will
summarize my results.
LNA Gain Enhancement
--------------------
LNA Gain Enhancement is working in automatic mode but not in manual mode.
To enable LNA enhancement, write 0x05 to register AGC11. This can be
left unchanged even when enabling manual gain mode.
Required updates for tuner_e4k.c:
Function e4k_enable_manual_gain():
Remove or comment the line that disables LNA Enhancement for auto mode
e4k_reg_set_mask(e4k, E4K_REG_AGC11, 0x7, 0);
Function e4k_init():
Pull line out of null condition to enable LNA Enhancement
e4k_reg_set_mask(e4k, E4K_REG_AGC11, 0x7, E4K_AGC11_LNA_GAIN_ENH |
(2 << 1));
Automatic Mode
--------------
The mixer control register AGC7 defines a threshold value. When
automatic mixer control is enabled and the LNA gain index reaches the
threshold value, the high mixer gain of 12 dB will be used. Upon reset,
the AGC7 register is cleared and the threshold value is never set by the
RTLSDR library. This results in always using the high mixer gain
(threshold value 0 corresponds to the lowest LNA gain).
The datasheet recommends writing 0x15 to AGC7. This corresponds to a
threshold of 15 dB (0x15 >> 1 = 0x0A LNA gain index). A value of 0x1D
would set the threshold to max. LNA gain.
NOTE:
When LNA Enhancement is enabled, setting the threshold to max. gain is
not useful. There will be a strong gain increasement step from 25 + 4 =
29 dB to 25 + 5 + 12 = 42 dB.
Required updates for tuner_e4k.c:
Function e4k_init():
Replace the line
e4k_reg_set_mask(e4k, E4K_REG_AGC7, E4K_AGC7_MIX_GAIN_AUTO, 0);
with this
e4k_reg_write(e4k, E4K_REG_AGC7, 0x14);
The above modification will set the threshold value and disable auto
mixer gain control. e4k_enable_manual_gain() is called later and will
modify only bit 0 of AGC7.
Manual Mode
-----------
In manual mode LNA enhancement is not used. So the list of gains must be
changed because the last two values assume that it is used.
The actually used gains are based on Table 6 and the register map of the
E4000 data sheet. The gain table contains those values plus the mixer
gain of 12 db for the last value and 4 db for all others. But the LNA
gain of 30 dB specified in the data sheet is only valid when LNA gain
enhancement is enabled.
Cite from data sheet section 1.16 LNA Gain enhancement referring
register AGC7:
"The LNA gain numbers quoted throughout this document assume that this
register is programmed to the recommended value."
Even when LNA Enhancement would work with manual mode, the second to
last value is wrong because LNA enhancement requires that the mixer gain
is at 12 dB.
Required updates for librtlsdr.c:
Change int e4k_gains[] from
const int e4k_gains[] = {
-10, 15, 40, 65, 90, 115, 140, 165, 190, 215, 240, 290, 340, 420
};
to
const int e4k_gains[] = {
-50 + 40, -25 + 40, 0 + 40, 25 + 40, 50 + 40, 75 + 40,
100 + 40, 125 + 40, 150 + 40, 175 + 40, 200 + 40, 250 + 40,
200 + 120, // 320, optional additional entry
250 + 120
};
Change top of e4000_set_gain() function from
int e4000_set_gain(void *dev, int gain) {
rtlsdr_dev_t* devt = (rtlsdr_dev_t*)dev;
int mixgain = (gain > 340) ? 12 : 4;
if(e4k_set_lna_gain(&devt->e4k_s, min(300, gain - mixgain * 10)) ==
-EINVAL)
to
int e4000_set_gain(void *dev, int gain) {
rtlsdr_dev_t* devt = (rtlsdr_dev_t*)dev;
int mixgain = (0 == (gain - 120) % 25) ? 12 : 4;
if(e4k_set_lna_gain(&devt->e4k_s, gain - mixgain * 10) == -EINVAL)
The above extraction of the mixer gain from the combined LNA and mixer
gain can be used for all possible valid LNA/mixer gain combinations.
Required updates for tuner_e4k.c:
Change last value of static const int32_t lnagain[] from 300 to 250
Optionally change second to last value from 250 to 249 to force
selection of the highest possible LNA gain index.
The 2-dim array may be also replaced by a smaller 1-dim array
when updating also e4k_set_lna_gain():
static const int32_t lna_gain[16] = {
-50, -25, -50, -25, 0, 25, 50, 75,
100, 125, 150, 175, 200, 249, 250, 250
};
int e4k_set_lna_gain(struct e4k_state *e4k, int32_t gain)
{
uint32_t i;
for(i = 0; i < ARRAY_SIZE(lnagain); ++i) {
if(lnagain[i] == gain) {
e4k_reg_set_mask(e4k, E4K_REG_GAIN1, 0xf, i);
return gain;
}
}
return -EINVAL;
}
Detecting Signal Strength
-------------------------
The signal strength can be calculated by determining the relative
strength of a signal (e.g. using a FFT) and subtracting the total gain.
To get the total gain in automatic mode, read the registers 0x14 to 0x17
(E4K_REG_GAIN1 to E4K_REG_GAIN4) and calculate the gains. Note again
that the max. LNA gain of 30 dB is only valid when LNA enhancement is
enabled and the mixer gain is at 12 dB. Otherwise, the max. LNA gain is
25 dB.
For signals in the range of -50 to -10 dBm, the RSSI indicator can be
also read from register 0x1C (E4K_REG_AGC3) in automatic mode to
calculate the input power in dBm:
double InputPower = 10 * log10(RSSI)) - 28.5 - LNA_Gain;
The above calculation can be used when the RSSI value is in the range
from 5 to 24. Higher RSSI values occur with strong signals at min. LNA
gain and give too low results due to clipped signals.
Jochen Arndt