Ejemplo n.º 1
0
void init_stream() {
    boost::this_thread::sleep(boost::posix_time::milliseconds(WARM_UP_TIME));
    stream_cmd.time_spec = time_start_recv  = uhd::time_spec_t(2.0) + usrp->get_time_now();
	cout << "Time to start receiving: " << time_start_recv.get_real_secs() << endl;
    stream_cmd.stream_now   = false;
    usrp->issue_stream_cmd(stream_cmd);
}
Ejemplo n.º 2
0
bool uhd_device::start()
{
	LOG(INFO) << "Starting USRP...";

	if (started) {
		LOG(ERR) << "Device already started";
		return false;
	}

	started = true;
	setPriority();

	// Start asynchronous event (underrun check) loop
	async_event_thrd = new Thread(32768);
	async_event_thrd->start((void * (*)(void*))async_event_loop, (void*)this);

	// Start streaming
	restart(uhd::time_spec_t(0.0));

	// Display usrp time
	double time_now = usrp_dev->get_time_now().get_real_secs();
	LOG(INFO) << "The current time is " << time_now << " seconds";

	return true;
}
Ejemplo n.º 3
0
/***********************************************************************
 * RX Hammer
 **********************************************************************/
void rx_hammer(uhd::usrp::multi_usrp::sptr usrp, const std::string &rx_cpu, const std::string &rx_otw){
    uhd::set_thread_priority_safe();

    //create a receive streamer
    uhd::stream_args_t stream_args(rx_cpu, rx_otw);
    for (size_t ch = 0; ch < usrp->get_num_mboards(); ch++) //linear channel mapping
        stream_args.channels.push_back(ch);
    uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args);

    //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 < stream_args.channels.size(); 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;
        usrp->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;
            num_overflows++;
            break;

        default:
            std::cerr << "Error code: " << md.error_code << std::endl;
            std::cerr << "Unexpected error on recv, continuing..." << std::endl;
            break;
        }
    }
}
Ejemplo n.º 4
0
/***********************************************************************
 * Benchmark TX Rate
 **********************************************************************/
