コード例 #1
0
ファイル: db_tvrx.cpp プロジェクト: Gabotero/UHD
/***********************************************************************
 * Structors
 **********************************************************************/
tvrx::tvrx(ctor_args_t args) : rx_dboard_base(args){
    ////////////////////////////////////////////////////////////////////
    // Register properties
    ////////////////////////////////////////////////////////////////////
    this->get_rx_subtree()->create<std::string>("name")
        .set("TVRX");
    this->get_rx_subtree()->create<int>("sensors"); //phony property so this dir exists
    BOOST_FOREACH(const std::string &name, get_tvrx_gain_ranges().keys()){
        this->get_rx_subtree()->create<double>("gains/"+name+"/value")
            .coerce(boost::bind(&tvrx::set_gain, this, _1, name));
        this->get_rx_subtree()->create<meta_range_t>("gains/"+name+"/range")
            .set(get_tvrx_gain_ranges()[name]);
    }
    this->get_rx_subtree()->create<double>("freq/value")
        .coerce(boost::bind(&tvrx::set_freq, this, _1));
    this->get_rx_subtree()->create<meta_range_t>("freq/range")
        .set(tvrx_freq_range);
    this->get_rx_subtree()->create<std::string>("antenna/value")
        .set(tvrx_antennas.at(0));
    this->get_rx_subtree()->create<std::vector<std::string> >("antenna/options")
        .set(tvrx_antennas);
    this->get_rx_subtree()->create<std::string>("connection")
        .set("I");
    this->get_rx_subtree()->create<bool>("enabled")
        .set(true); //always enabled
    this->get_rx_subtree()->create<bool>("use_lo_offset")
        .set(false);
    this->get_rx_subtree()->create<double>("bandwidth/value")
        .set(6.0e6);
    this->get_rx_subtree()->create<meta_range_t>("bandwidth/range")
        .set(freq_range_t(6.0e6, 6.0e6));

    //enable only the clocks we need
    this->get_iface()->set_clock_enabled(dboard_iface::UNIT_RX, true);

    //set the gpio directions and atr controls (identically)
    this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, 0x0); // All unused in atr
    if (this->get_iface()->get_special_props().soft_clock_divider){
        this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, 0x1); // GPIO0 is clock
    }
    else{
        this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, 0x0); // All Inputs
    }

    //send initial register settings if necessary

    //set default freq
    _lo_freq = tvrx_freq_range.start() + tvrx_if_freq; //init _lo_freq to a sane default
    this->get_rx_subtree()->access<double>("freq/value").set(tvrx_freq_range.start());

    //set default gains
    BOOST_FOREACH(const std::string &name, get_tvrx_gain_ranges().keys()){
        this->get_rx_subtree()->access<double>("gains/"+name+"/value")
            .set(get_tvrx_gain_ranges()[name].start());
    }
}
コード例 #2
0
/***********************************************************************
 * WBX Common Implementation
 **********************************************************************/
