Exemple #1
0
void flush_recv(uhd::rx_streamer::sptr rx_stream){
    std::vector<std::complex<float> > buff(rx_stream->get_max_num_samps());
    uhd::rx_metadata_t md;

    do{
        rx_stream->recv(&buff.front(), buff.size(), md);
    } while (md.error_code != uhd::rx_metadata_t::ERROR_CODE_TIMEOUT);
}
Exemple #2
0
/***********************************************************************
 * RX Hammer
 **********************************************************************/
void rx_hammer(uhd::usrp::multi_usrp::sptr usrp, const std::string &rx_cpu, uhd::rx_streamer::sptr rx_stream){
    uhd::set_thread_priority_safe();

    //print pre-test summary
    std::cout << boost::format(
        "Testing receive rate %f Msps"
    ) % (usrp->get_rx_rate()/1e6) << std::endl;

    //setup variables and allocate buffer
    uhd::rx_metadata_t md;
    const size_t max_samps_per_packet = rx_stream->get_max_num_samps();
    std::vector<char> buff(max_samps_per_packet*uhd::convert::get_bytes_per_item(rx_cpu));
    std::vector<void *> buffs;
    for (size_t ch = 0; ch < rx_stream->get_num_channels(); ch++)
        buffs.push_back(&buff.front()); //same buffer for each channel
    bool had_an_overflow = false;
    uhd::time_spec_t last_time;
    const double rate = usrp->get_rx_rate();
    double timeout = 1;

    uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE);
    cmd.time_spec = usrp->get_time_now() + uhd::time_spec_t(0.05);
    cmd.stream_now = (buffs.size() == 1);
    srand( time(NULL) );

    while (not boost::this_thread::interruption_requested()){
        cmd.num_samps = rand() % 100000;
        rx_stream->issue_stream_cmd(cmd);
        num_rx_samps += rx_stream->recv(buffs, max_samps_per_packet, md, timeout, true);

        //handle the error codes
        switch(md.error_code){
        case uhd::rx_metadata_t::ERROR_CODE_NONE:
            if (had_an_overflow){
                had_an_overflow = false;
                num_dropped_samps += boost::math::iround((md.time_spec - last_time).get_real_secs()*rate);
            }
            break;

        case uhd::rx_metadata_t::ERROR_CODE_OVERFLOW:
            had_an_overflow = true;
            last_time = md.time_spec;
            if (!md.out_of_sequence)
                num_overflows++;
            break;

        default:
            std::cerr << "Receiver error: " << md.strerror() << std::endl;
            std::cerr << "Unexpected error on recv, continuing..." << std::endl;
            break;
        }
    }
}
Exemple #3
0
/***********************************************************************
 * Data capture routine
 **********************************************************************/
static void capture_samples(
    uhd::usrp::multi_usrp::sptr usrp,
    uhd::rx_streamer::sptr rx_stream,
    std::vector<samp_type > &buff,
    const size_t nsamps_requested)
{
    buff.resize(nsamps_requested);
    uhd::rx_metadata_t md;

    // Right after the stream is started, there will be transient data.
    // That transient data is discarded and only "good" samples are returned.
    size_t nsamps_to_discard = size_t(usrp->get_rx_rate() * 0.001); // 1ms to be discarded
    std::vector<samp_type> discard_buff(nsamps_to_discard);

    uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE);
    stream_cmd.num_samps = buff.size() + nsamps_to_discard;
    stream_cmd.stream_now = true;
    usrp->issue_stream_cmd(stream_cmd);
    size_t num_rx_samps = 0;

    // Discard the transient samples.
    rx_stream->recv(&discard_buff.front(), discard_buff.size(), md);
    if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE)
    {
        throw std::runtime_error(str(boost::format(
            "Receiver error: %s"
        ) % md.strerror()));
    }

    // Now capture the data we want
    num_rx_samps = rx_stream->recv(&buff.front(), buff.size(), md);

    //validate the received data
    if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE)
    {
        throw std::runtime_error(str(boost::format(
            "Receiver error: %s"
        ) % md.strerror()));
    }

    //we can live if all the data didnt come in
    if (num_rx_samps > buff.size()/2)
    {
        buff.resize(num_rx_samps);
        return;
    }
    if (num_rx_samps != buff.size())
        throw std::runtime_error("did not get all the samples requested");
}
Exemple #4
0
bool uhd_device::flush_recv(size_t num_pkts)
{
	uhd::rx_metadata_t md;
	size_t num_smpls;
	uint32_t buff[rx_spp];
	float timeout;

	// Use .01 sec instead of the default .1 sec
	timeout = .01;

	for (size_t i = 0; i < num_pkts; i++) {
		num_smpls = rx_stream->recv(buff, rx_spp, md,
					    timeout, true);
		if (!num_smpls) {
			switch (md.error_code) {
			case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT:
				return true;
			default:
				continue;
			}
		}
	}

	return true;
}
Exemple #5
0
/***********************************************************************
 * Data capture routine
 **********************************************************************/
