Changing interp rate dynamically?

I’ve created an “analog repeater” that’s just:

usrp source -> amp -> usrp sink

and I’d like to control the “bandwidth” that’s repeated
dynamically … on the fly via a GUI slider. I have created all of
this, and on init everything works just fine. But the moment I
change the bandwidth value to -anything-, including the original
values, the TX stops.

I’m also displaying the output of the ‘amp’ on a waterfall scope, so
I can see that the USRP source is generating data all of this time.
It seems like the decim rate of the source is being changed properly.

I’ve tracked this down through Python and C++, and everything looks
OK … nothing else is touched in the process of setting the sink’s
interp rate. In usrp_standard_tx::set_interp_rate, an FPGA register
is changed to reflect the new interp rate; I haven’t tried tracking
down that side of things, since I’ve never investigated FPGA code and
really don’t have time to right now.

Hence the question for folks who hopefully know better: Can the
interp rate be changed dynamically … after its original init? I
should think this would be OK, but obviously it’s not working for
me. Thanks in advance! - MLD

On Sep 14, 2007, at 1:40 PM, Brian P. wrote:

From a quick look, I don’t see any reason why it couldn’t be
dynamically changed. It might cause some strange results while the
pipeline still has things sampled at two different sample frequencies,
but I don’t think it should hang.

I should have said that the TX stops transmitting a signal, not just
“stops”. The USRP sink still seems to be accepting data, since there
are not overflows, but watching the spectrum on another computer, the
signal just disappears. Changing the USRP sink’s center frequency
works, as does changing the gain. But changing the interp seems to
zero out the TX signal. - MLD

On Fri, Sep 14, 2007 at 01:16:58PM -0400, Michael D. wrote:

I’m also displaying the output of the ‘amp’ on a waterfall scope, so
Hence the question for folks who hopefully know better: Can the
interp rate be changed dynamically … after its original init? I
should think this would be OK, but obviously it’s not working for
me. Thanks in advance! - MLD

Hmmm, I would expect it to work.
Changing the decimation on the fly definitely works.
Can’t say that I’ve tried changing the interpolation on the fly.

Eric

On 9/14/07, Michael D. [email protected] wrote:

I’m also displaying the output of the ‘amp’ on a waterfall scope, so
Hence the question for folks who hopefully know better: Can the
interp rate be changed dynamically … after its original init? I
should think this would be OK, but obviously it’s not working for
me. Thanks in advance! - MLD

For informational purposes, the interpolation strobes and filtering
modules are found here:
http://gnuradio.org/trac/browser/gnuradio/trunk/usrp/fpga/sdr_lib/master_control.v
http://gnuradio.org/trac/browser/gnuradio/trunk/usrp/fpga/sdr_lib/cic_interp.v
http://gnuradio.org/trac/browser/gnuradio/trunk/usrp/fpga/sdr_lib/strobe_gen.v

The register is a simple register updated once the serial data is
properly written (read: atomic operation). The strobe_gen is a
downcounter which resets to the input of whatever that rate register
is feeding the module when the counter gets down to 0.

From a quick look, I don’t see any reason why it couldn’t be
dynamically changed. It might cause some strange results while the
pipeline still has things sampled at two different sample frequencies,
but I don’t think it should hang.

Brian

Revisiting this topic, since it’s been 3 weeks and I’ve heard back
nothing … which probably means that everyone is too busy trying to
get release 3.1 out the door to deal with this issue? Should I just
enter this as a bug to be fixed?

My original observation is that the USRP’s TX interp rate doesn’t
seem to work when changed dynamically. Brian and Eric and others
replied back that the FPGA code looks OK, but that it’s never really
been tested for that purpose (the RX decim does work, and has been
tested). I have followed the TX path in software to the point where
data is transferred to the USRP, and the data looks OK to that
point. It is possible that the USB transport is messing with the
data, but I think that’s unlikely. It’s much more likely that the
FPGA code has a bug. Unfortunately I do not “do” FPGA code yet,
though I’m trying to learn, so I can’t debug past where the data
leaves the host computer.

Thus I created a -very- simple python script to test this issue. My
example code creates a sig_source with sinusoid and connects that to
a USRP sink, set to 455 MHz at maximum gain and a given interp_rate.
It starts the TB/FG running, then sleeps for 15 seconds. It sets up
a USRP for TX at a given interp_rate, then starts the FG running
(which will be a separate thread) and sleeps for 15 seconds. It then
resets the interp_rate to -the same value-, and waits for the FG to
finish (via user-interrupt).

I simultaneously run a waterfall scope on another computer, and can
see the sinusoid as a “vertical line” on the scope (which is as
expected). After 15 seconds, the code sets the interp rate to the -
same value- as before, and the waterfall scope changes
dramatically … most of the energy is “near” DC, but it looks
somewhat like a time-sinusoid-modulated frequency-sinc.

Something is going on with the TX interp rate, most likely on the
FPGA in my experimenting thus far (and/or: tell me what I’m doing
incorrectly in my python script). Please try out the example script,
and see for yourselves. - MLD

