Discussion:
RTL2832U FIR filter
Michael Karcher
2012-07-14 19:23:20 UTC
Permalink
Hello people,

in some experiments with my RTL2832 stick, I managed to find out how the
FIR filter works. The FIR filter is running at the XTAL frequency
(typically 28.8MHz). In the SDR mode, the filter is a symmetric FIR
filter with 32 real-number-valued taps. Using the symmetry, only 16
coefficients need to be specified. The coefficients are stored in the 20
bytes written to the FIR register. The first coefficient describes the
outermost tap, the last one the tap 0.5 taps away from the symmetry
axis. The first 8 values are 8-bit numbers, the second 8 values are 12
bit numbers, resulting in 64 + 96 = 160 bits (20 bytes).

The first 8 bytes written to the chip are the first 8 coefficients. The
12-bit coefficients are stored like this pairwise in three bytes: In the
byte sequence "12 34 56", the first coefficient is 0x123 and the second
coefficient is 0x456. Both the 8-bit and the 12-bit numbers are to be
interpreted as two's complement signed numbers (thus the 8-bit
coefficients range from -128 to +127, while the 12-bit coefficients
range from -2048 to +2047). The resolution of all 16 coefficients is the
same.

I furthermore found out that this is not the only filtering going on in
the RTL2832 chip in SDR mode. There seems to be a second anti-aliasing
filter before the DAC, making signals disappear that are at frequencies
above 0.7 times the sample rate (in the baseband), even if the
programmable FIR filter lets them pass.

As an example, I provide the decoded default coefficients:

-54 -36 -41 -40 -32 -14 14 53 101 156 215 273 327 372 404 421
421 404 372 327 273 215 156 101 53 14 -14 -32 -40 -41 -36 -54

This filter has a quite flat passband in the interesting range for DAB
(-768kHz..+768kHz) but by far not enough attenuation at 1280kHz (which
will alias to 768kHz at a sampling rate of 2048kHz) to get satisfactory
adjacent channel rejection. The experimentally observed alias rejection
is good enough, which lead to the conclusion that there is another
low-pass filter, which might be part of the resampling unit.

Regards,
Michael Karcher
Michael Karcher
2012-07-14 17:46:48 UTC
Permalink
Hello people,

in some experiments with my RTL2832 stick, I managed to find out how the
FIR filter works. The FIR filter is running at the XTAL frequency
(typically 28.8MHz). In the SDR mode, the filter is a symmetric FIR
filter with 32 real-number-valued taps. Using the symmetry, only 16
coefficients need to be specified. The coefficients are stored in the 20
bytes written to the FIR register. The first coefficient describes the
outermost tap, the last one the tap 0.5 taps away from the symmetry
axis. The first 8 values are 8-bit numbers, the second 8 values are 12
bit numbers, resulting in 64 + 96 = 160 bits (20 bytes).

The first 8 bytes written to the chip are the first 8 coefficients. The
12-bit coefficients are stored like this pairwise in three bytes: In the
byte sequence "12 34 56", the first coefficient is 0x123 and the second
coefficient is 0x456. Both the 8-bit and the 12-bit numbers are to be
interpreted as two's complement signed numbers (thus the 8-bit
coefficients range from -128 to +127, while the 12-bit coefficients
range from -2048 to +2047). The resolution of all 16 coefficients is the
same.

I furthermore found out that this is not the only filtering going on in
the RTL2832 chip in SDR mode. There seems to be a second anti-aliasing
filter before the DAC, making signals disappear that are at frequencies
above 0.7 times the sample rate (in the baseband), even if the
programmable FIR filter lets them pass.

As an example, I provide the decoded default coefficients:

-54 -36 -41 -40 -32 -14 14 53 101 156 215 273 327 372 404 421
421 404 372 327 273 215 156 101 53 14 -14 -32 -40 -41 -36 -54

This filter has a quite flat passband in the interesting range for DAB
(-768kHz..+768kHz) but by far not enough attenuation at 1280kHz (which
will alias to 768kHz at a sampling rate of 2048kHz) to get satisfactory
adjacent channel rejection. The experimentally observed alias rejection
is good enough, which lead to the conclusion that there is another
low-pass filter, which might be part of the resampling unit.

BTW: the 900kHz low sample rate limit seems to be valid for a 36MHz
XTAL, not the common 28.8MHz XTAL.

Regards,
Michael Karcher
Michael Karcher
2012-07-14 19:57:01 UTC
Permalink
Post by Michael Karcher
BTW: the 900kHz low sample rate limit seems to be valid for a 36MHz
XTAL, not the common 28.8MHz XTAL.
Please ignore this comment, it is plain wrong. You might choose to
ignore the whole mail, too, as I resent it with my subscribed address
and without that comment some hours later.

Regards,
Michael Karcher
Harald Welte
2012-07-14 19:56:19 UTC
Permalink
Hi Michael,
Post by Michael Karcher
in some experiments with my RTL2832 stick, I managed to find out how the
FIR filter works. [...]
congratulations, it's really great to see that this has been figured
out. Thanks for sharing your results.

