Hey,

sorry to post again, but I think this time I have a solution.
In my grc-generated python file I added the lines:

cmd_time_1 = self.sender_A.get_time_now() + uhd.time_spec_t(5.0)
self.uhd_rfnoc_streamer_fifo_0_0.set_start_time(cmd_time_1)
self.uhd_rfnoc_streamer_fifo_0.set_start_time(cmd_time_1)

Unfortunately this command did not do anything so i had to modify
rfnoc_block_impl.cc in the gr-ettus folder. I added:

#define BETTER
#ifdef BETTER
  if (_start_time_set) {
    _tx.metadata.has_time_spec = true;
    _tx.metadata.time_spec = _start_time;
    std::cout << "Patch: Start Time Stream inserted"<< std::endl;
  }
  else {
    _tx.metadata.has_time_spec = false;
  }
#endif

around line 300 after the commands

  _tx.metadata.start_of_burst = false;
  _tx.metadata.end_of_burst = false;
  _tx.metadata.has_time_spec = false;

so that now the _start_time_set variable actually is used.

(I then of course used make and make install in the gr-ettus/build)

Now I get the desired behauviour and in addition can set a start time for
both my streams.

Kudos to this guy
https://discuss-gnuradio.gnu.narkive.com/joj8MDyW/gnu-radio-3-7-12-rfnoc-set-start-time
who used this, to correct the set_start_time command and I hoped that this
would also fix my random phase offset problem, which was the case.


Best Regards

Felix


