1 // 2 // Copyright 2013-2016 Ettus Research LLC 3 // Copyright 2018 Ettus Research, a National Instruments Company 4 // Copyright 2019 Ettus Research, a National Instruments Brand 5 // 6 // SPDX-License-Identifier: GPL-3.0-or-later 7 // 8 9 #ifndef INCLUDED_X300_IMPL_HPP 10 #define INCLUDED_X300_IMPL_HPP 11 12 #include "x300_clock_ctrl.hpp" 13 #include "x300_conn_mgr.hpp" 14 #include "x300_defaults.hpp" 15 #include "x300_device_args.hpp" 16 #include "x300_fw_common.h" 17 #include "x300_mb_controller.hpp" 18 #include "x300_mboard_type.hpp" 19 #include "x300_regs.hpp" 20 #include <uhd/property_tree.hpp> 21 #include <uhd/rfnoc/chdr_types.hpp> 22 #include <uhd/types/device_addr.hpp> 23 #include <uhd/types/sensors.hpp> 24 #include <uhd/types/wb_iface.hpp> 25 #include <uhd/usrp/subdev_spec.hpp> 26 #include <uhd/utils/tasks.hpp> 27 #include <uhdlib/rfnoc/clock_iface.hpp> 28 #include <uhdlib/rfnoc/mb_iface.hpp> 29 #include <uhdlib/rfnoc/mgmt_portal.hpp> 30 #include <uhdlib/rfnoc/rfnoc_common.hpp> 31 #include <uhdlib/rfnoc/rfnoc_device.hpp> 32 #include <uhdlib/transport/links.hpp> 33 #include <uhdlib/usrp/cores/i2c_core_100_wb32.hpp> 34 #include <uhdlib/usrp/cores/spi_core_3000.hpp> 35 #include <atomic> 36 #include <functional> 37 #include <memory> 38 #include <mutex> 39 40 41 uhd::device_addrs_t x300_find(const uhd::device_addr_t& hint_); 42 43 class x300_impl : public uhd::rfnoc::detail::rfnoc_device 44 { 45 public: 46 x300_impl(const uhd::device_addr_t&); 47 void setup_mb(const size_t which, const uhd::device_addr_t&); 48 ~x300_impl(void); 49 50 /************************************************************************** 51 * rfnoc_device API 52 *************************************************************************/ get_mb_iface(const size_t mb_idx)53 virtual uhd::rfnoc::mb_iface& get_mb_iface(const size_t mb_idx) 54 { 55 if (mb_idx >= _mb_ifaces.size()) { 56 throw uhd::index_error( 57 std::string("Cannot get mb_iface, invalid motherboard index: ") 58 + std::to_string(mb_idx)); 59 } 60 return _mb_ifaces.at(mb_idx); 61 } 62 63 private: 64 /************************************************************************** 65 * Types 66 *************************************************************************/ 67 // vector of member objects per motherboard 68 struct mboard_members_t 69 { 70 uhd::usrp::x300::x300_device_args_t args; 71 72 //! Remote Device ID for this motherboard 73 uhd::rfnoc::device_id_t device_id; 74 75 bool initialization_done = false; 76 uhd::task::sptr claimer_task; 77 uhd::usrp::x300::xport_path_t xport_path; 78 uhd::device_addr_t send_args; 79 uhd::device_addr_t recv_args; 80 81 // perifs in the zpu 82 uhd::wb_iface::sptr zpu_ctrl; 83 spi_core_3000::sptr zpu_spi; 84 i2c_core_100_wb32::sptr zpu_i2c; 85 86 // other perifs on mboard 87 x300_clock_ctrl::sptr clock; 88 89 // which FPGA image is loaded 90 std::string loaded_fpga_image; 91 92 size_t hw_rev; 93 94 uhd::usrp::x300::conn_manager::sptr conn_mgr; 95 }; 96 97 //! X300-Specific Implementation of rfnoc::mb_iface 98 class x300_mb_iface : public uhd::rfnoc::mb_iface 99 { 100 public: 101 x300_mb_iface(uhd::usrp::x300::conn_manager::sptr conn_mgr, 102 const double radio_clk_freq, 103 const uhd::rfnoc::device_id_t remote_dev_id); 104 ~x300_mb_iface(); 105 uint16_t get_proto_ver(); 106 uhd::rfnoc::chdr_w_t get_chdr_w(); 107 uhd::endianness_t get_endianness(const uhd::rfnoc::device_id_t local_device_id); 108 uhd::rfnoc::device_id_t get_remote_device_id(); 109 std::vector<uhd::rfnoc::device_id_t> get_local_device_ids(); 110 uhd::transport::adapter_id_t get_adapter_id( 111 const uhd::rfnoc::device_id_t local_device_id); 112 void reset_network(); 113 uhd::rfnoc::clock_iface::sptr get_clock_iface(const std::string& clock_name); 114 uhd::rfnoc::chdr_ctrl_xport::sptr make_ctrl_transport( 115 uhd::rfnoc::device_id_t local_device_id, 116 const uhd::rfnoc::sep_id_t& local_epid); 117 uhd::rfnoc::chdr_rx_data_xport::uptr make_rx_data_transport( 118 uhd::rfnoc::mgmt::mgmt_portal& mgmt_portal, 119 const uhd::rfnoc::sep_addr_pair_t& addrs, 120 const uhd::rfnoc::sep_id_pair_t& epids, 121 const uhd::rfnoc::sw_buff_t pyld_buff_fmt, 122 const uhd::rfnoc::sw_buff_t mdata_buff_fmt, 123 const uhd::device_addr_t& xport_args, 124 const std::string& streamer_id); 125 uhd::rfnoc::chdr_tx_data_xport::uptr make_tx_data_transport( 126 uhd::rfnoc::mgmt::mgmt_portal& mgmt_portal, 127 const uhd::rfnoc::sep_addr_pair_t& addrs, 128 const uhd::rfnoc::sep_id_pair_t& epids, 129 const uhd::rfnoc::sw_buff_t pyld_buff_fmt, 130 const uhd::rfnoc::sw_buff_t mdata_buff_fmt, 131 const uhd::device_addr_t& xport_args, 132 const std::string& streamer_id); 133 134 private: 135 const uhd::rfnoc::device_id_t _remote_dev_id; 136 std::unordered_map<uhd::rfnoc::device_id_t, uhd::transport::adapter_id_t> 137 _adapter_map; 138 uhd::rfnoc::clock_iface::sptr _bus_clk; 139 uhd::rfnoc::clock_iface::sptr _radio_clk; 140 uhd::usrp::x300::conn_manager::sptr _conn_mgr; 141 }; 142 143 /************************************************************************** 144 * Private Methods 145 *************************************************************************/ 146 void check_fw_compat(const uhd::fs_path& mb_path, const mboard_members_t& members); 147 void check_fpga_compat(const uhd::fs_path& mb_path, const mboard_members_t& members); 148 149 /************************************************************************** 150 * Private Attributes 151 *************************************************************************/ 152 std::vector<mboard_members_t> _mb; 153 154 std::mutex _mb_iface_mutex; 155 std::unordered_map<size_t, x300_mb_iface> _mb_ifaces; 156 157 static const uhd::rfnoc::chdr::chdr_packet_factory _pkt_factory; 158 }; 159 160 #endif /* INCLUDED_X300_IMPL_HPP */ 161