diff options
author | Martin Braun <martin.braun@ettus.com> | 2016-08-01 18:17:41 -0700 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2016-08-09 12:42:52 -0700 |
commit | 3bf4b000f7d9a7f4af82c21753556ede7e8df6e3 (patch) | |
tree | 2228d7eb58c4d83d91192cb9b6a908e4e49f6317 /host/lib/usrp/x300/x300_radio_ctrl_impl.hpp | |
parent | c5b076173e2d866f3ee99c113a37183c5ec20f0b (diff) | |
download | uhd-3bf4b000f7d9a7f4af82c21753556ede7e8df6e3.tar.gz uhd-3bf4b000f7d9a7f4af82c21753556ede7e8df6e3.tar.bz2 uhd-3bf4b000f7d9a7f4af82c21753556ede7e8df6e3.zip |
Merging RFNoC support for X310
Diffstat (limited to 'host/lib/usrp/x300/x300_radio_ctrl_impl.hpp')
-rw-r--r-- | host/lib/usrp/x300/x300_radio_ctrl_impl.hpp | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/host/lib/usrp/x300/x300_radio_ctrl_impl.hpp b/host/lib/usrp/x300/x300_radio_ctrl_impl.hpp new file mode 100644 index 000000000..f2150a982 --- /dev/null +++ b/host/lib/usrp/x300/x300_radio_ctrl_impl.hpp @@ -0,0 +1,198 @@ +// +// Copyright 2015-2016 Ettus Research +// +// 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_RFNOC_X300_RADIO_CTRL_IMPL_HPP +#define INCLUDED_LIBUHD_RFNOC_X300_RADIO_CTRL_IMPL_HPP + +#include "radio_ctrl_impl.hpp" +#include "x300_clock_ctrl.hpp" +#include "spi_core_3000.hpp" +#include "x300_adc_ctrl.hpp" +#include "x300_dac_ctrl.hpp" +#include "x300_regs.hpp" +#include "rx_frontend_core_3000.hpp" +#include "tx_frontend_core_200.hpp" +#include <uhd/usrp/dboard_eeprom.hpp> +#include <uhd/usrp/dboard_manager.hpp> +#include <uhd/usrp/gpio_defs.hpp> + +namespace uhd { + namespace rfnoc { + +/*! \brief Provide access to an X300 radio. + */ +class x300_radio_ctrl_impl : public radio_ctrl_impl +{ +public: + typedef boost::shared_ptr<x300_radio_ctrl_impl> sptr; + + /************************************************************************ + * Structors + ***********************************************************************/ + UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR_DECL(x300_radio_ctrl) + virtual ~x300_radio_ctrl_impl(); + + /************************************************************************ + * API calls + ***********************************************************************/ + double set_rate(double rate); + + void set_tx_antenna(const std::string &ant, const size_t chan); + void set_rx_antenna(const std::string &ant, const size_t chan); + + double set_tx_frequency(const double freq, const size_t chan); + double set_rx_frequency(const double freq, const size_t chan); + double get_tx_frequency(const size_t chan); + double get_rx_frequency(const size_t chan); + + double set_tx_gain(const double gain, const size_t chan); + double set_rx_gain(const double gain, const size_t chan); + + size_t get_chan_from_dboard_fe(const std::string &fe, const direction_t dir); + std::string get_dboard_fe_from_chan(const size_t chan, const direction_t dir); + + double get_output_samp_rate(size_t port); + + /************************************************************************ + * Hardware setup and control + ***********************************************************************/ + /*! Set up the radio. No API calls may be made before this one. + */ + void setup_radio( + uhd::i2c_iface::sptr zpu_i2c, x300_clock_ctrl::sptr clock, bool verbose); + + void reset_codec(); + + void self_test_adc( + boost::uint32_t ramp_time_ms = 100); + + static void extended_adc_test( + const std::vector<x300_radio_ctrl_impl::sptr>&, double duration_s); + + static void synchronize_dacs( + const std::vector<x300_radio_ctrl_impl::sptr>& radios); + + static double self_cal_adc_xfer_delay( + const std::vector<x300_radio_ctrl_impl::sptr>& radios, + x300_clock_ctrl::sptr clock, + boost::function<void(double)> wait_for_clk_locked, + bool apply_delay); + +protected: + virtual bool check_radio_config(); + +private: + class radio_regmap_t : public uhd::soft_regmap_t { + public: + typedef boost::shared_ptr<radio_regmap_t> sptr; + class misc_outs_reg_t : public uhd::soft_reg32_wo_t { + public: + UHD_DEFINE_SOFT_REG_FIELD(DAC_ENABLED, /*width*/ 1, /*shift*/ 0); //[0] + UHD_DEFINE_SOFT_REG_FIELD(DAC_RESET_N, /*width*/ 1, /*shift*/ 1); //[1] + UHD_DEFINE_SOFT_REG_FIELD(ADC_RESET, /*width*/ 1, /*shift*/ 2); //[2] + UHD_DEFINE_SOFT_REG_FIELD(ADC_DATA_DLY_STB, /*width*/ 1, /*shift*/ 3); //[3] + UHD_DEFINE_SOFT_REG_FIELD(ADC_DATA_DLY_VAL, /*width*/ 5, /*shift*/ 4); //[8:4] + UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER_ENABLED, /*width*/ 1, /*shift*/ 9); //[9] + UHD_DEFINE_SOFT_REG_FIELD(DAC_SYNC, /*width*/ 1, /*shift*/ 10); //[10] + + misc_outs_reg_t(): uhd::soft_reg32_wo_t(regs::sr_addr(regs::MISC_OUTS)) { + //Initial values + set(DAC_ENABLED, 0); + set(DAC_RESET_N, 0); + set(ADC_RESET, 0); + set(ADC_DATA_DLY_STB, 0); + set(ADC_DATA_DLY_VAL, 16); + set(ADC_CHECKER_ENABLED, 0); + set(DAC_SYNC, 0); + } + } misc_outs_reg; + + class misc_ins_reg_t : public uhd::soft_reg64_ro_t { + public: + UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER0_Q_LOCKED, /*width*/ 1, /*shift*/ 32); //[0] + UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER0_I_LOCKED, /*width*/ 1, /*shift*/ 33); //[1] + UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER1_Q_LOCKED, /*width*/ 1, /*shift*/ 34); //[2] + UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER1_I_LOCKED, /*width*/ 1, /*shift*/ 35); //[3] + UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER0_Q_ERROR, /*width*/ 1, /*shift*/ 36); //[4] + UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER0_I_ERROR, /*width*/ 1, /*shift*/ 37); //[5] + UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER1_Q_ERROR, /*width*/ 1, /*shift*/ 38); //[6] + UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER1_I_ERROR, /*width*/ 1, /*shift*/ 39); //[7] + + misc_ins_reg_t(): uhd::soft_reg64_ro_t(regs::RB_MISC_IO) { } + } misc_ins_reg; + + radio_regmap_t(int radio_num) : soft_regmap_t("radio" + boost::lexical_cast<std::string>(radio_num) + "_regmap") { + add_to_map(misc_outs_reg, "misc_outs_reg", PRIVATE); + add_to_map(misc_ins_reg, "misc_ins_reg", PRIVATE); + } + }; + + struct x300_regs { + static const uint32_t TX_FE_BASE = 224; + static const uint32_t RX_RE_BASE = 232; + }; + + void _update_atr_leds(const std::string &rx_ant); + + void _self_cal_adc_capture_delay(bool print_status); + + void _check_adc(const boost::uint32_t val); + + void set_rx_fe_corrections(const std::string &fe_name, const double lo_freq); + void set_tx_fe_corrections(const std::string &fe_name, const double lo_freq); + +private: // members + enum radio_connection_t { PRIMARY, SECONDARY }; + + radio_connection_t _radio_type; + std::string _radio_slot; + //! Radio clock rate is the rate at which the ADC and DAC are running at. + // Not necessarily this block's sampling rate (tick rate). + double _radio_clk_rate; + + radio_regmap_t::sptr _regs; + usrp::gpio_atr::gpio_atr_3000::sptr _leds; + spi_core_3000::sptr _spi; + x300_adc_ctrl::sptr _adc; + x300_dac_ctrl::sptr _dac; + usrp::gpio_atr::gpio_atr_3000::sptr _fp_gpio; + + std::map<size_t, usrp::dboard_eeprom_t> _db_eeproms; + usrp::dboard_manager::sptr _db_manager; + + struct rx_fe_perif { + std::string name; + std::string db_fe_name; + rx_frontend_core_3000::sptr core; + }; + struct tx_fe_perif { + std::string name; + std::string db_fe_name; + tx_frontend_core_200::sptr core; + }; + + std::map<size_t, rx_fe_perif> _rx_fe_map; + std::map<size_t, tx_fe_perif> _tx_fe_map; + + bool _ignore_cal_file; + +}; /* class radio_ctrl_impl */ + +}} /* namespace uhd::rfnoc */ + +#endif /* INCLUDED_LIBUHD_RFNOC_X300_RADIO_CTRL_IMPL_HPP */ +// vim: sw=4 et: |