No, I tried modifying it. I have attached the same for your reference.
Regards
Snehasish
Sent from Mail<https://go.microsoft.com/fwlink/?LinkId=550986> for Windows 10
From: Jonathon Pendlum<mailto:[email protected]>
Sent: 26 May 2021 23:36
To: Snehasish Kar<mailto:[email protected]>
Cc: Rob Kossler<mailto:[email protected]>;
[email protected]<mailto:[email protected]>
Subject: Re: [USRP-users] Re: Timeout while streaming IQ samples to host in
RFNOC
Hi Snehasish,
Do you get a timeout when connecting the FIR filter via rfnoc_rx_to_file's
"--block-id" option? What about the FIFO block? Also, I would highly suggest
updating to the UHD 3.15 LTS branch.
Jonathon
On Wed, May 26, 2021 at 1:20 PM Snehasish Kar
<[email protected]<mailto:[email protected]>> wrote:
Hello Jonathan
Tried with the example as you said, but if only try to stream from rfnoc radio
I am able get IQ samples in the host . But as soon as I connect a fir filter
with cutoff frequency 20MHz and transition 5MHz, it gives a timeout error.
My current flowgraph looks something like this:
Radio=>fifo=>fir filter=>fifo=> host
Regards
Snehasish
Get Outlook for iOS<https://aka.ms/o0ukef>
From: Jonathon Pendlum
<[email protected]<mailto:[email protected]>>
Sent: Friday, May 21, 2021 12:13:48 AM
To: Snehasish Kar <[email protected]<mailto:[email protected]>>
Cc: Rob Kossler <[email protected]<mailto:[email protected]>>;
[email protected]<mailto:[email protected]>
<[email protected]<mailto:[email protected]>>
Subject: Re: [USRP-users] Re: Timeout while streaming IQ samples to host in
RFNOC
Hello Snehasish,
I would suggest starting with a known working in-tree example like
rfnoc_rx_to_file.cpp. It has a section that connects a user defined RFNoC
block, and you can easily modify that to instead connect the FIFOs and FIR
filter.
Jonathon
On Thu, May 20, 2021 at 4:31 AM Snehasish Kar
<[email protected]<mailto:[email protected]>> wrote:
Hello Rob
Tried that but it didn’t work. I am using the standard RFNOC fir filter and
radio.
Regards
Snehasish
Sent from Mail<https://go.microsoft.com/fwlink/?LinkId=550986> for Windows 10
From: Rob Kossler<mailto:[email protected]>
Sent: 18 May 2021 21:39
To: Snehasish Kar<mailto:[email protected]>
Cc: [email protected]<mailto:[email protected]>
Subject: Re: [USRP-users] Timeout while streaming IQ samples to host in RFNOC
Perhaps try issue_stream_cmd on the radio ctrl rather than the rx_streamer.
Rob
On Mon, May 17, 2021 at 12:45 PM Snehasish Kar
<[email protected]<mailto:[email protected]>> wrote:
Hello
I am using the below code to stream IQ samples to host using RFNOC, but while
streaming I am getting timeout. My rfnoc graph looks something like this:
Radio_0=>fifo=>fir_filter=>fifo=>host
Radio_1=>fifo=>fir_filter=>fifo=>host
With the above flowgraph we are able to stream samples in gnuradio.
Sample rate used: 100msps
Host PC configuration: intel i7 processor 9th gen
RAM: 8GB
Interface: PCIE express
UHD version: UHD_3.14.1.0-0-unknown
Below is the output of uhd_usrp_probe:
:~/Desktop/uhd_rfnoc_file_writter/Debug$ uhd_usrp_probe
[INFO] [UHD] linux; GNU C++ version 7.5.0; Boost_106501; UHD_3.14.1.0-0-unknown
[INFO] [X300] X300 initialization sequence...
[INFO] [X300] Connecting to niusrpriorpc at localhost:5444...
[INFO] [X300] Using LVBITX bitfile
/usr/local/share/uhd/images/usrp_x310_fpga_XG.lvbitx...
[INFO] [X300] Radio 1x clock: 200 MHz
[INFO] [GPS] Found an internal GPSDO: LC_XO, Firmware Rev 0.929a
[WARNING] [GPS] update_cache: Malformed GPSDO string: LC_XO, Firmware Rev 0.929a
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000000)
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1311 MB/s)
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1315 MB/s)
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000000001)
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000000001)
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)
[INFO] [0/FIR_0] Initializing block control (NOC ID: 0xF112000000000000)
[INFO] [0/FIR_1] Initializing block control (NOC ID: 0xF112000000000000)
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000000)
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000000)
[INFO] [0/FIFO_0] Initializing block control (NOC ID: 0xF1F0000000000000)
[INFO] [0/FIFO_1] Initializing block control (NOC ID: 0xF1F0000000000000)
[INFO] [0/FIFO_2] Initializing block control (NOC ID: 0xF1F0000000000000)
[INFO] [0/FIFO_3] Initializing block control (NOC ID: 0xF1F0000000000000)
[WARNING] [X300] Cannot update master clock rate! X300 Series does not allow
changing the clock rate during runtime.
_____________________________________________________
/
| Device: X-Series Device
| _____________________________________________________
| /
| | Mboard: X310
| | revision: 11
| | revision_compat: 7
| | product: 30960
| | mac-addr0: 00:80:2f:18:de:4d
| | mac-addr1: 00:80:2f:18:de:4e
| | gateway: 192.168.10.1
| | ip-addr0: 192.168.10.2
| | subnet0: 255.255.255.0
| | ip-addr1: 192.168.20.2
| | subnet1: 255.255.255.0
| | ip-addr2: 192.168.30.2
| | subnet2: 255.255.255.0
| | ip-addr3: 192.168.40.2
| | subnet3: 255.255.255.0
| | serial: 314B293
| | FW Version: 6.0
| | FPGA Version: 35.1
| | FPGA git hash: fffffff-dirty
| | RFNoC capable: Yes
| |
| | Time sources: internal, external, gpsdo
| | Clock sources: internal, external, gpsdo
| | Sensors: gps_gpgga, gps_gprmc, gps_time, gps_locked, gps_servo,
ref_locked
| | _____________________________________________________
| | /
| | | RX Dboard: A
| | | ID: TwinRX Rev B (0x0093)
| | | Serial: 3147FB8
| | | _____________________________________________________
| | | /
| | | | RX Frontend: 0
| | | | Name: TwinRX RX0
| | | | Antennas: RX1, RX2
| | | | Sensors: lo_locked
| | | | Freq range: 10.000 to 6000.000 MHz
| | | | Gain range all: 0.0 to 93.0 step 1.0 dB
| | | | Bandwidth range: 80000000.0 to 80000000.0 step 0.0 Hz
| | | | Connection Type: II
| | | | Uses LO offset: No
| | | _____________________________________________________
| | | /
| | | | RX Frontend: 1
| | | | Name: TwinRX RX1
| | | | Antennas: RX1, RX2
| | | | Sensors: lo_locked
| | | | Freq range: 10.000 to 6000.000 MHz
| | | | Gain range all: 0.0 to 93.0 step 1.0 dB
| | | | Bandwidth range: 80000000.0 to 80000000.0 step 0.0 Hz
| | | | Connection Type: QQ
| | | | Uses LO offset: No
| | | _____________________________________________________
| | | /
| | | | RX Codec: A
| | | | Name: ads62p48
| | | | Gain range digital: 0.0 to 6.0 step 0.5 dB
| | _____________________________________________________
| | /
| | | RX Dboard: B
| | | ID: TwinRX Rev B (0x0093)
| | | Serial: 3147FC1
| | | _____________________________________________________
| | | /
| | | | RX Frontend: 0
| | | | Name: TwinRX RX0
| | | | Antennas: RX1, RX2
| | | | Sensors: lo_locked
| | | | Freq range: 10.000 to 6000.000 MHz
| | | | Gain range all: 0.0 to 93.0 step 1.0 dB
| | | | Bandwidth range: 80000000.0 to 80000000.0 step 0.0 Hz
| | | | Connection Type: II
| | | | Uses LO offset: No
| | | _____________________________________________________
| | | /
| | | | RX Frontend: 1
| | | | Name: TwinRX RX1
| | | | Antennas: RX1, RX2
| | | | Sensors: lo_locked
| | | | Freq range: 10.000 to 6000.000 MHz
| | | | Gain range all: 0.0 to 93.0 step 1.0 dB
| | | | Bandwidth range: 80000000.0 to 80000000.0 step 0.0 Hz
| | | | Connection Type: QQ
| | | | Uses LO offset: No
| | | _____________________________________________________
| | | /
| | | | RX Codec: B
| | | | Name: ads62p48
| | | | Gain range digital: 0.0 to 6.0 step 0.5 dB
| | _____________________________________________________
| | /
| | | TX Dboard: A
| | | ID: Unknown (0x0092)
| | | Serial: 3147FB8
| | | _____________________________________________________
| | | /
| | | | TX Frontend: 0
| | | | Name: Unknown (0x0092) - 0
| | | | Antennas:
| | | | Sensors:
| | | | Freq range: 0.000 to 0.000 MHz
| | | | Gain Elements: None
| | | | Bandwidth range: 0.0 to 0.0 step 0.0 Hz
| | | | Connection Type: IQ
| | | | Uses LO offset: No
| | | _____________________________________________________
| | | /
| | | | TX Codec: A
| | | | Name: ad9146
| | | | Gain Elements: None
| | _____________________________________________________
| | /
| | | TX Dboard: B
| | | ID: Unknown (0x0092)
| | | Serial: 3147FC1
| | | _____________________________________________________
| | | /
| | | | TX Frontend: 0
| | | | Name: Unknown (0x0092) - 0
| | | | Antennas:
| | | | Sensors:
| | | | Freq range: 0.000 to 0.000 MHz
| | | | Gain Elements: None
| | | | Bandwidth range: 0.0 to 0.0 step 0.0 Hz
| | | | Connection Type: IQ
| | | | Uses LO offset: No
| | | _____________________________________________________
| | | /
| | | | TX Codec: B
| | | | Name: ad9146
| | | | Gain Elements: None
| | _____________________________________________________
| | /
| | | RFNoC blocks on this device:
| | |
| | | * DmaFIFO_0
| | | * Radio_0
| | | * Radio_1
| | | * DDC_0
| | | * DDC_1
| | | * FIR_0
| | | * FIR_1
| | | * DUC_0
| | | * DUC_1
| | | * FIFO_0
| | | * FIFO_1
| | | * FIFO_2
| | | * FIFO_3
Source code:
void uhd_interface::start_streamming(int32_t num_samples_to_receive, int16_t
max_channels, uint64_t samples_per_burst, int32_t total_no_of_samps) {
uhd::rx_metadata_t md;
bool overflow_message = true;
try {
uhd::rfnoc::graph::sptr rx_graph =
usrp_rfnoc->create_graph("antidrone_rx_chain");
usrp_rfnoc->clear();
//rx_graph->connect(radio_ctrl[0]->get_block_id(),
fifo_ctrl[0]->get_block_id());
//rx_graph->connect(fifo_ctrl[0]->get_block_id(),
fir_ctrl[0]->get_block_id());
//rx_graph->connect(fir_ctrl[0]->get_block_id(),
fifo_ctrl[1]->get_block_id());
//rx_graph->connect(radio_ctrl[1]->get_block_id(),
fifo_ctrl[2]->get_block_id());
//rx_graph->connect(fifo_ctrl[2]->get_block_id(),
fir_ctrl[1]->get_block_id());
//rx_graph->connect(fir_ctrl[1]->get_block_id(),
fifo_ctrl[3]->get_block_id());
rx_graph->connect(radio_ctrl[0]->get_block_id(), 0,
fifo_ctrl[1]->get_block_id(), 0);
} catch (const std::exception& ex) {
char msg[100]={0x00};
sprintf(msg,"error: unable to create/set a
radio/parameter %s", ex.what());
log_printf(msg, error_lvl, __FILE__, __LINE__);
}
uhd::device_addr_t stream_args_rfnoc;
std::vector<std::string> block_port{"0", "1"};
stream_args_rfnoc["block_id"] =
fifo_ctrl[1]->get_block_id().to_string();
stream_args_rfnoc["block_port"] = block_port[0];
//stream_args_rfnoc["block_id"] =
fifo_ctrl[3]->get_block_id().to_string();
//stream_args_rfnoc["block_port"] = block_port[1];
uhd::stream_args_t stream_args("sc16","sc16");
stream_args.args = stream_args_rfnoc;
size_t spp = radio_ctrl[0]->get_args().cast<size_t>("spp", spp);
stream_args.args["spp"] = boost::lexical_cast<std::string>(spp);
//TODO: considering 1000 samples but check
rx_stream = uhd_src->get_rx_stream(stream_args);
{
char msg[100]={0x00};
sprintf(msg, "info: Daemon launched with pid %d",
getpid());
log_printf(msg, error_lvl, __FILE__, __LINE__);
}
//samples_per_burst = 1000;
uhd::stream_cmd_t
stream_cmd(/*uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS*/
uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE);
stream_cmd.num_samps = total_no_of_samps;
stream_cmd.stream_now = true;
//stream_cmd.time_spec = uhd_src->get_time_now() +
::uhd::time_spec_t(0.1);//time_spec;
rx_stream->issue_stream_cmd(stream_cmd);
samples_per_burst = rx_stream->get_max_num_samps();
std::vector<std::vector<std::complex<float>>>
buffer_data(max_channels, std::vector<std::complex<float> >(samples_per_burst));
std::vector<void *> buffs(max_channels);
for(int8_t i = 0;i<max_channels;i++) {
buffs[i] = &buffer_data[i].front();
}
uint64_t total_samps_recvd =0x00;
int32_t total_size_wrote_to_file =0x00;
int32_t counter = 0x00;
//std::complex<float> array1[100000][1000]{{0x00}};
//std::complex<float> array2[100000][1000]{{0x00}};
//fprintf(stderr,"total num of samps %d\n", total_no_of_samps);
while(!stop_rx and ((total_samps_recvd!=total_no_of_samps) or
(total_no_of_samps==0x00))) {
buffs.clear();
size_t num_rx_samps = 0x00;
try {
num_rx_samps = rx_stream->recv(buffs,
samples_per_burst, md, 1.0);
if(error_lvl==3) {
char msg[700]={0x00};
sprintf(msg,"\n========================================================\n
Number of samples received
%u\n========================================================", num_rx_samps);
log_printf(msg,
error_lvl, __FILE__, __LINE__);
//std::cout <<
"total_samps_recvd : " << total_samps_recvd << " total_no_of_samps : " <<
total_no_of_samps << "\n";
}
} catch (const std::exception& ex){
char msg[100]={0x00};
sprintf(msg,"error: error while
streaming %s", ex.what());
log_printf(msg, error_lvl, __FILE__,
__LINE__);
}
if (md.error_code ==
uhd::rx_metadata_t::ERROR_CODE_TIMEOUT) {
log_printf("error: timeout while streaming",
error_lvl, __FILE__, __LINE__);
break;
}
if (md.error_code ==
uhd::rx_metadata_t::ERROR_CODE_OVERFLOW) {
if (overflow_message) {
overflow_message = false;
log_printf("error:
overflow detected", error_lvl, __FILE__, __LINE__);
}
continue;
}
if (md.error_code !=
uhd::rx_metadata_t::ERROR_CODE_NONE){
char msg[100]={0x00};
sprintf(msg,"error: %s",md.strerror());
log_printf(msg , error_lvl, __FILE__,
__LINE__);
}
total_samps_recvd+=num_rx_samps;
#if 1
//Read IQ samples from usrp and store the in the FILE
for(int32_t i=0;i<max_channels;i++) {
FILE *fp = fopen(file_name[i],"a+");
size_t len =
fwrite(&buffer_data[i].front(), sizeof(std::complex<float>), num_rx_samps, fp);
fclose(fp);
}
#endif
#if 0
//Read IQ samples from usrp and store the in the FILE
for(int32_t i=0;i<max_channels;i++) {
switch(i) {
case 0: memcpy(array1[counter],
&buffer_data[i].front(), sizeof(std::complex<float>)*num_rx_samps); break;
case 1: memcpy(array2[counter],
&buffer_data[i].front(), sizeof(std::complex<float>)*num_rx_samps); break;
}
}
counter++;
#endif
}
fprintf(stderr, "total samples received file: %d\n",
total_samps_recvd);
log_printf("warning: stopping streaming mode", error_lvl,
__FILE__, __LINE__);
log_printf("warning: buffer flush started!", error_lvl, __FILE__,
__LINE__);
uhd::stream_cmd_t
stream_cmd_stop(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS);
rx_stream->issue_stream_cmd(stream_cmd_stop);
//std::cout << "total_samps_recvd : " << total_samps_recvd << "
total_no_of_samps : " << total_no_of_samps << "\n";
#if 0
constexpr double timeout { 0.010 }; //10ms
static std::complex<short> dummy_buffer[50000000];
static uhd::rx_metadata_t dummy_meta { };
while (rx_stream->recv(dummy_buffer, 50000000, dummy_meta,
timeout)) {}
uhd_src->clear_command_time(); //Reset all time counters untill
next tune!!
log_printf("warning: buffer flush completed!", error_lvl,
__FILE__, __LINE__);
#endif
}
Hoping for an early reply.
Regards
Snehasish
Sent from Mail<https://go.microsoft.com/fwlink/?LinkId=550986> for Windows 10
_______________________________________________
USRP-users mailing list --
[email protected]<mailto:[email protected]>
To unsubscribe send an email to
[email protected]<mailto:[email protected]>
_______________________________________________
USRP-users mailing list --
[email protected]<mailto:[email protected]>
To unsubscribe send an email to
[email protected]<mailto:[email protected]>
/*
* uhd_file_writter.cpp
*
* Created on: May 21, 2021
* Author: Snehasish
*/
#include <uhd/device3.hpp>
#include <uhd/exception.hpp>
#include <uhd/rfnoc/radio_ctrl.hpp>
#include <uhd/rfnoc/ddc_block_ctrl.hpp>
#include <uhd/rfnoc/source_block_ctrl_base.hpp>
#include <uhd/rfnoc/dma_fifo_block_ctrl.hpp>
#include <uhd/types/sensors.hpp>
#include <uhd/types/tune_request.hpp>
#include <uhd/utils/safe_main.hpp>
#include <uhd/utils/thread.hpp>
#include <boost/format.hpp>
#include <uhd/rfnoc/fir_block_ctrl.hpp>
#include <chrono>
#include <complex>
#include <csignal>
#include <fstream>
#include <iostream>
#include <thread>
#include <inttypes.h>
#include <liquid/liquid.h>
const int64_t UPDATE_INTERVAL = 1; // 1 second update interval for BW summary
static bool stop_signal_called = false;
void sig_int_handler(int)
{
stop_signal_called = true;
}
void recv_to_file(uhd::rx_streamer::sptr rx_stream, const std::string& file,
const size_t samps_per_buff, const double rx_rate, const unsigned long long
num_requested_samples, unsigned long long num_total_samps = 0) {
uhd::rx_metadata_t md;
std::vector<std::complex<float>> buff(samps_per_buff);
std::ofstream outfile;
if (not file.empty()) {
outfile.open(file.c_str(), std::ofstream::binary);
}
bool overflow_message = true;
// setup streaming
uhd::stream_cmd_t stream_cmd((num_requested_samples == 0) ?
uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS :
uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE);
stream_cmd.num_samps = size_t(num_requested_samples);
stream_cmd.stream_now = true;
stream_cmd.time_spec = uhd::time_spec_t();
std::cout << "Issuing stream cmd" << std::endl;
rx_stream->issue_stream_cmd(stream_cmd);
// Run this loop until either time expired (if a duration was given), until
// the requested number of samples were collected (if such a number was
// given), or until Ctrl-C was pressed.
while (not stop_signal_called and (num_requested_samples != num_total_samps
or num_requested_samples == 0)) {
const auto now = std::chrono::steady_clock::now();
size_t num_rx_samps = rx_stream->recv(&buff.front(), buff.size(), md,
3.0, false);
if (md.error_code == uhd::rx_metadata_t::ERROR_CODE_TIMEOUT) {
std::cout << "Timeout while streaming"<< std::endl;
break;
}
if (md.error_code == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW) {
if (overflow_message) {
overflow_message = false;
std::cout<< "overflow" <<std::endl;
}
continue;
}
if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) {
continue;
}
num_total_samps += num_rx_samps;
if (outfile.is_open()) {
outfile.write((const char*)&buff.front(),
num_rx_samps*sizeof(std::complex<float>));
}
}
const auto actual_stop_time = std::chrono::steady_clock::now();
stream_cmd.stream_mode = uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS;
std::cout << "Issuing stop stream cmd" << std::endl;
rx_stream->issue_stream_cmd(stream_cmd);
// Run recv until nothing is left
int num_post_samps = 0;
do {
num_post_samps = rx_stream->recv(&buff.front(), buff.size(), md, 3.0);
} while (num_post_samps and md.error_code ==
uhd::rx_metadata_t::ERROR_CODE_NONE);
if (outfile.is_open())
outfile.close();
}
typedef boost::function<uhd::sensor_value_t(const std::string&)>
get_sensor_fn_t;
bool check_locked_sensor(std::vector<std::string> sensor_names,
const char* sensor_name,
get_sensor_fn_t get_sensor_fn,
double setup_time)
{
if (std::find(sensor_names.begin(), sensor_names.end(), sensor_name)
== sensor_names.end())
return false;
auto setup_timeout = std::chrono::steady_clock::now()
+ std::chrono::milliseconds(int64_t(setup_time *
1000));
bool lock_detected = false;
std::cout << boost::format("Waiting for \"%s\": ") % sensor_name;
std::cout.flush();
while (true) {
if (lock_detected and (std::chrono::steady_clock::now() >
setup_timeout)) {
std::cout << " locked." << std::endl;
break;
}
if (get_sensor_fn(sensor_name).to_bool()) {
std::cout << "+";
std::cout.flush();
lock_detected = true;
} else {
if (std::chrono::steady_clock::now() > setup_timeout) {
std::cout << std::endl;
throw std::runtime_error(
str(boost::format(
"timed out waiting for consecutive locks on sensor
\"%s\"")
% sensor_name));
}
std::cout << "_";
std::cout.flush();
}
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
std::cout << std::endl;
return true;
}
int UHD_SAFE_MAIN(int argc, char* argv[])
{
uhd::set_thread_priority_safe();
std::vector<int32_t>taps { -3, 0, 26, 67, 66, -52, -281, -434, -220, 476,
1300, 1441, 189, \
-2241, -4293, -3628,
1388, 10218, 19846, 26134, 26134, 19846, \
10218, 1388,
-3628, -4293, -2241, 189, 1441, 1300, 476, -220, \
-434, -281,
-52, 66, 67, 26, 0, -3
\
};
uint32_t d_ntaps = estimate_req_filter_len((5e3/1e6),60.0); //filter taps
size
std::vector<float> low_pass_filter_taps;
std::vector<int> taps_lpf(d_ntaps, 0x00);
low_pass_filter_taps.resize(d_ntaps, 0x00);
liquid_firdes_kaiser(d_ntaps, 125e3/1e6, 60.0, 0.0f,
&low_pass_filter_taps.front());
for(int32_t i=0;i<d_ntaps;i++){
taps_lpf[i] = low_pass_filter_taps[i]*32767;
}
// variables to be set by po
std::string args, file="/home/vehere/test.bin", format, ant, subdev, ref,
wirefmt, streamargs, radio_args,
block_id, block_args;
size_t total_num_samps = 100e6, spb = 1000, radio_id = 0, radio_chan = 0;
double rate = 100e6, freq=2.462e9, gain=70, bw = 100e6;
/************************************************************************
* Create device and block controls
***********************************************************************/
std::cout << "Creating the USRP device with: %s..." << args <<std::endl;
uhd::device3::sptr usrp = uhd::device3::make(args);
// Create handle for radio object
uhd::rfnoc::block_id_t radio_ctrl_id(0, "Radio", radio_id);
// This next line will fail if the radio is not actually available
uhd::rfnoc::radio_ctrl::sptr radio_ctrl =
usrp->get_block_ctrl<uhd::rfnoc::radio_ctrl>(radio_ctrl_id);
std::cout << "Using radio " << radio_id << ", channel " << radio_chan <<
std::endl;
// Create block controls for DDCs
uhd::rfnoc::block_id_t ddc_ctrl_id0(0, "DDC", 0);
uhd::rfnoc::ddc_block_ctrl::sptr ddc_ctrl0 =
usrp->get_block_ctrl<uhd::rfnoc::ddc_block_ctrl>(ddc_ctrl_id0);
ddc_ctrl0->set_arg<double> ("freq", 1e6, 0);
// Create block controls for DMA-FIFO
uhd::rfnoc::block_id_t dmafifo_ctrl_id(0, "DmaFIFO", 0);
uhd::rfnoc::dma_fifo_block_ctrl::sptr dmafifo_ctrl =
usrp->get_block_ctrl<uhd::rfnoc::dma_fifo_block_ctrl>(dmafifo_ctrl_id);
dmafifo_ctrl->resize(0, 33554432, 0);
dmafifo_ctrl->resize(33554432, 33554432, 1);
uhd::rfnoc::block_id_t fir_ctrl_id(0, "FIR", radio_id);
uhd::rfnoc::fir_block_ctrl::sptr fir_ctrl =
usrp->get_block_ctrl<uhd::rfnoc::fir_block_ctrl>(fir_ctrl_id);
fir_ctrl->set_taps(taps_lpf);
uhd::rfnoc::block_id_t fifo_ctrl_id(0, "FIFO", radio_id);
uhd::rfnoc::block_ctrl_base::sptr fifo_ctrl =
usrp->get_block_ctrl(fifo_ctrl_id);
uhd::rfnoc::block_id_t fifo_ctrl_id1(0, "FIFO", radio_id+1);
uhd::rfnoc::block_ctrl_base::sptr fifo_ctrl1 =
usrp->get_block_ctrl(fifo_ctrl_id1);
/************************************************************************
* Set up radio
***********************************************************************/
radio_ctrl->set_args(radio_args);
// set the sample rate
std::cout << "Setting RX Rate: %f Msps..."<< (rate/1e6)<<std::endl;
radio_ctrl->set_rate(rate);
std::cout << "Actual RX Rate: %f Msps..." << (radio_ctrl->get_rate() / 1e6)
<< std::endl;
// set the center frequency
std::cout << boost::format("Setting RX Freq: %f MHz...") % (freq / 1e6) <<
std::endl;
uhd::tune_request_t tune_request(freq);
radio_ctrl->set_rx_frequency(freq, 0);
std::cout << "Actual RX Freq: %f MHz..." << radio_ctrl->get_rx_frequency(0)
/ 1e6 << std::endl;
// set the rf gain
radio_ctrl->set_rx_gain(gain, 0);
std::cout << "Actual RX Gain: %f dB..." <<
radio_ctrl->get_rx_gain(radio_chan) << std::endl;
// set the antenna
radio_ctrl->set_rx_antenna("RX1", 0);
size_t spp = radio_ctrl->get_arg<int>("spp");
/************************************************************************
* Set up streaming
***********************************************************************/
uhd::device_addr_t streamer_args(streamargs);
uhd::rfnoc::graph::sptr rx_graph = usrp->create_graph("rfnoc_rx_to_file");
usrp->clear();
rx_graph->connect(radio_ctrl->get_block_id(), 0,
dmafifo_ctrl->get_block_id(), 0);
rx_graph->connect(dmafifo_ctrl->get_block_id(), 0,
fir_ctrl->get_block_id(), 0);
rx_graph->connect(fir_ctrl->get_block_id(), 0,
fifo_ctrl1->get_block_id(), 0);
// Set the stream args on the radio:
streamer_args["block_id"] = fifo_ctrl_id1.to_string();
streamer_args["block_port"] = str(boost::format("%d") % radio_chan);
#if 0
else {
// Otherwise, see if the requested block exists and connect it to the
radio:
if (not usrp->has_block(block_id)) {
std::cout << "Block does not exist on current device: " << block_id
<< std::endl;
return EXIT_FAILURE;
}
uhd::rfnoc::source_block_ctrl_base::sptr blk_ctrl =
usrp->get_block_ctrl<uhd::rfnoc::source_block_ctrl_base>(block_id);
if (not block_args.empty()) {
// Set the block args on the other block:
blk_ctrl->set_args(uhd::device_addr_t(block_args));
}
// Connect:
std::cout << "Connecting " << radio_ctrl_id << " ==> " <<
blk_ctrl->get_block_id()
<< std::endl;
rx_graph->connect(
radio_ctrl_id, radio_chan, blk_ctrl->get_block_id(),
uhd::rfnoc::ANY_PORT);
streamer_args["block_id"] = blk_ctrl->get_block_id().to_string();
spp = blk_ctrl->get_args().cast<size_t>("spp", spp);
}
#endif
// create a receive streamer
std::cout << "Samples per packet: " << spp << std::endl;
uhd::stream_args_t stream_args("fc32", "sc16"); // We should read the wire
format from the blocks
stream_args.args = streamer_args;
stream_args.args["spp"] = boost::lexical_cast<std::string>(spp);
std::cout << "Using streamer args: " << stream_args.args.to_string() <<
std::endl;
uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args);
if (total_num_samps == 0) {
std::signal(SIGINT, &sig_int_handler);
std::cout << "Press Ctrl + C to stop streaming..." << std::endl;
}
recv_to_file(rx_stream, file, spb, rate, total_num_samps);
std::cout << std::endl << "Done!" << std::endl << std::endl;
return EXIT_SUCCESS;
}
_______________________________________________
USRP-users mailing list -- [email protected]
To unsubscribe send an email to [email protected]