static void capture_samples(
    uhd::usrp::multi_usrp::sptr usrp,
    uhd::rx_streamer::sptr rx_stream,
    std::vector<samp_type > &buff,
    const size_t nsamps_requested
){
    buff.resize(nsamps_requested);
    uhd::rx_metadata_t md;

    uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE);
    stream_cmd.num_samps = buff.size();
    stream_cmd.stream_now = true;
    usrp->issue_stream_cmd(stream_cmd);
    const size_t num_rx_samps = rx_stream->recv(&buff.front(), buff.size(), md);

    //validate the received data
    if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE){
        throw std::runtime_error(str(boost::format(
            "Receiver error: %s"
        ) % md.strerror()));
    }
    //we can live if all the data didnt come in
    if (num_rx_samps > buff.size()/2){
        buff.resize(num_rx_samps);
        return;
    }
    if (num_rx_samps != buff.size()){
        throw std::runtime_error("did not get all the samples requested");
    }
}
Exemple #6
0
/*!
 * Test the broken chain message:
 *    Issue a stream command with num samps and more.
 *    We expect to get an inline broken chain message.
 */
bool test_broken_chain_message(UHD_UNUSED(uhd::usrp::multi_usrp::sptr usrp), uhd::rx_streamer::sptr rx_stream, uhd::tx_streamer::sptr){
    std::cout << "Test broken chain message... " << std::flush;

    uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_MORE);
    stream_cmd.stream_now = true;
    stream_cmd.num_samps = rx_stream->get_max_num_samps();
    rx_stream->issue_stream_cmd(stream_cmd);

    std::vector<std::complex<float> > buff(rx_stream->get_max_num_samps());
    uhd::rx_metadata_t md;

    rx_stream->recv( //once for the requested samples
        &buff.front(), buff.size(), md
    );

    rx_stream->recv( //again for the inline message
        &buff.front(), buff.size(), md
    );

    switch(md.error_code){
    case uhd::rx_metadata_t::ERROR_CODE_BROKEN_CHAIN:
        std::cout << boost::format(
            "success:\n"
            "    Got error code broken chain message.\n"
        ) << std::endl;
        return true;

    case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT:
        std::cout << boost::format(
            "failed:\n"
            "    Inline message recv timed out.\n"
        ) << std::endl;
        return false;

    default:
        std::cout << boost::format(
            "failed:\n"
            "    Got unexpected error code 0x%x.\n"
        ) % md.error_code << std::endl;
        return false;
    }
}
Exemple #7
0
/*!
 * Test the late command message:
 *    Issue a stream command with a time that is in the past.
 *    We expect to get an inline late command message.
 */
