Hi again,

I created a minimum example (gnuradio) that shows the issue described below.
To summarize: Retuning to a different dsp frequency on an USRP X310 (+UBX160) 
does not work (command ignored) ONLY if a timed command (in future is used).
The code shows it in a simple manner. Commenting out the single line with 
set_command_time makes the example work.

I am absolutely out of ideas and would appreciate any input!

Best,
Lukas


#!/usr/bin/env python2
# -*- coding: utf-8 -*-

from gnuradio import analog
from gnuradio import gr
from gnuradio import uhd
import threading
import time

class switch_on_click_debug_tx_retune(gr.top_block):

    def __init__(self):
        gr.top_block.__init__(self, "Switch On Click Debug Tx Retune")
        self.variable_function_probe_0 = variable_function_probe_0 = 0
        self.samp_rate = samp_rate = 5e6
        self.uhd_usrp_sink_0 = uhd.usrp_sink(",".join(("", 
"dboard_clock_rate=20e6")), uhd.stream_args(cpu_format="fc32", 
channels=range(1)))
        self.uhd_usrp_sink_0.set_clock_rate(200e6, uhd.ALL_MBOARDS)
        self.uhd_usrp_sink_0.set_clock_source('internal', 0)
        self.uhd_usrp_sink_0.set_samp_rate(samp_rate)
        self.uhd_usrp_sink_0.set_center_freq(900e6, 0)
        self.uhd_usrp_sink_0.set_gain(0, 0)

        def _hopper():
            i = 0
            while True:
                if i % 2 == 0:
                   fdsp = 0
                else:
                   fdsp = -2e6
                print("Change TX dsp_freq=" + str(fdsp))
                tune_req_tx = uhd.tune_request()
                tune_req_tx.rf_freq_policy = uhd.tune_request.POLICY_NONE
                tune_req_tx.dsp_freq_policy = uhd.tune_request.POLICY_MANUAL
                tune_req_tx.rf_freq = 900e6
                tune_req_tx.dsp_freq = fdsp

                now = self.uhd_usrp_sink_0.get_time_now()
                # *** HOPPING WORKS IF THE NEXT LINE IS COMMENTED *** !!!
                self.uhd_usrp_sink_0.set_command_time(now + uhd.time_spec(0.1))
                res1 = self.uhd_usrp_sink_0.set_center_freq(  tune_req_tx, 0)
                self.uhd_usrp_sink_0.clear_command_time()

                i = i + 1
                time.sleep(4.0)
        _hopper_thread = threading.Thread(target=_hopper)
        _hopper_thread.daemon = True
        _hopper_thread.start()

        self.analog_sig_source_x_1 = analog.sig_source_c(samp_rate, 
analog.GR_COS_WAVE, 1e6, 1, 0)
        self.connect((self.analog_sig_source_x_1, 0), (self.uhd_usrp_sink_0, 0))

    def get_samp_rate(self):
        return self.samp_rate

    def set_samp_rate(self, samp_rate):
        self.samp_rate = samp_rate
        self.uhd_usrp_sink_0.set_samp_rate(self.samp_rate)
        self.analog_sig_source_x_1.set_sampling_freq(self.samp_rate)

def main(top_block_cls=switch_on_click_debug_tx_retune, options=None):

    tb = top_block_cls()
    tb.start()
    try:
        raw_input('Press Enter to quit: ')
    except EOFError:
        pass
    tb.stop()
    tb.wait()


if __name__ == '__main__':
    main()




PS: I look at the output on a spectrum analyzer and observe how the frequency 
changes.


















