On 02/28/2020 01:01 PM, Lukas Haase via USRP-users wrote:
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
Lukas.

Thanks for sticking with this. I'll have a discussion with Ettus R&D to see if this is a known issue and/or if there's a workaround.

Remind me which version of UHD you're using?



#!/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" <[email protected]>
An: "[email protected]" <[email protected]>
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
[email protected]
http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com


_______________________________________________
USRP-users mailing list
[email protected]
http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com

Reply via email to