wbx_base::wbx_version4::wbx_version4(wbx_base *_self_wbx_base) {
    //register our handle on the primary wbx_base instance
    self_base = _self_wbx_base;

    ////////////////////////////////////////////////////////////////////
    // Register RX properties
    ////////////////////////////////////////////////////////////////////
    this->get_rx_subtree()->create<std::string>("name").set("WBXv4 RX");
    this->get_rx_subtree()->create<double>("freq/value")
         .coerce(boost::bind(&wbx_base::wbx_version4::set_lo_freq, this, dboard_iface::UNIT_RX, _1))
         .set((wbx_v4_freq_range.start() + wbx_v4_freq_range.stop())/2.0);
    this->get_rx_subtree()->create<meta_range_t>("freq/range").set(wbx_v4_freq_range);

    ////////////////////////////////////////////////////////////////////
    // Register TX properties
    ////////////////////////////////////////////////////////////////////
    this->get_tx_subtree()->create<std::string>("name").set("WBXv4 TX");
    BOOST_FOREACH(const std::string &name, wbx_v4_tx_gain_ranges.keys()){
        self_base->get_tx_subtree()->create<double>("gains/"+name+"/value")
            .coerce(boost::bind(&wbx_base::wbx_version4::set_tx_gain, this, _1, name))
            .set(wbx_v4_tx_gain_ranges[name].start());
        self_base->get_tx_subtree()->create<meta_range_t>("gains/"+name+"/range")
            .set(wbx_v4_tx_gain_ranges[name]);
    }
    this->get_tx_subtree()->create<double>("freq/value")
         .coerce(boost::bind(&wbx_base::wbx_version4::set_lo_freq, this, dboard_iface::UNIT_TX, _1))
         .set((wbx_v4_freq_range.start() + wbx_v4_freq_range.stop())/2.0);
    this->get_tx_subtree()->create<meta_range_t>("freq/range").set(wbx_v4_freq_range);
    this->get_tx_subtree()->create<bool>("enabled")
        .subscribe(boost::bind(&wbx_base::wbx_version4::set_tx_enabled, this, _1))
        .set(true); //start enabled

    //set attenuator control bits
    int v4_iobits = TX_ATTN_MASK;
    int v4_tx_mod = ADF4351_PDBRF;

    //set the gpio directions and atr controls
    self_base->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, v4_tx_mod|v4_iobits);
    self_base->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, RXBB_PDB|ADF4351_PDBRF);
    self_base->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, TX_PUP_5V|TX_PUP_3V|v4_tx_mod|v4_iobits);
    self_base->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, RX_PUP_5V|RX_PUP_3V|ADF4351_CE|RXBB_PDB|ADF4351_PDBRF|RX_ATTN_MASK);

    //setup ATR for the mixer enables (always enabled to prevent phase slip between bursts)
    //set TX gain iobits to min gain (max attenuation) when RX_ONLY or IDLE to suppress LO leakage
    self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_IDLE,        v4_tx_mod, TX_ATTN_MASK | TX_MIXER_DIS | v4_tx_mod);
    self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_RX_ONLY,     v4_tx_mod, TX_ATTN_MASK | TX_MIXER_DIS | v4_tx_mod);
    self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_TX_ONLY,     v4_tx_mod, TX_ATTN_MASK | TX_MIXER_DIS | v4_tx_mod);
    self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_FULL_DUPLEX, v4_tx_mod, TX_ATTN_MASK | TX_MIXER_DIS | v4_tx_mod);

    self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE,        RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
    self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY,     RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
    self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY,     RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
    self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
}
コード例 #3
0
ファイル: db_wbx.cpp プロジェクト: vlqk/uhd-8bit
/***********************************************************************
 * Structors
 **********************************************************************/
wbx_xcvr::wbx_xcvr(ctor_args_t args) : xcvr_dboard_base(args){

    //enable the clocks that we need
    this->get_iface()->set_clock_enabled(dboard_iface::UNIT_TX, true);
    this->get_iface()->set_clock_enabled(dboard_iface::UNIT_RX, true);

    //set the gpio directions and atr controls (identically)
    this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, TXIO_MASK);
    this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, RXIO_MASK);
    this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, TXIO_MASK);
    this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, RXIO_MASK);
    if (wbx_debug) std::cerr << boost::format(
        "WBX GPIO Direction: RX: 0x%08x, TX: 0x%08x"
    ) % RXIO_MASK % TXIO_MASK << std::endl;

    //set some default values
    set_rx_lo_freq((wbx_freq_range.start() + wbx_freq_range.stop())/2.0);
    set_tx_lo_freq((wbx_freq_range.start() + wbx_freq_range.stop())/2.0);
    set_rx_ant("RX2");

    BOOST_FOREACH(const std::string &name, wbx_tx_gain_ranges.keys()){
        set_tx_gain(wbx_tx_gain_ranges[name].start(), name);
    }
    BOOST_FOREACH(const std::string &name, wbx_rx_gain_ranges.keys()){
        set_rx_gain(wbx_rx_gain_ranges[name].start(), name);
    }
}
コード例 #4
0
ファイル: db_sbx.cpp プロジェクト: GREO/uhd
/***********************************************************************
 * Structors
 **********************************************************************/
