diff options
| -rw-r--r-- | host/lib/usrp/mpmd/mpmd_impl.cpp | 30 | ||||
| -rw-r--r-- | mpm/python/usrp_mpm/dboard_manager/base.py | 38 | ||||
| -rw-r--r-- | mpm/python/usrp_mpm/periph_manager/base.py | 38 | 
3 files changed, 106 insertions, 0 deletions
| diff --git a/host/lib/usrp/mpmd/mpmd_impl.cpp b/host/lib/usrp/mpmd/mpmd_impl.cpp index 38a089788..93e777af2 100644 --- a/host/lib/usrp/mpmd/mpmd_impl.cpp +++ b/host/lib/usrp/mpmd/mpmd_impl.cpp @@ -106,6 +106,36 @@ namespace {                  );              })          ; + +        /*** Sensors ********************************************************/ +        auto sensor_list = +            mb->rpc->request_with_token<std::vector<std::string>>( +                "get_mb_sensors" +            ); +        UHD_LOG_DEBUG("MPMD", +            "Found " << sensor_list.size() << " motherboard sensors." +        ); +        for (const auto& sensor_name : sensor_list) { +            UHD_LOG_TRACE("MPMD", +                "Adding motherboard sensor `" << sensor_name << "'" +            ); +            tree->create<sensor_value_t>( +                    mb_path / "sensors" / sensor_name) +                .set_publisher([mb, sensor_name](){ +                    return sensor_value_t( +                        mb->rpc->request_with_token<sensor_value_t::sensor_map_t>( +                            "get_mb_sensor", sensor_name +                        ) +                    ); +                }) +                .set_coercer([](const sensor_value_t &){ +                    throw uhd::runtime_error( +                        "Trying to write read-only sensor value!" +                    ); +                    return sensor_value_t("", "", ""); +                }) +            ; +        }      }      void reset_time_synchronized(uhd::property_tree::sptr tree) diff --git a/mpm/python/usrp_mpm/dboard_manager/base.py b/mpm/python/usrp_mpm/dboard_manager/base.py index 56655f946..b87033860 100644 --- a/mpm/python/usrp_mpm/dboard_manager/base.py +++ b/mpm/python/usrp_mpm/dboard_manager/base.py @@ -34,6 +34,10 @@ class DboardManagerBase(object):      # Very important: A list of PIDs that apply to the current device. Must be      # list, even if there's only one entry.      pids = [] +    # See PeriphManager.mboard_sensor_callback_map for a description. +    rx_sensor_callback_map = {} +    # See PeriphManager.mboard_sensor_callback_map for a description. +    tx_sensor_callback_map = {}      # A dictionary that maps chips or components to chip selects for SPI.      # If this is given, a dictionary called self._spi_nodes is created which      # maps these keys to actual spidev paths. Also throws a warning/error if @@ -108,3 +112,37 @@ class DboardManagerBase(object):          Call this function if the frequency of the reference clock changes.          """          self.log.warning("update_ref_clock_freq() called but not implemented") + +    def get_sensors(self, direction): +        """ +        Return a list of RX daughterboard sensor names. + +        direction needs to be either RX or TX. +        """ +        if direction.lower() == 'rx': +            return list(self.rx_sensor_callback_map.keys()) +        else: +            return list(self.tx_sensor_callback_map.keys()) + +    def get_sensor(self, direction, sensor_name): +        """ +        Return a dictionary that represents the sensor values for a given +        sensor. If the requested sensor sensor_name does not exist, throw an +        exception. direction is either RX or TX. + +        See PeriphManager.get_mb_sensor() for a description of the return value +        format. +        """ +        callback_map = \ +            rx_sensor_callback_map if direction.lower() == 'rx' \ +            else tx_sensor_callback_map +        if sensor_name not in callback_map: +            error_msg = "Was asked for non-existent sensor `{}'.".format( +                sensor_name +            ) +            self.log.error(error_msg) +            raise RuntimeError(error_msg) +        return getattr( +            self, self.callback_map.get('sensor_name') +        )() + diff --git a/mpm/python/usrp_mpm/periph_manager/base.py b/mpm/python/usrp_mpm/periph_manager/base.py index 0aa1adf59..72066b9ef 100644 --- a/mpm/python/usrp_mpm/periph_manager/base.py +++ b/mpm/python/usrp_mpm/periph_manager/base.py @@ -93,6 +93,9 @@ class PeriphManagerBase(object):      # particular version of MPM supports. Leave at None to skip a max rev      # check.      mboard_max_rev = None +    # A list of available sensors on the motherboard. This dictionary is a map +    # of the form sensor_name -> method name +    mboard_sensor_callback_map = {}      # This is a sanity check value to see if the correct number of      # daughterboards are detected. If somewhere along the line more than      # max_num_dboards dboards are found, an error or warning is raised, @@ -461,3 +464,38 @@ class PeriphManagerBase(object):              xbar_file.write(laddr_value)          return True +    def get_mb_sensors(self): +        """ +        Return a list of sensor names. +        """ +        return list(self.mboard_sensor_callback_map.keys()) + +    def get_mb_sensor(self, sensor_name): +        """ +        Return a dictionary that represents the sensor values for a given +        sensor. If the requested sensor sensor_name does not exist, throw an +        exception. + +        The returned dictionary has the following keys (all values are +        strings): +        - name: This is typically the same as sensor_name +        - type: One of the following strings: BOOLEAN, INTEGER, REALNUM, STRING +                Note that this matches uhd::sensor_value_t::data_type_t +        - value: The value. If type is STRING, it is interpreted as-is. If it's +                 REALNUM or INTEGER, it needs to be convertable to float or +                 int, respectively. If it's BOOLEAN, it needs to be either +                 'true' or 'false', although any string that is not 'true' will +                 be interpreted as false. +        - unit: This depends on the type. It is generally only relevant for +                pretty-printing the sensor value. +        """ +        if sensor_name not in self.get_mb_sensors(): +            error_msg = "Was asked for non-existent sensor `{}'.".format( +                sensor_name +            ) +            self.log.error(error_msg) +            raise RuntimeError(error_msg) +        return getattr( +            self, self.mboard_sensor_callback_map.get(sensor_name) +        )() + | 
