aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/e300/e300_remote_codec_ctrl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/usrp/e300/e300_remote_codec_ctrl.cpp')
-rw-r--r--host/lib/usrp/e300/e300_remote_codec_ctrl.cpp148
1 files changed, 148 insertions, 0 deletions
diff --git a/host/lib/usrp/e300/e300_remote_codec_ctrl.cpp b/host/lib/usrp/e300/e300_remote_codec_ctrl.cpp
new file mode 100644
index 000000000..bcc8ee4cf
--- /dev/null
+++ b/host/lib/usrp/e300/e300_remote_codec_ctrl.cpp
@@ -0,0 +1,148 @@
+//
+// Copyright 2014 Ettus Research LLC
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#include "e300_remote_codec_ctrl.hpp"
+
+#include <boost/cstdint.hpp>
+#include <uhd/exception.hpp>
+#include <uhd/utils/byteswap.hpp>
+#include <cstring>
+#include <iostream>
+
+namespace uhd { namespace usrp { namespace e300 {
+
+class e300_remote_codec_ctrl_impl : public e300_remote_codec_ctrl
+{
+public:
+ e300_remote_codec_ctrl_impl(uhd::transport::zero_copy_if::sptr xport) : _xport(xport)
+ {
+ }
+
+ virtual ~e300_remote_codec_ctrl_impl(void)
+ {
+ }
+
+ double set_gain(const std::string &which, const double value)
+ {
+ _clear();
+ _args.action = uhd::htonx<boost::uint32_t>(transaction_t::ACTION_SET_GAIN);
+ if (which == "TX1") _args.which = uhd::htonx<boost::uint32_t>(transaction_t::CHAIN_TX1);
+ else if (which == "TX2") _args.which = uhd::htonx<boost::uint32_t>(transaction_t::CHAIN_TX2);
+ else if (which == "RX1") _args.which = uhd::htonx<boost::uint32_t>(transaction_t::CHAIN_RX1);
+ else if (which == "RX2") _args.which = uhd::htonx<boost::uint32_t>(transaction_t::CHAIN_RX2);
+ else throw std::runtime_error("e300_remote_codec_ctrl_impl incorrect chain string.");
+ _args.gain = value;
+
+ _transact();
+ return _retval.gain;
+ }
+
+ double set_clock_rate(const double rate)
+ {
+ _clear();
+ _args.action = uhd::htonx<boost::uint32_t>(
+ transaction_t::ACTION_SET_CLOCK_RATE);
+ _args.which = uhd::htonx<boost::uint32_t>(
+ transaction_t::CHAIN_NONE); /*Unused*/
+ _args.rate = rate;
+
+ _transact();
+ return _retval.gain;
+ }
+
+ void set_active_chains(bool tx1, bool tx2, bool rx1, bool rx2)
+ {
+ _clear();
+ _args.action = uhd::htonx<boost::uint32_t>(
+ transaction_t::ACTION_SET_ACTIVE_CHANS);
+ /*Unused*/
+ _args.which = uhd::htonx<boost::uint32_t>(
+ transaction_t::CHAIN_NONE);
+ _args.bits = uhd::htonx<boost::uint32_t>(
+ (tx1 ? (1<<0) : 0) |
+ (tx2 ? (1<<1) : 0) |
+ (rx1 ? (1<<2) : 0) |
+ (rx2 ? (1<<3) : 0));
+
+ _transact();
+ }
+
+ double tune(const std::string &which, const double value)
+ {
+ _clear();
+ _args.action = uhd::htonx<boost::uint32_t>(transaction_t::ACTION_TUNE);
+ if (which == "TX1") _args.which = uhd::htonx<boost::uint32_t>(transaction_t::CHAIN_TX1);
+ else if (which == "TX2") _args.which = uhd::htonx<boost::uint32_t>(transaction_t::CHAIN_TX2);
+ else if (which == "RX1") _args.which = uhd::htonx<boost::uint32_t>(transaction_t::CHAIN_RX1);
+ else if (which == "RX2") _args.which = uhd::htonx<boost::uint32_t>(transaction_t::CHAIN_RX2);
+ else throw std::runtime_error("e300_remote_codec_ctrl_impl incorrect chain string.");
+ _args.freq = value;
+
+ _transact();
+ return _retval.freq;
+ }
+
+ void data_port_loopback(const bool on)
+ {
+ _clear();
+ _args.action = uhd::htonx<boost::uint32_t>(transaction_t::ACTION_SET_LOOPBACK);
+ _args.which = uhd::htonx<boost::uint32_t>(transaction_t::CHAIN_NONE); /*Unused*/
+ _args.bits = uhd::htonx<boost::uint32_t>(on ? 1 : 0);
+
+ _transact();
+ }
+
+private:
+ void _transact() {
+ {
+ uhd::transport::managed_send_buffer::sptr buff = _xport->get_send_buff(10.0);
+ if (not buff or buff->size() < sizeof(_args))
+ throw std::runtime_error("e300_remote_codec_ctrl_impl send timeout");
+ std::memcpy(buff->cast<void *>(), &_args, sizeof(_args));
+ buff->commit(sizeof(_args));
+ }
+ {
+ uhd::transport::managed_recv_buffer::sptr buff = _xport->get_recv_buff(10.0);
+ if (not buff or buff->size() < sizeof(_retval))
+ throw std::runtime_error("e300_remote_codec_ctrl_impl recv timeout");
+ std::memcpy(&_retval, buff->cast<const void *>(), sizeof(_retval));
+ }
+
+ if (_args.action != _retval.action)
+ throw std::runtime_error("e300_remote_codec_ctrl_impl trancation failed.");
+ }
+
+ void _clear() {
+ _args.action = 0;
+ _args.which = 0;
+ _args.bits = 0;
+ _retval.action = 0;
+ _retval.which = 0;
+ _retval.bits = 0;
+ }
+
+ uhd::transport::zero_copy_if::sptr _xport;
+ transaction_t _args;
+ transaction_t _retval;
+};
+
+ad9361_ctrl::sptr e300_remote_codec_ctrl::make(uhd::transport::zero_copy_if::sptr xport)
+{
+ return sptr(new e300_remote_codec_ctrl_impl(xport));
+}
+
+}}};