sbx_xcvr::sbx_xcvr(ctor_args_t args) : xcvr_dboard_base(args){

    //enable the clocks that we need
    this->get_iface()->set_clock_enabled(dboard_iface::UNIT_TX, true);
    this->get_iface()->set_clock_enabled(dboard_iface::UNIT_RX, true);

    //set the gpio directions and atr controls (identically)
    this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, (TXIO_MASK|TX_LED_IO));
    this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, (RXIO_MASK|RX_LED_IO));
    this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, (TXIO_MASK|TX_LED_IO));
    this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, (RXIO_MASK|RX_LED_IO));

    //flash LEDs
    flash_leds();

    UHD_LOGV(often) << boost::format(
        "SBX GPIO Direction: RX: 0x%08x, TX: 0x%08x"
    ) % RXIO_MASK % TXIO_MASK << std::endl;

    //set some default values
    set_rx_lo_freq((sbx_freq_range.start() + sbx_freq_range.stop())/2.0);
    set_tx_lo_freq((sbx_freq_range.start() + sbx_freq_range.stop())/2.0);
    set_rx_ant("RX2");

    BOOST_FOREACH(const std::string &name, sbx_tx_gain_ranges.keys()){
        set_tx_gain(sbx_tx_gain_ranges[name].start(), name);
    }
    BOOST_FOREACH(const std::string &name, sbx_rx_gain_ranges.keys()){
        set_rx_gain(sbx_rx_gain_ranges[name].start(), name);
    }
}
コード例 #5
0
ファイル: db_dbsrx.cpp プロジェクト: sunila/airblue_7dec12
/***********************************************************************
 * Structors
 **********************************************************************/
dbsrx::dbsrx(ctor_args_t args) : rx_dboard_base(args){
    //warn user about incorrect DBID on USRP1, requires R193 populated
    if (this->get_iface()->get_special_props().soft_clock_divider and this->get_rx_id() == 0x000D)
        uhd::warning::post(
            str(boost::format(
                "DBSRX: incorrect dbid\n"
                "Expected dbid 0x0002 and R193\n"
                "found dbid == %d\n"
                "Please see the daughterboard app notes" 
                ) % this->get_rx_id().to_pp_string())
        );

    //warn user about incorrect DBID on non-USRP1, requires R194 populated
    if (not this->get_iface()->get_special_props().soft_clock_divider and this->get_rx_id() == 0x0002)
        uhd::warning::post(
            str(boost::format(
                "DBSRX: incorrect dbid\n"
                "Expected dbid 0x000D and R194\n"
                "found dbid == %d\n"
                "Please see the daughterboard app notes" 
                ) % this->get_rx_id().to_pp_string())
        );

    //enable only the clocks we need
    this->get_iface()->set_clock_enabled(dboard_iface::UNIT_RX, true);

    //set the gpio directions and atr controls (identically)
    this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, 0x0); // All unused in atr
    if (this->get_iface()->get_special_props().soft_clock_divider){
        this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, 0x1); // GPIO0 is clock
    }
    else{
        this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, 0x0); // All Inputs
    }

    //send initial register settings
    this->send_reg(0x0, 0x5);

    //set defaults for LO, gains, and filter bandwidth
    _bandwidth = 33e6;
    set_lo_freq(dbsrx_freq_range.start());

    BOOST_FOREACH(const std::string &name, dbsrx_gain_ranges.keys()){
        set_gain(dbsrx_gain_ranges[name].start(), name);
    }

    set_bandwidth(33e6); // default bandwidth from datasheet
}
コード例 #6
0
ファイル: db_wbx_simple.cpp プロジェクト: GREO/uhd
/***********************************************************************
 * Structors
 **********************************************************************/
wbx_simple::wbx_simple(ctor_args_t args) : wbx_base(args){

    //set the gpio directions and atr controls (antenna switches all under ATR)
    this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, ANTSW_IO, ANTSW_IO);
    this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, ANTSW_IO, ANTSW_IO);
    this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, ANTSW_IO, ANTSW_IO);
    this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, ANTSW_IO, ANTSW_IO);

    //setup ATR for the antenna switches (constant)
    this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_IDLE,        ANT_RX, ANTSW_IO);
    this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_RX_ONLY,     ANT_RX, ANTSW_IO);
    this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_TX_ONLY,     ANT_TX, ANTSW_IO);
    this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_FULL_DUPLEX, ANT_TX, ANTSW_IO);

    this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE,        ANT_TXRX, ANTSW_IO);
    this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY,     ANT_RX2, ANTSW_IO);
    this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, ANT_RX2, ANTSW_IO);

    //set some default values
    set_rx_lo_freq((wbx_freq_range.start() + wbx_freq_range.stop())/2.0);
    set_tx_lo_freq((wbx_freq_range.start() + wbx_freq_range.stop())/2.0);
    set_rx_ant("RX2");
}
コード例 #7
0
ファイル: db_dbsrx.cpp プロジェクト: sunila/airblue_7dec12
/***********************************************************************
 * Tuning
 **********************************************************************/
