Hi Rob,
 
That's a good point and I thought about this very early on but figures it would not matter because the phase of the "Tx signal source" is just constant.
 
In terms of phase we could think of it as "phase_we_want_to_measure + phase_of_tx_source". But since phase_of_tx_source does not change over runs, it shouldn't cause any differences. However, it was 2 months ago when I did this. I will have another look at it with your code.
 
Thanks for pointing out the LO synchronization. When you say "from run to run", you mean when I quit/execute again the python script for example, right? I was sure that I had to take this as a fact for now. I am not familiar with the option of synchronizing the LO settings. In all the docs (e.g. https://kb.ettus.com/Synchronization_and_MIMO_Capability_with_USRP_Devices, https://kb.ettus.com/Synchronizing_USRP_Events_Using_Timed_Commands_in_UHD) I have not read about it. Can you elaborate on this?
 
Thanks again,
Lukas
 
 
 
Gesendet: Freitag, 20. März 2020 um 13:44 Uhr
Von: "Rob Kossler" <rkoss...@nd.edu>
An: "Lukas Haase" <lukasha...@gmx.at>, usrp-users <usrp-users@lists.ettus.com>
Betreff: Re: [USRP-users] USRP X310 ignored DSP retuning on TX when using a timed command
OK.  Thinking about it a little more, I think that perhaps the tx-to-rx phase measurement methodology was flawed.  So, maybe this is not any issue.  I changed the Python (new version attached) to send the gnuradio Tx signal source (which also drives Tx0 and Tx1) to one input of the multiply_conjugate (replacing Rx1 which previously was the other input).  When I run, now the phase "walks", but always over the same range of values.  When I retune Tx0 and Rx0, the "walk" resets but still walks over the same range.  As to why the phase walks, I don't know the answer right off.
 
On a separate topic, I noticed that your code does not synchronize the LO setting.  This means that the RF phase between the channels could vary from run to run.
 
On Fri, Mar 20, 2020 at 12:04 PM Rob Kossler <rkoss...@nd.edu> wrote:
Lukas,
After looking at this a bit, I think that there is indeed an issue.  I think that it is possible to get consistent tx-to-tx phase results and consistent rx-to-rx phase results, but NOT consistent rx-to-tx phase results.  A few remarks:
  • Setup
    • 2-channel X310/UBX-160 with two external loopback RF cables (with attenuation) such that Tx0=>Rx0 and Tx1=>Rx1 (I likely don't even need the loopback cables because I could operate on just the leakage signal from each channel, but I decided to use external cables). 
    • UHD 3.15.LTS and gnuradio 3.7.13.5.
  • Methodology
    • Transmit an identical waveform (1 MHz tone) out of both Tx ports
    • Measure relative Rx phase by using a multiply_conjugate block for the 2 Rx channels (see below for description of why I changed what you sent me) with output connected to a complex_to_mag_phase block and subsequent moving_average
    • Use digital tuning (with timed commands) to toggle between 2 dsp frequencies while noting the relative phase results
  • Test cases
    • Case 1: Verify rx-to-rx phase results by sending tune requests to the 2 Rx channels (but sending nothing to the Tx channels)
    • Case 2: Verify tx-to-tx phase results by sending tune requests to the 2 Tx channels (but sending nothing to the Rx channels)
    • Case 3: Verify rx-to-tx phase results by sending tune requests to channel 0 Rx and Tx (but sending nothing to channel 1 Rx and Tx)
    • Case 4: Verify rx-to-tx phase results by sending tune requests to channel 1 Rx and Tx (but sending nothing to channel 0 Rx and Tx)
Cases 1 and 2 show consistent results, but cases 3 and 4 do not. I cannot conceive of what the problem is. It is so perplexing that I hesitate to send this email because it seems I must be doing something wrong.  Perhaps there is a problem in the methodology above along with the test cases.  But, it seems sound to me.
 
The Rx block diagram you sent me does not match the Python code you sent.  This threw me off for a while.  In your block diagram, the phase measurement is made from the division of the two low pass filter outputs.  In the Python code you sent, the phase measurement uses only the first low pass filter output.  The reason this is important is that I suspected early on that the problem might be related to your gnuradio signal_source used for IF downconversion.  This signal source is not synchronous with the USRP as you change USRP freqs. However, I figured that it wasn't a problem because it was "divided out".  But, since it is actually not divided out,I believe that this was providing misleading results.
 
In the end, I just changed your code to add a "multiply_conjugate_cc" block with the two Rx channels as the two inputs.  This effectively uses one channel to downconvert the other and thus eliminates the need for the signal source in the Rx block diagram.  I then connected this multiply_conjugate directly to the complex_to_mag_phase.  You could simplify the code by removing the other multiply blocks, low pass filters, and divide since these are not used. Also, I put all of the functionality in the rxtx (together) button callback.  I did not really use the other buttons.  Attached is the modified code.
 
Rob
 
On Fri, Mar 20, 2020 at 2:38 AM Rob Kossler <rkoss...@nd.edu> wrote:
Hi Lukas,
A few remarks:
  • The 2nd code you sent works fine.  Thanks.
  • I'm not sure that starting/stopping as I do in my program is causing the issue.  The only reason I didn't continuously stream both Rx and Tx like you do in gnuradio is because my software is not setup to do that.
  • So, I still think it's possible that UHD can do the job with continuous streaming but perhaps there is still something in the gnuradio config that is not quite right.  But, I don't know what that is right now.  I need to think about this a bit....
Rob
 
On Thu, Mar 19, 2020 at 8:17 PM Lukas Haase <lukasha...@gmx.at> wrote:
Hi Rob,
 
Sorry I really should have ran the python file before uploading. The issue was that I combined to files into one and forgot to remove the imported file.
Here is a new one (tested): http://paste.ubuntu.com/p/VsGRmsbZQ5/
 
 
Thanks for reporting your results .... very interesting!
 
Why do you think second mode makes sense to you? (assuming you are using timed commands to to retune TX+RX at the same time)
 
In general, it seems to me that things are related to streaming start/stop. Maybe things are reset when streaming starts/ends but not when re-tuning?
 
Maybe this is what Marcus was mentioning: resetting phase accumulator vs. "increment register is updated with the new phase increment"?
 
MAYBE stopping/starting resets the phase accumulator to zero and just timed retuning doesn't reset anything. But still, my question is left why this would result in a random phase offset between DUC and DDC.
 
Thanks again!!
Lukas
 
 
Gesendet: Donnerstag, 19. März 2020 um 19:16 Uhr
Von: "Rob Kossler" <rkoss...@nd.edu>
An: "Lukas Haase" <lukasha...@gmx.at>
Cc: "USRP-users@lists.ettus.com" <usrp-users@lists.ettus.com>
Betreff: Re: [USRP-users] USRP X310 ignored DSP retuning on TX when using a timed command
Lukas,
I installed gnuradio and tried to run but encounter the following.  I'm guessing this is your block.
Traceback (most recent call last):
  File "test.py", line 25, in <module>
    import epy_block_1
ImportError: No module named epy_block_1
Rob
 
On Thu, Mar 19, 2020 at 6:28 PM Rob Kossler <rkoss...@nd.edu> wrote:
Ok.  False alarm.  I forgot about the dboard clock needing set to 20MHz for RF freq below 1 GHz.  When I made this change, now I get consistent Rx-Tx phase for the first mode where both Tx and Rx start/stop at each test.
Rob
 
On Thu, Mar 19, 2020 at 6:10 PM Rob Kossler <rkoss...@nd.edu> wrote:
Ok. I modified my code to be more like yours...
  • toggling dsp freq rather than LO freq
  • LO at 900 MHz
  • external connections Tx0 => Splitter_1x2 => both Rx0 and Rx1
  • Previously, I was starting / stopping both Rx & Tx in between each test.  Now, I added a mode where the Tx is on continuously, and the Rx starts & stops for each test after the dsp freq change
The results are the following:
  • In the first mode where both Tx and Rx start/stop at each test, I get consistent group delay (as measured by the correlation peak index) for both Rx-Rx and Rx-Tx.  But for phase, the Rx-Rx phase is consistent, but the Rx-Tx phase seems random
  • In the second mode where Tx is on continuously and I start/stop Rx after each dsp freq change, the group delay is constant for Rx-Rx but random for Rx-Tx.  The phase results are constant for Rx-Rx but random for Rx-Tx.
Regarding the 2nd mode, this makes sense to me.  But, for the 1st mode, I don't understand why the Rx-Tx phase seems random. Still thinking about it....
Rob
 
On Thu, Mar 19, 2020 at 4:35 PM Rob Kossler <rkoss...@nd.edu> wrote:
Lukas,
Just before receiving your email, I ran the following with my custom c++ & matlab software using X310/UBX-160 with the connections I described.  The following shows the output which is very consistent.  I used a 100 tone multi-tone waveform spread over 4 MHz bandwidth (using 5 MS/s sample rate on Tx and Rx).  Note the consistency of results as I toggled between 2 frequencies: 2450 and 2460 MHz.
 
My method was the following:
  • Tx waveform was 500 points long
  • Rx capture was 5000 points long
  • Compute cross-correlation (using Matlab xcorr) as follows: xcorr(rx0, conj(tx)) AND xcorr(rx0,conj(rx1))
  • Find the correlation peak (which was very pronounced) which shows the sample delay between the two signals.  Extract the phase at the peak
Oops, I just realized that I used a constant DSP freq (10 MHz) and I changed the LO freq in my test.  I will try again with moving the DSP freq instead.
Rob
 
Test 1: freq = 2450.0 MHz
  Rx0/Tx0 xcorr peak at index 108 with phase -121.8
  Rx0/Rx1 xcorr peak at index 115 with phase -95.7
Test 2: freq = 2460.0 MHz
  Rx0/Tx0 xcorr peak at index 108 with phase -58.7
  Rx0/Rx1 xcorr peak at index 115 with phase 13.1
Test 3: freq = 2450.0 MHz
  Rx0/Tx0 xcorr peak at index 108 with phase -121.7
  Rx0/Rx1 xcorr peak at index 115 with phase -95.8
Test 4: freq = 2460.0 MHz
  Rx0/Tx0 xcorr peak at index 108 with phase -58.6
  Rx0/Rx1 xcorr peak at index 115 with phase 13.0
Test 5: freq = 2450.0 MHz
  Rx0/Tx0 xcorr peak at index 108 with phase -121.7
  Rx0/Rx1 xcorr peak at index 115 with phase -95.8
Test 6: freq = 2460.0 MHz
  Rx0/Tx0 xcorr peak at index 108 with phase -58.8
  Rx0/Rx1 xcorr peak at index 115 with phase 12.7
Test 7: freq = 2450.0 MHz
  Rx0/Tx0 xcorr peak at index 108 with phase -121.8
  Rx0/Rx1 xcorr peak at index 115 with phase -95.9
Test 8: freq = 2460.0 MHz
  Rx0/Tx0 xcorr peak at index 108 with phase -58.7
  Rx0/Rx1 xcorr peak at index 115 with phase 12.9
Test 9: freq = 2450.0 MHz
  Rx0/Tx0 xcorr peak at index 108 with phase -121.8
  Rx0/Rx1 xcorr peak at index 115 with phase -95.8
Test 10: freq = 2460.0 MHz
  Rx0/Tx0 xcorr peak at index 108 with phase -58.7
  Rx0/Rx1 xcorr peak at index 115 with phase 12.9
>>
 
 
On Thu, Mar 19, 2020 at 4:21 PM Lukas Haase <lukasha...@gmx.at> wrote:
Hi Rob,
 
Yes, I confirm your conclusion.
 
  • I calculate the relative phase by dividing the outputs of both receivers. To understand better, note that I have an additional "IF stage" in my own signal flow such that I exclude DC offset correction etc. the USRP may perform. This is the block diagram of the transmitter part: https://snipboard.io/YFgIKs.jpg . I send "exp(1j*1MHz*t) . This shows the receiver part: https://snipboard.io/i9jLJg.jpg . I multiply the received signal with exp(-1j*1MHz*t) and filter them. Then I divide both streams and take the phase part. I take a moving average (for flucatuations), add pi and display the number.
  • https://snipboard.io/YFgIKs.jpg https://snipboard.io/YFgIKs.jpg https://snipboard.io/YFgIKs.jpg That's so nice, thank you!! My code is here: http://paste.ubuntu.com/p/MbCJfPGzYW/ . I'm not sure if you have gnuradio(and QT) installed but if yes, simply "python2 switch_on_click.py" should do. Let me quickly elaborate how it works:
    • Class "switch_on_click" implements a normal gnuradio flow with USRP transmitter and receiver.
    • It also uses a custom module together with buttons and a probe block to call functions upon clicking on a button
    • The callback functions are defined in class "blk"
    • The most important is "def button_rtx_handler" on line 106 which is executed when user clicks on button "Switch RTX (together)"
  • Again, thank you for trying this out!! If it works, would you mind sharing this code then? I may be able to check then where it breaks on my system
  • I use 900 MHz as default center frequency (and "rf_freq"). When clicking, I jump between dsp_freq=0 and dsp_freq=500e3. As to my waveform, you can infer from my screenshots and code above: I am transmitting and receiving a 1MHz waveform (which acts as an additional "IF stage"). The received signal is then downconcerted from 1MHz to DC. I use 5 MSsps sampling rate.
 
Again, thank you SO much.
 
Best,
Lukas
 
 
Gesendet: Donnerstag, 19. März 2020 um 10:43 Uhr
Von: "Rob Kossler" <rkoss...@nd.edu>
An: "Lukas Haase" <lukasha...@gmx.at>
Cc: "USRP-users@lists.ettus.com" <usrp-users@lists.ettus.com>
Betreff: Re: [USRP-users] USRP X310 ignored DSP retuning on TX when using a timed command
Hi Lukas,
So, the conclusion is that your Rx0-to-Rx1 relative phase is nearly constant such that it seems that both Rx0/Rx1 are phase coherent and Tx0/Tx1 are phase coherent.  But, phase from Tx-to-Rx is random.  Please correct me if that is wrong.  
 
I have a few comments:
  • How do you measure/calculate the relative phase?
  • Can you send me the full Python code to look at?  As I mentioned previously, I am not too good at gnuradio/Python, but I might be able to spot something.
  • As to your question, I always use synchronous measurements.  And, I'm confident that my Rx-to-Rx phase is coherent.  But, I haven't really looked at Tx-to-Rx in a while so I will do so later today.  Here are the steps I plan to take:
    1. Connect Tx0 to Rx1.  Note that there is a pretty strong leakage signal from Tx0 to Rx0 so I don't really need to provide a physical connection in order to get a signal on Rx0.  The signal attenuation in this leakage path is approx 40 dB so it is not too much different than the signal level I will receive on Rx1 if I use an external 30 dB attenuator.
    2. Set Rx and Tx frequency to freq 1
    3. Measure and note the relative phase for Rx0/Tx0 and Rx1/Tx0 for freq 1
    4. Set Rx and Tx frequency to freq 2
    5. Measure and note the relative phase for Rx0/Tx0 and Rx1/Tx0 for freq 2
    6. Repeat steps 2-5 a few times to ensure that the measurements are repeatable
  • Questions: what should I use for freq 1 and freq 2?  What waveform are you transmitting?  What sample rates for Tx and Rx?
Rob
 
 
 
On Wed, Mar 18, 2020 at 7:47 PM Lukas Haase via USRP-users <usrp-users@lists.ettus.com> wrote:
Hi Rob,
 
I think the issue is really having two usrp_multi devices with timed commands and same timestmap or similar. From your tests below:
 
1.) I can confirm that the relative phase between two RX in your suggested test is always the same! In fact, it is always 4.56 rad, even across restarts and for different frequencies! That somewhat makes sense because the phase offset is now only dependent on the difference between the two channels (fixed) and cable lengths from the splitter (fixed). I verified by removing the timed command on usrp source, the phase offset becomes random after each retune. Of course, this is independent of TX tuning (timed vs. not). For reference, this is the code used:
 
        tune_req_rx = uhd.tune_request()
        tune_req_rx.rf_freq_policy = uhd.tune_request.POLICY_NONE
        tune_req_rx.dsp_freq_policy = uhd.tune_request.POLICY_MANUAL
        tune_req_rx.dsp_freq = -dsp_freq
        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.dsp_freq = dsp_freq
 
        now = usrp_sink.get_time_now()
        when = now + uhd.time_spec(1.0)
 
        usrp_sink.set_command_time(when)
        usrp_source.set_command_time(when)
        res1 = usrp_sink.set_center_freq(tune_req_tx)          # TX
        res2 = usrp_source.set_center_freq(tune_req_rx, 0)  #RX1
        res3 = usrp_source.set_center_freq(tune_req_rx, 1)  #RX2
        usrp_sink.clear_command_time()
        usrp_source.clear_command_time()
 
2.) I also tried your second suggestion. Before reading on, you wanna guess what the outcome is?
I connected "TX/RX" to "RX2" on UBX #1 (TX1 --> RX1) and "TX/RX" to "RX2" on UBX #2 (TX2 --> RX2). In absence of a second 30dB attenuator I used two antennas closely spaced together. For reference, my code looks now like:
 
        tune_req_rx = uhd.tune_request()
        tune_req_rx.rf_freq_policy = uhd.tune_request.POLICY_NONE
        tune_req_rx.dsp_freq_policy = uhd.tune_request.POLICY_MANUAL
        tune_req_rx.dsp_freq = -dsp_freq
        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.dsp_freq = dsp_freq
 
        now = usrp_sink.get_time_now()
        when = now + uhd.time_spec(1.0)
 
        usrp_sink.set_command_time(when)
        usrp_source.set_command_time(when)
        res1 = usrp_sink.set_center_freq(tune_req_tx, 0)     # TX1
        res2 = usrp_sink.set_center_freq(tune_req_tx, 1)     # TX2
        res3 = usrp_source.set_center_freq(tune_req_rx, 0) # RX1
        res4 = usrp_source.set_center_freq(tune_req_rx, 1) # RX2
        usrp_sink.clear_command_time()
        usrp_source.clear_command_time()
 