bool test_late_command_message(uhd::usrp::multi_usrp::sptr usrp, uhd::rx_streamer::sptr rx_stream, uhd::tx_streamer::sptr){
    std::cout << "Test late command message... " << std::flush;

    usrp->set_time_now(uhd::time_spec_t(200.0)); //set time

    uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE);
    stream_cmd.num_samps = rx_stream->get_max_num_samps();
    stream_cmd.stream_now = false;
    stream_cmd.time_spec = uhd::time_spec_t(100.0); //time in the past
    rx_stream->issue_stream_cmd(stream_cmd);

    std::vector<std::complex<float> > buff(rx_stream->get_max_num_samps());
    uhd::rx_metadata_t md;

    const size_t nsamps = rx_stream->recv(
        &buff.front(), buff.size(), md
    );

    switch(md.error_code){
    case uhd::rx_metadata_t::ERROR_CODE_LATE_COMMAND:
        std::cout << boost::format(
            "success:\n"
            "    Got error code late command message.\n"
        ) << std::endl;
        return true;

    case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT:
        std::cout << boost::format(
            "failed:\n"
            "    Inline message recv timed out.\n"
        ) << std::endl;
        return false;

    default:
        std::cout << boost::format(
            "failed:\n"
            "    Got unexpected error code 0x%x, nsamps %u.\n"
        ) % md.error_code % nsamps << std::endl;
        return false;
    }
}
Exemple #8
0
// Thread to import data from the USRP !Size of the arrays in complex -> 2*buffer_size !
void usrpGetData(uhd::rx_streamer::sptr rx_stream, uhd::usrp::multi_usrp::sptr dev, size_t buffer_size, board_60GHz_RX *my_60GHz_RX) {
    // Set priority of the thread
    int which = PRIO_PROCESS;
    id_t pid;
    int priority = -20;
    int ret;

    pid = getpid();
    ret = setpriority(which, pid, priority);
    if(ret!=0) {
        std::cout << "Main priority went wrong in usrpT: " << ret << std::endl ;
    }

    // Create storage for a single buffer from USRP
    short *buff_short;
    buff_short=new short[2*buffer_size];


    size_t n_rx_last;
    uhd::rx_metadata_t md;
    //int time=buffer_size/(25)-100; // microsecondes

    while (1) {
        n_rx_last=0;

        // Fill buff_short
        while (n_rx_last==0) {
            n_rx_last=rx_stream->recv(&buff_short[0], buffer_size, md, 3.0);
            std::this_thread::yield(); // Avoid active waiting
        };

        // Check if no overflow
        if (n_rx_last!=buffer_size) {
            std::cerr << "I expect the buffer size to be always the same!\n";
            std::cout<<"Read only:"<<n_rx_last<<"\n";
            std::cout<<"Buffer:"<<buffer_size<<"\n";
            //exit(1);
        };

        // Add the just received buffer to the queue
        mtxUsrp.lock();
        usrpQ.push(buff_short);
        mtxUsrp.unlock();
        // Change memory cell used
        buff_short=new short [2*buffer_size];

        // Gives the start to detection part
        sem_post( &usrpReady);

    }//end while 1
}
void rx_worker(
    uhd::rx_streamer::sptr rx_stream,
    unsigned int samps_per_pulse,
    std::vector<std::complex<int16_t>* >& recv_ptr
){
    uhd::rx_metadata_t rxmd;
    float timeout = 1.1;
    rxmd.error_code = uhd::rx_metadata_t::ERROR_CODE_NONE;
    size_t nrx_samples = rx_stream->recv(recv_ptr, samps_per_pulse, rxmd, timeout);
    if (rxmd.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE){
        std::cerr << "Error!\t";
        std::cerr << rxmd.error_code << std::endl;
    }
}
Exemple #10
0
// Thread to import data from the USRP !Size of the arrays in complex -> 2*buffer_size !
void usrpGetData(uhd::rx_streamer::sptr rx_stream,uhd::usrp::multi_usrp::sptr dev, size_t buffer_size){

  // Set highest priority for this thread
  set_realtime_priority();

  // Create storage for a single buffer from USRP
  short *buff_short;
  buff_short=new short[2*buffer_size]; 

  // Initialisation  
  size_t n_rx_last;
  uhd::rx_metadata_t md;
  //int time=buffer_size/(25)-100; // microsecondes

  while (1){
    n_rx_last=0;

    // Fill buff_short
    while (n_rx_last==0) {
      n_rx_last=rx_stream->recv(&buff_short[0], buffer_size, md, 3.0);
      std::this_thread::yield(); // Avoid active waiting
    };

    // Check if no overflow
    if (n_rx_last!=buffer_size) {
      std::cerr << "I expect the buffer size to be always the same!\n";
      std::cout<<"Read only:"<<n_rx_last<<"\n";
      std::cout<<"Buffer:"<<buffer_size<<"\n";
      //exit(1); 
    };

    // Add the just received buffer to the queue
    mtxUsrp.lock();
    usrpQ.push(buff_short);
    mtxUsrp.unlock();
    // Change memory cell used
    buff_short=new short [2*buffer_size];

    // Gives the start to detection part
    sem_post( &usrpReady); 

    std::this_thread::sleep_for(std::chrono::microseconds(5));
  }//end while 1
}
Exemple #11
0
int uhd_device::readSamples(short *buf, int len, bool *overrun,
			TIMESTAMP timestamp, bool *underrun, unsigned *RSSI)
{
	ssize_t rc;
	uhd::time_spec_t ts;
	uhd::rx_metadata_t metadata;
	uint32_t pkt_buf[rx_spp];

	if (skip_rx)
		return 0;

	*overrun = false;
	*underrun = false;

	// Shift read time with respect to transmit clock
	timestamp += ts_offset;

	ts = convert_time(timestamp, rx_rate);
	LOG(DEBUG) << "Requested timestamp = " << ts.get_real_secs();

	// Check that timestamp is valid
	rc = rx_smpl_buf->avail_smpls(timestamp);
	if (rc < 0) {
		LOG(ERR) << rx_smpl_buf->str_code(rc);
		LOG(ERR) << rx_smpl_buf->str_status();
		return 0;
	}

	// Receive samples from the usrp until we have enough
	while (rx_smpl_buf->avail_smpls(timestamp) < len) {
		size_t num_smpls = rx_stream->recv(
					(void*)pkt_buf,
					rx_spp,
					metadata,
					0.1,
					true);
		rx_pkt_cnt++;

		// Check for errors 
		rc = check_rx_md_err(metadata, num_smpls);
		switch (rc) {
		case ERROR_UNRECOVERABLE:
			LOG(ALERT) << "UHD: Version " << uhd::get_version_string();
			LOG(ALERT) << "UHD: Unrecoverable error, exiting...";
			exit(-1);
		case ERROR_TIMING:
			restart(prev_ts);
		case ERROR_UNHANDLED:
			continue;
		}


		ts = metadata.time_spec;
		LOG(DEBUG) << "Received timestamp = " << ts.get_real_secs();

		rc = rx_smpl_buf->write(pkt_buf,
					num_smpls,
					metadata.time_spec);

		// Continue on local overrun, exit on other errors
		if ((rc < 0)) {
			LOG(ERR) << rx_smpl_buf->str_code(rc);
			LOG(ERR) << rx_smpl_buf->str_status();
			if (rc != smpl_buf::ERROR_OVERFLOW)
				return 0;
		}
	}

	// We have enough samples
	rc = rx_smpl_buf->read(buf, len, timestamp);
	if ((rc < 0) || (rc != len)) {
		LOG(ERR) << rx_smpl_buf->str_code(rc);
		LOG(ERR) << rx_smpl_buf->str_status();
		return 0;
	}

	return len;
}
Exemple #12
0
int uhd_device::open(const std::string &args, bool extref)
{
	// Find UHD devices
	uhd::device_addr_t addr(args);
	uhd::device_addrs_t dev_addrs = uhd::device::find(addr);
	if (dev_addrs.size() == 0) {
		LOG(ALERT) << "No UHD devices found with address '" << args << "'";
		return -1;
	}

	// Use the first found device
	LOG(INFO) << "Using discovered UHD device " << dev_addrs[0].to_string();
	try {
		usrp_dev = uhd::usrp::multi_usrp::make(dev_addrs[0]);
	} catch(...) {
		LOG(ALERT) << "UHD make failed, device " << dev_addrs[0].to_string();
		return -1;
	}

	// Check for a valid device type and set bus type
	if (!parse_dev_type())
		return -1;

	if (extref)
		set_ref_clk(true);

	// Create TX and RX streamers
	uhd::stream_args_t stream_args("sc16");
	tx_stream = usrp_dev->get_tx_stream(stream_args);
	rx_stream = usrp_dev->get_rx_stream(stream_args);

	// Number of samples per over-the-wire packet
	tx_spp = tx_stream->get_max_num_samps();
	rx_spp = rx_stream->get_max_num_samps();

	// Set rates
	double _tx_rate = select_rate(dev_type, sps);
	double _rx_rate = _tx_rate / sps;
	if ((_tx_rate > 0.0) && (set_rates(_tx_rate, _rx_rate) < 0))
		return -1;

	// Create receive buffer
	size_t buf_len = SAMPLE_BUF_SZ / sizeof(uint32_t);
	rx_smpl_buf = new smpl_buf(buf_len, rx_rate);

	// Set receive chain sample offset 
	double offset = get_dev_offset(dev_type, sps);
	if (offset == 0.0) {
		LOG(ERR) << "Unsupported configuration, no correction applied";
		ts_offset = 0;
	} else  {
		ts_offset = (TIMESTAMP) (offset * rx_rate);
	}

	// Initialize and shadow gain values 
	init_gains();

	// Print configuration
	LOG(INFO) << "\n" << usrp_dev->get_pp_string();

	switch (dev_type) {
	case B100:
		return RESAMP_64M;
	case USRP2:
	case X3XX:
		return RESAMP_100M;
	}

	return NORMAL;
}
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,
    double time_requested       = 0.0,
    bool bw_summary             = false,
    bool stats                  = false,
    bool enable_size_map        = false,
    bool continue_on_bad_packet = false)
{
    unsigned long long num_total_samps = 0;

    uhd::rx_metadata_t md;
    std::vector<samp_type> 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);

    const auto start_time = std::chrono::steady_clock::now();
    const auto stop_time =
        start_time + std::chrono::milliseconds(int64_t(1000 * time_requested));
    // Track time and samps between updating the BW summary
    auto last_update                     = start_time;
    unsigned long long last_update_samps = 0;

    typedef std::map<size_t, size_t> SizeMap;
    SizeMap mapSizes;

    // 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)
           and (time_requested == 0.0 or std::chrono::steady_clock::now() <= stop_time)) {
        const auto now = std::chrono::steady_clock::now();

        size_t num_rx_samps =
            rx_stream->recv(&buff.front(), buff.size(), md, 3.0, enable_size_map);

        if (md.error_code == uhd::rx_metadata_t::ERROR_CODE_TIMEOUT) {
            std::cout << boost::format("Timeout while streaming") << std::endl;
            break;
        }
        if (md.error_code == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW) {
            if (overflow_message) {
                overflow_message = false;
                std::cerr
                    << boost::format(
                           "Got an overflow indication. Please consider the following:\n"
                           "  Your write medium must sustain a rate of %fMB/s.\n"
                           "  Dropped samples will not be written to the file.\n"
                           "  Please modify this example for your purposes.\n"
                           "  This message will not appear again.\n")
                           % (rx_rate * sizeof(samp_type) / 1e6);
            }
            continue;
        }
        if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) {
            std::string error = str(boost::format("Receiver error: %s") % md.strerror());
            if (continue_on_bad_packet) {
                std::cerr << error << std::endl;
                continue;
            } else
                throw std::runtime_error(error);
        }

        if (enable_size_map) {
            SizeMap::iterator it = mapSizes.find(num_rx_samps);
            if (it == mapSizes.end())
                mapSizes[num_rx_samps] = 0;
            mapSizes[num_rx_samps] += 1;
        }

        num_total_samps += num_rx_samps;

        if (outfile.is_open()) {
            outfile.write((const char*)&buff.front(), num_rx_samps * sizeof(samp_type));
        }

        if (bw_summary) {
            last_update_samps += num_rx_samps;
            const auto time_since_last_update = now - last_update;
            if (time_since_last_update > std::chrono::seconds(UPDATE_INTERVAL)) {
                const double time_since_last_update_s =
                    std::chrono::duration<double>(time_since_last_update).count();
                const double rate = double(last_update_samps) / time_since_last_update_s;
                std::cout << "\t" << (rate / 1e6) << " MSps" << std::endl;
                last_update_samps = 0;
                last_update       = now;
            }
        }
    }
    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();

    if (stats) {
        std::cout << std::endl;

        const double actual_duration_seconds =
            std::chrono::duration<float>(actual_stop_time - start_time).count();

        std::cout << boost::format("Received %d samples in %f seconds") % num_total_samps
                         % actual_duration_seconds
                  << std::endl;
        const double rate = (double)num_total_samps / actual_duration_seconds;
        std::cout << (rate / 1e6) << " MSps" << std::endl;

        if (enable_size_map) {
            std::cout << std::endl;
            std::cout << "Packet size map (bytes: count)" << std::endl;
            for (SizeMap::iterator it = mapSizes.begin(); it != mapSizes.end(); it++)
                std::cout << it->first << ":\t" << it->second << std::endl;
        }
    }
}
Exemple #14
0
/***********************************************************************
 * Benchmark RX Rate
 **********************************************************************/