> Gesendet: Donnerstag, 27. Februar 2020 um 19:30 Uhr
> Von: "Lukas Haase" <lukasha...@gmx.at>
> An: "USRP-users@lists.ettus.com" <usrp-users@lists.ettus.com>
> Betreff: Re: How do timed commands work for two blocks (USRP Sink+USRP 
> Source)?
>
> A quick update which may make things easier to debug: I am observing TX/RX on 
> a spectrum analyzer and see if the frequency changes.
> As soon as I enable timed command, the tune command is ignored!
>
> For simplicity, I am completely removing the RX parts (uhd_usrp_source_0).
>
> Now this works:
>
> tune_req_tx = uhd.tune_request()
> tune_req_tx.rf_freq_policy = uhd.tune_request.POLICY_MANUAL
> tune_req_tx.dsp_freq_policy = uhd.tune_request.POLICY_MANUAL
> tune_req_tx.rf_freq = 900e6
> tune_req_tx.dsp_freq = -2e6
>
> now = usrp_sink.get_time_now()
> #usrp_sink.set_command_time(now + uhd.time_spec(1))
> res1 = usrp_sink.set_center_freq(  tune_req_tx, 0)
> usrp_sink.clear_command_time()
>
> When this code is executed, the signal jumps by 2 MHz at the spectrum 
> analyzer.
>
> Now I only uncomment set_timed_command above:
>
> usrp_sink.set_command_time(now + uhd.time_spec(1))
>
> and repeat. NO frequency change any more!
>
> That means as soon as I use timed command (set_command_time) for changing the 
> DSP frequency on a TX it is just IGNORED!
>
> This must be a bug ... or do I really do something fundamentally wrong?
>
>
> USRP X310 with 2xUBX-160. TX/RX from dautherboard 1 is connected to spectrum 
> analyzer.
>
>
> Thank you!
> Lukas
>
>
>
> Lukas Haase wrote:
> > How do these timed commands work exactly when using USRP Source together 
> > with USRP Sink? (I need to phase-align RX and TX hence use timed commands 
> > at the same time).
> > Since they are both internally use the same hardware device (and board) I 
> > feel timed commands sent to both blocks result in some unpredictable 
> > results (at least for me).
> >
> > For simplicity, consider this simple test setup: Loopback configuration (TX 
> > into RX via 30dB attentuator); transmit a 1MHz baseband signal into USRP 
> > Sink. Then, use just retuning via DSP:
> >
> >     # dsp_freq changes every time this code is called:
> >     #dsp_freq = 0
> >     dsp_freq = 100e3
> >     tune_req_tx = uhd.tune_request()
> >     tune_req_tx.rf_freq_policy = uhd.tune_request.POLICY_MANUAL
> >     tune_req_tx.dsp_freq_policy = uhd.tune_request.POLICY_MANUAL
> >     tune_req_tx.rf_freq = 900e6
> >     tune_req_tx.dsp_freq = -dsp_freq
> >
> >     tune_req_rx = uhd.tune_request()
> >     tune_req_rx.rf_freq_policy = uhd.tune_request.POLICY_MANUAL
> >     tune_req_rx.dsp_freq_policy = uhd.tune_request.POLICY_MANUAL
> >     tune_req_rx.rf_freq = 900e6
> >     tune_req_rx.dsp_freq = dsp_freq
> >
> >     res1 = uhd_usrp_sink_0.set_center_freq(  tune_req_tx, 0)
> >     res2 = uhd_usrp_source_0.set_center_freq(tune_req_rx, 0)
> >
> > This code works exactly as expected ... my received baseband signal always 
> > stays at 1 MHz (the retuning is transparent to my baseband!) but the phase 
> > always changes.
> > This makes sense because I do not use timed commands and hence the DUC/DDC 
> > is not aligned properly.
> >
> > Now I change to this code:
> >
> >     tune_req_tx = uhd.tune_request()
> >     tune_req_tx.rf_freq_policy = uhd.tune_request.POLICY_MANUAL
> >     tune_req_tx.dsp_freq_policy = uhd.tune_request.POLICY_MANUAL
> >     tune_req_tx.rf_freq = rf_freq
> >     tune_req_tx.dsp_freq = -dsp_freq
> >
> >     tune_req_rx = uhd.tune_request()
> >     tune_req_rx.rf_freq_policy = uhd.tune_request.POLICY_MANUAL
> >     tune_req_rx.dsp_freq_policy = uhd.tune_request.POLICY_MANUAL
> >     tune_req_rx.rf_freq = rf_freq
> >     tune_req_rx.dsp_freq = dsp_freq
> >
> >     # create timed command:
> >     now = usrp_sink.get_time_now()
> >     uhd_usrp_sink_0.set_command_time(now + uhd.time_spec(0.2))
> >     uhd_usrp_source_0.set_command_time(now + uhd.time_spec(0.2))
> >     res1 = uhd_usrp_sink_0.set_center_freq(  tune_req_tx, 0)
> >     res2 = uhd_usrp_source_0.set_center_freq(tune_req_rx, 0)
> >     uhd_usrp_sink_0.clear_command_time()
> >     uhd_usrp_source_0.clear_command_time()
> >
> > Suddenly my frequency is offset by 100kHz. This makes totally no sense!
> >
> > As I mentioned above, I assume the reason is that all these timed commands 
> > eventually arrive on the same hardware and maybe overwrite themselves in a 
> > way creating unpredictable behavior.
> >
> > So, what is the correct way to do it (with USRP Source/Sink blocks in 
> > gnuradio)??
> >
> > Thanks
> > Lukas
> >
> >
> > PS: If it's multiple receiver blocks I can use the same USRP Source block 
> > with Num Channels > 1. I guess that would make live easier. But I have 
> > TX+RX to phase align.
>
>

_______________________________________________
USRP-users mailing list
USRP-users@lists.ettus.com
http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com

Reply via email to