A couple of days ago I posted on Reddit a small modification to librtlsdr.c to disable the RTL2832 AGC and internal amplifiers (link to post: http://www.reddit.com/r/RTLSDR/comments/vunuy/experiments_with_agc/c57sbpx the correct part is after the EDIT).
Add the following lines of code:
/* disable RF and IF AGC */ uint16_t tmp; tmp = rtlsdr_demod_read_reg(dev, 1, 0x04, 1); tmp &= ~0xc0; rtlsdr_demod_write_reg(dev, 1, 0x04, tmp, 1);
/* disable AGC PGA */ rtlsdr_demod_write_reg(dev, 1, 0xd7, 0x00, 1);
/* disable GI PGA */ rtlsdr_demod_write_reg(dev, 1, 0xe5, 0x00, 1);
just after:
/* disable AGC (en_dagc, bit 0) */ rtlsdr_demod_write_reg(dev, 1, 0x11, 0x00, 1);
Since I don't have adequate tools to test the results, could you please test it, and if it does work, add the patch to your repository?
Thank you!
Hello Francesco,
I have tested it and it does not work. Your posting did however inspire me to do some wild experiments just setting bits on some other registers, the purpose of which was unclear to me.
To disable the AGC:
// Changing from 0x25 to 0xd5 here switches the AGC off SM5BSZ July2 2012 // rtlsdr_demod_write_reg(dev, 0, 0x19, 0x25, 1); rtlsdr_demod_write_reg(dev, 0, 0x19, 0xd5, 1);
Just a couple of lines above the place of your modification.
Performance becomes very good:-) http://www.sm5bsz.com/linuxdsp/hware/rtlsdr/rtlsdr.htm
The dynamic range is 80 dB if gain is set for a noise figure of 10 dB or more. With more gain one can get 3 dB lower NF at the cost of 6 dB lower dynamic range.
Regards
Leif / SM5BSZ
A couple of days ago I posted on Reddit a small modification to librtlsdr.c to disable the RTL2832 AGC and internal amplifiers (link to post: http://www.reddit.com/r/RTLSDR/comments/vunuy/experiments_with_agc/c57sbpx the correct part is after the EDIT).
Add the following lines of code:
/* disable RF and IF AGC */ uint16_t tmp; tmp = rtlsdr_demod_read_reg(dev, 1, 0x04, 1); tmp &= ~0xc0; rtlsdr_demod_write_reg(dev, 1, 0x04, tmp, 1);
/* disable AGC PGA */ rtlsdr_demod_write_reg(dev, 1, 0xd7, 0x00, 1);
/* disable GI PGA */ rtlsdr_demod_write_reg(dev, 1, 0xe5, 0x00, 1);
just after:
/* disable AGC (en_dagc, bit 0) */ rtlsdr_demod_write_reg(dev, 1, 0x11, 0x00, 1);
Since I don't have adequate tools to test the results, could you please test it, and if it does work, add the patch to your repository?
Thank you!
-- Francesco Gugliuzza HackLabProject.org Administrator Linux user #374630 Tel (VoIP geographic number): +39 0921440446 Tel (Libera il VoIP number): 5125320 E-mail: f.gugliuzza@hacklabproject.org
Hi Leif! Nice work, and I'm glad to hear my post inspired you, even if my code didn't work at all! I'm now setting 0x05 (0000 0101) instead of the original 0x25 (0010 0101) or your 0xd5 (1101 0101), to avoid setting unknown bits, and it seems to have the same effect (I see an about 10 dB noise floor drop when on minimum gain with no signal).
Could you test the new value and check if you get the expected results?
Thank you!
Hi,
On 07.07.2012 13:42, Francesco Gugliuzza wrote:
Hi Leif! Nice work, and I'm glad to hear my post inspired you, even if my code didn't work at all!
Your code was changing settings of the RF- and IF-AGC, which do nothing more than modulating the AGC_RF and AGC_IF outputs of the RTL2832, which are connected to the GAIN0/GAIN1 inputs of the E4000. But since we're using the serial interface gain control mode, enabling the RF/IF-AGC won't have any effect, because the GAIN0/1 inputs are ignored.
I'm now setting 0x05 (0000 0101) instead of the original 0x25 (0010 0101) or your 0xd5 (1101 0101), to avoid setting unknown bits, and it seems to have the same effect (I see an about 10 dB noise floor drop when on minimum gain with no signal).
That's also what I observed, clearing bit 5 is enough to disable the AGC. I also noticed that both DAGC gain registers (page 1, 0x12 and page 0, 0x17) have no effect once bit 5 in the settings register is cleared. The control logic still seems to operate though, which can be observed by reading register 0x05 in page 3.
Regards, Steve
Hello Francesco,
As far as I can see there is no difference when I set 0x05 or 0xd5. The bits are no longer unknown - the posting from Steve Markgraf tells us that they mean nothing for a e4000 in "serial interface gain control mode" so the appropriate value should be 0x05.
When I first implemented code for rtlsdr in Linrad I did not know how to disable the AGC. As a resuilt the system performance was at the "toy" level. (Not too bad for USD 20)
Steve Markgraf wrote 2012-06-22:
The remaining AGC that's active is not in the E4K, but it's the Digital AGC (DAGC) of the RTL2832. Unfortunately we don't know how to disable it, since the way it's supposed to be disabled does not work.
That is somehow in contrast to Steves latest posting....
Anyway, today the performance is well above the "toy level" now that we know how to disable the AGC.
Regards
Leif
Hi Leif! Nice work, and I'm glad to hear my post inspired you, even if my code didn't work at all! I'm now setting 0x05 (0000 0101) instead of the original 0x25 (0010 0101) or your 0xd5 (1101 0101), to avoid setting unknown bits, and it seems to have the same effect (I see an about 10 dB noise floor drop when on minimum gain with no signal).
Could you test the new value and check if you get the expected results?
Thank you!
-- Francesco Gugliuzza HackLabProject.org Administrator Linux user #374630 Tel (VoIP geographic number): +39 0921440446 Tel (Libera il VoIP number): 5125320 E-mail: f.gugliuzza@hacklabproject.org
Hi,
On 07.07.2012 20:27, Leif Asbrink wrote:
As far as I can see there is no difference when I set 0x05 or 0xd5. The bits are no longer unknown - the posting from Steve Markgraf tells us that they mean nothing for a e4000 in "serial interface gain control mode" so the appropriate value should be 0x05.
No, I was not referring to the bits in register 0x19, but to the piece of code that Francesco posted earlier (which writes to registers in page 1).
Steve Markgraf wrote 2012-06-22:
The remaining AGC that's active is not in the E4K, but it's the Digital AGC (DAGC) of the RTL2832. Unfortunately we don't know how to disable it, since the way it's supposed to be disabled does not work.
That is somehow in contrast to Steves latest posting....
It is? Notice the date of the post. We did not know how to disable it until you figured out, I played around with register 0x19 earlier though, but managed to overlook the effect of bit 5. The "way it's supposed to work" I was referring to is clearing bit 0 of register 0x11 in page 1, which has no effect at all (en_dagc).
I've now pushed a change to librtlsdr that disables the AGC by default, and added the function rtlsdr_set_agc_mode() that can be used to re-enable it again.
Regards, Steve
Hi,
Am 08.07.2012 12:01, schrieb Steve Markgraf:
I've now pushed a change to librtlsdr that disables the AGC by default, and added the function rtlsdr_set_agc_mode() that can be used to re-enable it again.
This works well. I use rtlsdr_set_tuner_if_gain() now to compensate for the gain loss and found a bug there: The i2c repeater needs to be enabled.
--- a/src/librtlsdr.c +++ b/src/librtlsdr.c @@ -775,7 +775,9 @@ int rtlsdr_set_tuner_if_gain(rtlsdr_dev_t *dev, int stage, int gain) return -1;
if (dev->tuner->set_if_gain) { + rtlsdr_set_i2c_repeater(dev, 1); r = dev->tuner->set_if_gain(dev, stage, gain); + rtlsdr_set_i2c_repeater(dev, 0); }
return r;
Hi,
On 08.07.2012 23:19, Stefan Sydow wrote:
This works well. I use rtlsdr_set_tuner_if_gain() now to compensate for the gain loss and found a bug there: The i2c repeater needs to be enabled.
Indeed, thanks for noticing. Fixed now.
Regards, Steve