summaryrefslogtreecommitdiffstats
path: root/host/lib
diff options
context:
space:
mode:
authorJason Abele <jason@ettus.com>2011-12-12 13:08:32 -0800
committerJosh Blum <josh@joshknows.com>2011-12-16 11:15:03 -0800
commita9554d721c3b49525fcc645ae23e74e4cd092eb0 (patch)
tree97d5bbb23e62c312349ee8799df930ab2bdbc37c /host/lib
parentf592102763d717f4a1baa3013fff86fab5ca1c48 (diff)
downloaduhd-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
Diffstat (limited to 'host/lib')
-rw-r--r--host/lib/usrp/dboard/db_wbx_version3.cpp16
-rw-r--r--host/lib/usrp/dboard/db_wbx_version4.cpp17
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];