aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/x300/x300_mb_controller.hpp
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2019-07-03 20:15:35 -0700
committerMartin Braun <martin.braun@ettus.com>2019-11-26 12:16:25 -0800
commitc256b9df6502536c2e451e690f1ad5962c664d1a (patch)
treea83ad13e6f5978bbe14bb3ecf8294ba1e3d28db4 /host/lib/usrp/x300/x300_mb_controller.hpp
parent9a8435ed998fc5c65257f4c55768750b227ab19e (diff)
downloaduhd-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.hpp153
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