I think the problem is that the CIC interpolator needs to be stopped
before you change the rate. It may also need to be reset, but I don’t
think so. I think the decimator had the same problem a while ago, and
it was fixed by stopping, changing the rate, and then restarting. This
should be somewhere in the host code.

Matt

On Oct 10, 2007, at 2:49 PM, Matt E. wrote:

I think the problem is that the CIC interpolator needs to be stopped
before you change the rate. It may also need to be reset, but I don’t
think so. I think the decimator had the same problem a while ago, and
it was fixed by stopping, changing the rate, and then restarting.
This
should be somewhere in the host code.

All of the following in usrp/host/apps/lib/legacy/

By “stop” do you mean “disable”? From usrp_standard.cc:627
++++
bool s = disable_tx ();
bool ok = _write_fpga_reg (FR_INTERP_RATE, d_interp_rate/4 - 1);
restore_tx (s);
++++

The decim code does exactly the same thing usrp_standard.cc:251
++++
bool s = disable_rx ();
int v = has_rx_halfband() ? d_decim_rate/2 - 1 : d_decim_rate - 1;
bool ok = _write_fpga_reg (FR_DECIM_RATE, v);
restore_rx (s);
++++
The code for “disable_XX” and “restore_XX” are in usrp_basic.cc; RX
is 634:636 and TX is 1070:1096. Both of these eventually call
“usrp_set_fpga_XX_enable()”, which are in usrp_prims.cc: 644:654.
Both of these functions call “usrp_set_switch()” with
VRQ_FPGA_SET_xx_ENABLE, which is at usrp_prims.cc:570, and just does
a write_cmd over USB to the FPGA at that register.

Possibly the code for disable_tx isn’t doing what it’s supposed to
do, w/r.t. writing to the FPGA’s register? I have verified that the
local code and variables are doing what they’re supposed to do.

Any other places I should be investigating? Thanks! - MLD

Then the interpolator will need to be reset when changing the
interpolation rate. This will require a verilog change.

Matt

Can I do a reset from C++ on the host? Would this be a good way to
try this out first to see if it works? I don’t do FPGA programming
yet. - MLD

Matt E. wrote:

yes, that should do it, but you’ll need to reset all setting registers.

To clarify –
By “reset” I mean “set again”. More of a “re-set” than a “reset”
:slight_smile:

Matt

On Oct 15, 2007, at 6:52 PM, Matt E. wrote:

yes, that should do it, but you’ll need to reset all setting
registers.
To clarify –
By “reset” I mean “set again”. More of a “re-set” than a
“reset” :slight_smile:

OK. What parameters do I need to re-set? Is there an ordering that
makes a difference?

yes, that should do it, but you’ll need to reset all setting registers.

Matt

On Mon, Oct 15, 2007 at 09:09:43PM -0400, Michael D. wrote:

On Oct 15, 2007, at 6:52 PM, Matt E. wrote:

yes, that should do it, but you’ll need to reset all setting
registers.
To clarify –
By “reset” I mean “set again”. More of a “re-set” than a
“reset” :slight_smile:

OK. What parameters do I need to re-set? Is there an ordering that
makes a difference?

FWIW, I’m a bit pessimistic about whether re-setting all the setting
registers will work. Concerns: (1) you’ll glitch everything when you
assert the reset, and (2) the order probably matters.

Eric

On Mon, Oct 15, 2007 at 10:20:43AM -0400, Michael D. wrote:

Can I do a reset from C++ on the host? Would this be a good way to
try this out first to see if it works? I don’t do FPGA programming
yet. - MLD

Resetting from the host would reset everything which would be bad :wink:

On Oct 14, 2007, at 11:53 PM, Matt E. wrote:

Then the interpolator will need to be reset when changing the
interpolation rate. This will require a verilog change.

Eric

On Oct 15, 2007, at 10:09 PM, Eric B. wrote:

FWIW, I’m a bit pessimistic about whether re-setting all the setting
registers will work. Concerns: (1) you’ll glitch everything when you
assert the reset, and (2) the order probably matters.

I am truly happy to let someone else deal with this; my offer is to
try anything that might possibly work and that I’m capable of
programming. The latter limits this to C++ (in the USRP module),
which likely isn’t the correct place for a bug-fix anyway.

I’d love to see thus bug fixed yesterday (or, even better, the week
before), as it greatly limits the functionality and usefulness of
some of my work scripts. I will fill out a bug report when I get a
chance, hopefully tomorrow afternoon … then it’s up to y’all to
figure out what’s best. - MLD

Michael D. wrote:

On Oct 15, 2007, at 6:52 PM, Matt E. wrote:

yes, that should do it, but you’ll need to reset all setting registers.
To clarify –
By “reset” I mean “set again”. More of a “re-set” than a
“reset” :slight_smile:

OK. What parameters do I need to re-set? Is there an ordering that
makes a difference?

Everything that was set in the first place.