void benchmark_rx_rate(
        uhd::usrp::multi_usrp::sptr usrp,
        const std::string &rx_cpu,
        uhd::rx_streamer::sptr rx_stream,
        bool random_nsamps,
        const boost::posix_time::ptime &start_time,
        std::atomic<bool>& burst_timer_elapsed
) {
    uhd::set_thread_priority_safe();

    //print pre-test summary
    std::cout << boost::format(
        "[%s] Testing receive rate %f Msps on %u channels"
    ) % NOW() % (usrp->get_rx_rate()/1e6) % rx_stream->get_num_channels() << std::endl;

    //setup variables and allocate buffer
    uhd::rx_metadata_t md;
    const size_t max_samps_per_packet = rx_stream->get_max_num_samps();
    std::vector<char> buff(max_samps_per_packet*uhd::convert::get_bytes_per_item(rx_cpu));
    std::vector<void *> buffs;
    for (size_t ch = 0; ch < rx_stream->get_num_channels(); ch++)
        buffs.push_back(&buff.front()); //same buffer for each channel
    bool had_an_overflow = false;
    uhd::time_spec_t last_time;
    const double rate = usrp->get_rx_rate();

    uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);
    cmd.time_spec = usrp->get_time_now() + uhd::time_spec_t(INIT_DELAY);
    cmd.stream_now = (buffs.size() == 1);
    rx_stream->issue_stream_cmd(cmd);

    const float burst_pkt_time =
        std::max<float>(0.100f, (2 * max_samps_per_packet/rate));
    float recv_timeout = burst_pkt_time + INIT_DELAY;

    bool stop_called = false;
    while (true) {
        //if (burst_timer_elapsed.load(boost::memory_order_relaxed) and not stop_called) {
        if (burst_timer_elapsed and not stop_called) {
            rx_stream->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS);
            stop_called = true;
        }
        if (random_nsamps) {
            cmd.num_samps = rand() % max_samps_per_packet;
            rx_stream->issue_stream_cmd(cmd);
        }
        try {
            num_rx_samps += rx_stream->recv(buffs, max_samps_per_packet, md, recv_timeout)*rx_stream->get_num_channels();
            recv_timeout = burst_pkt_time;
        }
        catch (uhd::io_error &e) {
            std::cerr << "[" << NOW() << "] Caught an IO exception. " << std::endl;
            std::cerr << e.what() << std::endl;
            return;
        }

        //handle the error codes
        switch(md.error_code){
        case uhd::rx_metadata_t::ERROR_CODE_NONE:
            if (had_an_overflow) {
                had_an_overflow = false;
                const long dropped_samps =
                    (md.time_spec - last_time).to_ticks(rate);
                if (dropped_samps < 0) {
                    std::cerr
                        << "[" << NOW() << "] Timestamp after overrun recovery "
                           "ahead of error timestamp! Unable to calculate "
                           "number of dropped samples."
                           "(Delta: " << dropped_samps << " ticks)\n";
                }
                num_dropped_samps += std::max<long>(1, dropped_samps);
            }
            if ((burst_timer_elapsed or stop_called) and md.end_of_burst) {
                return;
            }
            break;

        // ERROR_CODE_OVERFLOW can indicate overflow or sequence error
        case uhd::rx_metadata_t::ERROR_CODE_OVERFLOW:
            last_time = md.time_spec;
            had_an_overflow = true;
            // check out_of_sequence flag to see if it was a sequence error or overflow
            if (!md.out_of_sequence) {
                num_overruns++;
            } else {
                num_seqrx_errors++;
                std::cerr << "[" << NOW() << "] Detected Rx sequence error." << std::endl;
            }
            break;

        case uhd::rx_metadata_t::ERROR_CODE_LATE_COMMAND:
            std::cerr << "[" << NOW() << "] Receiver error: " << md.strerror() << ", restart streaming..."<< std::endl;
            num_late_commands++;
            // Radio core will be in the idle state. Issue stream command to restart streaming.
            cmd.time_spec = usrp->get_time_now() + uhd::time_spec_t(0.05);
            cmd.stream_now = (buffs.size() == 1);
            rx_stream->issue_stream_cmd(cmd);
            break;

        case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT:
            if (burst_timer_elapsed) {
                return;
            }
            std::cerr << "[" << NOW() << "] Receiver error: " << md.strerror() << ", continuing..." << std::endl;
            num_timeouts_rx++;
            break;

            // Otherwise, it's an error
        default:
            std::cerr << "[" << NOW() << "] Receiver error: " << md.strerror() << std::endl;
            std::cerr << "[" << NOW() << "] Unexpected error on recv, continuing..." << std::endl;
            break;
        }
    }
}
Exemple #15
0
void storeDataX(uhd::rx_streamer::sptr rx_stream, uhd::usrp::multi_usrp::sptr dev, size_t buffer_size, uint nDetect){



  // Create storage for a single buffer from USRP
  short *buff_short;
  buff_short=new short[2*buffer_size]; 
 
  short *storage_short;
  storage_short=new short [2*nDetect];

  uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE);
	  
    std::cout << "Stop the transmitter by pressing ctrl-c \n";
	  
      stream_cmd.num_samps = buffer_size;
      stream_cmd.stream_now = true;
    
       stream_cmd.stream_mode=uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS;

       dev->issue_stream_cmd(stream_cmd);


  uhd::rx_metadata_t md;
  size_t n_rx_samps=0;

  int n_rx_last;

  while (1){
    n_rx_samps=0;
    // Fill the storage buffer loop
    while (n_rx_samps<nDetect){
      n_rx_last=0;
      // Fill buff_short
      while (n_rx_last==0) {
	n_rx_last=rx_stream->recv(&buff_short[0], buffer_size, md, 3.0);
	//std::this_thread::yield();
      };

      sec_count++;
      // Check if no overflow
      if (n_rx_last!=(int)buffer_size) {
	std::cerr << "I expect the buffer size to be always the same!\n";
	std::cout<<"Read only:"<<n_rx_last<<"\n";
	std::cout<<"Buffer:"<<buffer_size<<"\n";
	exit(1); 
      };
      
      // Fill storage
      int i1=2*n_rx_samps;
      int i2=0;   
      while ((i1<(int) (2*nDetect)) && (i2<2*((int) buffer_size))){	  
	storage_short[i1]=buff_short[i2];
	i1++; i2++;
      };
      
      //storage_short=buff_short;
      n_rx_samps=n_rx_samps+n_rx_last;
      //std::cout << "n_rx_samps=" << n_rx_samps  << std::endl;	 
    }//storage_short now full


    mtxQ.lock();
    bufferQ.push(buff_short);
    mtxQ.unlock();
    //delete buff_short;
    buff_short=new short [2*buffer_size]; // Change memory cell used

    //usleep(1000000/4);
    sem_post( &isReady); // Gives the start to detection part

  }//end while 1
}