mirror of
				https://github.com/fairwaves/UHD-Fairwaves.git
				synced 2025-11-03 21:43:15 +00:00 
			
		
		
		
	Compare commits
	
		
			22 Commits
		
	
	
		
			achemeris/
			...
			1.0.10
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					b1e80e5c27 | ||
| 
						 | 
					014e8123a3 | ||
| 
						 | 
					16bc2bdd18 | ||
| 
						 | 
					9cf7377866 | ||
| 
						 | 
					a4568b4704 | ||
| 
						 | 
					b24a4d0bb8 | ||
| 
						 | 
					dc5718daea | ||
| 
						 | 
					25394541fa | ||
| 
						 | 
					b362710778 | ||
| 
						 | 
					c9b7e8c884 | ||
| 
						 | 
					e7eb8e87cc | ||
| 
						 | 
					2a6b94bea9 | ||
| 
						 | 
					143a9008d1 | ||
| 
						 | 
					1e1a889448 | ||
| 
						 | 
					f385a4355a | ||
| 
						 | 
					09f323dc3c | ||
| 
						 | 
					fee336bc5a | ||
| 
						 | 
					fc4efd5cb0 | ||
| 
						 | 
					0f7b0cbeab | ||
| 
						 | 
					6e30c16773 | ||
| 
						 | 
					401e64014c | ||
| 
						 | 
					1dbd567102 | 
							
								
								
									
										40
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										40
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
								
							@@ -1,3 +1,43 @@
 | 
				
			|||||||
 | 
					umtrx (1.0.10) trusty; urgency=low
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  * collectd: rewritten counter collection plugin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Kirill Zakharenko <earwin@gmail.com>  Mon, 21 Mar 2016 19:21:00 +0100
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					umtrx (1.0.9) trusty; urgency=low
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  * collectd: osmo-nitb counter collection plugin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Kirill Zakharenko <earwin@gmail.com>  Mon, 24 Feb 2016 19:35:56 +0300
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					umtrx (1.0.8) trusty; urgency=low
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  * host: integrate support class for umsel2
 | 
				
			||||||
 | 
					  * host: integrate support class for umsel2
 | 
				
			||||||
 | 
					  * host: implement selection for umsel2 + lms
 | 
				
			||||||
 | 
					  * host: umsel2 register work for adf355-2
 | 
				
			||||||
 | 
					  * host: umsel2 adf355-2 tuning algorithm
 | 
				
			||||||
 | 
					  * host: freq update sequence, copied registers from gui
 | 
				
			||||||
 | 
					  * host: print locked for debugging
 | 
				
			||||||
 | 
					  * umsel: device args for enabling umsel2 and verbose
 | 
				
			||||||
 | 
					  * add lmsvga1 device args parameter to override VGA1_DEF
 | 
				
			||||||
 | 
					  * autodetect DCDC translation version on startup
 | 
				
			||||||
 | 
					  * add lmsvga2 args parameter to override UMTRX_VGA2_DEF
 | 
				
			||||||
 | 
					  * turn off vin bypass to amplifiers by default
 | 
				
			||||||
 | 
					  * throw exception if incorrect DCDC version were provided
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Kirill Zakharenko <earwin@gmail.com>  Mon, 28 Dec 2015 15:07:56 +0300
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					umtrx (1.0.7) trusty; urgency=low
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  * host: Properly handle most corner cases in VSWR calculations
 | 
				
			||||||
 | 
					  * host: Add "STRING" to umtrx_monitor error output
 | 
				
			||||||
 | 
					  * host: Add string getters/setters to the Python property tree library
 | 
				
			||||||
 | 
					  * host: Checking in umtrx_query_versions.py
 | 
				
			||||||
 | 
					  * debian: packaged python utils in host/utils
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Kirill Zakharenko <earwin@gmail.com>  Mon, 25 Dec 2015 19:35:56 +0100
 | 
				
			||||||
 | 
					
 | 
				
			||||||
umtrx (1.0.6) trusty; urgency=low
 | 
					umtrx (1.0.6) trusty; urgency=low
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  * host: make boost property tree thread safe
 | 
					  * host: make boost property tree thread safe
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										6
									
								
								debian/umtrx.install
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								debian/umtrx.install
									
									
									
									
										vendored
									
									
								
							@@ -1,2 +1,8 @@
 | 
				
			|||||||
usr/bin
 | 
					usr/bin
 | 
				
			||||||
images/u2plus_umtrx_v2.bin images/umtrx_txrx_uhd.bin usr/share/umtrx/firmware
 | 
					images/u2plus_umtrx_v2.bin images/umtrx_txrx_uhd.bin usr/share/umtrx/firmware
 | 
				
			||||||
 | 
					host/utils/umtrx_property_tree.py host/utils/umtrx_vswr.py usr/share/umtrx
 | 
				
			||||||
 | 
					host/utils/umtrx_query_sensors.py host/utils/umtrx_query_versions.py host/utils/umtrx_net_burner.py usr/share/umtrx
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					host/utils/collectd/umtrx.types.db usr/share/collectd
 | 
				
			||||||
 | 
					host/utils/collectd/umtrx2collectd.py usr/share/umtrx
 | 
				
			||||||
 | 
					host/utils/collectd/umtrx.conf etc/collectd/collectd.conf.d
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										3
									
								
								debian/umtrx.links
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								debian/umtrx.links
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					/usr/share/umtrx/umtrx_net_burner.py /usr/bin/umtrx_net_burner
 | 
				
			||||||
 | 
					/usr/share/umtrx/umtrx_query_sensors.py /usr/bin/umtrx_query_sensors
 | 
				
			||||||
 | 
					/usr/share/umtrx/umtrx_query_versions.py /usr/bin/umtrx_query_versions
 | 
				
			||||||
