diff options
| author | Jason Abele <jason@ettus.com> | 2011-12-12 13:08:32 -0800 | 
|---|---|---|
| committer | Josh Blum <josh@joshknows.com> | 2011-12-16 11:15:03 -0800 | 
| commit | a9554d721c3b49525fcc645ae23e74e4cd092eb0 (patch) | |
| tree | 97d5bbb23e62c312349ee8799df930ab2bdbc37c | |
| parent | f592102763d717f4a1baa3013fff86fab5ca1c48 (diff) | |
| download | uhd-a9554d721c3b49525fcc645ae23e74e4cd092eb0.tar.gz uhd-a9554d721c3b49525fcc645ae23e74e4cd092eb0.tar.bz2 uhd-a9554d721c3b49525fcc645ae23e74e4cd092eb0.zip | |
Make WBX v3+ TX set max attenuation when idle
    Because WBX v3+ uses digital step attenuator for TX gain control
    we can set max attenuation via ATR when WBX is in RX_ONLY or IDLE
    This will reduce the LO leakage during non-transmit times
| -rw-r--r-- | host/lib/usrp/dboard/db_wbx_version3.cpp | 16 | ||||
| -rw-r--r-- | host/lib/usrp/dboard/db_wbx_version4.cpp | 17 | 
2 files changed, 21 insertions, 12 deletions
| diff --git a/host/lib/usrp/dboard/db_wbx_version3.cpp b/host/lib/usrp/dboard/db_wbx_version3.cpp index 1e7e448fa..2cca8e4f9 100644 --- a/host/lib/usrp/dboard/db_wbx_version3.cpp +++ b/host/lib/usrp/dboard/db_wbx_version3.cpp @@ -114,16 +114,17 @@ wbx_base::wbx_version3::wbx_version3(wbx_base *_self_wbx_base) {      int v3_tx_mod = ADF4350_PDBRF;      //set the gpio directions and atr controls -    self_base->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, v3_tx_mod); +    self_base->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, v3_tx_mod|v3_iobits);      self_base->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, RXBB_PDB|ADF4350_PDBRF);      self_base->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, TX_PUP_5V|TX_PUP_3V|v3_tx_mod|v3_iobits);      self_base->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, RX_PUP_5V|RX_PUP_3V|ADF4350_CE|RXBB_PDB|ADF4350_PDBRF|RX_ATTN_MASK);      //setup ATR for the mixer enables (always enabled to prevent phase slip between bursts) -    self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_IDLE,        v3_tx_mod, TX_MIXER_DIS | v3_tx_mod); -    self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_RX_ONLY,     v3_tx_mod, TX_MIXER_DIS | v3_tx_mod); -    self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_TX_ONLY,     v3_tx_mod, TX_MIXER_DIS | v3_tx_mod); -    self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_FULL_DUPLEX, v3_tx_mod, TX_MIXER_DIS | v3_tx_mod); +    //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,        v3_tx_mod, TX_ATTN_MASK | TX_MIXER_DIS | v3_tx_mod); +    self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_RX_ONLY,     v3_tx_mod, TX_ATTN_MASK | TX_MIXER_DIS | v3_tx_mod); +    self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_TX_ONLY,     v3_tx_mod, TX_ATTN_MASK | TX_MIXER_DIS | v3_tx_mod); +    self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_FULL_DUPLEX, v3_tx_mod, TX_ATTN_MASK | TX_MIXER_DIS | v3_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); @@ -152,10 +153,13 @@ double wbx_base::wbx_version3::set_tx_gain(double gain, const std::string &name)      assert_has(wbx_v3_tx_gain_ranges.keys(), name, "wbx tx gain name");      if(name == "PGA0"){          boost::uint16_t io_bits = tx_pga0_gain_to_iobits(gain); +          self_base->_tx_gains[name] = gain;          //write the new gain to tx gpio outputs -        self_base->get_iface()->set_gpio_out(dboard_iface::UNIT_TX, io_bits, TX_ATTN_MASK); +        //Update ATR with gain io_bits, only update for TX_ONLY and FULL_DUPLEX ATR states +        self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_TX_ONLY,     io_bits, TX_ATTN_MASK); +        self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_FULL_DUPLEX, io_bits, TX_ATTN_MASK);      }      else UHD_THROW_INVALID_CODE_PATH();      return self_base->_tx_gains[name]; //shadow diff --git a/host/lib/usrp/dboard/db_wbx_version4.cpp b/host/lib/usrp/dboard/db_wbx_version4.cpp index cebaee2d7..3a85826cd 100644 --- a/host/lib/usrp/dboard/db_wbx_version4.cpp +++ b/host/lib/usrp/dboard/db_wbx_version4.cpp @@ -115,16 +115,17 @@ wbx_base::wbx_version4::wbx_version4(wbx_base *_self_wbx_base) {      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); +    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) -    self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_IDLE,        v4_tx_mod, 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_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_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_MIXER_DIS | v4_tx_mod); +    //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); @@ -153,10 +154,14 @@ double wbx_base::wbx_version4::set_tx_gain(double gain, const std::string &name)      assert_has(wbx_v4_tx_gain_ranges.keys(), name, "wbx tx gain name");      if(name == "PGA0"){          boost::uint16_t io_bits = tx_pga0_gain_to_iobits(gain); +          self_base->_tx_gains[name] = gain;          //write the new gain to tx gpio outputs -        self_base->get_iface()->set_gpio_out(dboard_iface::UNIT_TX, io_bits, TX_ATTN_MASK); +        //Update ATR with gain io_bits, only update for TX_ONLY and FULL_DUPLEX ATR states +        self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_TX_ONLY,     io_bits, TX_ATTN_MASK); +        self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_FULL_DUPLEX, io_bits, TX_ATTN_MASK); +      }      else UHD_THROW_INVALID_CODE_PATH();      return self_base->_tx_gains[name]; | 
