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