> Hello together,
>
> I wanted to give you a short update about phase-synchronizing my
> USRPx310's ubx160 daugtherboards and clarify the problem I am facing for
> better understandig.
>
> I am using both TX-Ports of my USRP to transmit the same complex cosine
> generated with GNU-Radio. My image is a custom RFNoC image and contains
> 2xDDC, 2xDUC, 2xRadio,1xDMA-FIFO,1xAddsub and 2xFIFO. My center frequency
> is 2.45 GHz and the frequency of the cosine is 100 KHz.
>
> My flowgraph looks like this,
>
> SigSource--->RFNoC_FIFO_0--->DMA_FIFO--->RFNoC-DUC_0-->RFNoC_Radio_A
>          |                |          |
>          -->RFNoC_FIFO_1---          --->RFNoC_DUC_1-->RFNoC_Radio_B
>
> and both antenna outputs are connected to an Agilent infiniium
> oscilloscope.
> Thus I can measure the phase offset between both of my output ports, by
> measuring the phase offset of both displayed cosines. My goal is to
> receive the same/almost the same relative phase offset with each new
> restart of the flowgraph. Sadly, using the RFNoC blocks, I get a different
> phase offset every time.
>
> When I use UHD-USRP Sink instead, (with the same Image and without RFNoC
> blocks) I do get a consistent phase offset between both ports with every
> restart of the flowgraph or even power cycles. This is the behaviour I
> want for my RFNoC Flowgraph as well; and because it is the same image, I
> am pretty sure there just must be a way to clone this behaviour to the
> RFNoC realm as well.
>
> My approach up till now was, to use timed commands in my GRC-generated
> python code for both RFnoC-Radio Blocks A and B, which each represent one
> daugtherboard, I think. I then put the .set_tx_freq commands in the code
> betweeen set_command time and clear_command time:
>
>   #A.get_time_now equals B.get_time_now
>   cmd_time = self.sender_A.get_time_now() + uhd.time_spec_t(0.1)
>   self.sender_A.set_command_time(cmd_time)
>   self.sender_B.set_command_time(cmd_time)
>   ----
>   Tuning Commands
>   self.sender_A.set_tx_freq(c_freq, i)
>   self.sender_B.set_tx_freq(c_freq, i)
>   ---
>
>   self.sender_A.clear_command_time(0)
>   self.sender_B.clear_command_time(0)
>   # End Timed Commands
>
> This approach however did not work for me.
>
> After my attempt with the timed commands failed, I tried to change all
> paramters. When I set the frequency of my cosine to zero I actually got a
> consistent phase offset. My conclusion is, that the mixers lock with a
> consistent relative phase offset every time, because DC Signals do not
> have relative phases. Because of that I think that maybe really both
> Radio-Blocks start streaming with a random time offset or something
> similar.
>
> Now to my questions
>
> 1) Is using the timed commands really the way to go? Remember I do NOT
> want to synchronize multiple USRP-Devices but only that both
> D-Boards/Radio-Blocks of one device, lock with the same relative phase.
>
> 2) Do I have to start the streaming manually somehow, with a timestamp or
> something similar? And when the answer is yes, how do I do it in python
> without the multi_usrp_api?
>
> 3) How can I control the start of streaming in my python code so that both
> RFNoC Radios start at the same time?
>
> 4) How does the UHD_USRP_Sink Block work? I mean is there a verilog code
> for it too and does it call the rfnoc_radio and rfnoc_duc modules etc.?
> What are the parameters for the UHD_USRP_Sink Blocks DMA_FIFO and DUC?
> I am asking this because I would like to clone that blocks behaviour
>
> 5) Any other question that I am not smart enough to ask but that deserves
> an answer either way :D
>
> Again, any help is greatly appreciated because the synchronisation of both
> TX-paths with RFnoC is crucial for my project and I can not work around
> this issue.
>
> Best regard and thank you for reading
>
> Felix
>
>
>> Hey Sam,
>>
>> thank you for your answer. Is your suggested [1] really useful for the
>> RFNoC Radio Blocks I am using? I think I only can use the commands from
>> path/include/ettus/rfnoc_radio.h, because the RFNoC_Radio Blocks are not
>> derived from usrp_block. (As far as I know)
>>
>> I then tried the timed commands and modified them a little because I
>> have
>> to use two rfnoc_radio_blocks, one for each dboard which I sadly can not
>> tune together. My thoughtprocess is, to tune the daugtherbaords in the
>> initiantion process, before they lock in the wrong phase. Here is the
>> code
>> I modified (With sender_A and sender_B beeing my two RFNoC Radio Blocks
>> which each represent one daugtherboard from the same USRP):
>>
>>         # Radio B
>>         self.sender_B = ettus.rfnoc_radio(
>>             self.device3,
>>             uhd.stream_args( # Tx Stream Args
>>                 cpu_format="fc32",
>>                 otw_format="sc16",
>>              args='(cpu="fc32", otw="sc16")',
>>             ),
>>             uhd.stream_args( # Rx Stream Args
>>                 cpu_format="fc32",
>>                 otw_format="sc16",
>>                 args="", # empty
>>             ),
>>             1, -1
>>         )
>>         #Ende Radio B
>>         # Radio A
>>         self.sender_A = ettus.rfnoc_radio(
>>             self.device3,
>>             uhd.stream_args( # Tx Stream Args
>>                 cpu_format="fc32",
>>                 otw_format="sc16",
>>              args='(cpu="fc32", otw="sc16")',
>>             ),
>>             uhd.stream_args( # Rx Stream Args
>>                 cpu_format="fc32",
>>                 otw_format="sc16",
>>                 args="", # empty
>>             ),
>>             0, -1
>>         )
>>         # Ende Radio A
>>
>>         # Timed Stuff
>>         #------------------------------------------------------------------
>>         last_pps_time = self.sender_A.get_time_last_pps()
>>         while last_pps_time == self.sender_A.get_time_last_pps():
>>             print("waiting...")
>>         self.sender_A.set_time_next_pps(uhd.time_spec_t(0.0))
>>         self.sender_B.set_time_next_pps(uhd.time_spec_t(0.0))
>>         #time.sleep(1)
>>
>>         self.cmd_time = self.sender_A.get_time_now() +
>> uhd.time_spec_t(0.1)
>>         self.sender_A.set_command_time(self.cmd_time,0)
>>         self.sender_B.set_command_time(self.cmd_time,0)
>>         #------------------------------------------------------------------
>>
>>         self.sender_A.set_rate(usrp_rate)
>>         for i in xrange(1):
>>             self.sender_A.set_tx_freq(c_freq, i)
>>             self.sender_B.set_tx_freq(c_freq, i)
>>             self.sender_A.set_tx_gain(0, i)
>>             self.sender_A.set_tx_dc_offset(True, i)
>>
>>         self.sender_A.set_tx_antenna("TX/RX", 0)
>>
>>         self.sender_A.set_clock_source("internal")
>>
>>
>>         self.sender_B.set_rate(usrp_rate)
>>         for i in xrange(1):
>>             #self.sender_B.set_tx_freq(c_freq, i)
>>             self.sender_B.set_tx_gain(0, i)
>>             self.sender_B.set_tx_dc_offset(True, i)
>>
>>         self.sender_B.set_tx_antenna("TX/RX", 0)
>>
>>         self.sender_B.set_clock_source("internal")
>>         #----------------------------------
>>         self.sender_A.clear_command_time(0)
>>         self.sender_B.clear_command_time(0)
>>         #----------------------------------
>>         # Ende Timed Stuff
>>
>> The edited Code does not throw errors but doesn't solve my problem
>> either
>> because with each new start of the flowgraph, there is still a different
>> phase offset. Do I maybe missed instructions in the Initiation process,
>> that have to be timed also to achieve phase sync? Or maybe its something
>> about the DUC Blocks?
>>
>> I think the code is not all wrong, because when I use it in my
>> set_c_freq
>> method below for my qtrange_slider the phase seems to be constant with
>> each retune. Just still not with each restart of the flowgraph sadly.
>>
>> def set_c_freq(self, c_freq):
>>         last_pps_time = self.sender_A.get_time_last_pps()
>>         while last_pps_time == self.sender_A.get_time_last_pps():
>>             print("waiting...")
>>         self.sender_A.set_time_next_pps(uhd.time_spec_t(0.0))
>>         self.sender_B.set_time_next_pps(uhd.time_spec_t(0.0))
>>         self.cmd_time = self.sender_A.get_time_now() +
>> uhd.time_spec_t(0.1)
>>         self.sender_A.set_command_time(self.cmd_time,0)
>>         self.sender_B.set_command_time(self.cmd_time,0)
>>         #tc start
>>         self.c_freq = c_freq
>>         for i in xrange(1):
>>             self.sender_B.set_tx_freq(self.c_freq, i)
>>         for i in xrange(1):
>>             self.sender_A.set_tx_freq(self.c_freq, i)
>>         #tc ende
>>         self.sender_A.clear_command_time(0)
>>         self.sender_B.clear_command_time(0)
>>
>>
>> I also read your suggested reading [2] and am not sure if I have to
>> follow
>> the commands under Synchronizing Channel Phase. Reason for this, is
>> because the rfnoc_radio.h controller does not support the
>> issue_stream_command method (it is not listed in controller class
>> rfnoc_radio.h). Changing to one single cosine did not solve my problem
>> btw.
>>
>> Another thing that bothers me is, that the article talks about
>> synchronising multiple device whereas in my case I only want to sync my
>> two daugtherboards of the x310. Is it still the same process? (When I
>> use
>> the UHD_USRP_SINK Block with two inputs, the phase seems to be constant
>> with each restart even without tuning them with timed commands. This
>> behauviour is the goal; only that I want to use RFnoC instead)
>>
>> Thank you for your help and best regards,
>>
>> Felix
>>
>>
>>> Hey Felix,
>>>
>>> Your hunch is correct -- you'll need to use timed commands to issue
>>> your
>>> tune requests and to initiate streaming. This will involve editing the
>>> python script generated by GRC. Here's a relevant GRC manual section
>>> [1],
>>> and an example snippet of tuning with timed commands in the UHD Manual
>>> [2].
>>> Doing this correctly should ensure that you are able to keep a
>>> consistent
>>> phase offset between your TX channels at a given frequency.
>>>
>>> I'm not sure if it'd actually be an issue, but one thing from your
>>> flowgraph struck me. You might want to fork the output of your cosine
>>> block
>>> so that both TX streams are being fed data from a single source. I
>>> don't
>>> think this will solve your problem, but if the blocks are doing the
>>> same
>>> thing, may help take a variable out of the equation.
>>>
>>> Sam
>>>
>>> [1]
>>> https://www.gnuradio.org/doc/doxygen/classgr_1_1uhd_1_1usrp__block.html
>>> [2] https://files.ettus.com/manual/page_sync.html#sync_phase_lo
>>>
>>>
>>> On Thu, Aug 29, 2019 at 8:49 AM Felix Greiwe via USRP-users <
>>> usrp-users@lists.ettus.com> wrote:
>>>
>>>> Hello together,
>>>>
>>>> I am trying to transmit one complex cosine from both TX - Antenna of
>>>> my
>>>> USRP-x310 with two UBX-160 Daugtherboards. I am transmitting a cosine
>>>> with
>>>> the frequency of 100 kHz and the center frequency of my RFNoC Radio
>>>> Blocks
>>>> is 2.45 GHz. So basically I see a peak at 2.45 Ghz + 100 kHz at my
>>>> spectrum analyzer (plus the lo leakage at 2.45 GHz). Additionally I
>>>> receive the spectrum on another x310.
>>>>
>>>> In the following link you can see my flowgraph in GRC:
>>>> https://ibb.co/7W6mTKf
>>>>
>>>> As you can see i have two multiply blocks to change the phase of the
>>>> complex cosines, the value of the multiply blocks are
>>>>
>>>> > pow(math.e, 1j*phi*(math.pi/180)) and
>>>> > pow(math.e, 1j*psi*(math.pi/180)).
>>>>
>>>> I can change phi and psi with a qt gui range slider. Default value ist
>>>> multiplication by 1.
>>>>
>>>> My goal with this setup was to check the MIMO capabilities of the USRP
>>>> x310.
>>>> I calculated the Phase offset both transmitted waves should have at
>>>> the
>>>> antenna of my spectrum analyzer. With my multiplication blocks I
>>>> created
>>>> different phase offsets, thus causing destructive interference at the
>>>> receiving end (peak at analyzer is the smallest at this phase).
>>>>
>>>> However most of the time when I start different runs of my flowgraph
>>>> (or
>>>> when I power cycle the device) I always have to set a different phase
>>>> offset to see the destructive interference. To me it seems pretty
>>>> random
>>>> which phase offset both transmitting path get even though I don't
>>>> understand why.
>>>>
>>>> In another thread I read that maybe timed tuning will work for me but
>>>> I
>>>> did not quite understand what that improves in particular nor who I
>>>> use
>>>> it
>>>> in my  GRC generated python file. (Using the RFnoC Radio Blocks does
>>>> not
>>>> make it easier by the way.) This is the link:
>>>>
>>>>
>>>> http://ettus.80997.x6.nabble.com/USRP-users-use-a-usrp-x310-as-MIMO-transmitter-daughterboard-synchronization-tt11642.html
>>>>
>>>> Any ideas, suggestions and explanations on how to phase align the
>>>> transmit
>>>> path of my (single) USRP x310 would be greatly appreciated!
>>>>
>>>> Best regards
>>>>
>>>> Felix
>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> 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
>>
>
>
>
> _______________________________________________
> 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