usrp-users@lists.ettus.com

Discussion and technical support related to USRP, UHD, RFNoC

View all threads

Custom RFNoC block test with UHD C++ (UHD-3.15.LTS)

JA
Jorge Arroyo Giganto
Thu, Oct 8, 2020 5:32 PM

Hi,

I am trying to test my RFNoC gain block, the one from the ‘Getting Started
with RFNoC Development’ guide, through the UHD C++ API on an E310 (I'm
using UHD-3.15.LTS, I know that UHD 4.0 has just been released but I would
appreciate it if someone could help me with this version).

I'm quite sure that the bitstream I generated is correct, when loading the
image and then running uhd_usrp_probe, the name I used in the gain.xml file
shows up among the other RFNoC blocks. Also, when doing
gain_block_ctrl->sr_write() and then checking the value through the
readback register with gain_block_ctrl->user_reg_read32() everything
seems to work fine.

What I'm trying to figure out is how to transmit and receive samples from
the block, I've tried a couple of ways and I'm still not getting a good
result.

First, I tried to send a packet with 200 samples to the block
(tx_stream->send(&tx_buff,
tx_buff.size(), tx_md,0.5)
, with tx_stream obtained through a device3 usrp
object, including tx_stream_args.args["block_id"] = "gain" and
tx_stream_args.args["block_port"]
= "0"
in the tx stream arguments, the tx_md (metadata) set up with
tx_md.start_of_burst
= false, tx_md.end_of_burst = false
and tx_md.has_time_spec = false, and
I didn't use the radio at all this way. When trying to receive
(rx_stream->recv(&rx_buff,
rx_buff.size(), rx_md, 5.0, true)
, including the "block_id" and
*"block_port"
*arguments in the rx stream like in the tx, and in mode
STREAM_MODE_NUM_SAMPS_AND_DONE), and I got an ERROR_CODE_TIMEOUT.

Then, I tried this time connecting the RFNoC Radio block to the gain block
with an rfnoc::graph and setting the radio and gain "block_id" and
*"block_port"
*arguments in the tx stream. When doing recv(), I got an unknown error:
"Receiver error: Unknown error code: 0x30" (does someone know what this
means?) when checking the rx_md.error_code. However, recv() returned
200, like if it had received the samples I sent, but the rx buffer was
empty.

I also tried using the RFNoC Replay block, but didn't get anywhere either.
Does anyone know if this block is supported in the E310? (this was asked in
the mailing list a while ago in
http://ettus.80997.x6.nabble.com/USRP-users-RFNoC-Replay-block-for-E310-td11156.html,
but I'd like to know if someone has tested it since then).

Lastly, I tried using threads, one with the recv() waiting for samples
and the main program thread doing the send(), but I wasn't lucky again. I
got this other unknown error: "Receiver error: Unknown error code:
0x3ce8e2b0".

So, which would be the best way to test my block? Again, I only want to see
that samples enter and exit multiplied by the gain value to understand how
I can work with RFNoC blocks from C++.

Also, I'm confused about this, when sending samples to the block its result
should be kept in the FIFO that then UHD reads from, so I understand that
there should be no reason for an active tx streamer to be streaming while
doing the recv(), because the *recv() *should just read the result from
the FIFO, or am I getting something wrong?

Any help would be appreciated.

Thanks in advance,

Jorge

Hi, I am trying to test my RFNoC gain block, the one from the ‘Getting Started with RFNoC Development’ guide, through the UHD C++ API on an E310 (I'm using UHD-3.15.LTS, I know that UHD 4.0 has just been released but I would appreciate it if someone could help me with this version). I'm quite sure that the bitstream I generated is correct, when loading the image and then running uhd_usrp_probe, the name I used in the gain.xml file shows up among the other RFNoC blocks. Also, when doing *gain_block_ctrl->sr_write()* and then checking the value through the readback register with *gain_block_ctrl->user_reg_read32()* everything seems to work fine. What I'm trying to figure out is how to transmit and receive samples from the block, I've tried a couple of ways and I'm still not getting a good result. First, I tried to send a packet with 200 samples to the block (*tx_stream->send(&tx_buff, tx_buff.size(), tx_md,0.5)*, with tx_stream obtained through a device3 usrp object, including *tx_stream_args.args["block_id"] = "gain"* and *tx_stream_args.args["block_port"] = "0"* in the tx stream arguments, the *tx_md* (metadata) set up with *tx_md.start_of_burst = false, tx_md.end_of_burst = false* and *tx_md.has_time_spec = false*, and I didn't use the radio at all this way. When trying to receive (*rx_stream->recv(&rx_buff, rx_buff.size(), rx_md, 5.0, true)*, including the *"block_id"* and *"block_port" *arguments in the rx stream like in the tx, and in mode *STREAM_MODE_NUM_SAMPS_AND_DONE*), and I got an *ERROR_CODE_TIMEOUT*. Then, I tried this time connecting the RFNoC Radio block to the gain block with an *rfnoc::graph* and setting the radio and gain *"block_id"* and *"block_port" *arguments in the tx stream. When doing *recv()*, I got an unknown error: "Receiver error: Unknown error code: 0x30" (does someone know what this means?) when checking the *rx_md.error_code*. However, *recv()* returned 200, like if it had received the samples I sent, but the rx buffer was empty. I also tried using the RFNoC Replay block, but didn't get anywhere either. Does anyone know if this block is supported in the E310? (this was asked in the mailing list a while ago in http://ettus.80997.x6.nabble.com/USRP-users-RFNoC-Replay-block-for-E310-td11156.html, but I'd like to know if someone has tested it since then). Lastly, I tried using threads, one with the *recv()* waiting for samples and the main program thread doing the *send()*, but I wasn't lucky again. I got this other unknown error: "Receiver error: Unknown error code: 0x3ce8e2b0". So, which would be the best way to test my block? Again, I only want to see that samples enter and exit multiplied by the gain value to understand how I can work with RFNoC blocks from C++. Also, I'm confused about this, when sending samples to the block its result should be kept in the FIFO that then UHD reads from, so I understand that there should be no reason for an active tx streamer to be streaming while doing the *recv()*, because the *recv() *should just read the result from the FIFO, or am I getting something wrong? Any help would be appreciated. Thanks in advance, Jorge
RK
Rob Kossler
Thu, Oct 8, 2020 7:28 PM

On Thu, Oct 8, 2020 at 1:33 PM Jorge Arroyo Giganto via USRP-users
usrp-users@lists.ettus.com wrote:

I am trying to test my RFNoC gain block, the one from the ‘Getting Started with RFNoC Development’ guide, through the UHD C++ API on an E310 (I'm using UHD-3.15.LTS, I know that UHD 4.0 has just been released but I would appreciate it if someone could help me with this version).

I'm quite sure that the bitstream I generated is correct, when loading the image and then running uhd_usrp_probe, the name I used in the gain.xml file shows up among the other RFNoC blocks. Also, when doing gain_block_ctrl->sr_write() and then checking the value through the readback register with gain_block_ctrl->user_reg_read32() everything seems to work fine.

What I'm trying to figure out is how to transmit and receive samples from the block, I've tried a couple of ways and I'm still not getting a good result.

First, I tried to send a packet with 200 samples to the block (tx_stream->send(&tx_buff, tx_buff.size(), tx_md,0.5), with tx_stream obtained through a device3 usrp object, including tx_stream_args.args["block_id"] = "gain" and tx_stream_args.args["block_port"] = "0" in the tx stream arguments, the tx_md (metadata) set up with tx_md.start_of_burst = false, tx_md.end_of_burst = false and tx_md.has_time_spec = false, and I didn't use the radio at all this way. When trying to receive (rx_stream->recv(&rx_buff, rx_buff.size(), rx_md, 5.0, true), including the "block_id" and "block_port" arguments in the rx stream like in the tx, and in mode STREAM_MODE_NUM_SAMPS_AND_DONE), and I got an ERROR_CODE_TIMEOUT.

Try setting the tx end-of-burst to true. Also, the block_id maybe
should be "gain_0" rather than "gain".  I'm not confident in these
suggestions, but worth a try.

Then, I tried this time connecting the RFNoC Radio block to the gain block with an rfnoc::graph and setting the radio and gain "block_id" and "block_port" arguments in the tx stream. When doing recv(), I got an unknown error: "Receiver error: Unknown error code: 0x30" (does someone know what this means?) when checking the rx_md.error_code. However, recv() returned 200, like if it had received the samples I sent, but the rx buffer was empty.

Can you try "rfnoc_rx_to_file" which allows you to specify your custom
block name on the command line and it will insert your block between
the Radio and the rx_streamer?

I also tried using the RFNoC Replay block, but didn't get anywhere either. Does anyone know if this block is supported in the E310? (this was asked in the mailing list a while ago in http://ettus.80997.x6.nabble.com/USRP-users-RFNoC-Replay-block-for-E310-td11156.html, but I'd like to know if someone has tested it since then).

As far as I know, the Replay block does not work for the E310.

Lastly, I tried using threads, one with the recv() waiting for samples and the main program thread doing the send(), but I wasn't lucky again. I got this other unknown error: "Receiver error: Unknown error code: 0x3ce8e2b0".

So, which would be the best way to test my block? Again, I only want to see that samples enter and exit multiplied by the gain value to understand how I can work with RFNoC blocks from C++.

Also, I'm confused about this, when sending samples to the block its result should be kept in the FIFO that then UHD reads from, so I understand that there should be no reason for an active tx streamer to be streaming while doing the recv(), because the recv() should just read the result from the FIFO, or am I getting something wrong?

The various rfnoc blocks do have input/output FIFOs such that if the
number of samples is small (such as 200 in your case), they can stay
in the FIFO until you get around to calling recv().  But, if it is a
continuous stream coming from the Radio, the FIFOs will fill very
quickly if you are not consuming the data at the same rate by using
recv().

On Thu, Oct 8, 2020 at 1:33 PM Jorge Arroyo Giganto via USRP-users <usrp-users@lists.ettus.com> wrote: > I am trying to test my RFNoC gain block, the one from the ‘Getting Started with RFNoC Development’ guide, through the UHD C++ API on an E310 (I'm using UHD-3.15.LTS, I know that UHD 4.0 has just been released but I would appreciate it if someone could help me with this version). > > I'm quite sure that the bitstream I generated is correct, when loading the image and then running uhd_usrp_probe, the name I used in the gain.xml file shows up among the other RFNoC blocks. Also, when doing gain_block_ctrl->sr_write() and then checking the value through the readback register with gain_block_ctrl->user_reg_read32() everything seems to work fine. > > What I'm trying to figure out is how to transmit and receive samples from the block, I've tried a couple of ways and I'm still not getting a good result. > > First, I tried to send a packet with 200 samples to the block (tx_stream->send(&tx_buff, tx_buff.size(), tx_md,0.5), with tx_stream obtained through a device3 usrp object, including tx_stream_args.args["block_id"] = "gain" and tx_stream_args.args["block_port"] = "0" in the tx stream arguments, the tx_md (metadata) set up with tx_md.start_of_burst = false, tx_md.end_of_burst = false and tx_md.has_time_spec = false, and I didn't use the radio at all this way. When trying to receive (rx_stream->recv(&rx_buff, rx_buff.size(), rx_md, 5.0, true), including the "block_id" and "block_port" arguments in the rx stream like in the tx, and in mode STREAM_MODE_NUM_SAMPS_AND_DONE), and I got an ERROR_CODE_TIMEOUT. Try setting the tx end-of-burst to true. Also, the block_id maybe should be "gain_0" rather than "gain". I'm not confident in these suggestions, but worth a try. > Then, I tried this time connecting the RFNoC Radio block to the gain block with an rfnoc::graph and setting the radio and gain "block_id" and "block_port" arguments in the tx stream. When doing recv(), I got an unknown error: "Receiver error: Unknown error code: 0x30" (does someone know what this means?) when checking the rx_md.error_code. However, recv() returned 200, like if it had received the samples I sent, but the rx buffer was empty. Can you try "rfnoc_rx_to_file" which allows you to specify your custom block name on the command line and it will insert your block between the Radio and the rx_streamer? > I also tried using the RFNoC Replay block, but didn't get anywhere either. Does anyone know if this block is supported in the E310? (this was asked in the mailing list a while ago in http://ettus.80997.x6.nabble.com/USRP-users-RFNoC-Replay-block-for-E310-td11156.html, but I'd like to know if someone has tested it since then). As far as I know, the Replay block does not work for the E310. > Lastly, I tried using threads, one with the recv() waiting for samples and the main program thread doing the send(), but I wasn't lucky again. I got this other unknown error: "Receiver error: Unknown error code: 0x3ce8e2b0". > > So, which would be the best way to test my block? Again, I only want to see that samples enter and exit multiplied by the gain value to understand how I can work with RFNoC blocks from C++. > > Also, I'm confused about this, when sending samples to the block its result should be kept in the FIFO that then UHD reads from, so I understand that there should be no reason for an active tx streamer to be streaming while doing the recv(), because the recv() should just read the result from the FIFO, or am I getting something wrong? The various rfnoc blocks do have input/output FIFOs such that if the number of samples is small (such as 200 in your case), they can stay in the FIFO until you get around to calling recv(). But, if it is a continuous stream coming from the Radio, the FIFOs will fill very quickly if you are not consuming the data at the same rate by using recv().