diff options
Diffstat (limited to 'host/lib/usrp/common')
| -rw-r--r-- | host/lib/usrp/common/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | host/lib/usrp/common/ad9361_ctrl.cpp | 165 | ||||
| -rw-r--r-- | host/lib/usrp/common/ad9361_ctrl.hpp | 127 | ||||
| -rw-r--r-- | host/lib/usrp/common/ad9361_transaction.h | 102 | ||||
| -rw-r--r-- | host/lib/usrp/common/adf4001_ctrl.cpp | 151 | ||||
| -rw-r--r-- | host/lib/usrp/common/adf4001_ctrl.hpp | 142 | ||||
| -rw-r--r-- | host/lib/usrp/common/recv_packet_demuxer_3000.hpp | 14 | 
7 files changed, 703 insertions, 2 deletions
diff --git a/host/lib/usrp/common/CMakeLists.txt b/host/lib/usrp/common/CMakeLists.txt index fa07e3d1d..1728b63f9 100644 --- a/host/lib/usrp/common/CMakeLists.txt +++ b/host/lib/usrp/common/CMakeLists.txt @@ -1,5 +1,5 @@  # -# Copyright 2011-2012 Ettus Research LLC +# Copyright 2011-2013 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 @@ -29,6 +29,8 @@ ENDIF(ENABLE_USB)  INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})  LIBUHD_APPEND_SOURCES( +    ${CMAKE_CURRENT_SOURCE_DIR}/adf4001_ctrl.cpp +    ${CMAKE_CURRENT_SOURCE_DIR}/ad9361_ctrl.cpp      ${CMAKE_CURRENT_SOURCE_DIR}/apply_corrections.cpp      ${CMAKE_CURRENT_SOURCE_DIR}/validate_subdev_spec.cpp      ${CMAKE_CURRENT_SOURCE_DIR}/recv_packet_demuxer.cpp diff --git a/host/lib/usrp/common/ad9361_ctrl.cpp b/host/lib/usrp/common/ad9361_ctrl.cpp new file mode 100644 index 000000000..ae7cc6f9b --- /dev/null +++ b/host/lib/usrp/common/ad9361_ctrl.cpp @@ -0,0 +1,165 @@ +// +// Copyright 2012-2013 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 "ad9361_ctrl.hpp" +#include "ad9361_transaction.h" +#include <uhd/exception.hpp> +#include <uhd/types/ranges.hpp> +#include <uhd/utils/msg.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/format.hpp> +#include <cstring> + +using namespace uhd; + +struct ad9361_ctrl_impl : public ad9361_ctrl +{ +    ad9361_ctrl_impl(ad9361_ctrl_iface_sptr iface): +        _iface(iface), _seq(0) +    { +        ad9361_transaction_t request; + +        request.action = AD9361_ACTION_ECHO; +        this->do_transaction(request); + +        request.action = AD9361_ACTION_INIT; +        this->do_transaction(request); +    } + +    double set_gain(const std::string &which, const double value) +    { +        ad9361_transaction_t request; + +        if (which == "RX1") request.action = AD9361_ACTION_SET_RX1_GAIN; +        if (which == "RX2") request.action = AD9361_ACTION_SET_RX2_GAIN; +        if (which == "TX1") request.action = AD9361_ACTION_SET_TX1_GAIN; +        if (which == "TX2") request.action = AD9361_ACTION_SET_TX2_GAIN; + +        ad9361_double_pack(value, request.value.gain); +        const ad9361_transaction_t reply = this->do_transaction(request); +        return ad9361_double_unpack(reply.value.gain); +    } + +    //! set a new clock rate, return the exact value +    double set_clock_rate(const double rate) +    { +        //warning for known trouble rates +        if (rate > 56e6) UHD_MSG(warning) << boost::format( +            "The requested clock rate %f MHz may cause slow configuration.\n" +            "The driver recommends a master clock rate less than %f MHz.\n" +        ) % (rate/1e6) % 56.0 << std::endl; + +        //clip to known bounds +        const meta_range_t clock_rate_range(250e3, 61.44e6); +        const double clipped_rate = clock_rate_range.clip(rate); + +        ad9361_transaction_t request; +        request.action = AD9361_ACTION_SET_CLOCK_RATE; +        ad9361_double_pack(clipped_rate, request.value.rate); +        const ad9361_transaction_t reply = this->do_transaction(request); +        return ad9361_double_unpack(reply.value.rate); +    } + +    //! set which RX and TX chains/antennas are active +    void set_active_chains(bool tx1, bool tx2, bool rx1, bool rx2) +    { +        boost::uint32_t mask = 0; +        if (tx1) mask |= (1 << 0); +        if (tx2) mask |= (1 << 1); +        if (rx1) mask |= (1 << 2); +        if (rx2) mask |= (1 << 3); + +        ad9361_transaction_t request; +        request.action = AD9361_ACTION_SET_ACTIVE_CHAINS; +        request.value.enable_mask = mask; +        this->do_transaction(request); +    } + +    //! tune the given frontend, return the exact value +    double tune(const std::string &which, const double freq) +    { +        //clip to known bounds +        const meta_range_t freq_range(50e6, 6e9); +        const double clipped_freq = freq_range.clip(freq); + +        ad9361_transaction_t request; + +        if (which[0] == 'R') request.action = AD9361_ACTION_SET_RX_FREQ; +        if (which[0] == 'T') request.action = AD9361_ACTION_SET_TX_FREQ; + +        const double value = ad9361_ctrl::get_rf_freq_range().clip(clipped_freq); +        ad9361_double_pack(value, request.value.freq); +        const ad9361_transaction_t reply = this->do_transaction(request); +        return ad9361_double_unpack(reply.value.freq); +    } + +    //! turn on/off Catalina's data port loopback +    void data_port_loopback(const bool on) +    { +        ad9361_transaction_t request; +        request.action = AD9361_ACTION_SET_CODEC_LOOP; +        request.value.codec_loop = on? 1 : 0; +        this->do_transaction(request); +    } + +    ad9361_transaction_t do_transaction(const ad9361_transaction_t &request) +    { +        boost::mutex::scoped_lock lock(_mutex); + +        //declare in/out buffers +        unsigned char in_buff[64] = {}; +        unsigned char out_buff[64] = {}; + +        //copy the input transaction +        std::memcpy(in_buff, &request, sizeof(request)); +     +        //fill in other goodies +        ad9361_transaction_t *in = (ad9361_transaction_t *)in_buff; +        in->version = AD9361_TRANSACTION_VERSION; +        in->sequence = _seq++; + +        //transact +        _iface->ad9361_transact(in_buff, out_buff); +        ad9361_transaction_t *out = (ad9361_transaction_t *)out_buff; + +        //sanity checks +        UHD_ASSERT_THROW(out->version == in->version); +        UHD_ASSERT_THROW(out->sequence == in->sequence); + +        //handle errors +        const size_t len = strnlen(out->error_msg, AD9361_TRANSACTION_MAX_ERROR_MSG); +        const std::string error_msg(out->error_msg, len); +        if (not error_msg.empty()) throw uhd::runtime_error("ad9361 do transaction: " + error_msg); + +        //return result done! +        return *out; +    } + +    ad9361_ctrl_iface_sptr _iface; +    size_t _seq; +    boost::mutex _mutex; + +}; + + +/*********************************************************************** + * Make an instance of the implementation + **********************************************************************/ +ad9361_ctrl::sptr ad9361_ctrl::make(ad9361_ctrl_iface_sptr iface) +{ +    return sptr(new ad9361_ctrl_impl(iface)); +} diff --git a/host/lib/usrp/common/ad9361_ctrl.hpp b/host/lib/usrp/common/ad9361_ctrl.hpp new file mode 100644 index 000000000..6d79ef3e9 --- /dev/null +++ b/host/lib/usrp/common/ad9361_ctrl.hpp @@ -0,0 +1,127 @@ +// +// Copyright 2012-2013 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/>. +// + +#ifndef INCLUDED_AD9361_CTRL_HPP +#define INCLUDED_AD9361_CTRL_HPP + +#include <uhd/transport/zero_copy.hpp> +#include <uhd/types/serial.hpp> +#include <uhd/types/ranges.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/utility.hpp> +#include <boost/function.hpp> +#include <vector> +#include <string> + + +struct ad9361_ctrl_iface_type +{ +    virtual void ad9361_transact(const unsigned char in_buff[64], unsigned char out_buff[64]) = 0; +}; +typedef boost::shared_ptr<ad9361_ctrl_iface_type> ad9361_ctrl_iface_sptr; + + +struct ad9361_ctrl_over_zc : ad9361_ctrl_iface_type +{ +    ad9361_ctrl_over_zc(uhd::transport::zero_copy_if::sptr xport) +    { +        _xport = xport; +    } + +    void ad9361_transact(const unsigned char in_buff[64], unsigned char out_buff[64]) +    { +        { +            uhd::transport::managed_send_buffer::sptr buff = _xport->get_send_buff(10.0); +            if (not buff or buff->size() < 64) throw std::runtime_error("ad9361_ctrl_over_zc send timeout"); +            std::memcpy(buff->cast<void *>(), in_buff, 64); +            buff->commit(64); +        } +        { +            uhd::transport::managed_recv_buffer::sptr buff = _xport->get_recv_buff(10.0); +            if (not buff or buff->size() < 64) throw std::runtime_error("ad9361_ctrl_over_zc recv timeout"); +            std::memcpy(out_buff, buff->cast<const void *>(), 64); +        } +    } + +    uhd::transport::zero_copy_if::sptr _xport; +}; + + +class ad9361_ctrl : boost::noncopyable{ +public: +    typedef boost::shared_ptr<ad9361_ctrl> sptr; + +    //! make a new codec control object +    static sptr make(ad9361_ctrl_iface_sptr iface); + +    //! Get a list of gain names for RX or TX +    static std::vector<std::string> get_gain_names(const std::string &/*which*/) +    { +        return std::vector<std::string>(1, "PGA"); +    } + +    //! get the gain range for a particular gain element +    static uhd::meta_range_t get_gain_range(const std::string &which) +    { +        if(which[0] == 'R') { +            return uhd::meta_range_t(0.0, 73.0, 1.0); +        } else { +            return uhd::meta_range_t(0.0, 89.75, 0.25); +        } +    } + +    //! get the freq range for the frontend which +    static uhd::meta_range_t get_rf_freq_range(void) +    { +        return uhd::meta_range_t(30e6, 6e9); +    } + +    //! get the filter range for the frontend which +    static uhd::meta_range_t get_bw_filter_range(const std::string &/*which*/) +    { +        return uhd::meta_range_t(200e3, 56e6); +    } + +    //! get the filter range for the frontend which +    static uhd::meta_range_t get_samp_rate_range(void) +    { +        return uhd::meta_range_t(220e3, 61.44e6); +    } + +    //! set the filter bandwidth for the frontend +    double set_bw_filter(const std::string &/*which*/, const double /*bw*/) +    { +        return 56e6; //TODO +    } + +    //! set the gain for a particular gain element +    virtual double set_gain(const std::string &which, const double value) = 0; + +    //! set a new clock rate, return the exact value +    virtual double set_clock_rate(const double rate) = 0; + +    //! set which RX and TX chains/antennas are active +    virtual void set_active_chains(bool tx1, bool tx2, bool rx1, bool rx2) = 0; + +    //! tune the given frontend, return the exact value +    virtual double tune(const std::string &which, const double value) = 0; + +    //! turn on/off Catalina's data port loopback +    virtual void data_port_loopback(const bool on) = 0; +}; + +#endif /* INCLUDED_AD9361_CTRL_HPP */ diff --git a/host/lib/usrp/common/ad9361_transaction.h b/host/lib/usrp/common/ad9361_transaction.h new file mode 100644 index 000000000..7b41b811f --- /dev/null +++ b/host/lib/usrp/common/ad9361_transaction.h @@ -0,0 +1,102 @@ +// +// Copyright 2013 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/>. +// + +#ifndef INCLUDED_AD9361_TRANSACTION_H +#define INCLUDED_AD9361_TRANSACTION_H + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +//various constants +#define AD9361_TRANSACTION_VERSION 0x4 +#define AD9361_TRANSACTION_MAX_ERROR_MSG 40 + +//action types +#define AD9361_ACTION_ECHO 0 +#define AD9361_ACTION_INIT 1 +#define AD9361_ACTION_SET_RX1_GAIN 2 +#define AD9361_ACTION_SET_TX1_GAIN 3 +#define AD9361_ACTION_SET_RX2_GAIN 4 +#define AD9361_ACTION_SET_TX2_GAIN 5 +#define AD9361_ACTION_SET_RX_FREQ 6 +#define AD9361_ACTION_SET_TX_FREQ 7 +#define AD9361_ACTION_SET_CODEC_LOOP 8 +#define AD9361_ACTION_SET_CLOCK_RATE 9 +#define AD9361_ACTION_SET_ACTIVE_CHAINS 10 + +static inline void ad9361_double_pack(const double input, uint32_t output[2]) +{ +    const uint32_t *p = (const uint32_t *)&input; +    output[0] = p[0]; +    output[1] = p[1]; +} + +static inline double ad9361_double_unpack(const uint32_t input[2]) +{ +    double output = 0.0; +    uint32_t *p = (uint32_t *)&output; +    p[0] = input[0]; +    p[1] = input[1]; +    return output; +} + +typedef struct +{ +    //version is expected to be AD9361_TRANSACTION_VERSION +    //check otherwise for compatibility +    uint32_t version; + +    //sequence number - increment every call for sanity +    uint32_t sequence; + +    //action tells us what to do, see AD9361_ACTION_* +    uint32_t action; + +    union +    { +        //enable mask for chains +        uint32_t enable_mask; + +        //true to enable codec internal loopback +        uint32_t codec_loop; + +        //freq holds request LO freq and result from tune +        uint32_t freq[2]; + +        //gain holds request gain and result from action +        uint32_t gain[2]; + +        //rate holds request clock rate and result from action +        uint32_t rate[2]; + +    } value; + +    //error message comes back as a reply - +    //set to null string for no error \0 +    char error_msg[]; + +} ad9361_transaction_t; + + +#ifdef __cplusplus +} +#endif + +#endif /* INCLUDED_AD9361_TRANSACTION_H */ diff --git a/host/lib/usrp/common/adf4001_ctrl.cpp b/host/lib/usrp/common/adf4001_ctrl.cpp new file mode 100644 index 000000000..46171c7ce --- /dev/null +++ b/host/lib/usrp/common/adf4001_ctrl.cpp @@ -0,0 +1,151 @@ +// +// Copyright 2013 Ettus Research LLC +// +// Original ADF4001 driver written by: bistromath +//                                     Mar 1, 2013 +// +// Re-used and re-licensed with permission. +// +// 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 "adf4001_ctrl.hpp" + +#include <uhd/utils/msg.hpp> +#include <iostream> +#include <iomanip> + +using namespace uhd; +using namespace uhd::usrp; + +adf4001_regs_t::adf4001_regs_t(void) { +    ref_counter = 0; +    n = 0; +    charge_pump_current_1 = 0; +    charge_pump_current_2 = 0; +    anti_backlash_width = ANTI_BACKLASH_WIDTH_2_9NS; +    lock_detect_precision = LOCK_DETECT_PRECISION_3CYC; +    charge_pump_gain = CHARGE_PUMP_GAIN_1; +    counter_reset = COUNTER_RESET_NORMAL; +    power_down = POWER_DOWN_NORMAL; +    muxout = MUXOUT_TRISTATE_OUT; +    phase_detector_polarity = PHASE_DETECTOR_POLARITY_NEGATIVE; +    charge_pump_mode = CHARGE_PUMP_TRISTATE; +    fastlock_mode = FASTLOCK_MODE_DISABLED; +    timer_counter_control = TIMEOUT_3CYC; +} + + +boost::uint32_t adf4001_regs_t::get_reg(boost::uint8_t addr) { +    boost::uint32_t reg = 0; +    switch (addr) { +    case 0: +        reg |= (boost::uint32_t(ref_counter)         & 0x003FFF) << 2; +        reg |= (boost::uint32_t(anti_backlash_width) & 0x000003) << 16; +        reg |= (boost::uint32_t(lock_detect_precision) & 0x000001) << 20; +        break; +    case 1: +        reg |= (boost::uint32_t(n) & 0x001FFF) << 8; +        reg |= (boost::uint32_t(charge_pump_gain) & 0x000001) << 21; +        break; +    case 2: +        reg |= (boost::uint32_t(counter_reset) & 0x000001) << 2; +        reg |= (boost::uint32_t(power_down) & 0x000001) << 3; +        reg |= (boost::uint32_t(muxout) & 0x000007) << 4; +        reg |= (boost::uint32_t(phase_detector_polarity) & 0x000001) << 7; +        reg |= (boost::uint32_t(charge_pump_mode) & 0x000001) << 8; +        reg |= (boost::uint32_t(fastlock_mode) & 0x000003) << 9; +        reg |= (boost::uint32_t(timer_counter_control) & 0x00000F) << 11; +        reg |= (boost::uint32_t(charge_pump_current_1) & 0x000007) << 15; +        reg |= (boost::uint32_t(charge_pump_current_2) & 0x000007) << 18; +        reg |= (boost::uint32_t(power_down) & 0x000002) << 21; +        break; +    case 3: +        reg |= (boost::uint32_t(counter_reset) & 0x000001) << 2; +        reg |= (boost::uint32_t(power_down) & 0x000001) << 3; +        reg |= (boost::uint32_t(muxout) & 0x000007) << 4; +        reg |= (boost::uint32_t(phase_detector_polarity) & 0x000001) << 7; +        reg |= (boost::uint32_t(charge_pump_mode) & 0x000001) << 8; +        reg |= (boost::uint32_t(fastlock_mode) & 0x000003) << 9; +        reg |= (boost::uint32_t(timer_counter_control) & 0x00000F) << 11; +        reg |= (boost::uint32_t(charge_pump_current_1) & 0x000007) << 15; +        reg |= (boost::uint32_t(charge_pump_current_2) & 0x000007) << 18; +        reg |= (boost::uint32_t(power_down) & 0x000002) << 21; +        break; +    default: +        break; +    } + +    reg |= (boost::uint32_t(addr) & 0x03); + +    return reg; +} + + +adf4001_ctrl::adf4001_ctrl(spi_core_3000::sptr _spi, int slaveno): +    spi_iface(_spi), +    slaveno(slaveno) +    { + +    spi_config.mosi_edge = spi_config_t::EDGE_RISE; + +    //set defaults +    adf4001_regs.ref_counter = 1; +    adf4001_regs.n = 4; +    adf4001_regs.charge_pump_current_1 = 7; +    adf4001_regs.charge_pump_current_2 = 7; +    adf4001_regs.muxout = adf4001_regs_t::MUXOUT_DLD; +    adf4001_regs.counter_reset = adf4001_regs_t::COUNTER_RESET_NORMAL; +    adf4001_regs.phase_detector_polarity = adf4001_regs_t::PHASE_DETECTOR_POLARITY_POSITIVE; +    adf4001_regs.charge_pump_mode = adf4001_regs_t::CHARGE_PUMP_TRISTATE; + +    //everything else should be defaults + +    program_regs(); +} + +void adf4001_ctrl::set_lock_to_ext_ref(bool external) { +    if(external) { +        adf4001_regs.charge_pump_mode = adf4001_regs_t::CHARGE_PUMP_NORMAL; +    } else { +        adf4001_regs.charge_pump_mode = adf4001_regs_t::CHARGE_PUMP_TRISTATE; +    } + +    program_regs(); +} + +void adf4001_ctrl::program_regs(void) { +    //no control over CE, only LE, therefore we use the initialization latch method +    write_reg(3); +    boost::this_thread::sleep(boost::posix_time::microseconds(1)); + +    //write R counter latch (0) +    write_reg(0); +    boost::this_thread::sleep(boost::posix_time::microseconds(1)); + +    //write N counter latch (1) +    write_reg(1); +    boost::this_thread::sleep(boost::posix_time::microseconds(1)); +} + + +void adf4001_ctrl::write_reg(boost::uint8_t addr) { +    boost::uint32_t reg = adf4001_regs.get_reg(addr); //load the reg data + +        spi_iface->transact_spi(slaveno, +                                spi_config, +                                reg, +                                24, +                                false); +} diff --git a/host/lib/usrp/common/adf4001_ctrl.hpp b/host/lib/usrp/common/adf4001_ctrl.hpp new file mode 100644 index 000000000..a16cff3fa --- /dev/null +++ b/host/lib/usrp/common/adf4001_ctrl.hpp @@ -0,0 +1,142 @@ +// +// Copyright 2013 Ettus Research LLC +// +// Original ADF4001 driver written by: bistromath +//                                     Mar 1, 2013 +// +// Re-used and re-licensed with permission. +// +// 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/>. +// + +#ifndef INCLUDED_LIBUHD_USRP_COMMON_ADF4001_HPP +#define INCLUDED_LIBUHD_USRP_COMMON_ADF4001_HPP + +#include "spi_core_3000.hpp" +#include <uhd/types/serial.hpp> +#include <boost/cstdint.hpp> +#include <boost/thread/thread.hpp> + +namespace uhd { namespace usrp { + +class adf4001_regs_t { +public: + +    /* Function prototypes */ +    boost::uint32_t get_reg(boost::uint8_t addr); +    adf4001_regs_t(void); + +    /* Register values / addresses */ +    boost::uint16_t ref_counter; //14 bits +    boost::uint16_t n; //13 bits +    boost::uint8_t charge_pump_current_1; //3 bits +    boost::uint8_t charge_pump_current_2; //3 bits + +    enum anti_backlash_width_t { +        ANTI_BACKLASH_WIDTH_2_9NS = 0, +        ANTI_BACKLASH_WIDTH_1_3NS = 1, +        ANTI_BACKLASH_WIDTH_6_0NS = 2, +        ANTI_BACKLASH_WIDTH_2_9NS_WAT = 3 +    }; +    anti_backlash_width_t anti_backlash_width; + +    enum lock_detect_precision_t { +        LOCK_DETECT_PRECISION_3CYC = 0, +        LOCK_DETECT_PRECISION_5CYC = 1 +    }; +    lock_detect_precision_t lock_detect_precision; +    enum charge_pump_gain_t { +        CHARGE_PUMP_GAIN_1 = 0, +        CHARGE_PUMP_GAIN_2 = 1 +    }; +    charge_pump_gain_t charge_pump_gain; +    enum counter_reset_t { +        COUNTER_RESET_NORMAL = 0, +        COUNTER_RESET_RESET = 1 +    }; +    counter_reset_t    counter_reset; +    enum power_down_t { +        POWER_DOWN_NORMAL = 0, +        POWER_DOWN_ASYNC = 1, +        POWER_DOWN_SYNC = 3 +    }; +    power_down_t power_down; +    enum muxout_t { +        MUXOUT_TRISTATE_OUT = 0, +        MUXOUT_DLD = 1, +        MUXOUT_NDIV = 2, +        MUXOUT_AVDD = 3, +        MUXOUT_RDIV = 4, +        MUXOUT_NCH_OD_ALD = 5, +        MUXOUT_SDO = 6, +        MUXOUT_GND = 7 +    }; +    muxout_t muxout; +    enum phase_detector_polarity_t { +        PHASE_DETECTOR_POLARITY_NEGATIVE = 0, +        PHASE_DETECTOR_POLARITY_POSITIVE = 1 +    }; +    phase_detector_polarity_t phase_detector_polarity; +    enum charge_pump_mode_t { +        CHARGE_PUMP_NORMAL = 0, +        CHARGE_PUMP_TRISTATE = 1 +    }; +    charge_pump_mode_t charge_pump_mode; +    enum fastlock_mode_t { +        FASTLOCK_MODE_DISABLED = 0, +        FASTLOCK_MODE_1 = 1, +        FASTLOCK_MODE_2 = 2 +    }; +    fastlock_mode_t fastlock_mode; +    enum timer_counter_control_t { +        TIMEOUT_3CYC = 0, +        TIMEOUT_7CYC = 1, +        TIMEOUT_11CYC = 2, +        TIMEOUT_15CYC = 3, +        TIMEOUT_19CYC = 4, +        TIMEOUT_23CYC = 5, +        TIMEOUT_27CYC = 6, +        TIMEOUT_31CYC = 7, +        TIMEOUT_35CYC = 8, +        TIMEOUT_39CYC = 9, +        TIMEOUT_43CYC = 10, +        TIMEOUT_47CYC = 11, +        TIMEOUT_51CYC = 12, +        TIMEOUT_55CYC = 13, +        TIMEOUT_59CYC = 14, +        TIMEOUT_63CYC = 15, +    }; +    timer_counter_control_t timer_counter_control; +}; + + +class adf4001_ctrl { +public: + +    adf4001_ctrl(spi_core_3000::sptr _spi, int slaveno); +    void set_lock_to_ext_ref(bool external); + +private: +    spi_core_3000::sptr spi_iface; +    int slaveno; +    spi_config_t spi_config; +    adf4001_regs_t adf4001_regs; + +    void program_regs(void); +    void write_reg(boost::uint8_t addr); +}; + +}} + +#endif diff --git a/host/lib/usrp/common/recv_packet_demuxer_3000.hpp b/host/lib/usrp/common/recv_packet_demuxer_3000.hpp index 9de3666dd..4fb6c4604 100644 --- a/host/lib/usrp/common/recv_packet_demuxer_3000.hpp +++ b/host/lib/usrp/common/recv_packet_demuxer_3000.hpp @@ -92,7 +92,10 @@ namespace uhd{ namespace usrp{                      if (new_sid != sid)                      {                          boost::mutex::scoped_lock l(mutex); -                        _queues[new_sid].push(buff); +                        if (_queues.count(new_sid) == 0) UHD_MSG(error) +                            << "recv packet demuxer unexpected sid 0x" << std::hex << new_sid << std::dec +                            << std::endl; +                        else _queues[new_sid].push(buff);                          buff.reset();                      }                  } @@ -102,6 +105,15 @@ namespace uhd{ namespace usrp{              return buff;          } +        void realloc_sid(const boost::uint32_t sid) +        { +            boost::mutex::scoped_lock l(mutex); +            while(not _queues[sid].empty()) //allocated and clears if already allocated +            { +                _queues[sid].pop(); +            } +        } +          typedef std::queue<transport::managed_recv_buffer::sptr> queue_type_t;          std::map<boost::uint32_t, queue_type_t> _queues;          transport::zero_copy_if::sptr _xport;  | 
