Discussion:
Disabling RTL2832 AGC
Francesco Gugliuzza
2012-07-04 23:45:28 UTC
Permalink
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: ***@hacklabproject.org
Leif Asbrink
2012-07-06 10:02:22 UTC
Permalink
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
Post by Francesco Gugliuzza
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).
/* 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);
/* 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
Francesco Gugliuzza
2012-07-07 11:42:35 UTC
Permalink
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: ***@hacklabproject.org
Steve Markgraf
2012-07-07 11:57:33 UTC
Permalink
This post might be inappropriate. Click to display it.
Leif Asbrink
2012-07-07 18:27:59 UTC
Permalink
This post might be inappropriate. Click to display it.
Steve Markgraf
2012-07-08 10:01:03 UTC
Permalink
Hi,
Post by Leif Asbrink
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).
Post by Leif Asbrink
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
Stefan Sydow
2012-07-08 21:19:46 UTC
Permalink
Hi,
Post by 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;
Steve Markgraf
2012-07-08 21:39:20 UTC
Permalink
Hi,
Post by Stefan Sydow
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

Loading...