Ejemplo n.º 1
0
void BlindOFDM_UHDDevice::run(){

    if(is_sending){
        int num_tx_samps=0;

        while(is_sending){

            //cout << "Send PACKET at time " << tx_timestamp << endl;
            tx_md.start_of_burst = true;
            tx_md.end_of_burst = true;
            tx_md.has_time_spec = true;
            tx_md.time_spec = uhd::time_spec_t(tx_timestamp);
            if(time()>tx_timestamp){
                cout << "WRONG TX TIMESTAMP!!!!!!!!!!!!!!!!" << endl;
                //break;
                while(time()>tx_timestamp)
                        tx_timestamp=tx_timestamp+time_gap;
            }
            num_tx_samps=tx_stream->send(&tx_buff(0), tx_buff.size(), tx_md, tx_timestamp+tx_buff.size()/tx_rate);
            if(tx_buff2!=tx_buff){
                tx_buff=tx_buff2;
            }
            tx_timestamp=tx_timestamp+time_gap;
            tx_md.start_of_burst = false;
            tx_md.end_of_burst = true;
            tx_md.has_time_spec = false;
            tx_stream->send("", 0, tx_md);
            has_sent=true;
        }
        has_sent=false;


    }
    if(is_receiving){

        //uhd::rx_metadata_t rx_md;
        uhd::stream_args_t stream_args("fc64");
        uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args);
        cvec rx_buff2;
        int num_rx_samps=0;
        int lost_samples=500;
        //Receiving mode
        uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE);
        //allocate buffer with data to receive


         while(is_receiving){
             if(rx_buff_size!=rx_buff.size()){
                 rx_buff_size=rx_buff.size();
                 rx_buff2.set_size(lost_samples+rx_buff_size);
                 rx_buff2.zeros();
                 stream_cmd.num_samps = rx_buff2.size();
                 stream_cmd.stream_now = false;
             }
             //cout << "Receive PACKET at time " << timestamp << endl;
             timestamp=timestamp+time_gap;
             if((previous_correction!=correction)&&(abs(previous_correction-correction)*rx_rate>1)){
                  timestamp=timestamp+correction;
                  previous_correction=correction;

             }
            if(time()>timestamp){
                cout << "WRONG RX TIMESTAMP!!!!!!!!!!!!!!!!" << endl;
                //break;
                while(time()>timestamp)
                        timestamp=timestamp+time_gap;

            }
            stream_cmd.time_spec = uhd::time_spec_t(timestamp-lost_samples/rx_rate);
            usrp->issue_stream_cmd(stream_cmd);
            num_rx_samps=rx_stream->recv(&rx_buff2(0), rx_buff2.size(), rx_md, timestamp-lost_samples/rx_rate,false);
            rx_buff=rx_buff2.get(lost_samples,lost_samples+rx_buff_size-1);

         }

    }


}
Ejemplo n.º 2
0
int UHD_SAFE_MAIN(int argc, char *argv[]){
    
    uhd::set_thread_priority_safe();    

    std::string args, tx_file, rx_file, type, ref, wire_format, cpu_format;                
    size_t samples_per_buff;
    double rate, freq, tx_gain, rx_gain, rx_bw, delay, lo_off;

    rx_bw = RX_BW;
    rx_gain = RX_GAIN;
    wire_format = WIRE_FORMAT;
    cpu_format = CPU_FORMAT;
    rate = SAMP_RATE;
    args = ARGS;
    ref = REF_CLOCK;
    freq = CENT_FREQ;
    tx_gain = TX_GAIN;
    samples_per_buff = SAMPLES_PER_BUFFER;
    tx_file = TX_FILENAME;
    rx_file = RX_FILENAME;

    //------------------INIT TX------------------
                                        //Set the scheduling priority on the current thread. Same as set_thread_priority but does not throw on failure.
    std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl;
    uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args);       //Make the usrp by calling the constructor with param the args

    usrp->set_clock_source(ref);                                          //Set the clock source for the usrp device. This sets the source for a 10 MHz reference clock. Typical options for source: internal, external, MIMO.
    std::cout << boost::format("Setting TX Rate: %f Msps...") % (rate/1e6) << std::endl;                           
    usrp->set_tx_rate(rate);                                                                                        //Set the sample rate
    std::cout << boost::format("Actual TX Rate: %f Msps...") % (usrp->get_tx_rate()/1e6) << std::endl << std::endl;

    std::cout << boost::format("Setting TX Freq: %f MHz...") % (freq/1e6) << std::endl;                              //Set up tuning frequency
    uhd::tune_request_t tune_request;                                                                               
    tune_request = uhd::tune_request_t(freq);                                                                        //Generate the tune request
    usrp->set_tx_freq(tune_request);                                                                                //Tune to CENT_FREQ
    std::cout << boost::format("Actual TX Freq: %f MHz...") % (usrp->get_tx_freq()/1e6) << std::endl << std::endl;  //PRINT Actual CENT_FREQ

    std::cout << boost::format("Setting TX Gain: %f dB...") % tx_gain << std::endl;                                    
    usrp->set_tx_gain(tx_gain);                                                                                     //Set the tx_gain
    std::cout << boost::format("Actual TX Gain: %f dB...") % usrp->get_tx_gain() << std::endl << std::endl;
    
    //------------------CHECK STUFF------------------
    //Check Ref and LO Lock detect
    std::vector<std::string> sensor_names;
    sensor_names = usrp->get_tx_sensor_names(0);
    if (std::find(sensor_names.begin(), sensor_names.end(), "lo_locked") != sensor_names.end()) {
        uhd::sensor_value_t lo_locked = usrp->get_tx_sensor("lo_locked",0);
        std::cout << boost::format("Checking TX: %s ...") % lo_locked.to_pp_string() << std::endl;
        UHD_ASSERT_THROW(lo_locked.to_bool());
    }        


    //------------------INIT TX STREAM------------------
    //create a transmit streamer    
    uhd::stream_args_t stream_args(cpu_format, wire_format);              //Call the constructor of the class stream_args_t and generate the stream_args object with inputs the cpu_format and wire_format (this is the format per sample)
    uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args);    //Generate a tx_streamer object named tx_stream using the usrp->get_tx_stream(stream_args). Remember, usrp is already initialized

    //Setup tx_metadata
    uhd::tx_metadata_t tx_md;                                                  //TX metadata structure for describing received IF data. Includes time specification, and start and stop burst flags. The send routines will convert the metadata to IF data headers.        
    tx_md.start_of_burst = false;                                              //Set start of burst to true for the first packet in the chain. ?
    tx_md.end_of_burst = false;        

    //------------------LOAD DATA AND TX------------------
    std::vector<std::complex<float> > tx_buff(samples_per_buff);
    std::ifstream infile(tx_file.c_str(), std::ifstream::binary);

    if(!infile.good()){
        std::cout << "IN File error\n";
        return 0;
    }

    //loop until the entire file has been read
    int i = 0;

    for (int i = 0; i < samples_per_buff; ++i){
        infile.read((char*)&tx_buff.at(i), tx_buff.size()*sizeof(std::complex<float>));    
        // std::cout << tx_buff.at(i) << ' ';
    }
    
    tx_stream->send(&tx_buff.front(), samples_per_buff, tx_md);

    infile.close();                                                        //Close the file pointer

    //------------------INIT RX------------------

    //IS THIS NECESSARY?
    //always select the subdevice first, the channel mapping affects the other settings
    //usrp->set_rx_subdev_spec(subdev);

    std::cout << boost::format("Setting RX Rate: %f Msps...") % (rate/1e6) << std::endl;
    usrp->set_rx_rate(rate);
    std::cout << boost::format("Actual RX Rate: %f Msps...") % (usrp->get_rx_rate()/1e6) << std::endl << std::endl;

    //set the center frequency
    
    std::cout << boost::format("Setting RX Freq: %f MHz...") % (freq/1e6) << std::endl;
    usrp->set_rx_freq(tune_request);
    std::cout << boost::format("Actual RX Freq: %f MHz...") % (usrp->get_rx_freq()/1e6) << std::endl << std::endl;
    
    
    std::cout << boost::format("Setting RX Gain: %f dB...") % rx_gain << std::endl;
    usrp->set_rx_gain(rx_gain);
    std::cout << boost::format("Actual RX Gain: %f dB...") % usrp->get_rx_gain() << std::endl << std::endl;    

    boost::this_thread::sleep(boost::posix_time::seconds(1)); //allow 1sec  setup time
    //------------------CHECK STUFF------------------
    
    //Always check for locked sensor
    check_locked_sensor(usrp->get_rx_sensor_names(0), "lo_locked", boost::bind(&uhd::usrp::multi_usrp::get_rx_sensor, usrp, _1, 0), 1);

    //------------------INIT RX STREAM---------------
    
    //create a receive streamer with the same args as TX
    uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args);

    

    uhd::rx_metadata_t rx_md;
    std::vector<std::complex<float> > rx_buff(samples_per_buff);
    
    std::ofstream outfile;    
    outfile.open(rx_file.c_str(), std::ofstream::binary);
    if(!outfile.good()){
        std::cout << "OUT File error\n";
        return 0;
    }

    //If RX_CONT == 1 enable continuoys sampling else just sent some packets and done
    uhd::stream_cmd_t stream_cmd((RX_CONT == 1)?
        uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS:
        uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE
    );


    stream_cmd.num_samps = samples_per_buff;                        //You might have a problem here...
    stream_cmd.stream_now = true;                                   //Start streaming ASAP
    stream_cmd.time_spec = uhd::time_spec_t();                      //Setup the time to the USRP time (Why??)
    
    rx_stream->issue_stream_cmd(stream_cmd);                        //Issue a stream command to the usrp device. This tells the usrp to send samples into the host. See the documentation for stream_cmd_t for more info.

    size_t num_rx_samps = rx_stream->recv(&rx_buff.front(), rx_buff.size(), rx_md, 10.0, false);  // Receive buffers containing samples described by the metadata.    
    std::cout << "Samples received in a single shot: " << num_rx_samps << std::endl;
    if (outfile.is_open()){
        outfile.write((const char*)&rx_buff.front(), num_rx_samps*sizeof(std::complex<float>)-1);          
    }
    
    return EXIT_SUCCESS;
}