aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSugandha Gupta <sugandha.gupta@ettus.com>2018-06-05 13:48:07 -0700
committerMartin Braun <martin.braun@ettus.com>2018-06-15 16:37:03 -0500
commit67b5827faecd3dc3d9977dff7366b8ea2ab4c87a (patch)
tree8d4d6b3645cd4b1aa72e26b4be4b5e81d5c45bfa
parentf9101d7cc7552755d597982eeccecabe88b8a022 (diff)
downloaduhd-67b5827faecd3dc3d9977dff7366b8ea2ab4c87a.tar.gz
uhd-67b5827faecd3dc3d9977dff7366b8ea2ab4c87a.tar.bz2
uhd-67b5827faecd3dc3d9977dff7366b8ea2ab4c87a.zip
ad9361: Add API to set 1R1T/2R2T timing modes
LVDS interface can support both timing modes 1R1T/2R2T The API sets the required bit in catalina registers.
-rw-r--r--host/lib/include/uhdlib/usrp/common/ad9361_ctrl.hpp3
-rw-r--r--host/lib/usrp/common/ad9361_ctrl.cpp14
-rw-r--r--host/lib/usrp/common/ad9361_driver/ad9361_device.cpp42
-rw-r--r--host/lib/usrp/common/ad9361_driver/ad9361_device.h7
-rw-r--r--host/lib/usrp/e300/e300_remote_codec_ctrl.cpp5
5 files changed, 71 insertions, 0 deletions
diff --git a/host/lib/include/uhdlib/usrp/common/ad9361_ctrl.hpp b/host/lib/include/uhdlib/usrp/common/ad9361_ctrl.hpp
index 411de6f81..07906fef2 100644
--- a/host/lib/include/uhdlib/usrp/common/ad9361_ctrl.hpp
+++ b/host/lib/include/uhdlib/usrp/common/ad9361_ctrl.hpp
@@ -109,6 +109,9 @@ public:
//! set which RX and TX chains/antennas are active
virtual void set_active_chains(bool tx1, bool tx2, bool rx1, bool rx2) = 0;
+ //! set which timing mode is used
+ virtual void set_timing_mode(const std::string &timing_mode) = 0;
+
//! tune the given frontend, return the exact value
virtual double tune(const std::string &which, const double value) = 0;
diff --git a/host/lib/usrp/common/ad9361_ctrl.cpp b/host/lib/usrp/common/ad9361_ctrl.cpp
index 2b6821fc0..1982d83e7 100644
--- a/host/lib/usrp/common/ad9361_ctrl.cpp
+++ b/host/lib/usrp/common/ad9361_ctrl.cpp
@@ -168,6 +168,20 @@ public:
}
+ //! set which timing mode to use - 1R1T, 2R2T
+ void set_timing_mode(const std::string &timing_mode)
+ {
+ boost::lock_guard<boost::mutex> lock(_mutex);
+
+ _use_safe_spi();
+ if ((timing_mode != "2R2T") && (timing_mode != "1R1T")) {
+ throw uhd::assertion_error("ad9361_ctrl: Timing mode not supported");
+ }
+ _device.set_timing_mode((timing_mode == "2R2T")? ad9361_device_t::TIMING_MODE_2R2T : ad9361_device_t::TIMING_MODE_1R1T);
+ _use_timed_spi();
+
+ }
+
//! tune the given frontend, return the exact value
double tune(const std::string &which, const double freq)
{
diff --git a/host/lib/usrp/common/ad9361_driver/ad9361_device.cpp b/host/lib/usrp/common/ad9361_driver/ad9361_device.cpp
index 56df8bd12..9273edb02 100644
--- a/host/lib/usrp/common/ad9361_driver/ad9361_device.cpp
+++ b/host/lib/usrp/common/ad9361_driver/ad9361_device.cpp
@@ -1984,6 +1984,48 @@ void ad9361_device_t::set_active_chains(bool tx1, bool tx2, bool rx1, bool rx2)
_io_iface->poke8(0x014, 0x21);
}
+/* Setup Timing mode depending on active channels.
+ *
+ * LVDS interface can have two timing modes - 1R1T and 2R2T
+ */
+void ad9361_device_t::set_timing_mode(const ad9361_device_t::timing_mode_t timing_mode)
+{
+ switch (_client_params->get_digital_interface_mode()) {
+ case AD9361_DDR_FDD_LVCMOS: {
+ switch(timing_mode) {
+ case TIMING_MODE_1R1T: {
+ _io_iface->poke8(0x010, 0xc8); // Swap I&Q on Tx, Swap I&Q on Rx, Toggle frame sync mode
+ break;
+ }
+ case TIMING_MODE_2R2T: {
+ throw uhd::runtime_error("[ad9361_device_t] [set_timing_mode] 2R2T timing mode not supported for CMOS");
+ break;
+ }
+ default:
+ UHD_THROW_INVALID_CODE_PATH();
+ }
+ break;
+ }
+ case AD9361_DDR_FDD_LVDS: {
+ switch(timing_mode) {
+ case TIMING_MODE_1R1T: {
+ _io_iface->poke8(0x010, 0xc8); // Swap I&Q on Tx, Swap I&Q on Rx, Toggle frame sync mode, 1R1T timing.
+ break;
+ }
+ case TIMING_MODE_2R2T: {
+ _io_iface->poke8(0x010, 0xcc); // Swap I&Q on Tx, Swap I&Q on Rx, Toggle frame sync mode, 2R2T timing.
+ break;
+ }
+ default:
+ UHD_THROW_INVALID_CODE_PATH();
+ }
+ break;
+ }
+ default:
+ throw uhd::runtime_error("[ad9361_device_t] NOT IMPLEMENTED");
+ }
+}
+
/* Tune the RX or TX frequency.
*
* This is the publicly-accessible tune function. It makes sure the tune
diff --git a/host/lib/usrp/common/ad9361_driver/ad9361_device.h b/host/lib/usrp/common/ad9361_driver/ad9361_device.h
index 3f32ba8a8..a42469035 100644
--- a/host/lib/usrp/common/ad9361_driver/ad9361_device.h
+++ b/host/lib/usrp/common/ad9361_driver/ad9361_device.h
@@ -28,6 +28,7 @@ public:
enum direction_t { RX, TX };
enum gain_mode_t {GAIN_MODE_MANUAL, GAIN_MODE_SLOW_AGC, GAIN_MODE_FAST_AGC};
enum chain_t { CHAIN_1, CHAIN_2, CHAIN_BOTH };
+ enum timing_mode_t { TIMING_MODE_1R1T, TIMING_MODE_2R2T };
ad9361_device_t(ad9361_params::sptr client, ad9361_io::sptr io_iface) :
_client_params(client), _io_iface(io_iface),
@@ -93,6 +94,12 @@ public:
*/
void set_active_chains(bool tx1, bool tx2, bool rx1, bool rx2);
+ /* Setup Timing mode depending on active channels.
+ *
+ * LVDS interface can have two timing modes - 1R1T and 2R2T
+ */
+ void set_timing_mode(const timing_mode_t timing_mode);
+
/* Tune the RX or TX frequency.
*
* This is the publicly-accessible tune function. It makes sure the tune
diff --git a/host/lib/usrp/e300/e300_remote_codec_ctrl.cpp b/host/lib/usrp/e300/e300_remote_codec_ctrl.cpp
index 925c9bb6b..2dd401b1b 100644
--- a/host/lib/usrp/e300/e300_remote_codec_ctrl.cpp
+++ b/host/lib/usrp/e300/e300_remote_codec_ctrl.cpp
@@ -240,6 +240,11 @@ public:
UHD_THROW_INVALID_CODE_PATH();
}
+ void set_timing_mode(UHD_UNUSED(const std::string &timing_mode))
+ {
+ UHD_THROW_INVALID_CODE_PATH();
+ }
+
private:
void _transact() {
{