I mean to set those controls dynamically based on incoming stream tags,
similar to the way burst tags work. For instance I designed a tx_gain
tag that gets read by uhd_usrp_sink and sets the gain using
set_command_time. I just wanted to know the easiest way to move this
modified sink to an OIT of tree module, even though I’ll be duplicating
most of the gr-uhd code to do it.
On 04/12/2013 07:45 PM, Sean Nowlan wrote:
I mean to set those controls dynamically based on incoming stream
tags, similar to the way burst tags work. For instance I designed a
tx_gain tag that gets read by uhd_usrp_sink and sets the gain using
set_command_time. I just wanted to know the easiest way to move this
modified sink to an OIT of tree module, even though I’ll be
duplicating most of the gr-uhd code to do it.
I see. Sounds like it doesn’t fit well. I wouldn’t recommend tags or for
that matter modifying the source/sink block. Since 1) the control is
async to the data anyway, 2) the control would get delayed by the data
pipeline, 3) it wouldn’t make sense in the case of the source block.
Rather I would create another block which opens a usrp session and
accepts control messages to act on. I happen to have one in the works,
but its not ready yet.
Also, if it fit well, you would FWIW, open the usrp device session in
your control block/IP, whatever that may be, and talk directly to it.
That may be convenient. A lot less to maintain out of tree in either
case anyway.
-josh
On 04/14/2013 05:53 AM, Josh B. wrote:
that matter modifying the source/sink block. Since 1) the control is
async to the data anyway, 2) the control would get delayed by the data
pipeline, 3) it wouldn’t make sense in the case of the source block.Rather I would create another block which opens a usrp session and
accepts control messages to act on. I happen to have one in the works,
but its not ready yet.
So that is to say I’d use the standard gr_uhd_usrp_sink block for the
data pipe and I’d create a separate USRP session from my own custom
block to handle just the control logic (timed gain and DUC retuning
commands, etc.)?
It looks like you’re working on exactly the types of things I’d like to
do:
I was thinking, since there’s a limited command buffer in the USRP,
would it make sense to add a message queue and encode timestamps and
commands into the message? Is there a way to test the FPGA command
buffer for fullness or some other way to prevent overflow?
So that is to say I’d use the standard gr_uhd_usrp_sink block for the
data pipe and I’d create a separate USRP session from my own custom
block to handle just the control logic (timed gain and DUC retuning
commands, etc.)?
Yup. Basically when you open a device with some address arguments, if
its already open in that process you get the same underlying device
session. So its totally ok to do this.
It looks like you’re working on exactly the types of things I’d like to do:
grextras/lib/uhd_control_port.cpp at next · guruofquality/grextras · GitHub
I was thinking, since there’s a limited command buffer in the USRP,
would it make sense to add a message queue and encode timestamps and
commands into the message? Is there a way to test the FPGA command
buffer for fullness or some other way to prevent overflow?
The way the commands work is that they backpressure if there isnt space
in the fpga. The call to set gain for example will block the caller
until there is space in the FPGA for the command.
So, overflow I wouldnt worry about. Now blocking in the caller’s context
may be undesirable. Now you probably want to minimize how much stuff is
queued up to be handled as a command in the future. But a queue and
another thread may be the way to go.
Now where should said queue and thread go? Well the user could do in the
the control logic, a block like the control one above could handle it,
or you could argue that UHD itself should do this enqueuing itself so
write only commands would never block the caller. Now that I am thinking
it out-loud, the latter actually seems like it could be in general a
helpful edition for UHD.
-josh