I again look at the relative phase of RX1 and RX2 (obtained by dividing the two) and guess what: Also now the relative phase stays constant! (This time it actually slightly varies from 3.0 rad to 3.7 rad between two different frequencies).
What does that mean? I think it means that TX must be tuned coherently and RX must be tuned coherently, i.e., timed commands generally work for multiple TX's and multiple RX's individually. Do I get that right?
 
What doesn't seem to work is RX+TX together.
 
I am very desperately asking if you had coherent TX+RX setup working at any point or know somebody who did. It would be so much worth to know if this is something that never worked to begin with or if I'm just doing something wrong. On the other hand I don't want to believe being the only person on the planet having tried TX+RX phase coherent operation :-/
 
Any other further suggestions on how to continue debugging with the above in mind would be helpful too.
 
In my opinion there are two options left:
1.) There is still a nondeterministic delay between the TX and RX timed commands (to my understanding, even a constant delay would result in coherent phase)
2.) While the phase accumulators in RX are set to the same values (and in TX as well), they may be set to a different, random value.
 
However, I don't really know how to test these.
 
Thanks,
Lukas
 
 
Gesendet: Freitag, 13. März 2020 um 12:27 Uhr
Von: "Rob Kossler" <rkoss...@nd.edu>
An: "Lukas Haase" <lukasha...@gmx.at>
Cc: "Marcus D Leech" <patchvonbr...@gmail.com>, "USRP-users@lists.ettus.com" <usrp-users@lists.ettus.com>
Betreff: Re: [USRP-users] USRP X310 ignored DSP retuning on TX when using a timed command
Ok, great.  I am trying to think of ways to now add the phase measurement.  Ideas...
  • In order to get consistent phase, you would need to tune Rx and Tx DSP at the same time (rather than below where you are only tuning one of them).  So, assuming that this will not produce consistent phase results, then maybe try the following idea...
  • If you want to check just Rx DSP tuning (with fixed Tx DSP tuning), you could try a 2 channel Rx measurement where the Tx is split externally with 1:2 splitter in order to drive both Rx0 and Rx1.  Then, measure the relative phase Rx0/Rx1 and then tune back and forth between two Rx DSP freqs to see if the relative phase on Rx remains constant.  If so, this would give you good confidence that Rx DSP tuning is indeed happening synchronously
  • Assuming that the Rx IS synchronous in the step above (perhaps a bad assumption, but here goes), you could then check TX DSP tuning (with fixed Rx DSP tuning) by using two Tx and two Rx channels with Tx0 connected to Rx0 and Tx1 connected to Rx1.  At this point we are confident that Rx DSP tuning is synchronous so any synchronous misbehavior would imply a Tx sync problem.
