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