void dbsrx::set_lo_freq(double target_freq){
    target_freq = dbsrx_freq_range.clip(target_freq);

    double actual_freq=0.0, pfd_freq=0.0, ref_clock=0.0;
    int R=0, N=0, r=0, m=0;
    bool update_filter_settings = false;
    //choose refclock
    std::vector<double> clock_rates = this->get_iface()->get_clock_rates(dboard_iface::UNIT_RX);
    const double max_clock_rate = std::sorted(clock_rates).back();
    BOOST_FOREACH(ref_clock, std::reversed(std::sorted(clock_rates))){
        if (ref_clock > 27.0e6) continue;
        if (size_t(max_clock_rate/ref_clock)%2 == 1) continue; //reject asymmetric clocks (odd divisors)

        //choose m_divider such that filter tuning constraint is met
        m = 31;
        while ((ref_clock/m < 1e6 or ref_clock/m > 2.5e6) and m > 0){ m--; }

        if(dbsrx_debug) std::cerr << boost::format(
            "DBSRX: trying ref_clock %f and m_divider %d"
        ) % (ref_clock) % m << std::endl;

        if (m >= 32) continue;

        //choose R
        for(r = 0; r <= 6; r += 1) {
            //compute divider from setting
            R = 1 << (r+1);
            if (dbsrx_debug) std::cerr << boost::format("DBSRX R:%d\n") % R << std::endl;

            //compute PFD compare frequency = ref_clock/R
            pfd_freq = ref_clock / R;

            //constrain the PFD frequency to specified range
            if ((pfd_freq < dbsrx_pfd_freq_range.start()) or (pfd_freq > dbsrx_pfd_freq_range.stop())) continue;

            //compute N
            N = int(std::floor(target_freq/pfd_freq));

            //constrain N to specified range
            if ((N < 256) or (N > 32768)) continue;

            goto done_loop;
        }
    } 

    done_loop:

    //Assert because we failed to find a suitable combination of ref_clock, R and N 
    UHD_ASSERT_THROW(ref_clock <= 27.0e6 and ref_clock >= 0.0);
    UHD_ASSERT_THROW(ref_clock/m >= 1e6 and ref_clock/m <= 2.5e6);
    UHD_ASSERT_THROW((pfd_freq >= dbsrx_pfd_freq_range.start()) and (pfd_freq <= dbsrx_pfd_freq_range.stop()));
    UHD_ASSERT_THROW((N >= 256) and (N <= 32768));

    if(dbsrx_debug) std::cerr << boost::format(
        "DBSRX: choose ref_clock (current: %f, new: %f) and m_divider %d"
    ) % (this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX)) % ref_clock % m << std::endl;

    //if ref_clock or m divider changed, we need to update the filter settings
    if (ref_clock != this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX) or m != _max2118_write_regs.m_divider) update_filter_settings = true;

    //compute resulting output frequency
    actual_freq = pfd_freq * N;

    //apply ref_clock, R, and N settings
    this->get_iface()->set_clock_rate(dboard_iface::UNIT_RX, ref_clock);
    ref_clock = this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX);
    _max2118_write_regs.m_divider = m;
    _max2118_write_regs.r_divider = (max2118_write_regs_t::r_divider_t) r;
    _max2118_write_regs.set_n_divider(N);
    _max2118_write_regs.ade_vco_ade_read = max2118_write_regs_t::ADE_VCO_ADE_READ_ENABLED;
    
    //compute prescaler variables
    int scaler = actual_freq > 1125e6 ? 2 : 4;
    _max2118_write_regs.div2 = scaler == 4 ? max2118_write_regs_t::DIV2_DIV4 : max2118_write_regs_t::DIV2_DIV2;

    if(dbsrx_debug) std::cerr << boost::format(
        "DBSRX: scaler %d, actual_freq %f MHz, register bit: %d"
    ) % scaler % (actual_freq/1e6) % int(_max2118_write_regs.div2) << std::endl;

    //compute vco frequency and select vco
    double vco_freq = actual_freq * scaler;
    if (vco_freq < 2433e6)
        _max2118_write_regs.osc_band = 0;
    else if (vco_freq < 2711e6)
        _max2118_write_regs.osc_band = 1;
    else if (vco_freq < 3025e6)
        _max2118_write_regs.osc_band = 2;
    else if (vco_freq < 3341e6)
        _max2118_write_regs.osc_band = 3;
    else if (vco_freq < 3727e6)
        _max2118_write_regs.osc_band = 4;
    else if (vco_freq < 4143e6)
        _max2118_write_regs.osc_band = 5;
    else if (vco_freq < 4493e6)
        _max2118_write_regs.osc_band = 6;
    else
        _max2118_write_regs.osc_band = 7;

    //send settings over i2c
    send_reg(0x0, 0x4);

    //check vtune for lock condition
    read_reg(0x0, 0x0);

    if(dbsrx_debug) std::cerr << boost::format(
        "DBSRX: initial guess for vco %d, vtune adc %d"
    ) % int(_max2118_write_regs.osc_band) % int(_max2118_read_regs.adc) << std::endl;

    //if we are out of lock for chosen vco, change vco
    while ((_max2118_read_regs.adc == 0) or (_max2118_read_regs.adc == 7)){

        //vtune is too low, try lower frequency vco
        if (_max2118_read_regs.adc == 0){
            if (_max2118_write_regs.osc_band == 0){
                uhd::warning::post(
                    str(boost::format(
                        "DBSRX: Tuning exceeded vco range, _max2118_write_regs.osc_band == %d\n" 
                        ) % int(_max2118_write_regs.osc_band))
                );
                UHD_ASSERT_THROW(_max2118_read_regs.adc != 0); //just to cause a throw
            }
            if (_max2118_write_regs.osc_band <= 0) break;
            _max2118_write_regs.osc_band -= 1;
        }

        //vtune is too high, try higher frequency vco
        if (_max2118_read_regs.adc == 7){
            if (_max2118_write_regs.osc_band == 7){
                uhd::warning::post(
                    str(boost::format(
                        "DBSRX: Tuning exceeded vco range, _max2118_write_regs.osc_band == %d\n" 
                        ) % int(_max2118_write_regs.osc_band))
                );
                UHD_ASSERT_THROW(_max2118_read_regs.adc != 7); //just to cause a throw
            }
            if (_max2118_write_regs.osc_band >= 7) break;
            _max2118_write_regs.osc_band += 1;
        }

        if(dbsrx_debug) std::cerr << boost::format(
            "DBSRX: trying vco %d, vtune adc %d"
        ) % int(_max2118_write_regs.osc_band) % int(_max2118_read_regs.adc) << std::endl;

        //update vco selection and check vtune
        send_reg(0x2, 0x2);
        read_reg(0x0, 0x0);

        //allow for setup time before checking condition again
        boost::this_thread::sleep(boost::posix_time::milliseconds(10));
    }
      
    if(dbsrx_debug) std::cerr << boost::format(
        "DBSRX: final vco %d, vtune adc %d"
    ) % int(_max2118_write_regs.osc_band) % int(_max2118_read_regs.adc) << std::endl;

    //select charge pump bias current
    if (_max2118_read_regs.adc <= 2) _max2118_write_regs.cp_current = max2118_write_regs_t::CP_CURRENT_I_CP_100UA;
    else if (_max2118_read_regs.adc >= 5) _max2118_write_regs.cp_current = max2118_write_regs_t::CP_CURRENT_I_CP_400UA;
    else _max2118_write_regs.cp_current = max2118_write_regs_t::CP_CURRENT_I_CP_200UA;
    
    //update charge pump bias current setting
    send_reg(0x2, 0x2);

    //compute actual tuned frequency
    _lo_freq = this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX) / std::pow(2.0,(1 + _max2118_write_regs.r_divider)) * _max2118_write_regs.get_n_divider();

    //debug output of calculated variables
    if (dbsrx_debug) std::cerr
        << boost::format("DBSRX tune:\n")
        << boost::format("    VCO=%d, CP=%d, PFD Freq=%fMHz\n") % int(_max2118_write_regs.osc_band) % _max2118_write_regs.cp_current % (pfd_freq/1e6)
        << boost::format("    R=%d, N=%f, scaler=%d, div2=%d\n") % R % N % scaler % int(_max2118_write_regs.div2)
        << boost::format("    Ref    Freq=%fMHz\n") % (ref_clock/1e6)
        << boost::format("    Target Freq=%fMHz\n") % (target_freq/1e6)
        << boost::format("    Actual Freq=%fMHz\n") % (_lo_freq/1e6)
        << boost::format("    VCO    Freq=%fMHz\n") % (vco_freq/1e6)
        << std::endl;

    if (update_filter_settings) set_bandwidth(_bandwidth);
    get_locked();
}
コード例 #8
0
ファイル: db_dbsrx.cpp プロジェクト: 211217613/uhd
/***********************************************************************
 * Structors
 **********************************************************************/
