diff options
Diffstat (limited to 'host/lib/usrp/e300/e300_remote_codec_ctrl.cpp')
-rw-r--r-- | host/lib/usrp/e300/e300_remote_codec_ctrl.cpp | 148 |
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)); +} + +}}}; |