// // 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 . // #ifndef INCLUDED_N230_RESOURCE_MANAGER_HPP #define INCLUDED_N230_RESOURCE_MANAGER_HPP #include "radio_ctrl_core_3000.hpp" #include "spi_core_3000.hpp" #include "gpio_atr_3000.hpp" #include "rx_vita_core_3000.hpp" #include "tx_vita_core_3000.hpp" #include "time_core_3000.hpp" #include "rx_dsp_core_3000.hpp" #include "tx_dsp_core_3000.hpp" #include "user_settings_core_3000.hpp" #include "ad9361_ctrl.hpp" #include "ad936x_manager.hpp" #include #include #include #include #include #include #include #include "usrp3_fw_ctrl_iface.hpp" #include "n230_clk_pps_ctrl.hpp" #include "n230_cores.hpp" #include "n230_fpga_defs.h" #include "n230_frontend_ctrl.hpp" #include "n230_uart.hpp" namespace uhd { namespace usrp { namespace n230 { enum n230_eth_port_t { ETH0, ETH1 }; enum n230_eth_pref_t { PRI_ETH, SEC_ETH }; enum n230_endpoint_t { RADIO_TX_DATA, RADIO_RX_DATA, RADIO_CONTROL, CORE, GPS_UART }; enum n230_ver_src_t { SOFTWARE, FIRMWARE, FPGA }; enum n230_version_t { COMPAT_MAJOR, COMPAT_MINOR }; enum n230_data_dir_t { RX_DATA, TX_DATA }; //Radio resources class radio_resource_t : public boost::noncopyable { public: radio_ctrl_core_3000::sptr ctrl; gpio_atr::gpio_atr_3000::sptr gpio_atr; time_core_3000::sptr time; rx_vita_core_3000::sptr framer; rx_dsp_core_3000::sptr ddc; tx_vita_core_3000::sptr deframer; tx_dsp_core_3000::sptr duc; user_settings_core_3000::sptr user_settings; }; class n230_resource_manager : public boost::noncopyable { public: //Methods n230_resource_manager(const std::vector ip_addrs, const bool safe_mode); virtual ~n230_resource_manager(); static bool is_device_claimed(uhd::usrp::usrp3::usrp3_fw_ctrl_iface::sptr fw_ctrl); inline bool is_device_claimed() { if (_fw_ctrl.get()) { return is_device_claimed(_fw_ctrl); } else { return false; } } inline boost::uint32_t get_version(n230_ver_src_t src, n230_version_t type) { switch (src) { case FPGA: return _fpga_version.get(type); case FIRMWARE: return _fw_version.get(type); default: return 0; } } inline const std::string get_version_hash(n230_ver_src_t src) { switch (src) { case FPGA: return _fpga_version.get_hash_str(); case FIRMWARE: return _fw_version.get_hash_str(); default: return ""; } } //Firmware control interface inline wb_iface& get_fw_ctrl() const { return *_fw_ctrl; } inline wb_iface::sptr get_fw_ctrl_sptr() { return _fw_ctrl; } //Core settings control interface inline radio_ctrl_core_3000& get_core_ctrl() const { return *_core_ctrl; } inline radio_ctrl_core_3000::sptr get_core_ctrl_sptr() { return _core_ctrl; } //AD931 control interface inline ad9361_ctrl& get_codec_ctrl() const { return *_codec_ctrl; } inline ad9361_ctrl::sptr get_codec_ctrl_sptr() { return _codec_ctrl; } inline uhd::usrp::ad936x_manager& get_codec_mgr() const { return *_codec_mgr; } //Clock PPS controls inline n230_ref_pll_ctrl& get_ref_pll_ctrl() const { return *_ref_pll_ctrl; } inline n230_ref_pll_ctrl::sptr get_ref_pll_ctrl_sptr() { return _ref_pll_ctrl; } //Clock PPS controls inline n230_clk_pps_ctrl& get_clk_pps_ctrl() const { return *_clk_pps_ctrl; } inline n230_clk_pps_ctrl::sptr get_clk_pps_ctrl_sptr() { return _clk_pps_ctrl; } //Front-end control inline n230_frontend_ctrl& get_frontend_ctrl() const { return *_frontend_ctrl; } inline n230_frontend_ctrl::sptr get_frontend_ctrl_sptr() { return _frontend_ctrl; } //MiniSAS GPIO control inline gpio_atr::gpio_atr_3000::sptr get_minisas_gpio_ctrl_sptr(size_t idx) { return idx == 0 ? _ms0_gpio : _ms1_gpio; } inline gpio_atr::gpio_atr_3000& get_minisas_gpio_ctrl(size_t idx) { return *get_minisas_gpio_ctrl_sptr(idx); } //GPSDO control inline bool is_gpsdo_present() { return _gps_ctrl.get() and _gps_ctrl->gps_detected(); } inline uhd::gps_ctrl::sptr get_gps_ctrl(void) { return _gps_ctrl; } inline radio_resource_t& get_radio(size_t instance) { return _radios[instance]; } //Transport to stream data transport::zero_copy_if::sptr create_transport( n230_data_dir_t direction, size_t radio_instance, const device_addr_t ¶ms, sid_t& sid, transport::udp_zero_copy::buff_params& buff_out_params); //Misc inline double get_max_link_rate() { return fpga::N230_LINK_RATE_BPS * _eth_conns.size(); } private: struct ver_info_t { boost::uint8_t compat_major; boost::uint16_t compat_minor; boost::uint32_t version_hash; boost::uint32_t get(n230_version_t type) { switch (type) { case COMPAT_MAJOR: return compat_major; case COMPAT_MINOR: return compat_minor; default: return 0; } } const std::string get_hash_str() { return (str(boost::format("%07x%s") % (version_hash & 0x0FFFFFFF) % ((version_hash & 0xF0000000) ? "(modified)" : ""))); } }; struct n230_eth_conn_t { std::string ip_addr; n230_eth_port_t type; }; //-- Functions -- void _claimer_loop(); void _initialize_radio(size_t instance); std::string _get_fpga_upgrade_msg(); void _check_fw_compat(); void _check_fpga_compat(); const sid_t _generate_sid( const n230_endpoint_t type, const n230_eth_port_t xport, size_t instance = 0); transport::zero_copy_if::sptr _create_transport( const n230_eth_conn_t& eth_conn, const sid_t& sid, const device_addr_t &buff_params, transport::udp_zero_copy::buff_params& buff_params_out); void _program_dispatcher( transport::zero_copy_if& xport, const n230_eth_port_t port, const sid_t& sid); void _reset_codec_digital_interface(); bool _radio_register_loopback_self_test(wb_iface::sptr iface); bool _radio_data_loopback_self_test(wb_iface::sptr iface); inline const n230_eth_conn_t& _get_conn(const n230_eth_pref_t pref) { if (_eth_conns.size() == 1) return _eth_conns[0]; else return _eth_conns[(pref==PRI_ETH)?0:1]; } //-- Members -- std::vector _eth_conns; const bool _safe_mode; ver_info_t _fw_version; ver_info_t _fpga_version; //Firmware register interface uhd::usrp::usrp3::usrp3_fw_ctrl_iface::sptr _fw_ctrl; uhd::task::sptr _claimer_task; static boost::mutex _claimer_mutex; //All claims and checks in this process are serialized //Transport boost::uint8_t _last_host_enpoint; //Radio settings interface radio_ctrl_core_3000::sptr _core_ctrl; n230_core_spi_core::sptr _core_spi_ctrl; ad9361_ctrl::sptr _codec_ctrl; uhd::usrp::ad936x_manager::sptr _codec_mgr; //Core Registers fpga::core_radio_ctrl_reg_t _core_radio_ctrl_reg; fpga::core_misc_reg_t _core_misc_reg; fpga::core_pps_sel_reg_t _core_pps_sel_reg; fpga::core_status_reg_t _core_status_reg; //Radio peripherals radio_resource_t _radios[fpga::NUM_RADIOS]; //Misc IO peripherals n230_ref_pll_ctrl::sptr _ref_pll_ctrl; n230_clk_pps_ctrl::sptr _clk_pps_ctrl; n230_frontend_ctrl::sptr _frontend_ctrl; //miniSAS GPIO gpio_atr::gpio_atr_3000::sptr _ms0_gpio; gpio_atr::gpio_atr_3000::sptr _ms1_gpio; //GPSDO n230_uart::sptr _gps_uart; uhd::gps_ctrl::sptr _gps_ctrl; }; }}} //namespace #endif //INCLUDED_N230_RESOURCE_MANAGER_HPP