Sorry I can't think of better ideas.  
Rob
 
On Fri, Mar 13, 2020 at 12:12 PM Lukas Haase <lukasha...@gmx.at> wrote:
Hi Rob,

1.) yes, works(*)
2.) yes, works(*)

(*): qualitatively. I set the timed command to "get_current_time() + uhd.time_spec(2.0)" and I see the chance 2 seconds after my click on the screen. I cannot (do not know how) check if it actually happens at sample-precicse location.

Great, any ideas to simplify the setup would nice. I just don't know how I could continue to debugging the phase.

Best,
Luke


Gesendet: Freitag, 13. März 2020 um 11:08 Uhr
Von: "Rob Kossler" <rkoss...@nd.edu>
An: "Lukas Haase" <lukasha...@gmx.at>
Cc: "Marcus D Leech" <patchvonbr...@gmail.com>, "USRP-users@lists.ettus.com" <usrp-users@lists.ettus.com>
Betreff: Re: [USRP-users] USRP X310 ignored DSP retuning on TX when using a timed command

Thanks Lukas,
I wanted to confirm that you did not have an older version of FPGA firmware because there was a DDC/DUC bug fix[https://github.com/EttusResearch/fpga/commit/0b2364653405612a6d5dfaa0e69b1c6798771e6d] related to phase.  However, the version you provided with uhd_usrp_probe confirms that you have the bug fix included.  So, this is not the problem. 
 
>From what you said, I assume that you can successfully do the following:
1) with Rx tuning fixed (no re-tuning at all), tune Tx DSP only (do not change TX RF) and you can see the frequency change at the specified command time (i.e., if you specify the command time 1 sec in the future, the change does not occur until 1 sec in the future).
2) opposite of #1: with Tx tuning fixed, tune Rx DSP only and you can see the frequency change at the specified command time.
 
I am trying to simplify the issue by removing RF tuning completely and by tuning only 1 of Rx/Tx at a time.  Perhaps this will help lead to the answer.
Rob
 
  

On Fri, Mar 13, 2020 at 10:53 AM Lukas Haase <lukasha...@gmx.at[mailto:lukasha...@gmx.at]> wrote:Hi again Rob,

Yes, I confirm:

1.) Finally I get the commands to execute at the same time (TX and RX individually and both at the same time)
2.) Yes, the phase is random after each retune, even when I retune back to the same frequency
3.) (2) is only true if it includes *DSP* retuning. With naalog retuning (+integer-N retuning) I get phase coherence, as expected.

I actually expected the PLL retuning much more challenging than the DSP retuning but for some reason it seems to be the opposite...

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

Reply via email to