diff options
author | eb | 2009-05-06 00:35:04 +0000 |
---|---|---|
committer | eb | 2009-05-06 00:35:04 +0000 |
commit | 6558bc316b831f3ef4b4a48461b8e070daa00d9d (patch) | |
tree | 265162cb1e2ca3bfcf8695fb0e2e43fbe6362177 /usrp/host | |
parent | 7fd0afc85027948ae5303763ba4ad7e61a370b54 (diff) | |
download | gnuradio-6558bc316b831f3ef4b4a48461b8e070daa00d9d.tar.gz gnuradio-6558bc316b831f3ef4b4a48461b8e070daa00d9d.tar.bz2 gnuradio-6558bc316b831f3ef4b4a48461b8e070daa00d9d.zip |
Fix for ticket:371.
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@10972 221aa14e-8319-0410-a670-987f0aec2ac5
Diffstat (limited to 'usrp/host')
-rw-r--r-- | usrp/host/lib/legacy/db_xcvr2450.cc | 230 | ||||
-rw-r--r-- | usrp/host/lib/legacy/db_xcvr2450.h | 114 |
2 files changed, 204 insertions, 140 deletions
diff --git a/usrp/host/lib/legacy/db_xcvr2450.cc b/usrp/host/lib/legacy/db_xcvr2450.cc index 6f05bba2d..b363d0987 100644 --- a/usrp/host/lib/legacy/db_xcvr2450.cc +++ b/usrp/host/lib/legacy/db_xcvr2450.cc @@ -1,5 +1,5 @@ // -// Copyright 2008 Free Software Foundation, Inc. +// Copyright 2008,2009 Free Software Foundation, Inc. // // This file is part of GNU Radio // @@ -21,6 +21,8 @@ #include <db_xcvr2450.h> #include <db_base_impl.h> #include <cmath> +#include <boost/thread.hpp> +#include <boost/weak_ptr.hpp> #if 0 #define LO_OFFSET 4.25e6 @@ -43,11 +45,122 @@ */ + +// TX IO Pins +#define HB_PA_OFF (1 << 15) // 5GHz PA, 1 = off, 0 = on +#define LB_PA_OFF (1 << 14) // 2.4GHz PA, 1 = off, 0 = on +#define ANTSEL_TX1_RX2 (1 << 13) // 1 = Ant 1 to TX, Ant 2 to RX +#define ANTSEL_TX2_RX1 (1 << 12) // 1 = Ant 2 to TX, Ant 1 to RX +#define TX_EN (1 << 11) // 1 = TX on, 0 = TX off +#define AD9515DIV (1 << 4) // 1 = Div by 3, 0 = Div by 2 + +#define TX_OE_MASK HB_PA_OFF|LB_PA_OFF|ANTSEL_TX1_RX2|ANTSEL_TX2_RX1|TX_EN|AD9515DIV +#define TX_SAFE_IO HB_PA_OFF|LB_PA_OFF|ANTSEL_TX1_RX2|AD9515DIV + +// RX IO Pins +#define LOCKDET (1 << 15) // This is an INPUT!!! +#define EN (1 << 14) +#define RX_EN (1 << 13) // 1 = RX on, 0 = RX off +#define RX_HP (1 << 12) +#define RX_OE_MASK EN|RX_EN|RX_HP +#define RX_SAFE_IO EN + +struct xcvr2450_key { + std::string serial_no; + int which; + + bool operator==(const xcvr2450_key &x){ + return x.serial_no ==serial_no && x.which == which; + } +}; + +class xcvr2450 +{ +private: + usrp_basic *d_raw_usrp; + int d_which; + + bool d_is_shutdown; + int d_spi_format, d_spi_enable; + + int d_mimo, d_int_div, d_frac_div, d_highband, d_five_gig; + int d_cp_current, d_ref_div, d_rssi_hbw; + int d_txlpf_bw, d_rxlpf_bw, d_rxlpf_fine, d_rxvga_ser; + int d_rssi_range, d_rssi_mode, d_rssi_mux; + int d_rx_hp_pin, d_rx_hpf, d_rx_ant; + int d_tx_ant, d_txvga_ser, d_tx_driver_lin; + int d_tx_vga_lin, d_tx_upconv_lin, d_tx_bb_gain; + int d_pabias_delay, d_pabias, rx_rf_gain, rx_bb_gain, d_txgain; + int d_rx_rf_gain, d_rx_bb_gain; + + int d_reg_standby, d_reg_int_divider, d_reg_frac_divider, d_reg_bandselpll; + int d_reg_cal, dsend_reg, d_reg_lpf, d_reg_rxrssi_ctrl, d_reg_txlin_gain; + int d_reg_pabias, d_reg_rxgain, d_reg_txgain; + + int d_ad9515_div; + + void _set_rfagc(float gain); + void _set_ifagc(float gain); + void _set_pga(float pga_gain); + +public: + usrp_basic *usrp(){ + return d_raw_usrp; + } + + xcvr2450(usrp_basic_sptr usrp, int which); + ~xcvr2450(); + void shutdown(); + + void set_reg_standby(); + + // Integer-Divider Ratio (3) + void set_reg_int_divider(); + + // Fractional-Divider Ratio (4) + void set_reg_frac_divider(); + + // Band Select and PLL (5) + void set_reg_bandselpll(); + + // Calibration (6) + void set_reg_cal(); + + // Lowpass Filter (7) + void set_reg_lpf(); + + // Rx Control/RSSI (8) + void set_reg_rxrssi_ctrl(); + + // Tx Linearity/Baseband Gain (9) + void set_reg_txlin_gain(); + + // PA Bias DAC (10) + void set_reg_pabias(); + + // Rx Gain (11) + void set_reg_rxgain(); + + // Tx Gain (12) + void set_reg_txgain(); + + // Send register write to SPI + void send_reg(int v); + + void set_gpio(); + bool lock_detect(); + bool set_rx_gain(float gain); + bool set_tx_gain(float gain); + + struct freq_result_t set_freq(double target_freq); +}; + + /*****************************************************************************/ xcvr2450::xcvr2450(usrp_basic_sptr _usrp, int which) - : d_weak_usrp(_usrp), d_which(which) + : d_raw_usrp(_usrp.get()), d_which(which), d_is_shutdown(false) { // Handler for Tv Rx daughterboards. // @@ -126,23 +239,22 @@ xcvr2450::xcvr2450(usrp_basic_sptr _usrp, int which) xcvr2450::~xcvr2450() { //printf("xcvr2450::destructor\n"); - usrp()->common_write_atr_txval(C_TX, d_which, TX_SAFE_IO); - usrp()->common_write_atr_rxval(C_TX, d_which, TX_SAFE_IO); - usrp()->common_write_atr_txval(C_RX, d_which, RX_SAFE_IO); - usrp()->common_write_atr_rxval(C_RX, d_which, RX_SAFE_IO); + shutdown(); } -bool -xcvr2450::operator==(xcvr2450_key x) -{ - if((x.serial_no == usrp()->serial_number()) && (x.which == d_which)) { - return true; - } - else { - return false; +void +xcvr2450::shutdown() +{ + if (!d_is_shutdown){ + d_is_shutdown = true; + usrp()->common_write_atr_txval(C_TX, d_which, TX_SAFE_IO); + usrp()->common_write_atr_rxval(C_TX, d_which, TX_SAFE_IO); + usrp()->common_write_atr_txval(C_RX, d_which, RX_SAFE_IO); + usrp()->common_write_atr_rxval(C_RX, d_which, RX_SAFE_IO); } } + void xcvr2450::set_reg_standby() { @@ -361,7 +473,7 @@ xcvr2450::set_freq(double target_freq) double div = vco_freq/phdet_freq; d_int_div = int(floor(div)); d_frac_div = int((div-d_int_div)*65536.0); - double actual_freq = phdet_freq*(d_int_div+(d_frac_div/65536.0))/scaler; + // double actual_freq = phdet_freq*(d_int_div+(d_frac_div/65536.0))/scaler; //printf("RF=%f VCO=%f R=%d PHD=%f DIV=%3.5f I=%3d F=%5d ACT=%f\n", // target_freq, vco_freq, d_ref_div, phdet_freq, @@ -453,32 +565,46 @@ xcvr2450::set_tx_gain(float gain) /*****************************************************************************/ -//_xcvr2450_inst = weakref.WeakValueDictionary() -std::vector<xcvr2450_sptr> _xcvr2450_inst; +struct xcvr2450_table_entry { + xcvr2450_key key; + boost::weak_ptr<xcvr2450> value; + + xcvr2450_table_entry(const xcvr2450_key &_key, boost::weak_ptr<xcvr2450> _value) + : key(_key), value(_value) {} +}; + +typedef std::vector<xcvr2450_table_entry> xcvr2450_table; -xcvr2450_sptr +static boost::mutex s_table_mutex; +static xcvr2450_table s_table; + +static xcvr2450_sptr _get_or_make_xcvr2450(usrp_basic_sptr usrp, int which) { - xcvr2450_sptr inst; xcvr2450_key key = {usrp->serial_number(), which}; - std::vector<xcvr2450_sptr>::iterator itr; // = - //std::find(_xcvr2450_inst.begin(), _xcvr2450_inst.end(), key); - - for(itr = _xcvr2450_inst.begin(); itr != _xcvr2450_inst.end(); itr++) { - if(*(*itr) == key) { - //printf("Using existing xcvr2450 instance\n"); - inst = *itr; - break; + + boost::mutex::scoped_lock guard(s_table_mutex); + + for (xcvr2450_table::iterator p = s_table.begin(); p != s_table.end();){ + if (p->value.expired()) // weak pointer is now dead + p = s_table.erase(p); // erase it + else { + if (key == p->key){ // found it + return xcvr2450_sptr(p->value); + } + else + ++p; // keep looking } } - - if(itr == _xcvr2450_inst.end()) { - //printf("Creating new xcvr2450 instance\n"); - inst = xcvr2450_sptr(new xcvr2450(usrp, which)); - _xcvr2450_inst.push_back(inst); - } - return inst; + // We don't have the xcvr2450 we're looking for + + // create a new one and stick it in the table. + xcvr2450_sptr r(new xcvr2450(usrp, which)); + xcvr2450_table_entry t(key, r); + s_table.push_back(t); + + return r; } @@ -505,6 +631,22 @@ db_xcvr2450_base::~db_xcvr2450_base() { } +void +db_xcvr2450_base::shutdown_common() +{ + // If the usrp_basic in the xcvr2450 is the same as the usrp_basic + // in the daughterboard, shutdown the xcvr now (when only one of Tx + // and Rx is open, this is always true). + + if (d_xcvr->usrp() == usrp()){ + //std::cerr << "db_xcvr2450_base::shutdown_common: same -> shutting down\n"; + d_xcvr->shutdown(); + } + else { + //std::cerr << "db_xcvr2450_base::shutdown_common: different -> ignoring\n"; + } +} + struct freq_result_t db_xcvr2450_base::set_freq(double target_freq) { @@ -552,6 +694,16 @@ db_xcvr2450_tx::db_xcvr2450_tx(usrp_basic_sptr usrp, int which) db_xcvr2450_tx::~db_xcvr2450_tx() { + shutdown(); +} + +void +db_xcvr2450_tx::shutdown() +{ + if (!d_is_shutdown){ + d_is_shutdown = true; + shutdown_common(); + } } float @@ -601,6 +753,16 @@ db_xcvr2450_rx::db_xcvr2450_rx(usrp_basic_sptr usrp, int which) db_xcvr2450_rx::~db_xcvr2450_rx() { + shutdown(); +} + +void +db_xcvr2450_rx::shutdown() +{ + if (!d_is_shutdown){ + d_is_shutdown = true; + shutdown_common(); + } } float diff --git a/usrp/host/lib/legacy/db_xcvr2450.h b/usrp/host/lib/legacy/db_xcvr2450.h index 2ff89e3db..1f9dd7c2c 100644 --- a/usrp/host/lib/legacy/db_xcvr2450.h +++ b/usrp/host/lib/legacy/db_xcvr2450.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ // -// Copyright 2008 Free Software Foundation, Inc. +// Copyright 2008,2009 Free Software Foundation, Inc. // // This file is part of GNU Radio // @@ -25,114 +25,9 @@ #include <db_base.h> #include <boost/shared_ptr.hpp> -// TX IO Pins -#define HB_PA_OFF (1 << 15) // 5GHz PA, 1 = off, 0 = on -#define LB_PA_OFF (1 << 14) // 2.4GHz PA, 1 = off, 0 = on -#define ANTSEL_TX1_RX2 (1 << 13) // 1 = Ant 1 to TX, Ant 2 to RX -#define ANTSEL_TX2_RX1 (1 << 12) // 1 = Ant 2 to TX, Ant 1 to RX -#define TX_EN (1 << 11) // 1 = TX on, 0 = TX off -#define AD9515DIV (1 << 4) // 1 = Div by 3, 0 = Div by 2 - -#define TX_OE_MASK HB_PA_OFF|LB_PA_OFF|ANTSEL_TX1_RX2|ANTSEL_TX2_RX1|TX_EN|AD9515DIV -#define TX_SAFE_IO HB_PA_OFF|LB_PA_OFF|ANTSEL_TX1_RX2|AD9515DIV - -// RX IO Pins -#define LOCKDET (1 << 15) // This is an INPUT!!! -#define EN (1 << 14) -#define RX_EN (1 << 13) // 1 = RX on, 0 = RX off -#define RX_HP (1 << 12) -#define RX_OE_MASK EN|RX_EN|RX_HP -#define RX_SAFE_IO EN - -struct xcvr2450_key { - std::string serial_no; - int which; -}; - class xcvr2450; typedef boost::shared_ptr<xcvr2450> xcvr2450_sptr; -class xcvr2450 -{ -private: - boost::weak_ptr<usrp_basic> d_weak_usrp; - int d_which; - - int d_spi_format, d_spi_enable; - - int d_mimo, d_int_div, d_frac_div, d_highband, d_five_gig; - int d_cp_current, d_ref_div, d_rssi_hbw; - int d_txlpf_bw, d_rxlpf_bw, d_rxlpf_fine, d_rxvga_ser; - int d_rssi_range, d_rssi_mode, d_rssi_mux; - int d_rx_hp_pin, d_rx_hpf, d_rx_ant; - int d_tx_ant, d_txvga_ser, d_tx_driver_lin; - int d_tx_vga_lin, d_tx_upconv_lin, d_tx_bb_gain; - int d_pabias_delay, d_pabias, rx_rf_gain, rx_bb_gain, d_txgain; - int d_rx_rf_gain, d_rx_bb_gain; - - int d_reg_standby, d_reg_int_divider, d_reg_frac_divider, d_reg_bandselpll; - int d_reg_cal, dsend_reg, d_reg_lpf, d_reg_rxrssi_ctrl, d_reg_txlin_gain; - int d_reg_pabias, d_reg_rxgain, d_reg_txgain; - - int d_ad9515_div; - - void _set_rfagc(float gain); - void _set_ifagc(float gain); - void _set_pga(float pga_gain); - - usrp_basic_sptr usrp(){ - return usrp_basic_sptr(d_weak_usrp); // throws bad_weak_ptr if d_usrp.use_count() == 0 - } - -public: - xcvr2450(usrp_basic_sptr usrp, int which); - ~xcvr2450(); - - bool operator==(xcvr2450_key x); - - void set_reg_standby(); - - // Integer-Divider Ratio (3) - void set_reg_int_divider(); - - // Fractional-Divider Ratio (4) - void set_reg_frac_divider(); - - // Band Select and PLL (5) - void set_reg_bandselpll(); - - // Calibration (6) - void set_reg_cal(); - - // Lowpass Filter (7) - void set_reg_lpf(); - - // Rx Control/RSSI (8) - void set_reg_rxrssi_ctrl(); - - // Tx Linearity/Baseband Gain (9) - void set_reg_txlin_gain(); - - // PA Bias DAC (10) - void set_reg_pabias(); - - // Rx Gain (11) - void set_reg_rxgain(); - - // Tx Gain (12) - void set_reg_txgain(); - - // Send register write to SPI - void send_reg(int v); - - void set_gpio(); - bool lock_detect(); - bool set_rx_gain(float gain); - bool set_tx_gain(float gain); - - struct freq_result_t set_freq(double target_freq); -}; - /******************************************************************************/ @@ -154,6 +49,7 @@ public: protected: xcvr2450_sptr d_xcvr; + void shutdown_common(); }; @@ -162,6 +58,9 @@ protected: class db_xcvr2450_tx : public db_xcvr2450_base { +protected: + void shutdown(); + public: db_xcvr2450_tx(usrp_basic_sptr usrp, int which); ~db_xcvr2450_tx(); @@ -175,6 +74,9 @@ public: class db_xcvr2450_rx : public db_xcvr2450_base { +protected: + void shutdown(); + public: db_xcvr2450_rx(usrp_basic_sptr usrp, int which); ~db_xcvr2450_rx(); |