Hi Sam, Hi Rob,
This makes so much sense!
I think you are right.
And indeed, the issue I found only with TX, not RX.
Could you think of a possible hack sending a "dummy command" to the RF board
along with the timed tuning request?
Regarding the sending of time stamps in the TX in gr-uhd, I am confused though.
I do think this IS happening. I reproduce the work function of "USRP Sink" here:
int usrp_sink_impl::work(int noutput_items,
gr_vector_const_void_star& input_items,
gr_vector_void_star& output_items)
{
int ninput_items = noutput_items; // cuz it's a sync block
// default to send a mid-burst packet
_metadata.start_of_burst = false;
_metadata.end_of_burst = false;
// collect tags in this work()
const uint64_t samp0_count = nitems_read(0);
get_tags_in_range(_tags, 0, samp0_count, samp0_count + ninput_items);
if (not _tags.empty())
this->tag_work(ninput_items);
if (not pmt::is_null(_length_tag_key)) {
// check if there is data left to send from a burst tagged with
length_tag
// If a burst is started during this call to work(), tag_work() should
have
// been called and we should have _nitems_to_send > 0.
if (_nitems_to_send > 0) {
ninput_items = std::min<long>(_nitems_to_send, ninput_items);
// if we run out of items to send, it's the end of the burst
if (_nitems_to_send - long(ninput_items) == 0)
_metadata.end_of_burst = true;
} else {
// There is a tag gap since no length_tag was found immediately
following
// the last sample of the previous burst. Drop samples until the
next
// length_tag is found. Notify the user of the tag gap.
std::cerr << "tG" << std::flush;
// increment the timespec by the number of samples dropped
_metadata.time_spec += ::uhd::time_spec_t(0, ninput_items,
_sample_rate);
return ninput_items;
}
}
boost::this_thread::disable_interruption disable_interrupt;
#ifdef GR_UHD_USE_STREAM_API
// send all ninput_items with metadata
const size_t num_sent = _tx_stream->send(input_items, ninput_items,
_metadata, 1.0);
#else
const size_t num_sent = _dev->get_device()->send(input_items,
ninput_items,
_metadata,
*_type,
::uhd::device::SEND_MODE_FULL_BUFF,
1.0);
#endif
boost::this_thread::restore_interruption
restore_interrupt(disable_interrupt);
// if using length_tags, decrement items left to send by the number of
samples sent
if (not pmt::is_null(_length_tag_key) && _nitems_to_send > 0) {
_nitems_to_send -= long(num_sent);
}
// increment the timespec by the number of samples sent
_metadata.time_spec += ::uhd::time_spec_t(0, num_sent, _sample_rate);
// Some post-processing tasks if we actually transmitted the entire burst
if (not _pending_cmds.empty() && num_sent == size_t(ninput_items)) {
GR_LOG_DEBUG(d_debug_logger,
boost::format("Executing %d pending commands.") %
_pending_cmds.size());
BOOST_FOREACH (const pmt::pmt_t& cmd_pmt, _pending_cmds) {
msg_handler_command(cmd_pmt);
}
_pending_cmds.clear();
}
return num_sent;
}
From this code, it can be seen that the data is transmitted including _metadata:
const size_t num_sent = _tx_stream->send(input_items, ninput_items, _metadata,
1.0);
The "time_spec" is updated for each block that is sent out:
_metadata.time_spec += ::uhd::time_spec_t(0, num_sent, _sample_rate);
Now you mentioned "has_time_spec" below. I extended to code in the following
way:
// increment the timespec by the number of samples sent
_metadata.time_spec += ::uhd::time_spec_t(0, num_sent, _sample_rate);
GR_LOG_DEBUG(d_debug_logger, boost::format("Setting metadata time_spec:
%d:%f") % _metadata.time_spec.get_full_secs() %
_metadata.time_spec.get_frac_secs());
_metadata.has_time_spec = true;
To my understanding, gr-uhd now passes the correct timestamps on to UHD.
However, the timed command is still ignored.
Thanks,
Lukas
PS: I will attempt to use the tagged stream ... but then I will have the issue
that I need to tune TX *plus* RX at the same time! Furthermore, the streaming
tags API is super rudimentary. Also, skimming the source code for the tag
processing, I am not sure if this would change anything.
Gesendet: Dienstag, 03. März 2020 um 13:25 Uhr
Von: "Sam Reiter" <[email protected]>
An: "Rob Kossler" <[email protected]>
Cc: "Lukas Haase" <[email protected]>, "[email protected]"
<[email protected]>
Betreff: Re: [USRP-users] USRP X310 ignored DSP retuning on TX when using a
timed command
Everything Rob is saying is dead on - the "sense of time" for the radio is a
64-bit counter within the radio core that other blocks (like the DDC and DUC)
don't have access to. Those blocks need to derive a sense of time from the
timestamps of CHDR packets passing through them. I just wrapped up a new app
note that covers this (among other synchronization-related topics):
https://kb.ettus.com/Synchronizing_USRP_Events_Using_Timed_Commands_in_UHD#Clocking_and_Timekeeping_in_the_USRP
Lukas, I would doubt that this is an undiscovered bug as much as it is an issue
with implementation. If this were in C++, you'd want to set the 'has_time_spec'
and 'time_spec' fields of your TX metadata for at least 1 packet to impart a
sense of time on the DUC:
https://files.ettus.com/manual/structuhd_1_1tx__metadata__t.html[https://files.ettus.com/manual/structuhd_1_1tx__metadata__t.html]
I just spoke with someone on my end who said you need to use stream tags to do
this, but again, I don't currently have much direction for how that would be
implemented in your code.
Sam Reiter
On Tue, Mar 3, 2020 at 11:48 AM Rob Kossler
<[email protected][mailto:[email protected]]> wrote:
Also, note that there is no corresponding issue on receive because the Rx radio
always inserts the time stamp in the sample stream. So, I guess you would not
see this with the DDC.
Rob
On Tue, Mar 3, 2020 at 12:43 PM Rob Kossler
<[email protected][mailto:[email protected]]> wrote:
Hi Lukas,
The FPGA image on the USRP is divided into blocks such as the DUC block and the
Radio block. The latter controls the RF daughterboard and has access to the
device clock. So, when you provide a timed command to the Radio block (such as
for tuning the RF) it can implement the command at the specified time by
comparing to the device clock. The DUC block does not have access to the MB
clock and so when you give it a timed command, it monitors the incoming sample
stream to extract the time. If the sample stream does not include a time stamp,
the command never executes. Don't think of this as a bug, but rather as a
design limitation.
When I work directly with UHD from C++, I use the function
rx_streamer::issue_stream_command() which has options to stream data with no
time stamp or with a time stamp. When using timed commands with DUC or DDC, I
must include the time stamp or else the command will never be executed. But,
with GR, I don't know how to specify the corresponding options.
Rob
On Tue, Mar 3, 2020 at 12:29 PM Lukas Haase
<[email protected][mailto:[email protected]]> wrote:Hi Sam, Hi Rob,
Thanks for following up on this!
I am very happy you were able to reproduce this ... which means that at least
an issue exists :)
What Sam suggests makes sense even though hard to believe for me:
1. How could something like that go unnoticed for so long? (I am sure I am not
the first performing digital tuning)
2. In the past I got successful phase coherence using automatic tuning (passing
center frequency + offset to tune_request_t and using integer-N tuning) using
timed commands. This did not work reliably and only for certain frequencies but
in my opinion this should have INCLUDED the DUC tuning. If the DUC retune
wouldn't have been executed as part of this automatic tuning, I could not have
gotten phase coherence (and actually, not even the desired frequency).
The reason why I am only doing DUC tuning now is to avoid all the hassle with
integer-N tuning, PLL retuning and settling time.
Sam, what is the "radio block" you were talking about?
Anyway, would it be worthwile to attempt debugging this is absence of gr?
The only reason this prevented me from doing is that I would need to manually
create the baseband samples and continuously stream them out while in parallel
do the retuning.
I am not too familiar with UHD on its own but I assume this would be very
complicated, require multithreading etc.
Do you have any demo code that could be easily modified for this scenario?
Best,
Lukas
Gesendet: Dienstag, 03. März 2020 um 12:08 Uhr
Von: "Sam Reiter" <[email protected][mailto:[email protected]]>
An: "Rob Kossler" <[email protected][mailto:[email protected]]>
Cc: "Lukas Haase" <[email protected][mailto:[email protected]]>,
"[email protected][mailto:[email protected]]"
<[email protected][mailto:[email protected]]>
Betreff: Re: [USRP-users] USRP X310 ignored DSP retuning on TX when using a
timed command
For what it's worth, I was able to reproduce the behavior described here, but
didn't get to dig into it much. My leading suspicion would be what Rob
mentioned about timestamping. Lukas' code sets a command time, but I'm not
clear on how timestamp metadata for packets being sent to the radio are
handled. Might be a good question to loop the discuss-gnuradio mailing list in
on?
Sam Reiter
On Tue, Mar 3, 2020 at 10:59 AM Rob Kossler via USRP-users
<[email protected][mailto:[email protected]][mailto:[email protected][mailto:[email protected]]]>
wrote:
I wonder if the issue is related to a missing time stamp on the baseband
samples going from GR to UHD. If the stream does not have a time stamp, the
DUC is unable to apply the timed command because the DUC does not really know
the time - it must pull the time from the streaming samples. This is in
contrast to the radio block which does have access to time and can apply timed
commands by referring to the motherboard clock.
I am not too familiar with GR so I'm not sure how to know if GR is putting a
time stamp on the streaming samples.
Rob
On Mon, Mar 2, 2020 at 10:04 AM Lukas Haase via USRP-users
<[email protected][mailto:[email protected]][mailto:[email protected][mailto:[email protected]]]>
wrote:Hi Marcus,
Thank you that would be amazing!
I followed the tutorial and built everything from source:
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 18.04.4 LTS
Release: 18.04
Codename: bionic
$ uname -a
Linux sdr 5.3.0-40-generic #32~18.04.1-Ubuntu SMP Mon Feb 3 14:05:59 UTC 2020
x86_64 x86_64 x86_64 GNU/Linux
$ cd uhd
$ git status
HEAD detached at v3.15.0.0
$ cd ../gnuradio
$ git status
HEAD detached at v3.7.14.0
Thank you!
Lukas
PS: For some reason I sometimes do not get responses from this list. I just saw
it looking at the mailman archives. Hence I cannot respond (to keep headers
intact) but need to create a new message and manually "quote". I hope that
still preserves the context somehow.
Marcus Leech wrote:
> On 02/28/2020 01:01 PM, Lukas Haase via USRP-users wrote:
>> Hi again,
>>
>> I created a minimum example (gnuradio) that shows the issue described below.
>> To summarize: Retuning to a different dsp frequency on an USRP X310
>> (+UBX160) does not work (command ignored) ONLY if a timed command (in future
>> is used).
>> The code shows it in a simple manner. Commenting out the single line with
>> set_command_time makes the example work.
>>
>> I am absolutely out of ideas and would appreciate any input!
>>
>> Best,
>> Lukas
> Lukas.
>
> Thanks for sticking with this. I'll have a discussion with Ettus R&D to
> see if this is a known issue and/or if there's a workaround.
>
> Remind me which version of UHD you're using?
_______________________________________________
USRP-users mailing list
[email protected][mailto:[email protected]][mailto:[email protected][mailto:[email protected]]]
http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com_______________________________________________
USRP-users[http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com_______________________________________________USRP-users]
mailing list
[email protected][mailto:[email protected]][mailto:[email protected][mailto:[email protected]]]
http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com[http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com]
_______________________________________________
USRP-users mailing list
[email protected]
http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com