// // Copyright 2019 Ettus Research, a National Instruments Brand // // SPDX-License-Identifier: GPL-3.0-or-later // #ifndef INCLUDED_LIBUHD_CLIENT_ZERO_HPP #define INCLUDED_LIBUHD_CLIENT_ZERO_HPP #include #include #include #include #include #include #include #include namespace uhd { namespace rfnoc { namespace detail { /*! * Class that uses a register_iface to read important configuration information from the * RFNoC backend registers */ class client_zero : public uhd::rfnoc::register_iface_holder { public: client_zero(register_iface::sptr reg); //! Definition of an edge in the static router struct edge_def_t { uint16_t src_blk_index; uint8_t src_blk_port; uint16_t dst_blk_index; uint8_t dst_blk_port; }; //! Contents of the backend status block configuration register struct block_config_info { uint8_t protover; uint8_t num_inputs; uint8_t num_outputs; uint8_t ctrl_fifo_size; uint8_t ctrl_max_async_msgs; uint8_t data_mtu; }; //! Return the RFNoC protocol version for this motherboard uint16_t get_proto_ver() { return _proto_ver; }; //! Return the device type uint16_t get_device_type() { return _device_type; }; //! Return the number of blocks in our RFNoC graph size_t get_num_blocks() { return _num_blocks; }; //! Return the number of stream endpoints in our RFNoC graph size_t get_num_stream_endpoints() { return _num_stream_endpoints; }; //! Return the number of transports available size_t get_num_transports() { return _num_transports; }; //! Return whether or not the device includes a CHDR crossbar bool has_chdr_crossbar() { return _has_chdr_crossbar; }; //! Return the number of edges in our graph (the number of static connections) size_t get_num_edges() { return _num_edges; }; //! Return a vector containing the edge definitions std::vector& get_adjacency_list() { return _adjacency_list; }; /*! Return the NOC ID of the block located at `portno` * * \throws uhd::index_error if no NOC block is connected to the port */ uint32_t get_noc_id(uint16_t portno); /*! Return whether the port is actively flushing * * \throws uhd::index_error if no NOC block is connected to the port * \return boolean status */ bool get_flush_active(uint16_t portno); /*! Return whether the port is done flushing * * \throws uhd::index_error if no NOC block is connected to the port * \return boolean status */ bool get_flush_done(uint16_t portno); /*! Returns once the port is done flushing * * Note: this function queries the port once every millisecond * * \param portno Port number * \param timeout time, in milliseconds, to poll before quitting * \throws uhd::index_error if no NOC block is connected to the port * \return boolean whether or not the flush had completed in the timeout period */ bool poll_flush_done(uint16_t portno, std::chrono::milliseconds timeout); /*! Set the port's hardware flush timeout * * \param timeout number of cycles the device waits for the flushing to complete * \param portno Port number * \throws uhd::index_error if no NOC block is connected to the port */ void set_flush_timeout(uint32_t timeout, uint16_t portno); /*! Send a request to flush a port * * \param portno Port number * \throws uhd::index_error if no NOC block is connected to the port */ void set_flush(uint16_t portno); /*! Go through the entire flush process for a port * * \param portno Port number * \throws uhd::index_error if no NOC block is connected to the port * \return whether or not the flush succeeded */ bool complete_flush(uint16_t portno); /*! Reset a port's control logic * * It is recommended to flush a port calling this. * * \param portno Port number * \throws uhd::index_error if no NOC block is connected to the port */ void reset_ctrl(uint16_t portno); /*! Reset a port's CHDR logic * * It is recommended to flush a port calling this. * * \param portno Port number * \throws uhd::index_error if no NOC block is connected to the port */ void reset_chdr(uint16_t portno); /*! Get the port's configuration information * * \return Struct containing configuration information */ block_config_info get_block_info(uint16_t portno); // TODO: handle callbacks? private: uint16_t _proto_ver; uint16_t _device_type; uint16_t _num_blocks; uint16_t _num_stream_endpoints; uint16_t _num_transports; bool _has_chdr_crossbar; uint16_t _num_edges; std::vector _adjacency_list; std::vector _get_adjacency_list(); /* Helper function to determine if the given port number has a block connected * * \throws uhd::index_error if no NOC block is connected to the port */ void _check_port_number(uint16_t portno); //! Translate port number to base address for the register uint32_t _get_port_base_addr(uint16_t portno); //! Helper function to get the backend control flush status flags uint32_t _get_flush_status_flags(uint16_t portno); }; }}} /* namespace uhd::rfnoc::detail */ #endif /* INCLUDED_LIBUHD_CLIENT_ZERO_HPP */