dbsrx::dbsrx(ctor_args_t args) : rx_dboard_base(args){
    //warn user about incorrect DBID on USRP1, requires R193 populated
    if (this->get_iface()->get_special_props().soft_clock_divider and this->get_rx_id() == 0x000D)
        UHD_MSG(warning) << boost::format(
                "DBSRX: incorrect dbid\n"
                "Expected dbid 0x0002 and R193\n"
                "found dbid == %d\n"
                "Please see the daughterboard app notes"
                ) % this->get_rx_id().to_pp_string();

    //warn user about incorrect DBID on non-USRP1, requires R194 populated
    if (not this->get_iface()->get_special_props().soft_clock_divider and this->get_rx_id() == 0x0002)
        UHD_MSG(warning) << boost::format(
                "DBSRX: incorrect dbid\n"
                "Expected dbid 0x000D and R194\n"
                "found dbid == %d\n"
                "Please see the daughterboard app notes"
                ) % this->get_rx_id().to_pp_string();

    //send initial register settings
    this->send_reg(0x0, 0x5);

    //set defaults for LO, gains, and filter bandwidth
    double codec_rate = this->get_iface()->get_codec_rate(dboard_iface::UNIT_RX);
    _bandwidth = 0.8*codec_rate/2.0; // default to anti-alias at different codec_rate

    ////////////////////////////////////////////////////////////////////
    // Register properties
    ////////////////////////////////////////////////////////////////////
    this->get_rx_subtree()->create<std::string>("name")
        .set("DBSRX");
    this->get_rx_subtree()->create<sensor_value_t>("sensors/lo_locked")
        .set_publisher(boost::bind(&dbsrx::get_locked, this));
    BOOST_FOREACH(const std::string &name, dbsrx_gain_ranges.keys()){
        this->get_rx_subtree()->create<double>("gains/"+name+"/value")
            .set_coercer(boost::bind(&dbsrx::set_gain, this, _1, name))
            .set(dbsrx_gain_ranges[name].start());
        this->get_rx_subtree()->create<meta_range_t>("gains/"+name+"/range")
            .set(dbsrx_gain_ranges[name]);
    }
    this->get_rx_subtree()->create<double>("freq/value")
        .set_coercer(boost::bind(&dbsrx::set_lo_freq, this, _1));
    this->get_rx_subtree()->create<meta_range_t>("freq/range")
        .set(dbsrx_freq_range);
    this->get_rx_subtree()->create<std::string>("antenna/value")
        .set(dbsrx_antennas.at(0));
    this->get_rx_subtree()->create<std::vector<std::string> >("antenna/options")
        .set(dbsrx_antennas);
    this->get_rx_subtree()->create<std::string>("connection")
        .set("IQ");
    this->get_rx_subtree()->create<bool>("enabled")
        .set(true); //always enabled
    this->get_rx_subtree()->create<bool>("use_lo_offset")
        .set(false);
    this->get_rx_subtree()->create<double>("bandwidth/value")
        .set_coercer(boost::bind(&dbsrx::set_bandwidth, this, _1));
    this->get_rx_subtree()->create<meta_range_t>("bandwidth/range")
        .set(dbsrx_bandwidth_range);

    //enable only the clocks we need
    this->get_iface()->set_clock_enabled(dboard_iface::UNIT_RX, true);

    //set the gpio directions and atr controls (identically)
    this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, 0x0); // All unused in atr
    if (this->get_iface()->get_special_props().soft_clock_divider){
        this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, 0x1); // GPIO0 is clock when on USRP1
    }
    else{
        this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, 0x0); // All Inputs
    }

    //now its safe to set inital freq and bw
    this->get_rx_subtree()->access<double>("freq/value")
        .set(dbsrx_freq_range.start());
    this->get_rx_subtree()->access<double>("bandwidth/value")
        .set(2.0*_bandwidth); //_bandwidth in lowpass, convert to complex bandpass
}