diff options
author | Martin Braun <martin.braun@ettus.com> | 2019-07-03 20:15:35 -0700 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2019-11-26 12:16:25 -0800 |
commit | c256b9df6502536c2e451e690f1ad5962c664d1a (patch) | |
tree | a83ad13e6f5978bbe14bb3ecf8294ba1e3d28db4 /host/lib/usrp/x300/x300_mb_controller.hpp | |
parent | 9a8435ed998fc5c65257f4c55768750b227ab19e (diff) | |
download | uhd-c256b9df6502536c2e451e690f1ad5962c664d1a.tar.gz uhd-c256b9df6502536c2e451e690f1ad5962c664d1a.tar.bz2 uhd-c256b9df6502536c2e451e690f1ad5962c664d1a.zip |
x300/mpmd: Port all RFNoC devices to the new RFNoC framework
Co-Authored-By: Alex Williams <alex.williams@ni.com>
Co-Authored-By: Sugandha Gupta <sugandha.gupta@ettus.com>
Co-Authored-By: Brent Stapleton <brent.stapleton@ettus.com>
Co-Authored-By: Ciro Nishiguchi <ciro.nishiguchi@ni.com>
Diffstat (limited to 'host/lib/usrp/x300/x300_mb_controller.hpp')
-rw-r--r-- | host/lib/usrp/x300/x300_mb_controller.hpp | 153 |
1 files changed, 140 insertions, 13 deletions
diff --git a/host/lib/usrp/x300/x300_mb_controller.hpp b/host/lib/usrp/x300/x300_mb_controller.hpp index 9a220ab00..53f166a0e 100644 --- a/host/lib/usrp/x300/x300_mb_controller.hpp +++ b/host/lib/usrp/x300/x300_mb_controller.hpp @@ -8,26 +8,45 @@ #define INCLUDED_LIBUHD_X300_MB_CONTROLLER_HPP #include "x300_clock_ctrl.hpp" +#include "x300_device_args.hpp" +#include "x300_radio_mbc_iface.hpp" +#include "x300_regs.hpp" #include <uhd/rfnoc/mb_controller.hpp> +#include <uhd/types/sensors.hpp> #include <uhd/types/wb_iface.hpp> +#include <uhd/usrp/gps_ctrl.hpp> +#include <unordered_set> namespace uhd { namespace rfnoc { /*! X300-Specific version of the mb_controller * * Reminder: There is one of these per motherboard. + * + * The X300 motherboard controller is responsible for: + * - Controlling the timekeeper + * - Controlling all time- and clock-related settings + * - Initialize and hold the GPS control */ class x300_mb_controller : public mb_controller { public: - x300_mb_controller(uhd::i2c_iface::sptr zpu_i2c, + /************************************************************************** + * Structors + *************************************************************************/ + x300_mb_controller(const size_t hw_rev, + const std::string product_name, + uhd::i2c_iface::sptr zpu_i2c, uhd::wb_iface::sptr zpu_ctrl, - x300_clock_ctrl::sptr clock_ctrl) - : _zpu_i2c(zpu_i2c), _zpu_ctrl(zpu_ctrl), _clock_ctrl(clock_ctrl) - { - // nop - } + x300_clock_ctrl::sptr clock_ctrl, + uhd::usrp::mboard_eeprom_t mb_eeprom, + uhd::usrp::x300::x300_device_args_t args); + + ~x300_mb_controller(); + /************************************************************************** + * X300-Specific APIs + *************************************************************************/ //! Return reference to the ZPU-owned I2C controller uhd::i2c_iface::sptr get_zpu_i2c() { @@ -40,30 +59,107 @@ public: //! Return reference to LMK clock controller x300_clock_ctrl::sptr get_clock_ctrl() { return _clock_ctrl; } + void register_reset_codec_cb(std::function<void(void)>&& reset_cb) + { + _reset_cbs.push_back(std::move(reset_cb)); + } + + void set_initialization_done() { _initialization_done = true; } + + void register_radio(uhd::usrp::x300::x300_radio_mbc_iface* radio) + { + _radio_refs.push_back(radio); + } + + /************************************************************************** + * Timekeeper API + *************************************************************************/ //! X300-specific version of the timekeeper controls + // + // The X300 controls timekeepers via the ZPU class x300_timekeeper : public mb_controller::timekeeper { public: - x300_timekeeper(uhd::wb_iface::sptr zpu_ctrl) : _zpu_ctrl(zpu_ctrl) {} - + x300_timekeeper(const size_t tk_idx, uhd::wb_iface::sptr zpu_ctrl, const double tick_rate) + : _tk_idx(tk_idx), _zpu_ctrl(zpu_ctrl) + { + set_tick_rate(tick_rate); + } uint64_t get_ticks_now(); - uint64_t get_ticks_last_pps(); - void set_ticks_now(const uint64_t ticks); - void set_ticks_next_pps(const uint64_t ticks); - void set_period(const uint64_t period_ns); private: + uint32_t get_tk_addr(const uint32_t tk_addr); + const size_t _tk_idx; uhd::wb_iface::sptr _zpu_ctrl; - }; + }; /* x300_timekeeper */ + + /************************************************************************** + * Motherboard Control API (see mb_controller.hpp) + *************************************************************************/ + void init(); + std::string get_mboard_name() const; + void set_time_source(const std::string& source); + std::string get_time_source() const; + std::vector<std::string> get_time_sources() const; + void set_clock_source(const std::string& source); + std::string get_clock_source() const; + std::vector<std::string> get_clock_sources() const; + void set_sync_source(const std::string& clock_source, const std::string& time_source); + void set_sync_source(const device_addr_t& sync_source); + device_addr_t get_sync_source() const; + std::vector<device_addr_t> get_sync_sources(); + void set_clock_source_out(const bool enb); + void set_time_source_out(const bool enb); + sensor_value_t get_sensor(const std::string& name); + std::vector<std::string> get_sensor_names(); + uhd::usrp::mboard_eeprom_t get_eeprom(); + bool synchronize(std::vector<mb_controller::sptr>& mb_controllers, + const uhd::time_spec_t& time_spec = uhd::time_spec_t(0.0), + const bool quiet = false); private: + //! Return a string X300::MB_CTRL#N + std::string get_unique_id(); + + //! Init GPS + void init_gps(); + + //! Reset all registered DACs and ADCs + void reset_codecs(); + + //! Wait until reference clock locks, or a timeout occurs + // + // \returns lock status + bool wait_for_clk_locked(uint32_t which, double timeout); + + //! Returns true if a PPS signal is detected + bool is_pps_present(); + + //! Return LMK lock status + bool get_ref_locked(); + + /*! Calibrate the ADC transfer delay + * + * This will try various clock delay settings to the ADC, and pick the one + * with the best BER performance. + */ + void self_cal_adc_xfer_delay(const bool apply_delay); + + void extended_adc_test(double duration_s); + /************************************************************************** * Attributes *************************************************************************/ + //! Hardware revision + const size_t _hw_rev; + + //! Product name (X310, X300) + const std::string _product_name; + //! Reference to the ZPU-owned I2C controller uhd::i2c_iface::sptr _zpu_i2c; @@ -72,6 +168,37 @@ private: //! Reference to LMK clock controller x300_clock_ctrl::sptr _clock_ctrl; + + //! State of the MB EEPROM + uhd::usrp::mboard_eeprom_t _mb_eeprom; + + //! Copy of the device args + uhd::usrp::x300::x300_device_args_t _args; + + //! Reference to clock control register + uhd::usrp::x300::fw_regmap_t::sptr _fw_regmap; + + //! Reference to GPS control + uhd::gps_ctrl::sptr _gps; + + //! Reference to all callbacks to reset the ADCs/DACs + std::vector<std::function<void(void)>> _reset_cbs; + + //! Current clock source (external, internal, gpsdo) + std::string _current_refclk_src; + + //! Current time source (external, internal, gpsdo) + std::string _current_time_src; + + //! Reference to radios on this motherboard + std::vector<uhd::usrp::x300::x300_radio_mbc_iface*> _radio_refs; + + //! List of available sensors + std::unordered_set<std::string> _sensors{"ref_locked"}; + + //! Flag to tell us if initialization is complete. Some functions behave + // differently after initialization. + bool _initialization_done = false; }; }} // namespace uhd::rfnoc |