aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/x300/x300_impl.hpp
blob: 600d224a545104fae606f6ad3aa6737c9426b4f3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
//
// Copyright 2013-2016 Ettus Research LLC
// Copyright 2018 Ettus Research, a National Instruments Company
// Copyright 2019 Ettus Research, a National Instruments Brand
//
// SPDX-License-Identifier: GPL-3.0-or-later
//

#ifndef INCLUDED_X300_IMPL_HPP
#define INCLUDED_X300_IMPL_HPP

#include "x300_clock_ctrl.hpp"
#include "x300_conn_mgr.hpp"
#include "x300_defaults.hpp"
#include "x300_device_args.hpp"
#include "x300_fw_common.h"
#include "x300_mb_controller.hpp"
#include "x300_mboard_type.hpp"
#include "x300_regs.hpp"
#include <uhd/property_tree.hpp>
#include <uhd/types/device_addr.hpp>
#include <uhd/types/sensors.hpp>
#include <uhd/types/wb_iface.hpp>
#include <uhd/usrp/subdev_spec.hpp>
#include <uhd/utils/tasks.hpp>
#include <uhdlib/rfnoc/chdr_types.hpp>
#include <uhdlib/rfnoc/clock_iface.hpp>
#include <uhdlib/rfnoc/mb_iface.hpp>
#include <uhdlib/rfnoc/mgmt_portal.hpp>
#include <uhdlib/rfnoc/rfnoc_common.hpp>
#include <uhdlib/rfnoc/rfnoc_device.hpp>
#include <uhdlib/transport/links.hpp>
#include <uhdlib/usrp/cores/i2c_core_100_wb32.hpp>
#include <uhdlib/usrp/cores/spi_core_3000.hpp>
#include <atomic>
#include <functional>
#include <memory>
#include <mutex>


uhd::device_addrs_t x300_find(const uhd::device_addr_t& hint_);

class x300_impl : public uhd::rfnoc::detail::rfnoc_device
{
public:
    x300_impl(const uhd::device_addr_t&);
    void setup_mb(const size_t which, const uhd::device_addr_t&);
    ~x300_impl(void);

    /**************************************************************************
     * rfnoc_device API
     *************************************************************************/
    virtual uhd::rfnoc::mb_iface& get_mb_iface(const size_t mb_idx)
    {
        if (mb_idx >= _mb_ifaces.size()) {
            throw uhd::index_error(
                std::string("Cannot get mb_iface, invalid motherboard index: ")
                + std::to_string(mb_idx));
        }
        return _mb_ifaces.at(mb_idx);
    }

private:
    /**************************************************************************
     * Types
     *************************************************************************/
    // vector of member objects per motherboard
    struct mboard_members_t
    {
        uhd::usrp::x300::x300_device_args_t args;

        //! Remote Device ID for this motherboard
        uhd::rfnoc::device_id_t device_id;

        bool initialization_done = false;
        uhd::task::sptr claimer_task;
        uhd::usrp::x300::xport_path_t xport_path;
        uhd::device_addr_t send_args;
        uhd::device_addr_t recv_args;

        // perifs in the zpu
        uhd::wb_iface::sptr zpu_ctrl;
        spi_core_3000::sptr zpu_spi;
        i2c_core_100_wb32::sptr zpu_i2c;

        // other perifs on mboard
        x300_clock_ctrl::sptr clock;

        // which FPGA image is loaded
        std::string loaded_fpga_image;

        size_t hw_rev;
        std::string current_refclk_src;

        uhd::usrp::x300::conn_manager::sptr conn_mgr;
    };

    //! X300-Specific Implementation of rfnoc::mb_iface
    class x300_mb_iface : public uhd::rfnoc::mb_iface
    {
    public:
        x300_mb_iface(uhd::usrp::x300::conn_manager::sptr conn_mgr,
            const double radio_clk_freq,
            const uhd::rfnoc::device_id_t remote_dev_id);
        ~x300_mb_iface();
        uint16_t get_proto_ver();
        uhd::rfnoc::chdr_w_t get_chdr_w();
        uhd::endianness_t get_endianness(const uhd::rfnoc::device_id_t local_device_id);
        uhd::rfnoc::device_id_t get_remote_device_id();
        std::vector<uhd::rfnoc::device_id_t> get_local_device_ids();
        uhd::transport::adapter_id_t get_adapter_id(const uhd::rfnoc::device_id_t local_device_id);
        void reset_network();
        uhd::rfnoc::clock_iface::sptr get_clock_iface(const std::string& clock_name);
        uhd::rfnoc::chdr_ctrl_xport::sptr make_ctrl_transport(
            uhd::rfnoc::device_id_t local_device_id,
            const uhd::rfnoc::sep_id_t& local_epid);
        uhd::rfnoc::chdr_rx_data_xport::uptr make_rx_data_transport(
            uhd::rfnoc::mgmt::mgmt_portal& mgmt_portal,
            const uhd::rfnoc::sep_addr_pair_t& addrs,
            const uhd::rfnoc::sep_id_pair_t& epids,
            const uhd::rfnoc::sw_buff_t pyld_buff_fmt,
            const uhd::rfnoc::sw_buff_t mdata_buff_fmt,
            const uhd::device_addr_t& xport_args);
        uhd::rfnoc::chdr_tx_data_xport::uptr make_tx_data_transport(
            uhd::rfnoc::mgmt::mgmt_portal& mgmt_portal,
            const uhd::rfnoc::sep_addr_pair_t& addrs,
            const uhd::rfnoc::sep_id_pair_t& epids,
            const uhd::rfnoc::sw_buff_t pyld_buff_fmt,
            const uhd::rfnoc::sw_buff_t mdata_buff_fmt,
            const uhd::device_addr_t& xport_args);

    private:
        const uhd::rfnoc::device_id_t _remote_dev_id;
        std::unordered_map<uhd::rfnoc::device_id_t, uhd::transport::adapter_id_t> _adapter_map;
        uhd::rfnoc::clock_iface::sptr _bus_clk;
        uhd::rfnoc::clock_iface::sptr _radio_clk;
        uhd::usrp::x300::conn_manager::sptr _conn_mgr;
    };

    /**************************************************************************
     * Private Methods
     *************************************************************************/
    void check_fw_compat(const uhd::fs_path& mb_path, const mboard_members_t& members);
    void check_fpga_compat(const uhd::fs_path& mb_path, const mboard_members_t& members);

    /**************************************************************************
     * Private Attributes
     *************************************************************************/
    std::vector<mboard_members_t> _mb;

    std::mutex _mb_iface_mutex;
    std::unordered_map<size_t, x300_mb_iface> _mb_ifaces;

    static const uhd::rfnoc::chdr::chdr_packet_factory _pkt_factory;
};

#endif /* INCLUDED_X300_IMPL_HPP */