... and seeing that you're from a fu-berlin.de address: Did you
consider joining our Osmocom Berlin User Group meetings at some point?
(http://openbsc.osmocom.org/trac/wiki/OsmoUserGroup/Berlin)

[my apologies if you've already been there and I don't remember the
name...]

Regards,
Harald
--
- Harald Welte <***@gnumonks.org> http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
(ETSI EN 300 175-7 Ch. A6)
Francesco Gugliuzza
2012-07-14 23:22:37 UTC
Permalink
Post by Michael Karcher
I furthermore found out that this is not the only filtering going on in
the RTL2832 chip in SDR mode. There seems to be a second anti-aliasing
filter before the DAC, making signals disappear that are at frequencies
above 0.7 times the sample rate (in the baseband), even if the
programmable FIR filter lets them pass.
That's probably an effect of the E4000 output filter. You can see the
filter bandwidth being set in the tuner initalization code.
--
Francesco Gugliuzza
HackLabProject.org Administrator
Linux user #374630
Tel (VoIP geographic number): +39 0921440446
Tel (Libera il VoIP number): 5125320
E-mail: ***@hacklabproject.org
Michael Karcher
2012-07-15 07:16:20 UTC
Permalink
Post by Francesco Gugliuzza
Post by Michael Karcher
I furthermore found out that this is not the only filtering going on in
the RTL2832 chip in SDR mode. There seems to be a second anti-aliasing
filter before the DAC, making signals disappear that are at frequencies
above 0.7 times the sample rate (in the baseband), even if the
programmable FIR filter lets them pass.
That's probably an effect of the E4000 output filter. You can see the
filter bandwidth being set in the tuner initalization code.
Good point, but actually, I am sure it is not an effect of the tuner
output filter. My USB stick contains a fc0012 tuner, which is always set
to 6MHz bandwidth. The bandwidth of the suspected anti-alias filter
changes clearly when I change the sample rate, though, on the other
hand, if I manipulate the FIR coefficients to contain sharp dips in the
range of hundred kHz, the dip position does not change when I change the
sample rate. This makes me cofident that the suspected anti-alias filter
has to be located in or after the resampling unit.

Regards,
Michael Karcher
Francesco Gugliuzza
2012-07-15 10:40:33 UTC
Permalink
Post by Michael Karcher
Good point, but actually, I am sure it is not an effect of the tuner
output filter. My USB stick contains a fc0012 tuner, which is always set
to 6MHz bandwidth. The bandwidth of the suspected anti-alias filter
changes clearly when I change the sample rate, though, on the other
hand, if I manipulate the FIR coefficients to contain sharp dips in the
range of hundred kHz, the dip position does not change when I change the
sample rate. This makes me cofident that the suspected anti-alias filter
has to be located in or after the resampling unit.
The only thing I can think of now is the raised cosine filter used in
digital modulation receivers, but IMHO that should be implemented in
the FIR filter.
--
Francesco Gugliuzza
HackLabProject.org Administrator
Linux user #374630
Tel (VoIP geographic number): +39 0921440446
Tel (Libera il VoIP number): 5125320
E-mail: ***@hacklabproject.org
Stefan Sydow
2012-07-14 23:59:55 UTC
Permalink
Hello Michael,
Post by Michael Karcher
This filter has a quite flat passband in the interesting range for DAB
(-768kHz..+768kHz) but by far not enough attenuation at 1280kHz (which
will alias to 768kHz at a sampling rate of 2048kHz) to get satisfactory
adjacent channel rejection. The experimentally observed alias rejection
is good enough, which lead to the conclusion that there is another
low-pass filter, which might be part of the resampling unit.
I've got a passband of nearly 2MHz with the original coefficients.
Did I miss a factor 2 somewhere? I tried to construct a narrower filter
using the gnuradio function.

Here is a python script to construct the FIR register and plot the
frequency
response. Maybe the script is also helpful to you.

Regards,
Stefan
Michael Karcher
2012-07-15 11:35:15 UTC
Permalink
Post by Stefan Sydow
Hello Michael,
Post by Michael Karcher
This filter has a quite flat passband in the interesting range for DAB
(-768kHz..+768kHz) but by far not enough attenuation at 1280kHz (which
will alias to 768kHz at a sampling rate of 2048kHz) to get satisfactory
adjacent channel rejection. The experimentally observed alias rejection
is good enough, which lead to the conclusion that there is another
low-pass filter, which might be part of the resampling unit.
I've got a passband of nearly 2MHz with the original coefficients.
Did I miss a factor 2 somewhere? I tried to construct a narrower filter
using the gnuradio function.
No, I don't think you missed a factor of 2. I get a -3dB bandwidth of
1.2MHz, and the stopband rejection of -35dB indeed starts at around
2MHz. The actual required DAB range (768kHz) has a flatness of 0.55dB,
if I calculated all the stuff correctly.
Post by Stefan Sydow
Here is a python script to construct the FIR register and plot the
frequency
response. Maybe the script is also helpful to you.
Thanks for the script, just some minor notes: SAMP_RATE should be
28.8e6, not 28e6. Also you don't seem to do any overflow checking on the
conversion. If you are trying to build narrow filters, I expect you
might hit the 1/16 limit on the outer 8 coefficients, so the filter
coefficients might need to be shrunk (reducing the filter gain, of
course) before converting to integers.

I'm afraid that constructing a filter using gnuradio firdes and then
truncating it to 32 coefficients is likely not resulting in a good
filter. In my oppinion (not backed by math knowledge in that area,
though), the filter length should already be considered during
coefficient generation.

It looks like your plot uses the convention that 10dB is a factor of 10.
As the filter affects amplitude values and not power values, you should
use 20dB for a factor of 10, if I understand the dB scale correctly.

Regards,
Michael Karcher
Stefan Sydow
2012-07-15 13:36:06 UTC
Permalink
This post might be inappropriate. Click to display it.
Loading...