aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/common
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2021-09-16 13:33:23 +0200
committerAaron Rossetto <aaron.rossetto@ni.com>2021-09-17 13:29:01 -0700
commit6c8f24a9ca136c78fd73e94e937b3325a26a1fab (patch)
treeade34172b63790bc1d6f98078b7259c38ff19c46 /host/lib/usrp/common
parent652873b664393120b284e3303f82f80c7a1f4f9a (diff)
downloaduhd-6c8f24a9ca136c78fd73e94e937b3325a26a1fab.tar.gz
uhd-6c8f24a9ca136c78fd73e94e937b3325a26a1fab.tar.bz2
uhd-6c8f24a9ca136c78fd73e94e937b3325a26a1fab.zip
ad9361: Modify set-tx-gain procedure to update gain in one go
The previous behaviour of UHD for setting gain was: 1. Set "Mask Clr Atten Update". This will avoid "Immediately Update TPC Atten" to be cleared. 2. Then, assert "Immediately Update TPC Atten". 3. Poke the LSBs of the attenuation value. 4. Poke the MSB of the attenuation value. This order of operations has the downside of causing large Tx power spikes when setting the attenuation, because you need both registers to properly set the attenuation, but we are updating the gain immediately, even between the two attenuation register's update. Moreover, the upstream Linux driver for AD9361 by ADI also does not do this. We therefore change the procedure to match the kernel driver behaviour, which is: 0. [During initialization: Clear "Mask Clr Atten Update" 1. Poke the attenuation registers 2. Then, assert "Immediately Update TPC Atten". This avoids Tx power spikes. It also reduces the Tx-gain procedure to 3 pokes instead of 4.
Diffstat (limited to 'host/lib/usrp/common')
-rw-r--r--host/lib/usrp/common/ad9361_driver/ad9361_device.cpp20
1 files changed, 13 insertions, 7 deletions
diff --git a/host/lib/usrp/common/ad9361_driver/ad9361_device.cpp b/host/lib/usrp/common/ad9361_driver/ad9361_device.cpp
index 9275c83f5..5574022b6 100644
--- a/host/lib/usrp/common/ad9361_driver/ad9361_device.cpp
+++ b/host/lib/usrp/common/ad9361_driver/ad9361_device.cpp
@@ -1817,6 +1817,10 @@ void ad9361_device_t::initialize()
/* Set TXers & RXers on (only works in FDD mode) */
_io_iface->poke8(0x014, 0x21);
+
+ /* We won't be using immediate-Tx-attenuation, so we de-assert "Mask Clr
+ * Atten Update". */
+ _io_iface->poke8(0x077, 0x00);
}
void ad9361_device_t::set_io_iface(ad9361_io::sptr io_iface)
@@ -2203,11 +2207,6 @@ double ad9361_device_t::set_gain(direction_t direction, chain_t chain, const dou
return gain_index;
} else {
- /* Setting the below bits causes a change in the TX attenuation word
- * to immediately take effect. */
- _io_iface->poke8(0x077, 0x40);
- _io_iface->poke8(0x07c, 0x40);
-
/* Each gain step is -0.25dB. Calculate the attenuation necessary
* for the requested gain, convert it into gain steps, then write
* the attenuation word. Max gain (so zero attenuation) is 89.75.
@@ -2215,8 +2214,8 @@ double ad9361_device_t::set_gain(direction_t direction, chain_t chain, const dou
* "value" is out of bounds, so range checking must be performed
* outside this function.
*/
- double atten = AD9361_MAX_GAIN - value;
- uint32_t attenreg = uint32_t(atten * 4);
+ const double atten = AD9361_MAX_GAIN - value;
+ const uint32_t attenreg = uint32_t(atten * 4);
if (chain == CHAIN_1) {
_tx1_gain = value;
_io_iface->poke8(0x073, attenreg & 0xFF);
@@ -2226,6 +2225,13 @@ double ad9361_device_t::set_gain(direction_t direction, chain_t chain, const dou
_io_iface->poke8(0x075, attenreg & 0xFF);
_io_iface->poke8(0x076, (attenreg >> 8) & 0x01);
}
+
+ /* After we've set both registers for the new gain, we apply it (assert
+ * "Immediately Update TPC Atten"). This avoids the attenuation from
+ * intermediately becoming very small (i.e., high output power) during
+ * the set-gain cycle.
+ */
+ _io_iface->poke8(0x07c, 0x40);
return AD9361_MAX_GAIN - ((double)(attenreg) / 4);
}
}