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
>>>>>>>
>>>>>>>
#!/usr/bin/env python2
# -*- coding: utf-8 -*-

if __name__ == '__main__':
    import ctypes
    import sys
    if sys.platform.startswith('linux'):
        try:
            x11 = ctypes.cdll.LoadLibrary('libX11.so')
            x11.XInitThreads()
        except:
            print "Warning: failed to XInitThreads()"

from PyQt4 import Qt
from gnuradio import analog
from gnuradio import blocks
from gnuradio import eng_notation
from gnuradio import filter
from gnuradio import gr
from gnuradio import qtgui
from gnuradio import uhd
from gnuradio.eng_option import eng_option
from gnuradio.filter import firdes
from optparse import OptionParser
import sip
import sys
import threading
import time
from gnuradio import qtgui


class epy_block_1(gr.sync_block):  # other base classes are basic_block, decim_block, interp_block
    """Embedded Python Block example - a simple multiply const"""

    def __init__(self):  # only default arguments here
        """arguments to this function show up as parameters in GRC"""
        gr.sync_block.__init__(
            self,
            name='Buttons Callback',   # will show up in GRC
            in_sig=None,
            out_sig=None
        )

        self.last_state1 = False
        self.last_state2 = False
        self.last_state3 = False
        self.last_state4 = False
        self.last_state5 = False

        self.rf_freqs = [ 900e6 , 903e6 ]
        self.dsp_freqs = [ 500e3, 0 ]
        self.last_freq1 = 0
        self.last_freq2 = 0
        self.last_freq3 = 0 # RTX

        # https://lists.gnu.org/archive/html/discuss-gnuradio/2012-10/msg00263.html
        # https://github.com/gnuradio/gnuradio/issues/1199
        # https://gnuradio.blogspot.com/2015/06/re-discuss-gnuradio-problem-with-send_4.html
        # https://pretalx.sysmocom.de/media/Frequency_hopping_for_SDR_based_GSM_mobile_station.pdf
        # https://lists.gnu.org/archive/html/discuss-gnuradio/2016-06/msg00197.html
        # http://ettus.80997.x6.nabble.com/USRP-users-Disabling-CORDIC-td6592.html#a6595
        # http://lists.ettus.com/pipermail/usrp-users_lists.ettus.com/2017-June/053208.html

    def buttons_callback(self, state1, state2, state3, state4, state5, usrp_source, usrp_sink):
        if state1 is not self.last_state1 and state1 == True:
            self.button_tx_handler(usrp_source, usrp_sink)
        if state2 is not self.last_state2 and state2 == True:
            self.button_rx_handler(usrp_source, usrp_sink)
        if state3 is not self.last_state3 and state3 == True:
            self.button_start_handler(usrp_source, usrp_sink)
        if state4 is not self.last_state4 and state4 == True:
            self.button_tx_handler(usrp_source, usrp_sink)
            self.button_rx_handler(usrp_source, usrp_sink)
        if state5 is not self.last_state5 and state5 == True:
            self.button_rtx_handler(usrp_source, usrp_sink)

        self.last_state1 = state1
        self.last_state2 = state2
        self.last_state3 = state3
        self.last_state4 = state4
        self.last_state5 = state5

    def button_start_handler(self, usrp_source, usrp_sink):
        tune_req = uhd.tune_request()
        tune_req.rf_freq_policy = uhd.tune_request.POLICY_MANUAL
        tune_req.dsp_freq_policy = uhd.tune_request.POLICY_MANUAL
        tune_req.rf_freq = 900e6
        tune_req.dsp_freq = 0

        print("Clicked 3. Reset")

        exec_time = usrp_source.get_time_now() + uhd.time_spec(1)
        usrp_source.set_command_time(exec_time)
        usrp_sink.set_command_time(exec_time)

        res1 = usrp_source.set_center_freq(  tune_req, 1)
        res2 = usrp_sink.set_center_freq(  tune_req)

        usrp_source.clear_command_time()
        usrp_sink.clear_command_time()

        print res1
        print res2

    def button_rtx_handler(self, usrp_source, usrp_sink):
        rf_freq = 900e6 #self.rf_freqs[self.last_freq3]
        dsp_freq = self.dsp_freqs[self.last_freq3]
        self.last_freq3 = (self.last_freq3 + 1) % len(self.rf_freqs)
        
        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.rf_freq = rf_freq
        tune_req_rx.dsp_freq = -dsp_freq
        #tune_req_rx.args=uhd.device_addr(','.join(["mode_n=integer", "int_n_step=1000e3",]))

        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 = rf_freq
        tune_req_tx.dsp_freq = dsp_freq
        #tune_req_tx.args=uhd.device_addr(','.join(["mode_n=integer", "int_n_step=1000e3",]))

        now = usrp_sink.get_time_now()
        when = now + uhd.time_spec(1.0)

        print("Clicked to switch R-T-X frf=" + str(rf_freq) + ", fdsp=" + str(dsp_freq) + " at " + str(now.get_full_secs()) + ":" + str(now.get_frac_secs()) + " for " + str(when.get_full_secs()) + ":" + str(when.get_frac_secs()))

        #RK note: set all 4 true or 1 of the 4 to false
        #    case 0: all 4 true
        #    case 1: only tune_tx false; shows rx-to-rx phase consistent
        #    case 2: only tune_rx false; shows tx-to-tx phase consistent
        #    case 3: only tune_ch0 false; shows that rx-to-tx phase is NOT consistent
        #    case 4: only tune_ch1 false; also shows that rx-to-tx phase is NOT consistent
        tune_tx = True
        tune_rx = True
        tune_ch0 = True
        tune_ch1 = False

        #RK note: my thought is that you only need one of these since there is 
        #   only 1 motherboard.  But, it probably doesn't hurt to send twice
        usrp_sink.set_command_time(when)
        usrp_source.set_command_time(when)

        if tune_tx:
            if tune_ch0:
                usrp_sink.set_center_freq(tune_req_tx, 0)
            if tune_ch1:
                usrp_sink.set_center_freq(tune_req_tx, 1)
        if tune_rx:
            if tune_ch0:
                usrp_source.set_center_freq(tune_req_rx, 0)
            if tune_ch1:
                usrp_source.set_center_freq(tune_req_rx, 1)

        usrp_sink.clear_command_time()
        usrp_source.clear_command_time()

        #print res1
        #print res2
        #print res3
        #print res4

    def button_rx_handler(self, usrp_source, usrp_sink):
        rf_freq = self.rf_freqs[self.last_freq2]
        dsp_freq = self.dsp_freqs[self.last_freq2]
        self.last_freq2 = (self.last_freq2 + 1) % len(self.rf_freqs)
        print("Clicked 2: Switching RX frf=" + str(rf_freq) + ", fdsp=" + str(dsp_freq))
        
        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.rf_freq = 900e6
        tune_req_rx.dsp_freq = -dsp_freq

        now = usrp_source.get_time_now()
        usrp_source.set_command_time(now + uhd.time_spec(1))
        res1 = usrp_source.set_center_freq(  tune_req_rx, 1)
        usrp_source.clear_command_time()
        print res1


    def button_tx_handler(self, usrp_source, usrp_sink):
        rf_freq = self.rf_freqs[self.last_freq1]
        dsp_freq = self.dsp_freqs[self.last_freq1]
        self.last_freq1 = (self.last_freq1 + 1) % len(self.rf_freqs)
        print("Clicked 2 Switching TX frf=" + str(rf_freq) + ", fdsp=" + str(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.rf_freq = rf_freq
        tune_req_tx.dsp_freq = dsp_freq

        now = usrp_sink.get_time_now()
        usrp_sink.set_command_time(now + uhd.time_spec(0.1))
        res1 = usrp_sink.set_center_freq(  tune_req_tx)
        usrp_sink.clear_command_time()
        print res1

    def work(self, input_items, output_items):
        """example: multiply with constant"""
        output_items[0][:] = input_items[0] * self.example_param
        return len(output_items[0])

class switch_on_click(gr.top_block, Qt.QWidget):

    def __init__(self):
        gr.top_block.__init__(self, "Switch On Click")
        Qt.QWidget.__init__(self)
        self.setWindowTitle("Switch On Click")
        qtgui.util.check_set_qss()
        try:
            self.setWindowIcon(Qt.QIcon.fromTheme('gnuradio-grc'))
        except:
            pass
        self.top_scroll_layout = Qt.QVBoxLayout()
        self.setLayout(self.top_scroll_layout)
        self.top_scroll = Qt.QScrollArea()
        self.top_scroll.setFrameStyle(Qt.QFrame.NoFrame)
        self.top_scroll_layout.addWidget(self.top_scroll)
        self.top_scroll.setWidgetResizable(True)
        self.top_widget = Qt.QWidget()
        self.top_scroll.setWidget(self.top_widget)
        self.top_layout = Qt.QVBoxLayout(self.top_widget)
        self.top_grid_layout = Qt.QGridLayout()
        self.top_layout.addLayout(self.top_grid_layout)

        self.settings = Qt.QSettings("GNU Radio", "switch_on_click")
        self.restoreGeometry(self.settings.value("geometry").toByteArray())


        ##################################################
        # Variables
        ##################################################
        self.variable_function_probe_1_0 = variable_function_probe_1_0 = 0
        self.start_delay = start_delay = 3
        self.samp_rate = samp_rate = 5e6
        self.fif = fif = 1e6
        self.fcenter = fcenter = 900e6
        self.button5 = button5 = False
        self.button4 = button4 = False
        self.button3 = button3 = False
        self.button2 = button2 = False
        self.button1 = button1 = False

        ##################################################
        # Blocks
        ##################################################
        self.uhd_usrp_source_0 = uhd.usrp_source(
        	",".join(("", 'dboard_clock_rate=20e6,addr=192.168.43.2')),
        	uhd.stream_args(
        		cpu_format="fc32",
        		channels=range(2),
        	),
        )
        self.uhd_usrp_source_0.set_clock_rate(200e6, uhd.ALL_MBOARDS)
        self.uhd_usrp_source_0.set_clock_source('internal', 0)
        self.uhd_usrp_source_0.set_subdev_spec('A:0 B:0', 0)
        self.uhd_usrp_source_0.set_samp_rate(samp_rate)
        self.uhd_usrp_source_0.set_time_unknown_pps(uhd.time_spec())
        self.uhd_usrp_source_0.set_center_freq(fcenter, 0)
        self.uhd_usrp_source_0.set_gain(0, 0)
        self.uhd_usrp_source_0.set_antenna('RX2', 0)
        self.uhd_usrp_source_0.set_auto_dc_offset(True, 0)
        self.uhd_usrp_source_0.set_auto_iq_balance(True, 0)
        self.uhd_usrp_source_0.set_center_freq(fcenter, 1)
        self.uhd_usrp_source_0.set_gain(0, 1)
        self.uhd_usrp_source_0.set_antenna('RX2', 1)
        self.uhd_usrp_source_0.set_auto_dc_offset(True, 1)
        self.uhd_usrp_source_0.set_auto_iq_balance(True, 1)
        self.uhd_usrp_sink_0 = uhd.usrp_sink(
        	",".join(("", 'dboard_clock_rate=20e6,addr=192.168.43.2')),
        	uhd.stream_args(
        		cpu_format="fc32",
        		channels=range(2),
        	),
        )
        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_subdev_spec('A:0 B:0', 0)
        self.uhd_usrp_sink_0.set_samp_rate(samp_rate)
        #RK Note: my thought is that only "set_time_unkonwn_pps" is needed (above) since 1 motherboard
        #   but it probably doesn't hurt to send again
        self.uhd_usrp_sink_0.set_time_unknown_pps(uhd.time_spec())
        self.uhd_usrp_sink_0.set_center_freq(fcenter, 0)
        self.uhd_usrp_sink_0.set_gain(0, 0)
        self.uhd_usrp_sink_0.set_antenna('TX/RX', 0)
        self.uhd_usrp_sink_0.set_center_freq(fcenter, 1)
        self.uhd_usrp_sink_0.set_gain(0, 1)
        self.uhd_usrp_sink_0.set_antenna('TX/RX', 1)
        self.epy_block_1 = epy_block_1()
        _button5_push_button = Qt.QPushButton('Switch RTX (together)')
        self._button5_choices = {'Pressed': True, 'Released': False}
        _button5_push_button.pressed.connect(lambda: self.set_button5(self._button5_choices['Pressed']))
        _button5_push_button.released.connect(lambda: self.set_button5(self._button5_choices['Released']))
        self.top_grid_layout.addWidget(_button5_push_button)
        _button4_push_button = Qt.QPushButton('Switch RTX')
        self._button4_choices = {'Pressed': True, 'Released': False}
        _button4_push_button.pressed.connect(lambda: self.set_button4(self._button4_choices['Pressed']))
        _button4_push_button.released.connect(lambda: self.set_button4(self._button4_choices['Released']))
        self.top_grid_layout.addWidget(_button4_push_button)
        _button3_push_button = Qt.QPushButton('Start/Reset')
        self._button3_choices = {'Pressed': True, 'Released': False}
        _button3_push_button.pressed.connect(lambda: self.set_button3(self._button3_choices['Pressed']))
        _button3_push_button.released.connect(lambda: self.set_button3(self._button3_choices['Released']))
        self.top_grid_layout.addWidget(_button3_push_button)
        _button2_push_button = Qt.QPushButton('Switch RX')
        self._button2_choices = {'Pressed': True, 'Released': False}
        _button2_push_button.pressed.connect(lambda: self.set_button2(self._button2_choices['Pressed']))
        _button2_push_button.released.connect(lambda: self.set_button2(self._button2_choices['Released']))
        self.top_grid_layout.addWidget(_button2_push_button)
        _button1_push_button = Qt.QPushButton('Switch TX')
        self._button1_choices = {'Pressed': True, 'Released': False}
        _button1_push_button.pressed.connect(lambda: self.set_button1(self._button1_choices['Pressed']))
        _button1_push_button.released.connect(lambda: self.set_button1(self._button1_choices['Released']))
        self.top_grid_layout.addWidget(_button1_push_button)

        def _variable_function_probe_1_0_probe():
            while True:
                val = self.epy_block_1.buttons_callback(self.button1, self.button2, self.button3, self.button4, self.button5, self.uhd_usrp_source_0, self.uhd_usrp_sink_0)
                try:
                    self.set_variable_function_probe_1_0(val)
                except AttributeError:
                    pass
                time.sleep(1.0 / (10))
        _variable_function_probe_1_0_thread = threading.Thread(target=_variable_function_probe_1_0_probe)
        _variable_function_probe_1_0_thread.daemon = True
        _variable_function_probe_1_0_thread.start()

        self.qtgui_number_sink_0 = qtgui.number_sink(
            gr.sizeof_float,
            0,
            qtgui.NUM_GRAPH_HORIZ,
            1
        )
        self.qtgui_number_sink_0.set_update_time(0.10)
        self.qtgui_number_sink_0.set_title("Phase")

        labels = ['Phase', '', '', '', '',
                  '', '', '', '', '']
        units = ['rad', '', '', '', '',
                 '', '', '', '', '']
        colors = [("black", "white"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"),
                  ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black")]
        factor = [1, 1, 1, 1, 1,
                  1, 1, 1, 1, 1]
        for i in xrange(1):
            self.qtgui_number_sink_0.set_min(i, 0)
            self.qtgui_number_sink_0.set_max(i, 6.4)
            self.qtgui_number_sink_0.set_color(i, colors[i][0], colors[i][1])
            if len(labels[i]) == 0:
                self.qtgui_number_sink_0.set_label(i, "Data {0}".format(i))
            else:
                self.qtgui_number_sink_0.set_label(i, labels[i])
            self.qtgui_number_sink_0.set_unit(i, units[i])
            self.qtgui_number_sink_0.set_factor(i, factor[i])

        self.qtgui_number_sink_0.enable_autoscale(False)
        self._qtgui_number_sink_0_win = sip.wrapinstance(self.qtgui_number_sink_0.pyqwidget(), Qt.QWidget)
        self.top_grid_layout.addWidget(self._qtgui_number_sink_0_win)
        self.qtgui_freq_sink_x_0 = qtgui.freq_sink_c(
        	1024, #size
        	firdes.WIN_BLACKMAN_hARRIS, #wintype
        	0, #fc
        	samp_rate, #bw
        	"", #name
        	2 #number of inputs
        )
        self.qtgui_freq_sink_x_0.set_update_time(0.10)
        self.qtgui_freq_sink_x_0.set_y_axis(-140, 10)
        self.qtgui_freq_sink_x_0.set_y_label('Relative Gain', 'dB')
        self.qtgui_freq_sink_x_0.set_trigger_mode(qtgui.TRIG_MODE_FREE, 0.0, 0, "")
        self.qtgui_freq_sink_x_0.enable_autoscale(True)
        self.qtgui_freq_sink_x_0.enable_grid(True)
        self.qtgui_freq_sink_x_0.set_fft_average(1.0)
        self.qtgui_freq_sink_x_0.enable_axis_labels(True)
        self.qtgui_freq_sink_x_0.enable_control_panel(True)

        if not True:
          self.qtgui_freq_sink_x_0.disable_legend()

        if "complex" == "float" or "complex" == "msg_float":
          self.qtgui_freq_sink_x_0.set_plot_pos_half(not True)

        labels = ['', '', '', '', '',
                  '', '', '', '', '']
        widths = [1, 1, 1, 1, 1,
                  1, 1, 1, 1, 1]
        colors = ["blue", "red", "green", "black", "cyan",
                  "magenta", "yellow", "dark red", "dark green", "dark blue"]
        alphas = [1.0, 1.0, 1.0, 1.0, 1.0,
                  1.0, 1.0, 1.0, 1.0, 1.0]
        for i in xrange(2):
            if len(labels[i]) == 0:
                self.qtgui_freq_sink_x_0.set_line_label(i, "Data {0}".format(i))
            else:
                self.qtgui_freq_sink_x_0.set_line_label(i, labels[i])
            self.qtgui_freq_sink_x_0.set_line_width(i, widths[i])
            self.qtgui_freq_sink_x_0.set_line_color(i, colors[i])
            self.qtgui_freq_sink_x_0.set_line_alpha(i, alphas[i])

        self._qtgui_freq_sink_x_0_win = sip.wrapinstance(self.qtgui_freq_sink_x_0.pyqwidget(), Qt.QWidget)
        self.top_grid_layout.addWidget(self._qtgui_freq_sink_x_0_win)
        self.low_pass_filter_0_0 = filter.fir_filter_ccf(1, firdes.low_pass(
        	1, samp_rate, 500e3, 100e3, firdes.WIN_HAMMING, 6.76))
        self.low_pass_filter_0 = filter.fir_filter_ccf(1, firdes.low_pass(
        	1, samp_rate, 500e3, 100e3, firdes.WIN_HAMMING, 6.76))
        self.blocks_null_sink_1 = blocks.null_sink(gr.sizeof_gr_complex*1)
        self.blocks_null_sink_0 = blocks.null_sink(gr.sizeof_float*1)
        self.blocks_multiply_xx_0_0 = blocks.multiply_vcc(1)
        self.blocks_multiply_xx_0 = blocks.multiply_vcc(1)
        self.blocks_moving_average_xx_0 = blocks.moving_average_ff(1000, 1.0/1000.0, 4000, 1)
        self.blocks_divide_xx_0 = blocks.divide_cc(1)
        self.blocks_complex_to_magphase_0 = blocks.complex_to_magphase(1)
        self.blocks_add_const_vxx_0 = blocks.add_const_vff((3.141592654, ))
        self.analog_sig_source_x_1_0 = analog.sig_source_c(samp_rate, analog.GR_COS_WAVE, -fif, 1, 0)
        self.analog_sig_source_x_1 = analog.sig_source_c(samp_rate, analog.GR_COS_WAVE, fif, 1, 0)

        self.blocks_multiply_conj = blocks.multiply_conjugate_cc(1)


        ##################################################
        # Connections
        ##################################################
        self.connect((self.analog_sig_source_x_1, 0), (self.uhd_usrp_sink_0, 0))
        self.connect((self.analog_sig_source_x_1, 0), (self.uhd_usrp_sink_0, 1))
        self.connect((self.analog_sig_source_x_1_0, 0), (self.blocks_multiply_xx_0, 0))
        self.connect((self.analog_sig_source_x_1_0, 0), (self.blocks_multiply_xx_0_0, 0))
        self.connect((self.blocks_add_const_vxx_0, 0), (self.qtgui_number_sink_0, 0))
        self.connect((self.blocks_complex_to_magphase_0, 1), (self.blocks_moving_average_xx_0, 0))
        self.connect((self.blocks_complex_to_magphase_0, 0), (self.blocks_null_sink_0, 0))
        self.connect((self.blocks_divide_xx_0, 0), (self.blocks_null_sink_1, 0))
        self.connect((self.blocks_moving_average_xx_0, 0), (self.blocks_add_const_vxx_0, 0))
        self.connect((self.blocks_multiply_xx_0, 0), (self.low_pass_filter_0, 0))
        self.connect((self.blocks_multiply_xx_0_0, 0), (self.low_pass_filter_0_0, 0))
        self.connect((self.low_pass_filter_0, 0), (self.blocks_divide_xx_0, 0))
        #self.connect((self.low_pass_filter_0_0, 0), (self.blocks_complex_to_magphase_0, 0))
        self.connect((self.low_pass_filter_0_0, 0), (self.blocks_divide_xx_0, 1))
        self.connect((self.uhd_usrp_source_0, 1), (self.blocks_multiply_xx_0, 1))
        self.connect((self.uhd_usrp_source_0, 0), (self.blocks_multiply_xx_0_0, 1))
        self.connect((self.uhd_usrp_source_0, 0), (self.qtgui_freq_sink_x_0, 0))
        self.connect((self.uhd_usrp_source_0, 1), (self.qtgui_freq_sink_x_0, 1))

        #self.connect((self.uhd_usrp_source_0, 1), (self.blocks_multiply_conj, 0))
        self.connect((self.analog_sig_source_x_1_0, 0), (self.blocks_multiply_conj, 0))
        self.connect((self.uhd_usrp_source_0, 0), (self.blocks_multiply_conj, 1))
        self.connect((self.blocks_multiply_conj,0), (self.blocks_complex_to_magphase_0,0))

    def closeEvent(self, event):
        self.settings = Qt.QSettings("GNU Radio", "switch_on_click")
        self.settings.setValue("geometry", self.saveGeometry())
        event.accept()

    def get_variable_function_probe_1_0(self):
        return self.variable_function_probe_1_0

    def set_variable_function_probe_1_0(self, variable_function_probe_1_0):
        self.variable_function_probe_1_0 = variable_function_probe_1_0

    def get_start_delay(self):
        return self.start_delay

    def set_start_delay(self, start_delay):
        self.start_delay = start_delay

    def get_samp_rate(self):
        return self.samp_rate

    def set_samp_rate(self, samp_rate):
        self.samp_rate = samp_rate
        self.uhd_usrp_source_0.set_samp_rate(self.samp_rate)
        self.uhd_usrp_sink_0.set_samp_rate(self.samp_rate)
        self.qtgui_freq_sink_x_0.set_frequency_range(0, self.samp_rate)
        self.low_pass_filter_0_0.set_taps(firdes.low_pass(1, self.samp_rate, 500e3, 100e3, firdes.WIN_HAMMING, 6.76))
        self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.samp_rate, 500e3, 100e3, firdes.WIN_HAMMING, 6.76))
        self.analog_sig_source_x_1_0.set_sampling_freq(self.samp_rate)
        self.analog_sig_source_x_1.set_sampling_freq(self.samp_rate)

    def get_fif(self):
        return self.fif

    def set_fif(self, fif):
        self.fif = fif
        self.analog_sig_source_x_1_0.set_frequency(-self.fif)
        self.analog_sig_source_x_1.set_frequency(self.fif)

    def get_fcenter(self):
        return self.fcenter

    def set_fcenter(self, fcenter):
        self.fcenter = fcenter
        self.uhd_usrp_source_0.set_center_freq(self.fcenter, 0)
        self.uhd_usrp_source_0.set_center_freq(self.fcenter, 1)
        self.uhd_usrp_sink_0.set_center_freq(self.fcenter, 0)
        self.uhd_usrp_sink_0.set_center_freq(self.fcenter, 1)

    def get_button5(self):
        return self.button5

    def set_button5(self, button5):
        self.button5 = button5

    def get_button4(self):
        return self.button4

    def set_button4(self, button4):
        self.button4 = button4

    def get_button3(self):
        return self.button3

    def set_button3(self, button3):
        self.button3 = button3

    def get_button2(self):
        return self.button2

    def set_button2(self, button2):
        self.button2 = button2

    def get_button1(self):
        return self.button1

    def set_button1(self, button1):
        self.button1 = button1


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

    from distutils.version import StrictVersion
    if StrictVersion(Qt.qVersion()) >= StrictVersion("4.5.0"):
        style = gr.prefs().get_string('qtgui', 'style', 'raster')
        Qt.QApplication.setGraphicsSystem(style)
    qapp = Qt.QApplication(sys.argv)

    tb = top_block_cls()
    tb.start()
    tb.show()

    def quitting():
        tb.stop()
        tb.wait()
    qapp.connect(qapp, Qt.SIGNAL("aboutToQuit()"), quitting)
    qapp.exec_()


if __name__ == '__main__':
    main()
_______________________________________________
USRP-users mailing list
USRP-users@lists.ettus.com
http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com

Reply via email to