@@ -58,6 +58,7 @@ list(APPEND UMTRX_SOURCES
 | 
				
			|||||||
    cores/time64_core_200.cpp
 | 
					    cores/time64_core_200.cpp
 | 
				
			||||||
    cores/validate_subdev_spec.cpp
 | 
					    cores/validate_subdev_spec.cpp
 | 
				
			||||||
    cores/apply_corrections.cpp
 | 
					    cores/apply_corrections.cpp
 | 
				
			||||||
 | 
					    umsel2_ctrl.cpp
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
########################################################################
 | 
					########################################################################
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -131,7 +131,7 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class lms6002d_ctrl_impl : public lms6002d_ctrl {
 | 
					class lms6002d_ctrl_impl : public lms6002d_ctrl {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    lms6002d_ctrl_impl(uhd::spi_iface::sptr spiface, const int lms_spi_number, const int adf4350_spi_number, const double clock_rate);
 | 
					    lms6002d_ctrl_impl(uhd::spi_iface::sptr spiface, const int lms_spi_number, const double clock_rate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    double set_rx_freq(const double freq)
 | 
					    double set_rx_freq(const double freq)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -237,19 +237,7 @@ protected:
 | 
				
			|||||||
        if (unit==dboard_iface::UNIT_TX) {
 | 
					        if (unit==dboard_iface::UNIT_TX) {
 | 
				
			||||||
            actual_freq = lms.tx_pll_tune(ref_freq, f);
 | 
					            actual_freq = lms.tx_pll_tune(ref_freq, f);
 | 
				
			||||||
        } else if (unit==dboard_iface::UNIT_RX) {
 | 
					        } else if (unit==dboard_iface::UNIT_RX) {
 | 
				
			||||||
#if 1
 | 
					 | 
				
			||||||
            actual_freq = lms.rx_pll_tune(ref_freq, f);
 | 
					            actual_freq = lms.rx_pll_tune(ref_freq, f);
 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
            // New beta version of the code for UmSEL support.
 | 
					 | 
				
			||||||
            const double umsel_if = 359.5e6;
 | 
					 | 
				
			||||||
            double actual_lms_freq = lms.rx_pll_tune(ref_freq, umsel_if);
 | 
					 | 
				
			||||||
            if (verbosity>0) printf("lms6002d_ctrl_impl::set_freq() actual_lms_freq=%f\n", actual_lms_freq);
 | 
					 | 
				
			||||||
            double adf4350_freq = f - actual_lms_freq;
 | 
					 | 
				
			||||||
            actual_freq = tune_adf4350(adf4350_freq);
 | 
					 | 
				
			||||||
            if (verbosity>0) printf("lms6002d_ctrl_impl::set_freq() adf4350 freq=%f\n", actual_freq);
 | 
					 | 
				
			||||||
            actual_freq += actual_lms_freq;
 | 
					 | 
				
			||||||
            if (verbosity>0) printf("lms6002d_ctrl_impl::set_freq() actual_freq=%f\n", actual_freq);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            assert(!"Wrong units_t value passed to lms6002d_ctrl_impl::set_freq()");
 | 
					            assert(!"Wrong units_t value passed to lms6002d_ctrl_impl::set_freq()");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -410,202 +398,27 @@ private:
 | 
				
			|||||||
    int tx_vga1gain, tx_vga2gain;  // Stored values of Tx VGA1 and VGA2 gains.
 | 
					    int tx_vga1gain, tx_vga2gain;  // Stored values of Tx VGA1 and VGA2 gains.
 | 
				
			||||||
    bool rf_loopback_enabled;      // Whether RF loopback is enabled.
 | 
					    bool rf_loopback_enabled;      // Whether RF loopback is enabled.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Tune ADF4350 on an UmSEL
 | 
					 | 
				
			||||||
    double tune_adf4350(double target_freq);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    uhd::spi_iface::sptr _spiface;
 | 
					    uhd::spi_iface::sptr _spiface;
 | 
				
			||||||
    const int _lms_spi_number;
 | 
					    const int _lms_spi_number;
 | 
				
			||||||
    const int _adf4350_spi_number;
 | 
					 | 
				
			||||||
    const double _clock_rate;
 | 
					    const double _clock_rate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    boost::recursive_mutex _mutex;
 | 
					    boost::recursive_mutex _mutex;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lms6002d_ctrl::sptr lms6002d_ctrl::make(uhd::spi_iface::sptr spiface, const int lms_spi_number, const int adf4350_spi_number, const double clock_rate)
 | 
					lms6002d_ctrl::sptr lms6002d_ctrl::make(uhd::spi_iface::sptr spiface, const int lms_spi_number, const double clock_rate)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return sptr(new lms6002d_ctrl_impl(spiface, lms_spi_number, adf4350_spi_number, clock_rate));
 | 
					    return sptr(new lms6002d_ctrl_impl(spiface, lms_spi_number, clock_rate));
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/***********************************************************************
 | 
					 | 
				
			||||||
 * Tuning
 | 
					 | 
				
			||||||
 **********************************************************************/
 | 
					 | 
				
			||||||
double lms6002d_ctrl_impl::tune_adf4350(double target_freq) {
 | 
					 | 
				
			||||||
    UHD_LOGV(often) << boost::format(
 | 
					 | 
				
			||||||
        "UmSEL tune: target frequency %f Mhz"
 | 
					 | 
				
			||||||
    ) % (target_freq/1e6) << std::endl;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //clip the input
 | 
					 | 
				
			||||||
    // TODO::::::::::::::::::::::::::::::::
 | 
					 | 
				
			||||||
//    target_freq = sbx_freq_range.clip(target_freq);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //map prescaler setting to mininmum integer divider (N) values (pg.18 prescaler)
 | 
					 | 
				
			||||||
    static const uhd::dict<int, int> prescaler_to_min_int_div = map_list_of
 | 
					 | 
				
			||||||
        (0,23) //adf4350_regs_t::PRESCALER_4_5
 | 
					 | 
				
			||||||
        (1,75) //adf4350_regs_t::PRESCALER_8_9
 | 
					 | 
				
			||||||
    ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //map rf divider select output dividers to enums
 | 
					 | 
				
			||||||
    static const uhd::dict<int, adf4350_regs_t::rf_divider_select_t> rfdivsel_to_enum = map_list_of
 | 
					 | 
				
			||||||
        (1,  adf4350_regs_t::RF_DIVIDER_SELECT_DIV1)
 | 
					 | 
				
			||||||
        (2,  adf4350_regs_t::RF_DIVIDER_SELECT_DIV2)
 | 
					 | 
				
			||||||
        (4,  adf4350_regs_t::RF_DIVIDER_SELECT_DIV4)
 | 
					 | 
				
			||||||
        (8,  adf4350_regs_t::RF_DIVIDER_SELECT_DIV8)
 | 
					 | 
				
			||||||
        (16, adf4350_regs_t::RF_DIVIDER_SELECT_DIV16)
 | 
					 | 
				
			||||||
    ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    double actual_freq, pfd_freq;
 | 
					 | 
				
			||||||
    // TODO:: May be *2? Check
 | 
					 | 
				
			||||||
    double ref_freq = _clock_rate * 2;
 | 
					 | 
				
			||||||
    int R=0, BS=0, N=0, FRAC=0, MOD=0;
 | 
					 | 
				
			||||||
    int RFdiv = 1;
 | 
					 | 
				
			||||||
    adf4350_regs_t::reference_divide_by_2_t T     = adf4350_regs_t::REFERENCE_DIVIDE_BY_2_DISABLED;
 | 
					 | 
				
			||||||
    adf4350_regs_t::reference_doubler_t     D     = adf4350_regs_t::REFERENCE_DOUBLER_DISABLED;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //Reference doubler for 50% duty cycle
 | 
					 | 
				
			||||||
    // if ref_freq < 12.5MHz enable regs.reference_divide_by_2
 | 
					 | 
				
			||||||
    if(ref_freq <= 12.5e6) D = adf4350_regs_t::REFERENCE_DOUBLER_ENABLED;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //increase RF divider until acceptable VCO frequency
 | 
					 | 
				
			||||||
    //start with target_freq*2 because mixer has divide by 2
 | 
					 | 
				
			||||||
    double vco_freq = target_freq;
 | 
					 | 
				
			||||||
    while (vco_freq < 2.2e9) {
 | 
					 | 
				
			||||||
        vco_freq *= 2;
 | 
					 | 
				
			||||||
        RFdiv *= 2;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler)
 | 
					 | 
				
			||||||
    adf4350_regs_t::prescaler_t prescaler = vco_freq > 3e9 ? adf4350_regs_t::PRESCALER_8_9 : adf4350_regs_t::PRESCALER_4_5;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /*
 | 
					 | 
				
			||||||
     * The goal here is to loop though possible R dividers,
 | 
					 | 
				
			||||||
     * band select clock dividers, N (int) dividers, and FRAC
 | 
					 | 
				
			||||||
     * (frac) dividers.
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * Calculate the N and F dividers for each set of values.
 | 
					 | 
				
			||||||
     * The loop exists when it meets all of the constraints.
 | 
					 | 
				
			||||||
     * The resulting loop values are loaded into the registers.
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * from pg.21
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * f_pfd = f_ref*(1+D)/(R*(1+T))
 | 
					 | 
				
			||||||
     * f_vco = (N + (FRAC/MOD))*f_pfd
 | 
					 | 
				
			||||||
     *    N = f_vco/f_pfd - FRAC/MOD = f_vco*((R*(T+1))/(f_ref*(1+D))) - FRAC/MOD
 | 
					 | 
				
			||||||
     * f_rf = f_vco/RFdiv)
 | 
					 | 
				
			||||||
     * f_actual = f_rf/2
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    for(R = 1; R <= 1023; R+=1){
 | 
					 | 
				
			||||||
        //PFD input frequency = f_ref/R ... ignoring Reference doubler/divide-by-2 (D & T)
 | 
					 | 
				
			||||||
        pfd_freq = ref_freq*(1+D)/(R*(1+T));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //keep the PFD frequency at or below 25MHz (Loop Filter Bandwidth)
 | 
					 | 
				
			||||||
        if (pfd_freq > 25e6) continue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //ignore fractional part of tuning
 | 
					 | 
				
			||||||
        N = int(std::floor(vco_freq/pfd_freq));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //keep N > minimum int divider requirement
 | 
					 | 
				
			||||||
        if (N < prescaler_to_min_int_div[prescaler]) continue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        for(BS=1; BS <= 255; BS+=1){
 | 
					 | 
				
			||||||
            //keep the band select frequency at or below 100KHz
 | 
					 | 
				
			||||||
            //constraint on band select clock
 | 
					 | 
				
			||||||
            if (pfd_freq/BS > 100e3) continue;
 | 
					 | 
				
			||||||
            goto done_loop;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    } done_loop:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //Fractional-N calculation
 | 
					 | 
				
			||||||
    MOD = 4095; //max fractional accuracy
 | 
					 | 
				
			||||||
    FRAC = int((vco_freq/pfd_freq - N)*MOD);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //Reference divide-by-2 for 50% duty cycle
 | 
					 | 
				
			||||||
    // if R even, move one divide by 2 to to regs.reference_divide_by_2
 | 
					 | 
				
			||||||
    if(R % 2 == 0){
 | 
					 | 
				
			||||||
        T = adf4350_regs_t::REFERENCE_DIVIDE_BY_2_ENABLED;
 | 
					 | 
				
			||||||
        R /= 2;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //actual frequency calculation
 | 
					 | 
				
			||||||
    actual_freq = double((N + (double(FRAC)/double(MOD)))*ref_freq*(1+int(D))/(R*(1+int(T)))/RFdiv);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // TODO:: get_locked!
 | 
					 | 
				
			||||||
//    UHD_LOGV(often)
 | 
					 | 
				
			||||||
    std::cout
 | 
					 | 
				
			||||||
        << boost::format("UmSEL Intermediates: ref=%0.2f, outdiv=%f, fbdiv=%f") % (ref_freq*(1+int(D))/(R*(1+int(T)))) % double(RFdiv*2) % double(N + double(FRAC)/double(MOD)) << std::endl
 | 
					 | 
				
			||||||
        << boost::format("UmSEL tune: R=%d, BS=%d, N=%d, FRAC=%d, MOD=%d, T=%d, D=%d, RFdiv=%d, LD=%s"
 | 
					 | 
				
			||||||
            ) % R % BS % N % FRAC % MOD % T % D % RFdiv % true /* this->get_locked(unit).to_pp_string() */ << std::endl
 | 
					 | 
				
			||||||
        << boost::format("UmSEL Frequencies (MHz): REQ=%0.2f, ACT=%0.2f, VCO=%0.2f, PFD=%0.2f, BAND=%0.2f"
 | 
					 | 
				
			||||||
            ) % (target_freq/1e6) % (actual_freq/1e6) % (vco_freq/1e6) % (pfd_freq/1e6) % (pfd_freq/BS/1e6) << std::endl;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //load the register values
 | 
					 | 
				
			||||||
    adf4350_regs_t regs;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // TODO:: What?
 | 
					 | 
				
			||||||
//    if ((unit == dboard_iface::UNIT_TX) and (actual_freq == sbx_tx_lo_2dbm.clip(actual_freq)))
 | 
					 | 
				
			||||||
//        regs.output_power = adf4350_regs_t::OUTPUT_POWER_2DBM;
 | 
					 | 
				
			||||||
//    else
 | 
					 | 
				
			||||||
        regs.output_power = adf4350_regs_t::OUTPUT_POWER_5DBM;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    regs.frac_12_bit = FRAC;
 | 
					 | 
				
			||||||
    regs.int_16_bit = N;
 | 
					 | 
				
			||||||
    regs.mod_12_bit = MOD;
 | 
					 | 
				
			||||||
    regs.prescaler = prescaler;
 | 
					 | 
				
			||||||
    regs.r_counter_10_bit = R;
 | 
					 | 
				
			||||||
    regs.reference_divide_by_2 = T;
 | 
					 | 
				
			||||||
    regs.reference_doubler = D;
 | 
					 | 
				
			||||||
    regs.band_select_clock_div = BS;
 | 
					 | 
				
			||||||
    UHD_ASSERT_THROW(rfdivsel_to_enum.has_key(RFdiv));
 | 
					 | 
				
			||||||
    regs.rf_divider_select = rfdivsel_to_enum[RFdiv];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    regs.mute_till_lock_detect = adf4350_regs_t::MUTE_TILL_LOCK_DETECT_MUTE_ENABLED;
 | 
					 | 
				
			||||||
    regs.charge_pump_current = adf4350_regs_t::CHARGE_PUMP_CURRENT_2_50MA;
 | 
					 | 
				
			||||||
    regs.double_buffer = adf4350_regs_t::DOUBLE_BUFFER_ENABLED;
 | 
					 | 
				
			||||||
    regs.muxout = adf4350_regs_t::MUXOUT_3STATE;
 | 
					 | 
				
			||||||
    regs.low_noise_and_spur = adf4350_regs_t::LOW_NOISE_AND_SPUR_LOW_NOISE;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //write the registers
 | 
					 | 
				
			||||||
    //correct power-up sequence to write registers (5, 4, 3, 2, 1, 0)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if 0
 | 
					 | 
				
			||||||
    for(addr=5; addr>=0; addr--){
 | 
					 | 
				
			||||||
//        UHD_LOGV(often)
 | 
					 | 
				
			||||||
        std::cout << boost::format(
 | 
					 | 
				
			||||||
            "UmSEL SPI Reg (0x%02x): 0x%08x"
 | 
					 | 
				
			||||||
        ) % addr % regs.get_reg(addr) << std::endl;
 | 
					 | 
				
			||||||
        this->get_iface()->write_spi(
 | 
					 | 
				
			||||||
            uhd::usrp::dboard_iface::UNIT_SYNT, spi_config_t::EDGE_RISE,
 | 
					 | 
				
			||||||
            regs.get_reg(addr), 32
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
    _spiface->write_spi(_adf4350_spi_number, spi_config_t::EDGE_RISE, 0x0580000|5, 32);
 | 
					 | 
				
			||||||
    _spiface->write_spi(_adf4350_spi_number, spi_config_t::EDGE_RISE, 0x0BFF4F8|4, 32);
 | 
					 | 
				
			||||||
    _spiface->write_spi(_adf4350_spi_number, spi_config_t::EDGE_RISE, 0x0040000|3, 32);
 | 
					 | 
				
			||||||
    _spiface->write_spi(_adf4350_spi_number, spi_config_t::EDGE_RISE, 0x1006E40|2, 32);
 | 
					 | 
				
			||||||
    _spiface->write_spi(_adf4350_spi_number, spi_config_t::EDGE_RISE, 0x8008208|1, 32);
 | 
					 | 
				
			||||||
    _spiface->write_spi(_adf4350_spi_number, spi_config_t::EDGE_RISE, (325<<15)|(1<<3)|0, 32);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //return the actual frequency
 | 
					 | 
				
			||||||
//    UHD_LOGV(often) << boost::format(
 | 
					 | 
				
			||||||
    std::cout << boost::format(
 | 
					 | 
				
			||||||
        "UmSEL tune: actual frequency %f Mhz"
 | 
					 | 
				
			||||||
    ) % (actual_freq/1e6) << std::endl;
 | 
					 | 
				
			||||||
    return actual_freq;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// LMS RX dboard configuration
 | 
					// LMS RX dboard configuration
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lms6002d_ctrl_impl::lms6002d_ctrl_impl(uhd::spi_iface::sptr spiface, const int lms_spi_number, const int adf4350_spi_number, const double clock_rate) :
 | 
					lms6002d_ctrl_impl::lms6002d_ctrl_impl(uhd::spi_iface::sptr spiface, const int lms_spi_number, const double clock_rate) :
 | 
				
			||||||
                                             lms(umtrx_lms6002d_dev(spiface, lms_spi_number)),
 | 
					                                             lms(umtrx_lms6002d_dev(spiface, lms_spi_number)),
 | 
				
			||||||
                                             tx_vga1gain(lms.get_tx_vga1gain()),
 | 
					                                             tx_vga1gain(lms.get_tx_vga1gain()),
 | 
				
			||||||
                                             tx_vga2gain(lms.get_tx_vga2gain()),
 | 
					                                             tx_vga2gain(lms.get_tx_vga2gain()),
 | 
				
			||||||
                                             rf_loopback_enabled(false),
 | 
					                                             rf_loopback_enabled(false),
 | 
				
			||||||
                                             _spiface(spiface),
 | 
					                                             _spiface(spiface),
 | 
				
			||||||
                                             _lms_spi_number(lms_spi_number),
 | 
					                                             _lms_spi_number(lms_spi_number),
 | 
				
			||||||
                                             _adf4350_spi_number(adf4350_spi_number),
 | 
					 | 
				
			||||||
                                             _clock_rate(clock_rate)
 | 
					                                             _clock_rate(clock_rate)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    ////////////////////////////////////////////////////////////////////
 | 
					    ////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,7 @@ class lms6002d_ctrl
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    typedef boost::shared_ptr<lms6002d_ctrl> sptr;
 | 
					    typedef boost::shared_ptr<lms6002d_ctrl> sptr;
 | 
				
			||||||
    static sptr make(uhd::spi_iface::sptr spiface, const int lms_spi_number, const int adf4350_spi_number, const double clock_rate);
 | 
					    static sptr make(uhd::spi_iface::sptr spiface, const int lms_spi_number, const double clock_rate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    virtual double set_rx_freq(const double freq) = 0;
 | 
					    virtual double set_rx_freq(const double freq) = 0;
 | 
				
			||||||
    virtual double set_tx_freq(const double freq) = 0;
 | 
					    virtual double set_tx_freq(const double freq) = 0;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										478
									
								
								host/umsel2_ctrl.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										478
									
								
								host/umsel2_ctrl.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,478 @@
 | 
				
			|||||||
 | 
					// Copyright 2015-2015 Fairwaves LLC
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					// it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					// the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					// (at your option) any later version.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					// but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					// GNU General Public License for more details.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					// along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "umsel2_ctrl.hpp"
 | 
				
			||||||
 | 
					#include "umtrx_regs.hpp"
 | 
				
			||||||
 | 
					#include <uhd/exception.hpp>
 | 
				
			||||||
 | 
					#include <boost/thread.hpp>
 | 
				
			||||||
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					#include <cmath>
 | 
				
			||||||
 | 
					#include <map>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const int REG0_NVALUE_SHIFT = 4;
 | 
				
			||||||
 | 
					static const int REG0_NVALUE_MASK = 0xffff;
 | 
				
			||||||
 | 
					static const int REG0_PRESCALER_SHIFT = 20;
 | 
				
			||||||
 | 
					static const int REG0_AUTOCAL_SHIFT = 21;
 | 
				
			||||||
 | 
					static const int REG1_MFRAC_SHIFT = 4;
 | 
				
			||||||
 | 
					static const int REG1_MFRAC_MASK = 0xffffff;
 | 
				
			||||||
 | 
					static const int REG2_AUX_FRAC_SHIFT = 18;
 | 
				
			||||||
 | 
					static const int REG2_AUX_FRAC_MASK = ((1<<14)-1);
 | 
				
			||||||
 | 
					static const int REG2_AUX_MOD_SHIFT = 4;
 | 
				
			||||||
 | 
					static const int REG2_AUX_MOD_MASK = ((1<<14)-1);
 | 
				
			||||||
 | 
					static const int REG3_SD_LOAD_SHIFT = 30;
 | 
				
			||||||
 | 
					static const int REG3_PHASE_RSYNC_SHIFT = 29;
 | 
				
			||||||
 | 
					static const int REG3_PHASE_ADJ_SHIFT = 28;
 | 
				
			||||||
 | 
					static const int REG3_PHASE_SHIFT = 4;
 | 
				
			||||||
 | 
					static const int REG3_PHASE_MASK = ((1<<24)-1);
 | 
				
			||||||
 | 
					static const int REG4_MUXOUT_SHIFT = 27;
 | 
				
			||||||
 | 
					static const int REG4_MUXOUT_MASK = ((1<<3)-1);
 | 
				
			||||||
 | 
					static const int REG4_REF_DBL_SHIFT = 26;
 | 
				
			||||||
 | 
					static const int REG4_REF_DIV_SHIFT = 25;
 | 
				
			||||||
 | 
					static const int REG4_R_SHIFT = 15;
 | 
				
			||||||
 | 
					static const int REG4_R_MASK = ((1<<10)-1);
 | 
				
			||||||
 | 
					static const int REG4_DBL_BUFF_SHIFT = 14;
 | 
				
			||||||
 | 
					static const int REG4_CURRENT_SHIFT = 10;
 | 
				
			||||||
 | 
					static const int REG4_CURRENT_MASK = ((1<<4)-1);
 | 
				
			||||||
 | 
					static const int REG4_REF_MODE_SHIFT = 9;
 | 
				
			||||||
 | 
					static const int REG4_MUX_LOGIC_SHIFT = 8;
 | 
				
			||||||
 | 
					static const int REG4_PD_POL_SHIFT = 7;
 | 
				
			||||||
 | 
					static const int REG4_PWR_DOWN_SHIFT = 6;
 | 
				
			||||||
 | 
					static const int REG4_CP_3STATE_SHIFT = 5;
 | 
				
			||||||
 | 
					static const int REG4_CNTR_RESET = 4;
 | 
				
			||||||
 | 
					static const int REG5_RESERVED = 0x00800025;
 | 
				
			||||||
 | 
					static const int REG6_GATED_BLEED_SHIFT = 30;
 | 
				
			||||||
 | 
					static const int REG6_NEG_BLEED_SHIFT = 29;
 | 
				
			||||||
 | 
					static const int REG6_RESERVED_SHIFT = 25;
 | 
				
			||||||
 | 
					static const int REG6_RESERVED_VALUE = 0xA;
 | 
				
			||||||
 | 
					static const int REG6_FB_SEL_SHIFT = 24;
 | 
				
			||||||
 | 
					static const int REG6_RF_DIV_SHIFT = 21;
 | 
				
			||||||
 | 
					static const int REG6_RF_DIV_MASK = ((1<<3)-1);
 | 
				
			||||||
 | 
					static const int REG6_CP_BLEED_CURR_SHIFT = 13;
 | 
				
			||||||
 | 
					static const int REG6_CP_BLEED_CURR_MASK = ((1<<8)-1);
 | 
				
			||||||
 | 
					static const int REG6_MLTD_SHIFT = 11;
 | 
				
			||||||
 | 
					static const int REG6_AUX_PWR_EN_SHIFT = 9;
 | 
				
			||||||
 | 
					static const int REG6_AUX_PWR_SHIFT = 7;
 | 
				
			||||||
 | 
					static const int REG6_AUX_PWR_MASK = ((1<<2)-1);
 | 
				
			||||||
 | 
					static const int REG6_PWR_EN_SHIFT = 6;
 | 
				
			||||||
 | 
					static const int REG6_PWR_SHIFT = 4;
 | 
				
			||||||
 | 
					static const int REG6_PWR_MASK = ((1<<2)-1);
 | 
				
			||||||
 | 
					static const int REG7_RESERVED_SHIFT = 26;
 | 
				
			||||||
 | 
					static const int REG7_RESERVED_VALUE = 0x4;
 | 
				
			||||||
 | 
					static const int REG7_LE_SYNC_SHIFT = 25;
 | 
				
			||||||
 | 
					static const int REG7_LD_CYCLE_CNT_SHIFT = 8;
 | 
				
			||||||
 | 
					static const int REG7_LD_CYCLE_CNT_MASK = ((1<<2)-1);
 | 
				
			||||||
 | 
					static const int REG7_LOL_MODE_SHIFT = 7;
 | 
				
			||||||
 | 
					static const int REG7_FRAC_N_PREC_SHIFT = 5;
 | 
				
			||||||
 | 
					static const int REG7_FRAC_N_PREC_MASK = ((1<<2)-1);
 | 
				
			||||||
 | 
					static const int REG7_LD_MODE_SHIFT = 4;
 | 
				
			||||||
 | 
					static const int REG8_RESERVED = 0x102D0428;
 | 
				
			||||||
 | 
					static const int REG9_VCO_BAND_SHIFT = 24;
 | 
				
			||||||
 | 
					static const int REG9_VCO_BAND_MASK = ((1<<8)-1);
 | 
				
			||||||
 | 
					static const int REG9_TIMEOUT_SHIFT = 14;
 | 
				
			||||||
 | 
					static const int REG9_TIMEOUT_MASK = ((1<<10)-1);
 | 
				
			||||||
 | 
					static const int REG9_AUTO_LVL_TO_SHIFT = 9;
 | 
				
			||||||
 | 
					static const int REG9_AUTO_LVL_TO_MASK = ((1<<5)-1);
 | 
				
			||||||
 | 
					static const int REG9_SYNT_LOCK_TO_SHIFT = 4;
 | 
				
			||||||
 | 
					static const int REG9_SYNT_LOCK_TO_MASK = ((1<<5)-1);
 | 
				
			||||||
 | 
					static const int REG10_RESERVED_SHIFT = 14;
 | 
				
			||||||
 | 
					static const int REG10_RESERVED_VALUE = 0x300;
 | 
				
			||||||
 | 
					static const int REG10_ADC_CLK_DIV_SHIFT = 6;
 | 
				
			||||||
 | 
					static const int REG10_ADC_CLK_DIV_MASK = ((1<<8)-1);
 | 
				
			||||||
 | 
					static const int REG10_ADC_CONV_SHIFT = 5;
 | 
				
			||||||
 | 
					static const int REG10_ADC_EN_SHIFT = 4;
 | 
				
			||||||
 | 
					static const int REG11_RESERVED = 0x0061300B;
 | 
				
			||||||
 | 
					static const int REG12_RESYNC_CLOCK_SHIFT = 16;
 | 
				
			||||||
 | 
					static const int REG12_RESYNC_CLOCK_MASK = ((1<<16)-1);
 | 
				
			||||||
 | 
					static const int REG12_RESERVED_SHIFT = 4;
 | 
				
			||||||
 | 
					static const int REG12_RESERVED_VALUE = 0x41;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MODIFY_FIELD(reg, val, mask, shift) \
 | 
				
			||||||
 | 
					    reg = ((reg & ~(mask << shift)) | ((val & mask) << shift))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class umsel2_ctrl_impl : public umsel2_ctrl
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    umsel2_ctrl_impl(uhd::wb_iface::sptr ctrl, uhd::spi_iface::sptr spiface, const double ref_clock, const bool verbose):
 | 
				
			||||||
 | 
					        _ctrl(ctrl), _spiface(spiface), _ref_clock(ref_clock), verbose(verbose)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        this->init_synth(SPI_SS_AUX1);
 | 
				
			||||||
 | 
					        this->init_synth(SPI_SS_AUX2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //--------- basic self tests, use the muxout to verify communication ----------//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //set mux out to ground in both cases
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[SPI_SS_AUX1][4], 2, REG4_MUXOUT_MASK, REG4_MUXOUT_SHIFT);
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[SPI_SS_AUX2][4], 2, REG4_MUXOUT_MASK, REG4_MUXOUT_SHIFT);
 | 
				
			||||||
 | 
					        this->write_reg(SPI_SS_AUX1, 4);
 | 
				
			||||||
 | 
					        this->write_reg(SPI_SS_AUX2, 4);
 | 
				
			||||||
 | 
					        UHD_ASSERT_THROW((_ctrl->peek32(U2_REG_IRQ_RB) & AUX_LD1_IRQ_BIT) == 0);
 | 
				
			||||||
 | 
					        UHD_ASSERT_THROW((_ctrl->peek32(U2_REG_IRQ_RB) & AUX_LD2_IRQ_BIT) == 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //set slave1 to muxout vdd
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[SPI_SS_AUX1][4], 1, REG4_MUXOUT_MASK, REG4_MUXOUT_SHIFT);
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[SPI_SS_AUX2][4], 2, REG4_MUXOUT_MASK, REG4_MUXOUT_SHIFT);
 | 
				
			||||||
 | 
					        this->write_reg(SPI_SS_AUX1, 4);
 | 
				
			||||||
 | 
					        this->write_reg(SPI_SS_AUX2, 4);
 | 
				
			||||||
 | 
					        UHD_ASSERT_THROW((_ctrl->peek32(U2_REG_IRQ_RB) & AUX_LD1_IRQ_BIT) != 0);
 | 
				
			||||||
 | 
					        UHD_ASSERT_THROW((_ctrl->peek32(U2_REG_IRQ_RB) & AUX_LD2_IRQ_BIT) == 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //set slave2 to muxout vdd
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[SPI_SS_AUX1][4], 2, REG4_MUXOUT_MASK, REG4_MUXOUT_SHIFT);
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[SPI_SS_AUX2][4], 1, REG4_MUXOUT_MASK, REG4_MUXOUT_SHIFT);
 | 
				
			||||||
 | 
					        this->write_reg(SPI_SS_AUX1, 4);
 | 
				
			||||||
 | 
					        this->write_reg(SPI_SS_AUX2, 4);
 | 
				
			||||||
 | 
					        UHD_ASSERT_THROW((_ctrl->peek32(U2_REG_IRQ_RB) & AUX_LD1_IRQ_BIT) == 0);
 | 
				
			||||||
 | 
					        UHD_ASSERT_THROW((_ctrl->peek32(U2_REG_IRQ_RB) & AUX_LD2_IRQ_BIT) != 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //restore lock detect out
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[SPI_SS_AUX1][4], 6, REG4_MUXOUT_MASK, REG4_MUXOUT_SHIFT);
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[SPI_SS_AUX2][4], 6, REG4_MUXOUT_MASK, REG4_MUXOUT_SHIFT);
 | 
				
			||||||
 | 
					        this->write_reg(SPI_SS_AUX1, 4);
 | 
				
			||||||
 | 
					        this->write_reg(SPI_SS_AUX2, 4);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ~umsel2_ctrl_impl(void)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        try
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            this->pd_synth(SPI_SS_AUX1);
 | 
				
			||||||
 | 
					            this->pd_synth(SPI_SS_AUX2);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        catch(...){}
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uhd::freq_range_t get_rx_freq_range(const int)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return uhd::freq_range_t(54e6, 4400e6);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    double set_rx_freq(const int which, const double freq)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        const int slaveno = (which == 1)?SPI_SS_AUX1 : SPI_SS_AUX2;
 | 
				
			||||||
 | 
					        return this->tune_synth(slaveno, freq);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uhd::sensor_value_t get_locked(const int which)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        boost::uint32_t irq = _ctrl->peek32(U2_REG_IRQ_RB);
 | 
				
			||||||
 | 
					        bool locked = false;
 | 
				
			||||||
 | 
					        if (which == 1) locked = (irq & AUX_LD1_IRQ_BIT) != 0;
 | 
				
			||||||
 | 
					        if (which == 2) locked = (irq & AUX_LD2_IRQ_BIT) != 0;
 | 
				
			||||||
 | 
					        return uhd::sensor_value_t("LO", locked, "locked", "unlocked");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void init_synth(const int slaveno)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        //reset the registers
 | 
				
			||||||
 | 
					        _regs[slaveno][0] = 0;
 | 
				
			||||||
 | 
					        _regs[slaveno][1] = 0;
 | 
				
			||||||
 | 
					        _regs[slaveno][2] = 0;
 | 
				
			||||||
 | 
					        _regs[slaveno][3] = 0;
 | 
				
			||||||
 | 
					        _regs[slaveno][4] = 0;
 | 
				
			||||||
 | 
					        _regs[slaveno][5] = REG5_RESERVED;
 | 
				
			||||||
 | 
					        _regs[slaveno][6] = REG6_RESERVED_VALUE << REG6_RESERVED_SHIFT;
 | 
				
			||||||
 | 
					        _regs[slaveno][7] = REG7_RESERVED_VALUE << REG7_RESERVED_SHIFT;
 | 
				
			||||||
 | 
					        _regs[slaveno][8] = REG8_RESERVED;
 | 
				
			||||||
 | 
					        _regs[slaveno][9] = 0;
 | 
				
			||||||
 | 
					        _regs[slaveno][10] = REG10_RESERVED_VALUE << REG10_RESERVED_SHIFT;
 | 
				
			||||||
 | 
					        _regs[slaveno][11] = REG11_RESERVED;
 | 
				
			||||||
 | 
					        _regs[slaveno][12] = REG12_RESERVED_VALUE << REG12_RESERVED_SHIFT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //------------------------------------------------------------//
 | 
				
			||||||
 | 
					        //----------------------- register 0 -------------------------//
 | 
				
			||||||
 | 
					        //------------------------------------------------------------//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //autocal enabled
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][0], 1, 0x1, REG0_AUTOCAL_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //prescaler 4/5
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][0], 0, 0x1, REG0_PRESCALER_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //------------------------------------------------------------//
 | 
				
			||||||
 | 
					        //----------------------- register 3 -------------------------//
 | 
				
			||||||
 | 
					        //------------------------------------------------------------//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //sd load reset, phase resync, phase adjust = disabled
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][3], 0, 0x1, REG3_SD_LOAD_SHIFT);
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][3], 0, 0x1, REG3_PHASE_RSYNC_SHIFT);
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][3], 0, 0x1, REG3_PHASE_ADJ_SHIFT);
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][3], 0, REG3_PHASE_MASK, REG3_PHASE_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //------------------------------------------------------------//
 | 
				
			||||||
 | 
					        //----------------------- register 4 -------------------------//
 | 
				
			||||||
 | 
					        //------------------------------------------------------------//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //muxout to lock detect
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][4], 6, REG4_MUXOUT_MASK, REG4_MUXOUT_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //double buff disabled
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][4], 0, 0x1, REG4_DBL_BUFF_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //charge pump current 0.31mA@5.1k
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][4], 0, REG4_CURRENT_MASK, REG4_CURRENT_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //refin single ended
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][4], 0, 0x1, REG4_REF_MODE_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //mux level 3V
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][4], 1, 0x1, REG4_MUX_LOGIC_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //PD polarity positive
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][4], 1, 0x1, REG4_PD_POL_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //power down disabled
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][4], 0, 0x1, REG4_PWR_DOWN_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //charge-pump 3-state disabled
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][4], 0, 0x1, REG4_CP_3STATE_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //counter reset disabled
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][4], 0, 0x1, REG4_CNTR_RESET);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //------------------------------------------------------------//
 | 
				
			||||||
 | 
					        //----------------------- register 6 -------------------------//
 | 
				
			||||||
 | 
					        //------------------------------------------------------------//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //feedback fundamental
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][6], 1, 0x1, REG6_FB_SEL_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //bleed current 7.5uA
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][6], 2, REG6_CP_BLEED_CURR_MASK, REG6_CP_BLEED_CURR_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //mute until lock detect disabled
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][6], 0, 0x1, REG6_MLTD_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //aux output disabled (-1dBm)
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][6], 0, 0x1, REG6_AUX_PWR_EN_SHIFT);
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][6], 1, REG6_AUX_PWR_MASK, REG6_AUX_PWR_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //RF output power (5dBm)
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][6], 1, 0x1, REG6_PWR_EN_SHIFT);
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][6], 3, REG6_PWR_MASK, REG6_PWR_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //negative bleed enabled
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][6], 1, 0x1, REG6_NEG_BLEED_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //gated bleed disabled
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][6], 0, 0x1, REG6_GATED_BLEED_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //------------------------------------------------------------//
 | 
				
			||||||
 | 
					        //----------------------- register 7 -------------------------//
 | 
				
			||||||
 | 
					        //------------------------------------------------------------//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //LE Sync REFin
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][7], 1, 0x1, REG7_LE_SYNC_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //LD Cycles
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][7], 1024, REG7_LD_CYCLE_CNT_MASK, REG7_LD_CYCLE_CNT_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //LOL Mode disabled
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][7], 0, 0x1, REG7_LOL_MODE_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //Frac-N LD Prec 5.0ns
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][7], 0, REG7_FRAC_N_PREC_MASK, REG7_FRAC_N_PREC_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //LD Mode Frac-N
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][7], 0, 0x1, REG7_LD_MODE_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //------------------------------------------------------------//
 | 
				
			||||||
 | 
					        //----------------------- register 10 ------------------------//
 | 
				
			||||||
 | 
					        //------------------------------------------------------------//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //adc enable
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][10], 1, 0x1, REG10_ADC_EN_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //adc conversion enable
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][10], 1, 0x1, REG10_ADC_CONV_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //------------------------------------------------------------//
 | 
				
			||||||
 | 
					        //----------------------- register 12 ------------------------//
 | 
				
			||||||
 | 
					        //------------------------------------------------------------//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //phase resync 0
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][12], 0, REG12_RESYNC_CLOCK_MASK, REG12_RESYNC_CLOCK_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //write all registers
 | 
				
			||||||
 | 
					        for (int addr = 12; addr >= 0; addr--)
 | 
				
			||||||
 | 
					            this->write_reg(slaveno, addr);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void pd_synth(const int slaveno)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        //muxout to lock 3state
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][4], 0, REG4_MUXOUT_MASK, REG4_MUXOUT_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //charge pump 3state
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][4], 1, 0x1, REG4_CP_3STATE_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //power down
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][4], 1, 0x1, REG4_PWR_DOWN_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //outputs off
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][6], 0, 0x1, REG6_AUX_PWR_EN_SHIFT);
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][6], 0, 0x1, REG6_PWR_EN_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //write all registers
 | 
				
			||||||
 | 
					        for (int addr = 12; addr >= 0; addr--)
 | 
				
			||||||
 | 
					            this->write_reg(slaveno, addr);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    double tune_synth(const int slaveno, const double RFout)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (verbose) std::cout << " tune_synth(slaveno=" << slaveno << ")" << std::endl;
 | 
				
			||||||
 | 
					        if (verbose) std::cout << " RFout " << (RFout/1e6) << " MHz" << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //determine the reference out divider and VCOout
 | 
				
			||||||
 | 
					        double VCOout = 0;
 | 
				
			||||||
 | 
					        int RFOUTDIVSEL = 0;
 | 
				
			||||||
 | 
					        while (true)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            int RFOUTDIV = 1 << RFOUTDIVSEL;
 | 
				
			||||||
 | 
					            VCOout = RFout*RFOUTDIV;
 | 
				
			||||||
 | 
					            if (VCOout < 3.4e9) RFOUTDIVSEL++;
 | 
				
			||||||
 | 
					            else break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (verbose) std::cout << " RFOUTDIV " << (1 << RFOUTDIVSEL) << "" << std::endl;
 | 
				
			||||||
 | 
					        if (verbose) std::cout << " VCOout " << (VCOout/1e6) << " MHz" << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //use doubler to increase the pfd frequency (good for noise performance)
 | 
				
			||||||
 | 
					        int REFDBL = 0;
 | 
				
			||||||
 | 
					        int REFDIV = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //prescaler settings
 | 
				
			||||||
 | 
					        int PRESCALER = 0; //4/5
 | 
				
			||||||
 | 
					        const int Nmin = (PRESCALER==0)?23:75;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //calculate the R divider, N divider, and PDF frequency
 | 
				
			||||||
 | 
					        double NDIV = 0;
 | 
				
			||||||
 | 
					        int RDIV = 1;
 | 
				
			||||||
 | 
					        double fPFD = 0;
 | 
				
			||||||
 | 
					        while (true)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            fPFD = _ref_clock*(double(1+REFDBL)/double(RDIV*(1+REFDIV)));
 | 
				
			||||||
 | 
					            NDIV = VCOout/fPFD;
 | 
				
			||||||
 | 
					            if (NDIV < Nmin) RDIV++;
 | 
				
			||||||
 | 
					            else break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (verbose) std::cout << " RDIV " << RDIV << "" << std::endl;
 | 
				
			||||||
 | 
					        if (verbose) std::cout << " NDIV " << NDIV << "" << std::endl;
 | 
				
			||||||
 | 
					        if (verbose) std::cout << " fPFD " << (fPFD/1e6) << " MHz" << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //calculate the integer parts of the N divider
 | 
				
			||||||
 | 
					        int NINT = int(NDIV);
 | 
				
			||||||
 | 
					        double NFRAC = std::ldexp(NDIV-NINT, 24);
 | 
				
			||||||
 | 
					        int FRAC1 = int(NFRAC);
 | 
				
			||||||
 | 
					        int MOD2 = fPFD/1e6; //TODO MOD2 = fPFD/GCD(fPFD, fCHSP)
 | 
				
			||||||
 | 
					        int FRAC2 = int((NFRAC-FRAC1)*MOD2);
 | 
				
			||||||
 | 
					        if (verbose) std::cout << " NINT " << NINT << "" << std::endl;
 | 
				
			||||||
 | 
					        if (verbose) std::cout << " FRAC1 " << FRAC1 << "" << std::endl;
 | 
				
			||||||
 | 
					        if (verbose) std::cout << " MOD2 " << MOD2 << "" << std::endl;
 | 
				
			||||||
 | 
					        if (verbose) std::cout << " FRAC2 " << FRAC2 << "" << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //VCO Band Division
 | 
				
			||||||
 | 
					        //PFD/(band division × 16) < 150 kHz
 | 
				
			||||||
 | 
					        int VCObanddiv = 1;
 | 
				
			||||||
 | 
					        while (not(fPFD/(VCObanddiv*16) < 150e3)) VCObanddiv++;
 | 
				
			||||||
 | 
					        if (verbose) std::cout << " VCObanddiv " << VCObanddiv << "" << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //Maximize ALC Wait (to reduce Timeout to minimize time) so
 | 
				
			||||||
 | 
					        //that ALC Wait = 30 and Synthesizer Lock Timeout = 12.
 | 
				
			||||||
 | 
					        int ALC = 30;
 | 
				
			||||||
 | 
					        int SLT = 12;
 | 
				
			||||||
 | 
					        int TIMEOUT = std::ceil((fPFD*50e-6)/ALC);
 | 
				
			||||||
 | 
					        if (verbose) std::cout << " TIMEOUT " << TIMEOUT << "" << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //ADC Clock Divider (ADC_CLK_DIV)
 | 
				
			||||||
 | 
					        //PFD/((ADC_CLK_DIV × 4) × 2) < 100 kHz
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					        int ADC_CLK_DIV = 1;
 | 
				
			||||||
 | 
					        while (not(fPFD/((ADC_CLK_DIV*4)*2) < 100e3)) ADC_CLK_DIV++;
 | 
				
			||||||
 | 
					        if (verbose) std::cout << " ADC_CLK_DIV " << ADC_CLK_DIV << "" << std::endl;
 | 
				
			||||||
 | 
					        const long sleepUs = long(1e6*16*ADC_CLK_DIV/fPFD);
 | 
				
			||||||
 | 
					        */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //Copied from the ADI GUI
 | 
				
			||||||
 | 
					        //after trying to juxtapose the documentation with the GUI
 | 
				
			||||||
 | 
					        int ADC_CLK_DIV = 65;
 | 
				
			||||||
 | 
					        const long sleepUs = 160;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //load registers
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][0], NINT, REG0_NVALUE_MASK, REG0_NVALUE_SHIFT);
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][0], PRESCALER, 0x1, REG0_PRESCALER_SHIFT);
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][0], 1/*enb*/, 0x1, REG0_AUTOCAL_SHIFT);
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][1], FRAC1, REG1_MFRAC_MASK, REG1_MFRAC_SHIFT);
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][2], MOD2, REG2_AUX_MOD_MASK, REG2_AUX_MOD_SHIFT);
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][2], FRAC2, REG2_AUX_FRAC_MASK, REG2_AUX_FRAC_SHIFT);
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][4], RDIV, REG4_R_MASK, REG4_R_SHIFT);
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][4], REFDIV, 0x1, REG4_REF_DIV_SHIFT);
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][4], REFDBL, 0x1, REG4_REF_DBL_SHIFT);
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][6], RFOUTDIVSEL, REG6_RF_DIV_MASK, REG6_RF_DIV_SHIFT);
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][9], SLT, REG9_SYNT_LOCK_TO_MASK, REG9_SYNT_LOCK_TO_SHIFT);
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][9], ALC, REG9_AUTO_LVL_TO_MASK, REG9_AUTO_LVL_TO_SHIFT);
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][9], TIMEOUT, REG9_TIMEOUT_MASK, REG9_TIMEOUT_SHIFT);
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][9], VCObanddiv, REG9_VCO_BAND_MASK, REG9_VCO_BAND_SHIFT);
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][10], ADC_CLK_DIV, REG10_ADC_CLK_DIV_MASK, REG10_ADC_CLK_DIV_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //write other registers
 | 
				
			||||||
 | 
					        this->write_reg(slaveno, 6);
 | 
				
			||||||
 | 
					        this->write_reg(slaveno, 9);
 | 
				
			||||||
 | 
					        this->write_reg(slaveno, 10);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //FREQUENCY UPDATE SEQUENCE
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][4], 1, 0x1, REG4_CNTR_RESET);
 | 
				
			||||||
 | 
					        this->write_reg(slaveno, 4);
 | 
				
			||||||
 | 
					        this->write_reg(slaveno, 2);
 | 
				
			||||||
 | 
					        this->write_reg(slaveno, 1);
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][0], 0, 0x1, REG0_AUTOCAL_SHIFT);
 | 
				
			||||||
 | 
					        this->write_reg(slaveno, 0);
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][4], 0, 0x1, REG4_CNTR_RESET);
 | 
				
			||||||
 | 
					        this->write_reg(slaveno, 4);
 | 
				
			||||||
 | 
					        boost::this_thread::sleep(boost::posix_time::microseconds(sleepUs));
 | 
				
			||||||
 | 
					        if (verbose) std::cout << " sleep time " << (sleepUs) << " us" << std::endl;
 | 
				
			||||||
 | 
					        MODIFY_FIELD(_regs[slaveno][0], 1, 0x1, REG0_AUTOCAL_SHIFT);
 | 
				
			||||||
 | 
					        this->write_reg(slaveno, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //calculate actual tune value
 | 
				
			||||||
 | 
					        double Nactual = NINT + std::ldexp(double(FRAC1 + FRAC2/double(MOD2)), -24);
 | 
				
			||||||
 | 
					        double RFoutactual = (fPFD*Nactual)/(1 << RFOUTDIVSEL);
 | 
				
			||||||
 | 
					        if (verbose) std::cout << " Nactual " << Nactual << "" << std::endl;
 | 
				
			||||||
 | 
					        if (verbose) std::cout << " RFoutactual " << (RFoutactual/1e6) << " MHz" << std::endl;
 | 
				
			||||||
 | 
					        if (verbose) boost::this_thread::sleep(boost::posix_time::microseconds(10000));
 | 
				
			||||||
 | 
					        if (verbose) std::cout << " Locked " << this->get_locked((slaveno==SPI_SS_AUX1)?1:2).value << "" << std::endl;
 | 
				
			||||||
 | 
					        return RFoutactual;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void write_reg(const int slaveno, const int addr)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        int value = (_regs[slaveno][addr] & ~0xf) | addr;
 | 
				
			||||||
 | 
					        if (verbose) std::cout << "write_reg[" << addr << "] = 0x" << std::hex << value << std::dec << std::endl;
 | 
				
			||||||
 | 
					        _spiface->write_spi(slaveno, uhd::spi_config_t::EDGE_RISE, value, 32);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uhd::wb_iface::sptr _ctrl;
 | 
				
			||||||
 | 
					    uhd::spi_iface::sptr _spiface;
 | 
				
			||||||
 | 
					    const double _ref_clock;
 | 
				
			||||||
 | 
					    std::map<int, std::map<int, int> > _regs;
 | 
				
			||||||
 | 
					    const bool verbose;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					umsel2_ctrl::sptr umsel2_ctrl::make(uhd::wb_iface::sptr ctrl, uhd::spi_iface::sptr spiface, const double ref_clock, const bool verbose)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return umsel2_ctrl::sptr(new umsel2_ctrl_impl(ctrl, spiface, ref_clock, verbose));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										61
									
								
								host/umsel2_ctrl.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								host/umsel2_ctrl.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
				
			|||||||
 | 
					// Copyright 2015-2015 Fairwaves LLC
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					// it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					// the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					// (at your option) any later version.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					// but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					// GNU General Public License for more details.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					// along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef INCLUDED_UMSEL2_CTRL_HPP
 | 
				
			||||||
 | 
					#define INCLUDED_UMSEL2_CTRL_HPP
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <uhd/types/serial.hpp>
 | 
				
			||||||
 | 
					#include <uhd/types/wb_iface.hpp>
 | 
				
			||||||
 | 
					#include <uhd/types/sensors.hpp>
 | 
				
			||||||
 | 
					#include <uhd/types/ranges.hpp>
 | 
				
			||||||
 | 
					#include <boost/shared_ptr.hpp>
 | 
				
			||||||
 | 
					#include <boost/utility.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define UMSEL2_CH1_LMS_IF 360e6
 | 
				
			||||||
 | 
					#define UMSEL2_CH2_LMS_IF 400e6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*!
 | 
				
			||||||
 | 
					 * Control UmSEL2 board.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class umsel2_ctrl
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    typedef boost::shared_ptr<umsel2_ctrl> sptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static sptr make(uhd::wb_iface::sptr ctrl, uhd::spi_iface::sptr spiface, const double ref_clock, const bool verbose);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					     * Query the tune range.
 | 
				
			||||||
 | 
					     * \param which values 1 or 2
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual uhd::freq_range_t get_rx_freq_range(const int which) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					     * Tune the synthesizer
 | 
				
			||||||
 | 
					     * \param which values 1 or 2
 | 
				
			||||||
 | 
					     * \param freq the freq in Hz
 | 
				
			||||||
 | 
					     * \return the actual freq in Hz
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual double set_rx_freq(const int which, const double freq) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*!
 | 
				
			||||||
 | 
					     * Query lock detect.
 | 
				
			||||||
 | 
					     * \param which values 1 or 2
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual uhd::sensor_value_t get_locked(const int which) = 0;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* INCLUDED_UMSEL2_CTRL_HPP */
 | 
				
			||||||
@@ -38,8 +38,9 @@ const int umtrx_impl::UMTRX_VGA1_DEF = -20;
 | 
				
			|||||||
const int umtrx_impl::UMTRX_VGA2_DEF = 22;
 | 
					const int umtrx_impl::UMTRX_VGA2_DEF = 22;
 | 
				
			||||||
const int umtrx_impl::UMTRX_VGA2_MIN = 0;
 | 
					const int umtrx_impl::UMTRX_VGA2_MIN = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const double _dcdc_val_to_volt_init[256] =
 | 
					const double umtrx_impl::_dcdc_val_to_volt[umtrx_impl::DCDC_VER_COUNT][256] =
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
     9.38,  9.38,  9.40,  9.42,  9.42,  9.44,  9.46,  9.46,  9.48,  9.50, // 10
 | 
					     9.38,  9.38,  9.40,  9.42,  9.42,  9.44,  9.46,  9.46,  9.48,  9.50, // 10
 | 
				
			||||||
     9.50,  9.52,  9.54,  9.54,  9.56,  9.58,  9.58,  9.60,  9.60,  9.62, // 20
 | 
					     9.50,  9.52,  9.54,  9.54,  9.56,  9.58,  9.58,  9.60,  9.60,  9.62, // 20
 | 
				
			||||||
     9.64,  9.66,  9.66,  9.68,  9.70,  9.70,  9.72,  9.74,  9.76,  9.76, // 30
 | 
					     9.64,  9.66,  9.66,  9.68,  9.70,  9.70,  9.72,  9.74,  9.76,  9.76, // 30
 | 
				
			||||||
@@ -66,8 +67,35 @@ static const double _dcdc_val_to_volt_init[256] =
 | 
				
			|||||||
    20.02, 20.20, 20.38, 20.58, 20.76, 20.96, 21.18, 21.38, 21.60, 21.82, // 240
 | 
					    20.02, 20.20, 20.38, 20.58, 20.76, 20.96, 21.18, 21.38, 21.60, 21.82, // 240
 | 
				
			||||||
    21.92, 22.16, 22.40, 22.66, 22.92, 23.18, 23.46, 23.74, 24.02, 24.30, // 250
 | 
					    21.92, 22.16, 22.40, 22.66, 22.92, 23.18, 23.46, 23.74, 24.02, 24.30, // 250
 | 
				
			||||||
    24.62, 24.94, 25.28, 25.62, 25.98, 26.34
 | 
					    24.62, 24.94, 25.28, 25.62, 25.98, 26.34
 | 
				
			||||||
 | 
					  },{
 | 
				
			||||||
 | 
					    4.84,  4.84,  4.86,  4.88,  4.88,  4.90,  4.92,  4.94,  4.94,  4.96,  // 10
 | 
				
			||||||
 | 
					    4.98,  5.00,  5.02,  5.02,  5.04,  5.06,  5.06,  5.08,  5.10,  5.12,  // 20
 | 
				
			||||||
 | 
					    5.12,  5.14,  5.16,  5.18,  5.20,  5.22,  5.22,  5.24,  5.26,  5.28,  // 30
 | 
				
			||||||
 | 
					    5.30,  5.32,  5.32,  5.34,  5.36,  5.38,  5.40,  5.42,  5.44,  5.46,  // 40
 | 
				
			||||||
 | 
					    5.48,  5.50,  5.50,  5.52,  5.54,  5.56,  5.58,  5.60,  5.62,  5.64,  // 50
 | 
				
			||||||
 | 
					    5.66,  5.68,  5.70,  5.72,  5.74,  5.76,  5.78,  5.80,  5.82,  5.86,  // 60
 | 
				
			||||||
 | 
					    5.88,  5.90,  5.92,  5.94,  5.96,  5.98,  6.00,  6.02,  6.04,  6.08,  // 70
 | 
				
			||||||
 | 
					    6.10,  6.12,  6.14,  6.16,  6.20,  6.22,  6.24,  6.28,  6.30,  6.32,  // 80
 | 
				
			||||||
 | 
					    6.34,  6.36,  6.40,  6.42,  6.44,  6.48,  6.50,  6.54,  6.56,  6.58,  // 90
 | 
				
			||||||
 | 
					    6.62,  6.64,  6.68,  6.70,  6.74,  6.76,  6.78,  6.82,  6.84,  6.88,  // 100
 | 
				
			||||||
 | 
					    6.92,  6.94,  6.98,  7.00,  7.04,  7.08,  7.12,  7.14,  7.18,  7.22,  // 110
 | 
				
			||||||
 | 
					    7.26,  7.28,  7.30,  7.34,  7.38,  7.42,  7.46,  7.50,  7.54,  7.58,  // 120
 | 
				
			||||||
 | 
					    7.62,  7.66,  7.70,  7.74,  7.78,  7.82,  7.86,  7.90,  7.92,  7.98,  // 130
 | 
				
			||||||
 | 
					    8.02,  8.06,  8.10,  8.16,  8.20,  8.26,  8.30,  8.34,  8.40,  8.44,  // 140
 | 
				
			||||||
 | 
					    8.50,  8.54,  8.60,  8.66,  8.68,  8.74,  8.78,  8.84,  8.90,  8.96,  // 150
 | 
				
			||||||
 | 
					    9.02,  9.08,  9.14,  9.20,  9.26,  9.32,  9.38,  9.44,  9.52,  9.58,  // 160
 | 
				
			||||||
 | 
					    9.62,  9.68,  9.76,  9.82,  9.90,  9.96,  10.04, 10.12, 10.18, 10.26, // 170
 | 
				
			||||||
 | 
					    10.34, 10.42, 10.50, 10.58, 10.68, 10.76, 10.80, 10.88, 10.98, 11.08, // 180
 | 
				
			||||||
 | 
					    11.16, 11.26, 11.36, 11.44, 11.54, 11.64, 11.74, 11.86, 11.96, 12.08, // 190
 | 
				
			||||||
 | 
					    12.18, 12.30, 12.36, 12.48, 12.60, 12.72, 12.84, 12.96, 13.10, 13.24, // 200
 | 
				
			||||||
 | 
					    13.36, 13.50, 13.64, 13.78, 13.94, 14.08, 14.24, 14.40, 14.48, 14.66, // 210
 | 
				
			||||||
 | 
					    14.82, 15.00, 15.18, 15.36, 15.54, 15.74, 15.92, 16.12, 16.32, 16.54, // 220
 | 
				
			||||||
 | 
					    16.76, 16.98, 17.22, 17.44, 17.58, 17.82, 18.08, 18.34, 18.62, 18.90, // 230
 | 
				
			||||||
 | 
					    19.20, 19.48, 19.80, 20.10, 20.44, 20.78, 21.12, 21.50, 21.88, 22.26, // 240
 | 
				
			||||||
 | 
					    22.48, 22.90, 23.34, 23.80, 24.26, 24.74, 25.26, 25.76, 26.32, 26.86, // 250
 | 
				
			||||||
 | 
					    27.48, 28.12, 28.78, 29.50, 29.50, 29.50
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
const std::vector<double> umtrx_impl::_dcdc_val_to_volt(_dcdc_val_to_volt_init, &_dcdc_val_to_volt_init[256]);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/***********************************************************************
 | 
					/***********************************************************************
 | 
				
			||||||
 * Property tree "alias" function
 | 
					 * Property tree "alias" function
 | 
				
			||||||
@@ -179,6 +207,7 @@ static mtu_result_t determine_mtu(const std::string &addr, const mtu_result_t &u
 | 
				
			|||||||
 **********************************************************************/
 | 
					 **********************************************************************/
 | 
				
			||||||
umtrx_impl::umtrx_impl(const device_addr_t &device_addr)
 | 
					umtrx_impl::umtrx_impl(const device_addr_t &device_addr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    _umtrx_vga2_def = device_addr.cast<int>("lmsvga2", UMTRX_VGA2_DEF);
 | 
				
			||||||
    _device_ip_addr = device_addr["addr"];
 | 
					    _device_ip_addr = device_addr["addr"];
 | 
				
			||||||
    UHD_MSG(status) << "UmTRX driver version: " << UMTRX_VERSION << std::endl;
 | 
					    UHD_MSG(status) << "UmTRX driver version: " << UMTRX_VERSION << std::endl;
 | 
				
			||||||
    UHD_MSG(status) << "Opening a UmTRX device... " << _device_ip_addr << std::endl;
 | 
					    UHD_MSG(status) << "Opening a UmTRX device... " << _device_ip_addr << std::endl;
 | 
				
			||||||
@@ -270,6 +299,36 @@ umtrx_impl::umtrx_impl(const device_addr_t &device_addr)
 | 
				
			|||||||
    _tree->create<std::string>(mb_path / "hwrev").set(get_hw_rev());
 | 
					    _tree->create<std::string>(mb_path / "hwrev").set(get_hw_rev());
 | 
				
			||||||
    UHD_MSG(status) << "Detected UmTRX " << get_hw_rev() << std::endl;
 | 
					    UHD_MSG(status) << "Detected UmTRX " << get_hw_rev() << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    _hw_dcdc_ver = device_addr.cast<int>("dcdc_ver", -1);
 | 
				
			||||||
 | 
					    if (_hw_dcdc_ver < 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        detect_hw_dcdc_ver(mb_path);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        UHD_ASSERT_THROW(_hw_dcdc_ver < DCDC_VER_COUNT);
 | 
				
			||||||
 | 
					        UHD_MSG(status) << "Using DCDC version " << _hw_dcdc_ver << std::endl;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    _tree->create<int>(mb_path / "hwdcdc_ver").set(_hw_dcdc_ver);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					    // setup umsel2 control when present
 | 
				
			||||||
 | 
					    ////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					    const std::string detect_umsel = device_addr.get("umsel", "off");
 | 
				
			||||||
 | 
					    if (detect_umsel != "off")
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        //TODO delect umsel2 automatically with I2C communication
 | 
				
			||||||
 | 
					        const bool umsel_verbose = device_addr.has_key("umsel_verbose");
 | 
				
			||||||
 | 
					        _umsel2 = umsel2_ctrl::make(_ctrl/*peek*/, _ctrl/*spi*/, this->get_master_clock_rate(), umsel_verbose);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //register lock detect for umsel2
 | 
				
			||||||
 | 
					    if (_umsel2)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        _tree->create<sensor_value_t>(mb_path / "dboards" / "A" / "rx_frontends" / "0" / "sensors" / "aux_lo_locked")
 | 
				
			||||||
 | 
					            .publish(boost::bind(&umsel2_ctrl::get_locked, _umsel2, 1));
 | 
				
			||||||
 | 
					        _tree->create<sensor_value_t>(mb_path / "dboards" / "B" / "rx_frontends" / "0" / "sensors" / "aux_lo_locked")
 | 
				
			||||||
 | 
					            .publish(boost::bind(&umsel2_ctrl::get_locked, _umsel2, 2));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ////////////////////////////////////////////////////////////////////////
 | 
					    ////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
    // configure diversity switches
 | 
					    // configure diversity switches
 | 
				
			||||||
    ////////////////////////////////////////////////////////////////////////
 | 
					    ////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
@@ -490,8 +549,8 @@ umtrx_impl::umtrx_impl(const device_addr_t &device_addr)
 | 
				
			|||||||
    ////////////////////////////////////////////////////////////////////
 | 
					    ////////////////////////////////////////////////////////////////////
 | 
				
			||||||
    // create RF frontend interfacing
 | 
					    // create RF frontend interfacing
 | 
				
			||||||
    ////////////////////////////////////////////////////////////////////
 | 
					    ////////////////////////////////////////////////////////////////////
 | 
				
			||||||
    _lms_ctrl["A"] = lms6002d_ctrl::make(_ctrl/*spi*/, SPI_SS_LMS1, SPI_SS_AUX1, this->get_master_clock_rate() / _pll_div);
 | 
					    _lms_ctrl["A"] = lms6002d_ctrl::make(_ctrl/*spi*/, SPI_SS_LMS1, this->get_master_clock_rate() / _pll_div);
 | 
				
			||||||
    _lms_ctrl["B"] = lms6002d_ctrl::make(_ctrl/*spi*/, SPI_SS_LMS2, SPI_SS_AUX2, this->get_master_clock_rate() / _pll_div);
 | 
					    _lms_ctrl["B"] = lms6002d_ctrl::make(_ctrl/*spi*/, SPI_SS_LMS2, this->get_master_clock_rate() / _pll_div);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // LMS dboard do not have physical eeprom so we just hardcode values from host/lib/usrp/dboard/db_lms.cpp
 | 
					    // LMS dboard do not have physical eeprom so we just hardcode values from host/lib/usrp/dboard/db_lms.cpp
 | 
				
			||||||
    dboard_eeprom_t rx_db_eeprom, tx_db_eeprom, gdb_db_eeprom;
 | 
					    dboard_eeprom_t rx_db_eeprom, tx_db_eeprom, gdb_db_eeprom;
 | 
				
			||||||
@@ -554,7 +613,8 @@ umtrx_impl::umtrx_impl(const device_addr_t &device_addr)
 | 
				
			|||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            // Set LMS internal VGA1 gain to optimal value
 | 
					            // Set LMS internal VGA1 gain to optimal value
 | 
				
			||||||
            // VGA2 will be set in the set_tx_power()
 | 
					            // VGA2 will be set in the set_tx_power()
 | 
				
			||||||
            ctrl->set_tx_gain(UMTRX_VGA1_DEF, "VGA1");
 | 
					            const int vga1 = device_addr.cast<int>("lmsvga1", UMTRX_VGA1_DEF);
 | 
				
			||||||
 | 
					            ctrl->set_tx_gain(vga1, "VGA1");
 | 
				
			||||||
            _tx_power_range[fe_name] = generate_tx_power_range(fe_name);
 | 
					            _tx_power_range[fe_name] = generate_tx_power_range(fe_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Use PA control to control output power
 | 
					            // Use PA control to control output power
 | 
				
			||||||
@@ -570,9 +630,9 @@ umtrx_impl::umtrx_impl(const device_addr_t &device_addr)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        //rx freq
 | 
					        //rx freq
 | 
				
			||||||
        _tree->create<double>(rx_rf_fe_path / "freq" / "value")
 | 
					        _tree->create<double>(rx_rf_fe_path / "freq" / "value")
 | 
				
			||||||
            .coerce(boost::bind(&lms6002d_ctrl::set_rx_freq, ctrl, _1));
 | 
					            .coerce(boost::bind(&umtrx_impl::set_rx_freq, this, fe_name, _1));
 | 
				
			||||||
        _tree->create<meta_range_t>(rx_rf_fe_path / "freq" / "range")
 | 
					        _tree->create<meta_range_t>(rx_rf_fe_path / "freq" / "range")
 | 
				
			||||||
            .publish(boost::bind(&lms6002d_ctrl::get_rx_freq_range, ctrl));
 | 
					            .publish(boost::bind(&umtrx_impl::get_rx_freq_range, this, fe_name));
 | 
				
			||||||
        _tree->create<bool>(rx_rf_fe_path / "use_lo_offset").set(false);
 | 
					        _tree->create<bool>(rx_rf_fe_path / "use_lo_offset").set(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //tx freq
 | 
					        //tx freq
 | 
				
			||||||
@@ -712,12 +772,13 @@ umtrx_impl::~umtrx_impl(void)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int umtrx_impl::volt_to_dcdc_r(double v)
 | 
					int umtrx_impl::volt_to_dcdc_r(double v)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (v <= _dcdc_val_to_volt[0])
 | 
					    if (v <= _dcdc_val_to_volt[_hw_dcdc_ver][0])
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    else if (v >= _dcdc_val_to_volt[255])
 | 
					    else if (v >= _dcdc_val_to_volt[_hw_dcdc_ver][255])
 | 
				
			||||||
        return 255;
 | 
					        return 255;
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
        return std::lower_bound(_dcdc_val_to_volt.begin(), _dcdc_val_to_volt.end(), v) - _dcdc_val_to_volt.begin();
 | 
					        return std::lower_bound(&_dcdc_val_to_volt[_hw_dcdc_ver][0], &_dcdc_val_to_volt[_hw_dcdc_ver][256], v) -
 | 
				
			||||||
 | 
					                                &_dcdc_val_to_volt[_hw_dcdc_ver][0];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void umtrx_impl::set_pa_dcdc_r(uint8_t val)
 | 
					void umtrx_impl::set_pa_dcdc_r(uint8_t val)
 | 
				
			||||||
@@ -737,7 +798,7 @@ uhd::gain_range_t umtrx_impl::generate_tx_power_range(const std::string &which)
 | 
				
			|||||||
    // maintain high signal quality.
 | 
					    // maintain high signal quality.
 | 
				
			||||||
    uhd::gain_range_t pa_range = generate_pa_power_range(which);
 | 
					    uhd::gain_range_t pa_range = generate_pa_power_range(which);
 | 
				
			||||||
//    UHD_MSG(status) << "Original PA output power range: " << pa_range.to_pp_string() << std::endl;
 | 
					//    UHD_MSG(status) << "Original PA output power range: " << pa_range.to_pp_string() << std::endl;
 | 
				
			||||||
    uhd::gain_range_t vga_range(pa_range.start() - (UMTRX_VGA2_DEF-UMTRX_VGA2_MIN), pa_range.start()-1, 1.0);
 | 
					    uhd::gain_range_t vga_range(pa_range.start() - (_umtrx_vga2_def-UMTRX_VGA2_MIN), pa_range.start()-1, 1.0);
 | 
				
			||||||
    uhd::gain_range_t res_range(vga_range);
 | 
					    uhd::gain_range_t res_range(vga_range);
 | 
				
			||||||
    res_range.insert(res_range.end(), pa_range.begin(), pa_range.end());
 | 
					    res_range.insert(res_range.end(), pa_range.begin(), pa_range.end());
 | 
				
			||||||
//    UHD_MSG(status) << "Generated Tx output power range: " << res_range.to_pp_string() << std::endl;
 | 
					//    UHD_MSG(status) << "Generated Tx output power range: " << res_range.to_pp_string() << std::endl;
 | 
				
			||||||
@@ -763,16 +824,16 @@ double umtrx_impl::set_tx_power(double power, const std::string &which)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if (power >= min_pa_power)
 | 
					    if (power >= min_pa_power)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        UHD_MSG(status) << "Setting Tx power using PA (VGA2=" << UMTRX_VGA2_DEF << ", PA=" << power << ")" << std::endl;
 | 
					        UHD_MSG(status) << "Setting Tx power using PA (VGA2=" << _umtrx_vga2_def << ", PA=" << power << ")" << std::endl;
 | 
				
			||||||
        // Set VGA2 to the recommended value and use PA to control Tx power
 | 
					        // Set VGA2 to the recommended value and use PA to control Tx power
 | 
				
			||||||
        _lms_ctrl[which]->set_tx_gain(UMTRX_VGA2_DEF, "VGA2");
 | 
					        _lms_ctrl[which]->set_tx_gain(_umtrx_vga2_def, "VGA2");
 | 
				
			||||||
        actual_power = set_pa_power(power, which);
 | 
					        actual_power = set_pa_power(power, which);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        double vga2_gain = UMTRX_VGA2_DEF - (min_pa_power-power);
 | 
					        double vga2_gain = _umtrx_vga2_def - (min_pa_power-power);
 | 
				
			||||||
        UHD_MSG(status) << "Setting Tx power using VGA2 (VGA2=" << vga2_gain << ", PA=" << min_pa_power << ")" << std::endl;
 | 
					        UHD_MSG(status) << "Setting Tx power using VGA2 (VGA2=" << vga2_gain << ", PA=" << min_pa_power << ")" << std::endl;
 | 
				
			||||||
        // Set PA output power to minimum and use VGA2 to control Tx power
 | 
					        // Set PA output power to minimum and use VGA2 to control Tx power
 | 
				
			||||||
        actual_power = _lms_ctrl[which]->set_tx_gain(vga2_gain, "VGA2");
 | 
					        actual_power = _lms_ctrl[which]->set_tx_gain(vga2_gain, "VGA2");
 | 
				
			||||||
        actual_power = set_pa_power(min_pa_power, which) - (UMTRX_VGA2_DEF-actual_power);
 | 
					        actual_power = set_pa_power(min_pa_power, which) - (_umtrx_vga2_def-actual_power);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return actual_power;
 | 
					    return actual_power;
 | 
				
			||||||
@@ -871,6 +932,49 @@ uint8_t umtrx_impl::dc_offset_double2int(double corr)
 | 
				
			|||||||
    return (int)(corr*128 + 128.5);
 | 
					    return (int)(corr*128 + 128.5);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					double umtrx_impl::set_rx_freq(const std::string &which, const double freq)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (_umsel2)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        const double target_lms_freq = (which=="A")?UMSEL2_CH1_LMS_IF:UMSEL2_CH2_LMS_IF;
 | 
				
			||||||
 | 
					        const double actual_lms_freq = _lms_ctrl[which]->set_rx_freq(target_lms_freq);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const double target_umsel_freq = freq - actual_lms_freq;
 | 
				
			||||||
 | 
					        const double actual_umsel_freq = _umsel2->set_rx_freq((which=="A")?1:2, target_umsel_freq);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					        std::cout << "target_total_freq " << freq/1e6 << " MHz" << std::endl;
 | 
				
			||||||
 | 
					        std::cout << "target_lms_freq " << target_lms_freq/1e6 << " MHz" << std::endl;
 | 
				
			||||||
 | 
					        std::cout << "actual_lms_freq " << actual_lms_freq/1e6 << " MHz" << std::endl;
 | 
				
			||||||
 | 
					        std::cout << "target_umsel_freq " << target_umsel_freq/1e6 << " MHz" << std::endl;
 | 
				
			||||||
 | 
					        std::cout << "actual_umsel_freq " << actual_umsel_freq/1e6 << " MHz" << std::endl;
 | 
				
			||||||
 | 
					        std::cout << "actual_total_freq " << (actual_umsel_freq + actual_lms_freq)/1e6 << " MHz" << std::endl;
 | 
				
			||||||
 | 
					        //*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return actual_umsel_freq + actual_lms_freq;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return _lms_ctrl[which]->set_rx_freq(freq);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uhd::freq_range_t umtrx_impl::get_rx_freq_range(const std::string &which) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (_umsel2)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        const double target_lms_freq = (which=="A")?UMSEL2_CH1_LMS_IF:UMSEL2_CH2_LMS_IF;
 | 
				
			||||||
 | 
					        const uhd::freq_range_t range_umsel = _umsel2->get_rx_freq_range((which=="A")?1:2);
 | 
				
			||||||
 | 
					        return uhd::freq_range_t(
 | 
				
			||||||
 | 
					            range_umsel.start()+target_lms_freq,
 | 
				
			||||||
 | 
					            range_umsel.stop()+target_lms_freq);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return _lms_ctrl[which]->get_rx_freq_range();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uhd::sensor_value_t umtrx_impl::read_temp_c(const std::string &which)
 | 
					uhd::sensor_value_t umtrx_impl::read_temp_c(const std::string &which)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    boost::recursive_mutex::scoped_lock l(_i2c_mutex);
 | 
					    boost::recursive_mutex::scoped_lock l(_i2c_mutex);
 | 
				
			||||||
@@ -1001,7 +1105,7 @@ void umtrx_impl::detect_hw_rev(const fs_path& mb_path)
 | 
				
			|||||||
        pa_low = pa_low_env;
 | 
					        pa_low = pa_low_env;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (pa_low.empty())
 | 
					    if (pa_low.empty())
 | 
				
			||||||
        _pa_nlow = false;
 | 
					        _pa_nlow = true; //Turn off Vin bypass by default
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
        _pa_nlow = (boost::lexical_cast<int>(pa_low) == 0);
 | 
					        _pa_nlow = (boost::lexical_cast<int>(pa_low) == 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1061,3 +1165,34 @@ const char* umtrx_impl::get_hw_rev() const
 | 
				
			|||||||
    default:               return "[unknown]";
 | 
					    default:               return "[unknown]";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void umtrx_impl::detect_hw_dcdc_ver(const uhd::fs_path &)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    _hw_dcdc_ver = DCDC_VER_2_3_1_OLD;
 | 
				
			||||||
 | 
					    if (_hw_rev < UMTRX_VER_2_3_1)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint8_t old = _pa_dcdc_r;
 | 
				
			||||||
 | 
					    bool old_pa_nlow = _pa_nlow;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    set_nlow(true);
 | 
				
			||||||
 | 
					    set_pa_dcdc_r(0);
 | 
				
			||||||
 | 
					    boost::this_thread::sleep(boost::posix_time::seconds(1));
 | 
				
			||||||
 | 
					    double v_actual = read_dc_v("DCOUT").to_real();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    double err_min = std::abs(v_actual - _dcdc_val_to_volt[0][0]);
 | 
				
			||||||
 | 
					    for (unsigned j = 1; j < DCDC_VER_COUNT; ++j) {
 | 
				
			||||||
 | 
					       double err = std::abs(v_actual - _dcdc_val_to_volt[j][0]);
 | 
				
			||||||
 | 
					       if (err < err_min) {
 | 
				
			||||||
 | 
					           err_min = err;
 | 
				
			||||||
 | 
					           _hw_dcdc_ver = j;
 | 
				
			||||||
 | 
					       }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    set_pa_dcdc_r(old);
 | 
				
			||||||
 | 
					    set_nlow(old_pa_nlow);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    UHD_MSG(status) << "Detected UmTRX DCDC ver. " << _hw_dcdc_ver
 | 
				
			||||||
 | 
					                    << " (err: " << err_min << ")" << std::endl;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,6 +31,7 @@
 | 
				
			|||||||
#include "ads1015_ctrl.hpp"
 | 
					#include "ads1015_ctrl.hpp"
 | 
				
			||||||
#include "tmp102_ctrl.hpp"
 | 
					#include "tmp102_ctrl.hpp"
 | 
				
			||||||
#include "power_amp.hpp"
 | 
					#include "power_amp.hpp"
 | 
				
			||||||
 | 
					#include "umsel2_ctrl.hpp"
 | 
				
			||||||
#include <uhd/usrp/mboard_eeprom.hpp>
 | 
					#include <uhd/usrp/mboard_eeprom.hpp>
 | 
				
			||||||
#include <uhd/property_tree.hpp>
 | 
					#include <uhd/property_tree.hpp>
 | 
				
			||||||
#include <uhd/device.hpp>
 | 
					#include <uhd/device.hpp>
 | 
				
			||||||
@@ -118,8 +119,17 @@ private:
 | 
				
			|||||||
        UMTRX_VER_2_3_1
 | 
					        UMTRX_VER_2_3_1
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    enum umtrx_dcdc_ver {
 | 
				
			||||||
 | 
					        DCDC_VER_2_3_1_OLD = 0,
 | 
				
			||||||
 | 
					        DCDC_VER_2_3_1_NEW = 1,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        DCDC_VER_COUNT //Should be the last
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // hardware revision
 | 
					    // hardware revision
 | 
				
			||||||
    umtrx_hw_rev _hw_rev;
 | 
					    umtrx_hw_rev _hw_rev;
 | 
				
			||||||
 | 
					    int _hw_dcdc_ver;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsigned _pll_div;
 | 
					    unsigned _pll_div;
 | 
				
			||||||
    const char* get_hw_rev() const;
 | 
					    const char* get_hw_rev() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -128,16 +138,16 @@ private:
 | 
				
			|||||||
    static const int UMTRX_VGA2_DEF;
 | 
					    static const int UMTRX_VGA2_DEF;
 | 
				
			||||||
    static const int UMTRX_VGA2_MIN;
 | 
					    static const int UMTRX_VGA2_MIN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Conversion table for converting DCDC_R values to actual voltages.
 | 
					    static const double _dcdc_val_to_volt[umtrx_impl::DCDC_VER_COUNT][256];
 | 
				
			||||||
    static const std::vector<double> _dcdc_val_to_volt;
 | 
					 | 
				
			||||||
    // Find a dcdc_r value to approximate requested Vout voltage
 | 
					 | 
				
			||||||
    static int volt_to_dcdc_r(double v);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ads1015_ctrl _sense_pwr;
 | 
					    ads1015_ctrl _sense_pwr;
 | 
				
			||||||
    ads1015_ctrl _sense_dc;
 | 
					    ads1015_ctrl _sense_dc;
 | 
				
			||||||
    tmp102_ctrl  _temp_side_a;
 | 
					    tmp102_ctrl  _temp_side_a;
 | 
				
			||||||
    tmp102_ctrl  _temp_side_b;
 | 
					    tmp102_ctrl  _temp_side_b;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Optimal device specific value
 | 
				
			||||||
 | 
					    int _umtrx_vga2_def;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //PA control
 | 
					    //PA control
 | 
				
			||||||
    bool _pa_nlow;
 | 
					    bool _pa_nlow;
 | 
				
			||||||
    bool _pa_en1;
 | 
					    bool _pa_en1;
 | 
				
			||||||
@@ -152,6 +162,7 @@ private:
 | 
				
			|||||||
    std::string _device_ip_addr;
 | 
					    std::string _device_ip_addr;
 | 
				
			||||||
    umtrx_iface::sptr _iface;
 | 
					    umtrx_iface::sptr _iface;
 | 
				
			||||||
    umtrx_fifo_ctrl::sptr _ctrl;
 | 
					    umtrx_fifo_ctrl::sptr _ctrl;
 | 
				
			||||||
 | 
					    umsel2_ctrl::sptr _umsel2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //controls for perifs
 | 
					    //controls for perifs
 | 
				
			||||||
    uhd::dict<std::string, lms6002d_ctrl::sptr> _lms_ctrl;
 | 
					    uhd::dict<std::string, lms6002d_ctrl::sptr> _lms_ctrl;
 | 
				
			||||||
@@ -181,6 +192,7 @@ private:
 | 
				
			|||||||
    void set_tx_fe_corrections(const std::string &mb, const std::string &board, const double);
 | 
					    void set_tx_fe_corrections(const std::string &mb, const std::string &board, const double);
 | 
				
			||||||
    void set_tcxo_dac(const umtrx_iface::sptr &, const uint16_t val);
 | 
					    void set_tcxo_dac(const umtrx_iface::sptr &, const uint16_t val);
 | 
				
			||||||
    void detect_hw_rev(const uhd::fs_path &mb_path);
 | 
					    void detect_hw_rev(const uhd::fs_path &mb_path);
 | 
				
			||||||
 | 
					    void detect_hw_dcdc_ver(const uhd::fs_path &mb_path);
 | 
				
			||||||
    void commit_pa_state();
 | 
					    void commit_pa_state();
 | 
				
			||||||
    void set_enpa1(bool en);
 | 
					    void set_enpa1(bool en);
 | 
				
			||||||
    void set_enpa2(bool en);
 | 
					    void set_enpa2(bool en);
 | 
				
			||||||
@@ -195,6 +207,11 @@ private:
 | 
				
			|||||||
    uhd::transport::zero_copy_if::sptr make_xport(const size_t which, const uhd::device_addr_t &args);
 | 
					    uhd::transport::zero_copy_if::sptr make_xport(const size_t which, const uhd::device_addr_t &args);
 | 
				
			||||||
    std::complex<double> get_dc_offset_correction(const std::string &which) const;
 | 
					    std::complex<double> get_dc_offset_correction(const std::string &which) const;
 | 
				
			||||||
    void set_dc_offset_correction(const std::string &which, const std::complex<double> &corr);
 | 
					    void set_dc_offset_correction(const std::string &which, const std::complex<double> &corr);
 | 
				
			||||||
 | 
					    double set_rx_freq(const std::string &which, const double freq);
 | 
				
			||||||
 | 
					    uhd::freq_range_t get_rx_freq_range(const std::string &which) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Find a dcdc_r value to approximate requested Vout voltage
 | 
				
			||||||
 | 
					    int volt_to_dcdc_r(double v);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static double dc_offset_int2double(uint8_t corr);
 | 
					    static double dc_offset_int2double(uint8_t corr);
 | 
				
			||||||
    static uint8_t dc_offset_double2int(double corr);
 | 
					    static uint8_t dc_offset_double2int(double corr);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -104,6 +104,9 @@ localparam SR_SPI_CORE = 185;   // 3
 | 
				
			|||||||
#define U2_REG_TIME64_HI_RB_PPS READBACK_BASE + 4*14
 | 
					#define U2_REG_TIME64_HI_RB_PPS READBACK_BASE + 4*14
 | 
				
			||||||
#define U2_REG_TIME64_LO_RB_PPS READBACK_BASE + 4*15
 | 
					#define U2_REG_TIME64_LO_RB_PPS READBACK_BASE + 4*15
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define AUX_LD1_IRQ_BIT (1 << 14)
 | 
				
			||||||
 | 
					#define AUX_LD2_IRQ_BIT (1 << 15)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/////////////////////////////////////////////////
 | 
					/////////////////////////////////////////////////
 | 
				
			||||||
// LMS regs
 | 
					// LMS regs
 | 
				
			||||||
////////////////////////////////////////////////
 | 
					////////////////////////////////////////////////
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,6 @@
 | 
				
			|||||||
# Build and Install the UmTRX utils
 | 
					# Build and Install the UmTRX utils
 | 
				
			||||||
########################################################################
 | 
					########################################################################
 | 
				
			||||||
INSTALL(PROGRAMS
 | 
					INSTALL(PROGRAMS
 | 
				
			||||||
    umtrx_net_burner
 | 
					 | 
				
			||||||
    umtrx_nmea
 | 
					    umtrx_nmea
 | 
				
			||||||
    umtrx_gps_coord
 | 
					    umtrx_gps_coord
 | 
				
			||||||
    umtrx_auto_calibration
 | 
					    umtrx_auto_calibration
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										6
									
								
								host/utils/collectd/umtrx.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								host/utils/collectd/umtrx.conf
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					TypesDB "/usr/share/collectd/umtrx.types.db"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LoadPlugin exec
 | 
				
			||||||
 | 
					<Plugin exec>
 | 
				
			||||||
 | 
					  Exec "fairwaves:fairwaves" "/usr/share/umtrx/umtrx2collectd.py"
 | 
				
			||||||
 | 
					</Plugin>
 | 
				
			||||||
							
								
								
									
										1
									
								
								host/utils/collectd/umtrx.types.db
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								host/utils/collectd/umtrx.types.db
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					sensor        value:GAUGE:U:U
 | 
				
			||||||
							
								
								
									
										54
									
								
								host/utils/collectd/umtrx2collectd.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										54
									
								
								host/utils/collectd/umtrx2collectd.py
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,54 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/python -u
 | 
				
			||||||
 | 
					# -*- coding: utf-8 -*-
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import os
 | 
				
			||||||
 | 
					import sched, time
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from umtrx_property_tree import umtrx_property_tree
 | 
				
			||||||
 | 
					from umtrx_vswr import umtrx_vswr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BOARD_ID = "0"
 | 
				
			||||||
 | 
					SENSORS_PATH = "/mboards/{id}/sensors".format(id=BOARD_ID)
 | 
				
			||||||
 | 
					VSWR_CALIBRATION = 0  # = TM10_VSWR_cal
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					HOSTNAME = os.environ['COLLECTD_HOSTNAME'] if 'COLLECTD_HOSTNAME' in os.environ  else 'localhost'
 | 
				
			||||||
 | 
					INTERVAL = os.environ['COLLECTD_INTERVAL'] if 'COLLECTD_INTERVAL' in os.environ  else '60'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					umtrx = umtrx_property_tree()
 | 
				
			||||||
 | 
					umtrx.connect()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# typically this yields: ['tempA', 'tempB', 'voltagePR1', 'voltagePF1', 'voltagePR2', 'voltagePF2', 'voltagezero', 'voltageVin', 'voltageVinPA', 'voltageDCOUT']
 | 
				
			||||||
 | 
					sensors_list = umtrx.list_path_raw(SENSORS_PATH).get("result", [])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def publish():
 | 
				
			||||||
 | 
					    now = time.time()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    current_sensors = {sensor: umtrx.query_sensor_value(SENSORS_PATH + "/" + sensor) for sensor in sensors_list}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for channel in ["1", "2"]:
 | 
				
			||||||
 | 
					        vpf_name = "voltagePF" + channel
 | 
				
			||||||
 | 
					        vpr_name = "voltagePR" + channel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if vpf_name in current_sensors and vpr_name in current_sensors:
 | 
				
			||||||
 | 
					            vswr = umtrx_vswr(float(current_sensors[vpf_name]), float(current_sensors[vpr_name]), VSWR_CALIBRATION)
 | 
				
			||||||
 | 
					            current_sensors["VSWR" + channel] = vswr.vswr()
 | 
				
			||||||
 | 
					            current_sensors["ReturnLoss" + channel] = vswr.return_loss()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for name, value in current_sensors.items():
 | 
				
			||||||
 | 
					        print "PUTVAL {host}/umtrx-{id}/sensor-{name} interval={interval} {now}:{value}".format(
 | 
				
			||||||
 | 
					            host=HOSTNAME, id=BOARD_ID, name=name, interval=INTERVAL, now=now, value=value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					s = sched.scheduler(time.time, time.sleep)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def timer_loop():
 | 
				
			||||||
 | 
					    s.enter(float(INTERVAL), 1, timer_loop, ())
 | 
				
			||||||
 | 
					    publish()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					timer_loop()
 | 
				
			||||||
 | 
					s.run()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					umtrx.close()
 | 
				
			||||||
		Reference in New Issue
	
	Block a user