void benchmark_tx_rate(
        uhd::usrp::multi_usrp::sptr usrp,
        const std::string &tx_cpu,
        uhd::tx_streamer::sptr tx_stream,
        std::atomic<bool>& burst_timer_elapsed,
        const boost::posix_time::ptime &start_time,
        bool random_nsamps=false
) {
    uhd::set_thread_priority_safe();

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

    //setup variables and allocate buffer
    uhd::tx_metadata_t md;
    md.time_spec = usrp->get_time_now() + uhd::time_spec_t(INIT_DELAY);
    md.has_time_spec = (tx_stream->get_num_channels() > 1);
    const size_t max_samps_per_packet = tx_stream->get_max_num_samps();
    std::vector<char> buff(max_samps_per_packet*uhd::convert::get_bytes_per_item(tx_cpu));
    std::vector<const void *> buffs;
    for (size_t ch = 0; ch < tx_stream->get_num_channels(); ch++)
        buffs.push_back(&buff.front()); //same buffer for each channel
    md.has_time_spec = (buffs.size() != 1);

    if (random_nsamps) {
        std::srand((unsigned int)time(NULL));
        while (not burst_timer_elapsed) {
            size_t total_num_samps = rand() % max_samps_per_packet;
            size_t num_acc_samps = 0;
            const float timeout = 1;

            usrp->set_time_now(uhd::time_spec_t(0.0));
            while(num_acc_samps < total_num_samps){
                //send a single packet
                num_tx_samps += tx_stream->send(buffs, max_samps_per_packet, md, timeout)*tx_stream->get_num_channels();
                num_acc_samps += std::min(total_num_samps-num_acc_samps, tx_stream->get_max_num_samps());
            }
        }
    } else {
        while (not burst_timer_elapsed) {
            const size_t num_tx_samps_sent_now = tx_stream->send(buffs, max_samps_per_packet, md)*tx_stream->get_num_channels();
            num_tx_samps += num_tx_samps_sent_now;
            if (num_tx_samps_sent_now == 0) {
                num_timeouts_tx++;
                if ((num_timeouts_tx % 10000) == 1) {
                    std::cerr << "[" << NOW() << "] Tx timeouts: " << num_timeouts_tx << std::endl;
                }
            }
            md.has_time_spec = false;
        }
    }

    //send a mini EOB packet
    md.end_of_burst = true;
    tx_stream->send(buffs, 0, md);
}
Ejemplo n.º 5
0
template<typename samp_type> void send_from_file(
    uhd::usrp::multi_usrp::sptr usrp,
    const uhd::io_type_t &io_type,
    const std::string &file,
    size_t samps_per_buff,
	uhd::time_spec_t &send_time
){
    uhd::tx_metadata_t md;
    md.start_of_burst = true;
    md.end_of_burst = false;
    std::vector<samp_type> buff(samps_per_buff);
	std::vector<samp_type> buff_zeros(samps_per_buff);
    std::ifstream infile(file.c_str(), std::ifstream::binary);

	uhd::time_spec_t now = usrp->get_time_now();

	md.has_time_spec = true;
	md.time_spec = uhd::time_spec_t(0.5) + now;
	printf("send time %d %ld\n",md.time_spec.get_full_secs(),md.time_spec.get_tick_count(100e6));
	send_time = md.time_spec;

    //loop until the entire file has been read

	infile.read((char*)&buff.front(), buff.size()*sizeof(samp_type));
    size_t num_tx_samps = infile.gcount()/sizeof(samp_type);
		printf("%d\n",num_tx_samps);

	for(int i=0; i<samps_per_buff; i++){
		buff_zeros[i] = 0;	
	}

	int count=0;
	time_t start_time = time(NULL);
	time_t system_now = time(NULL);
    while(not md.end_of_burst){        
		if(system_now - start_time > run_time)
	        md.end_of_burst = true;//infile.eof();

		usrp->get_device()->send(
	            &buff.front(), num_tx_samps, md, io_type,
	            uhd::device::SEND_MODE_FULL_BUFF
	        );

		md.start_of_burst = false;
		md.has_time_spec = false;
		count++;
	system_now = time(NULL);
    }

    infile.close();
}
Ejemplo n.º 6
0
void transceive(
    uhd::usrp::multi_usrp::sptr usrp,
    uhd::tx_streamer::sptr tx_stream,
    uhd::rx_streamer::sptr rx_stream,
    unsigned int npulses,
    float pulse_time,
    //std::complex<int16_t>* txbuff,
    std::vector<std::complex<int16_t> >* txbuff0,
    std::vector<std::complex<int16_t> >* txbuff1,
    float tx_ontime,
    std::complex<int16_t>** outdata,
    size_t samps_per_pulse
){
    int debug = 0;
    if (debug){
        std::cout << "samps_per_pulse: " << samps_per_pulse << std::endl;
    }
    //create metadeta tags for transmit streams
    uhd::time_spec_t start_time = usrp->get_time_now() + 0.05;
    uhd::tx_metadata_t md;
    md.start_of_burst = true;
    md.end_of_burst = false;
    md.has_time_spec = true;
    md.time_spec = start_time;
    std::vector<std::complex<int16_t> *> vec_ptr;
    vec_ptr.resize(1);
    //vec_ptr[0] = &txbuff->front();
    
    usrp->set_gpio_attr("RXA","CTRL",0x0, TR_BIT); //GPIO mode
    usrp->set_gpio_attr("RXA","DDR",TR_BIT, TR_BIT); //Direction out
    
    //create metadata tags for receive stream
    uhd::rx_metadata_t rxmd;
    std::vector<std::complex<int16_t> > buff(samps_per_pulse,0);
    if (verbose) std::cout << "rx buff size: " << buff.size() << std::endl;
    if (verbose) std::cout << "tx buff size: " << txbuff0->size() << std::endl;
    uhd::stream_cmd_t stream_cmd = uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE;
    stream_cmd.num_samps = npulses*samps_per_pulse;
    stream_cmd.stream_now = false;
    stream_cmd.time_spec = start_time + 22 / usrp->get_rx_rate(); //Digital hardware delay is 22 samples long.  Found by experiment.
    if (verbose) std::cout << "time spec: " << stream_cmd.time_spec.get_real_secs() << std::endl;
    
    //loop for every pulse in the sequence
    size_t spb;
    std::vector<std::complex<int16_t>* > rx_dptr;
    rx_dptr.resize(usrp->get_rx_num_channels());
    spb = tx_stream->get_max_num_samps();
    if (verbose) std::cout << "npulses: " << npulses << std::endl;
    boost::thread_group rx_threads;
    boost::thread_group tx_threads;
    for (int ipulse=0; ipulse<npulses; ipulse++){
        if (debug) std::cout << "pulse number: " << ipulse << std::endl;
        for (size_t ichan=0; ichan<usrp->get_rx_num_channels(); ichan++){
         rx_dptr[ichan] = ipulse*samps_per_pulse + outdata[ichan];
        }
        
        float timeout = 1.1;
        
        //usrp->set_command_time(start_time-50e-6,0);
        //usrp->set_gpio_attr("RXA","OUT",TR_BIT, TR_BIT);
        
        if (ipulse==0){
            if (verbose) std::cout << "time spec: " << stream_cmd.time_spec.get_real_secs() << std::endl;
            if (verbose) std::cout << "Issuing stream command to start collecting samples\n";
            usrp->issue_stream_cmd(stream_cmd);
        }
        
        //usrp->set_command_time(start_time+tx_ontime,0);
        //usrp->set_gpio_attr("RXA","OUT",0x0, TR_BIT);
        
        size_t acc_samps=0;
        if (ipulse%2 == 0) {
            vec_ptr[0] = &txbuff0->front();
        }
        if (ipulse%2 == 1) {
            vec_ptr[0] = &txbuff1->front();
        }
        
        if (ipulse != npulses-1) {
             tx_threads.create_thread(boost::bind(tx_worker,
                 txbuff0->size(), tx_stream, start_time, vec_ptr[0], 0));
        }
        if (ipulse == npulses-1) {
             tx_threads.create_thread(boost::bind(tx_worker,
                 txbuff0->size(), tx_stream, start_time, vec_ptr[0], 1));
        }
        
        rx_threads.join_all();
        rx_threads.create_thread(boost::bind(rx_worker,
         rx_stream, samps_per_pulse, rx_dptr));
        
        //for (int k=0; k<10; k++){
        // //std::cout << "raw data: " << outdata[0][i][k] << "\t" << outdata[1][i][k] << std::endl;
        // std::cout << "raw data: " << rx_dptr[0][k] << " " << rx_dptr[1][k] << std::endl;
        //}
        //for (int k=0; k<samps_per_pulse; k++)
        //    outdata[i][k] += buff[k];
        
        
        start_time += float(pulse_time);
    }
    tx_threads.join_all();
    rx_threads.join_all();
}
Ejemplo n.º 7
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;
        }
    }
}