//  [Compile]
//      g++ retuneTime.cpp -o retuneTime -std=c++11 -O3 -luhd
//  [Usage to test retuning time between 739 MHz and 2128 MHz.]
//      ./retuneTime 739 2128
#include <iostream>
#include <iomanip>
#include <chrono>
#include <thread>
#include <uhd/usrp/multi_usrp.hpp>
#include <uhd/utils/thread_priority.hpp>

    
//constants
const double MasterClockRate_Hz = 15.36e6;
const double SamplingRate_Hz = MasterClockRate_Hz / 4.0;
const unsigned Runs = 16;
    

////
int main( int arguments , char * argumentPtr[ ] )
{  
    
    //command line inputs
    double carrierFreq_MHz[ 2 ];
    if ( arguments != 3 )
    {
        std::cerr << "Expected syntax shown below." << std::endl;
        std::cerr << "./retuneTime [carrierFreq0_MHz] [carrierFreq1_MHz]" << std::endl;
        return -1;
    }
    for ( int argument = 1 ; argument < arguments ; argument++ )
    {
        std::stringstream ss;
        ss << argumentPtr[ argument ];
        switch ( argument )
        {
            case 1:
                ss >> carrierFreq_MHz[ 0 ];
                carrierFreq_MHz[ 0 ] *= 1e6;
                break;
            case 2:
                ss >> carrierFreq_MHz[ 1 ];
                carrierFreq_MHz[ 1 ] *= 1e6;
                break;
            default:
                assert( false );
        }
    }
    
    //real time thread
    uhd::set_thread_priority_safe( );
    
    //init board and set frequencies
    auto rfBoard = uhd::usrp::multi_usrp::make( uhd::device_addr_t( "" ) );
    rfBoard->set_clock_source( "internal" );
    rfBoard->set_master_clock_rate( MasterClockRate_Hz );
    rfBoard->set_rx_rate( SamplingRate_Hz );

    //retuning loop
    for ( unsigned run = 0 ; run < Runs ; run++ )
    {
        const auto Time0 = std::chrono::steady_clock::now( );
        rfBoard->set_rx_freq( uhd::tune_request_t( carrierFreq_MHz[ run & 1 ] ) );
        const auto Time1 = std::chrono::steady_clock::now( );
        std::cerr << "Retuning time [ms]: " << std::chrono::duration_cast< std::chrono::milliseconds >( Time1 - Time0 ).count( ) << std::endl;
        std::this_thread::sleep_for( std::chrono::milliseconds( 1000 ) );
    }
    
    //return
    return 0;
    
}

