diff options
Diffstat (limited to 'mpm/python')
| -rw-r--r-- | mpm/python/usrp_mpm/periph_manager/base.py | 239 | 
1 files changed, 135 insertions, 104 deletions
| diff --git a/mpm/python/usrp_mpm/periph_manager/base.py b/mpm/python/usrp_mpm/periph_manager/base.py index 3ded0d3c2..e3bf89c33 100644 --- a/mpm/python/usrp_mpm/periph_manager/base.py +++ b/mpm/python/usrp_mpm/periph_manager/base.py @@ -158,7 +158,12 @@ class PeriphManagerBase(object):          # should always be a dictionary (or dictionary-like object).          self._init_args = {}          try: -            self._init_mboard_with_eeprom() +            self._eeprom_head, self._eeprom_rawdata = \ +                self._read_mboard_eeprom() +            self.mboard_info = self._get_mboard_info(self._eeprom_head) +            self.log.info("Device serial number: {}" +                          .format(self.mboard_info.get('serial', 'n/a'))) +            dboard_infos = self._get_dboard_eeprom_info()              self._default_args = self._update_default_args(args)              self.log.debug("Using default args: {}".format(self._default_args))              self._init_mboard_overlays(self._eeprom_head, self._default_args) @@ -169,7 +174,11 @@ class PeriphManagerBase(object):                  ]              else:                  override_db_pids = [] -            self._init_dboards(override_db_pids, self._default_args) +            self._init_dboards( +                dboard_infos, +                override_db_pids, +                self._default_args +            )              self._device_initialized = True              self._initialization_status = "No errors."          except Exception as ex: @@ -177,15 +186,19 @@ class PeriphManagerBase(object):              self._device_initialized = False              self._initialization_status = str(ex) -    def _init_mboard_with_eeprom(self): +    def _read_mboard_eeprom(self):          """ -        Starts the device initialization. Typically requires reading from an -        EEPROM. +        Read out mboard EEPROM. +        Returns a tuple: (eeprom_dict, eeprom_rawdata), where the the former is +        a de-serialized dictionary representation of the data, and the latter +        is a binary string with the raw data. + +        If no EEPROM is defined, returns empty values.          """          if len(self.mboard_eeprom_addr):              self.log.trace("Reading EEPROM from address `{}'..."                             .format(self.mboard_eeprom_addr)) -            (self._eeprom_head, self._eeprom_rawdata) = eeprom.read_eeprom( +            (eeprom_head, eeprom_rawdata) = eeprom.read_eeprom(                  get_eeprom_paths(self.mboard_eeprom_addr)[0],                  self.mboard_eeprom_offset,                  eeprom.MboardEEPROM.eeprom_header_format, @@ -194,54 +207,109 @@ class PeriphManagerBase(object):                  self.mboard_eeprom_max_len,              )              self.log.trace("Found EEPROM metadata: `{}'" -                           .format(str(self._eeprom_head))) +                           .format(str(eeprom_head)))              self.log.trace("Read {} bytes of EEPROM data." -                           .format(len(self._eeprom_rawdata))) -            for key in ('pid', 'serial', 'rev', 'eeprom_version'): -                # In C++, we can only handle dicts if all the values are of the -                # same type. So we must convert them all to strings here: -                try: -                    self.mboard_info[key] = str( -                        self._eeprom_head.get(key, ''), -                        'ascii' -                    ) -                except TypeError: -                    self.mboard_info[key] = str(self._eeprom_head.get(key, '')) -            if 'pid' in self._eeprom_head: -                if self._eeprom_head['pid'] not in self.pids.keys(): -                    self.log.error( -                        "Found invalid PID in EEPROM: 0x{:04X}. " \ -                        "Valid PIDs are: {}".format( -                            self._eeprom_head['pid'], -                            ", ".join(["0x{:04X}".format(x) -                                       for x in self.pids.keys()]), -                        ) -                    ) -                    raise RuntimeError("Invalid PID found in EEPROM.") -                self.mboard_info['product'] = \ -                    self.pids[self._eeprom_head['pid']] -            if 'rev' in self._eeprom_head: -                try: -                    rev_numeric = int(self._eeprom_head.get('rev')) -                except (ValueError, TypeError): -                    raise RuntimeError( -                        "Invalid revision info read from EEPROM!" +                           .format(len(eeprom_rawdata))) +            return eeprom_head, eeprom_rawdata +        # Nothing defined? Return defaults. +        self.log.trace("No mboard EEPROM path defined. " +                       "Skipping mboard EEPROM readout.") +        return {}, b'' + +    def _get_mboard_info(self, eeprom_head): +        """ +        Creates the mboard info dictionary from the EEPROM data. +        """ +        mboard_info = self.mboard_info +        if not eeprom_head: +            self.log.debug("No EEPROM info: Can't generate mboard_info") +            return mboard_info +        for key in ('pid', 'serial', 'rev', 'eeprom_version'): +            # In C++, we can only handle dicts if all the values are of the +            # same type. So we must convert them all to strings here: +            try: +                mboard_info[key] = str(eeprom_head.get(key, ''), 'ascii') +            except TypeError: +                mboard_info[key] = str(eeprom_head.get(key, '')) +        if 'pid' in eeprom_head: +            if eeprom_head['pid'] not in self.pids.keys(): +                self.log.error( +                    "Found invalid PID in EEPROM: 0x{:04X}. " \ +                    "Valid PIDs are: {}".format( +                        eeprom_head['pid'], +                        ", ".join(["0x{:04X}".format(x) +                                   for x in self.pids.keys()]),                      ) -                if self.mboard_max_rev is not None \ -                        and rev_numeric > self.mboard_max_rev: -                    raise RuntimeError( -                        "Device has revision `{}', but max supported " \ -                        "revision is `{}'".format( -                            rev_numeric, self.mboard_max_rev -                        )) -            else: -                raise RuntimeError("No revision found in EEPROM.") +                ) +                raise RuntimeError("Invalid PID found in EEPROM.") +            mboard_info['product'] = self.pids[eeprom_head['pid']] +        if 'rev' in eeprom_head: +            try: +                rev_numeric = int(eeprom_head.get('rev')) +            except (ValueError, TypeError): +                raise RuntimeError( +                    "Invalid revision info read from EEPROM!" +                ) +            if self.mboard_max_rev is not None \ +                    and rev_numeric > self.mboard_max_rev: +                raise RuntimeError( +                    "Device has revision `{}', but max supported " \ +                    "revision is `{}'".format( +                        rev_numeric, self.mboard_max_rev +                    ))          else: -            self.log.trace("No EEPROM address to read from.") -            self._eeprom_head = {} -            self._eeprom_rawdata = '' -        self.log.info("Device serial number: {}" -                      .format(self.mboard_info.get('serial', 'n/a'))) +            raise RuntimeError("No revision found in EEPROM.") +        return mboard_info + +    def _get_dboard_eeprom_info(self): +        """ +        Read back EEPROM info from the daughterboards +        """ +        if self.dboard_eeprom_addr is None: +            self.log.debug("No dboard EEPROM addresses given.") +            return [] +        dboard_eeprom_addrs = self.dboard_eeprom_addr \ +                              if isinstance(self.dboard_eeprom_addr, list) \ +                              else [self.dboard_eeprom_addr] +        dboard_eeprom_paths = [] +        self.log.trace("Identifying dboard EEPROM paths from addrs `{}'..." +                       .format(",".join(dboard_eeprom_addrs))) +        for dboard_eeprom_addr in dboard_eeprom_addrs: +            self.log.trace("Resolving %s...", dboard_eeprom_addr) +            dboard_eeprom_paths += get_eeprom_paths(dboard_eeprom_addr) +        self.log.trace("Found dboard EEPROM paths: {}" +                       .format(",".join(dboard_eeprom_paths))) +        if len(dboard_eeprom_paths) > self.max_num_dboards: +            self.log.warning("Found more EEPROM paths than daughterboards. " +                             "Ignoring some of them.") +            dboard_eeprom_paths = dboard_eeprom_paths[:self.max_num_dboards] +        dboard_info = [] +        for dboard_idx, dboard_eeprom_path in enumerate(dboard_eeprom_paths): +            self.log.debug("Reading EEPROM info for dboard %d...", dboard_idx) +            dboard_eeprom_md, dboard_eeprom_rawdata = eeprom.read_eeprom( +                dboard_eeprom_path, +                self.dboard_eeprom_offset, +                eeprom.DboardEEPROM.eeprom_header_format, +                eeprom.DboardEEPROM.eeprom_header_keys, +                self.dboard_eeprom_magic, +                self.dboard_eeprom_max_len, +            ) +            self.log.trace("Found dboard EEPROM metadata: `{}'" +                           .format(str(dboard_eeprom_md))) +            self.log.trace("Read %d bytes of dboard EEPROM data.", +                           len(dboard_eeprom_rawdata)) +            db_pid = dboard_eeprom_md.get('pid') +            if db_pid is None: +                self.log.warning("No dboard PID found in dboard EEPROM!") +            else: +                self.log.debug("Found dboard PID in EEPROM: 0x{:04X}" +                               .format(db_pid)) +            dboard_info.append({ +                'eeprom_md': dboard_eeprom_md, +                'eeprom_rawdata': dboard_eeprom_rawdata, +                'pid': db_pid, +            }) +        return dboard_info      def _update_default_args(self, default_args):          """ @@ -278,64 +346,30 @@ class PeriphManagerBase(object):          # TODO: Fine-tune this number, or wait for some smarter signal.          sleep(1) -    def _init_dboards(self, override_dboard_pids, default_args): +    def _init_dboards(self, dboard_infos, override_dboard_pids, default_args):          """          Initialize all the daughterboards + +        dboard_infos -- List of dictionaries as returned from +                       _get_dboard_eeprom_info() +        override_dboard_pids -- List of dboard PIDs to force +        default_args -- Default args          """ -        # Go, go, go! -        override_dboard_pids = override_dboard_pids or []          if override_dboard_pids:              self.log.warning("Overriding daughterboard PIDs with: {}" -                             .format(override_dboard_pids)) -        dboard_eeprom_addrs = self.dboard_eeprom_addr \ -                              if isinstance(self.dboard_eeprom_addr, list) \ -                              else [self.dboard_eeprom_addr] -        dboard_eeprom_paths = [] -        self.log.trace("Identifying dboard EEPROM paths from addrs `{}'..." -                       .format(",".join(dboard_eeprom_addrs))) -        for dboard_eeprom_addr in dboard_eeprom_addrs: -            self.log.trace("Resolving %s...", dboard_eeprom_addr) -            dboard_eeprom_paths += get_eeprom_paths(dboard_eeprom_addr) -        self.log.trace("Found dboard EEPROM paths: {}" -                       .format(",".join(dboard_eeprom_paths))) -        if len(dboard_eeprom_paths) > self.max_num_dboards: -            self.log.warning("Found more EEPROM paths than daughterboards. " -                             "Ignoring some of them.") -            dboard_eeprom_paths = dboard_eeprom_paths[:self.max_num_dboards] +                             .format(",".join(override_dboard_pids))) +        assert len(dboard_infos) <= self.max_num_dboards          if len(override_dboard_pids) and \ -                len(override_dboard_pids) < len(dboard_eeprom_paths): +                len(override_dboard_pids) < len(dboard_infos):              self.log.warning("--override-db-pids is going to skip dboards.") -            dboard_eeprom_paths = \ -                    dboard_eeprom_paths[:len(override_dboard_pids)] -        for dboard_idx, dboard_eeprom_path in enumerate(dboard_eeprom_paths): +            dboard_infos = dboard_infos[:len(override_dboard_pids)] +        for dboard_idx, dboard_info in enumerate(dboard_infos):              self.log.debug("Initializing dboard %d...", dboard_idx) -            dboard_eeprom_md, dboard_eeprom_rawdata = eeprom.read_eeprom( -                dboard_eeprom_path, -                self.dboard_eeprom_offset, -                eeprom.DboardEEPROM.eeprom_header_format, -                eeprom.DboardEEPROM.eeprom_header_keys, -                self.dboard_eeprom_magic, -                self.dboard_eeprom_max_len, -            ) -            self.log.trace("Found dboard EEPROM metadata: `{}'" -                           .format(str(dboard_eeprom_md))) -            self.log.trace("Read %d bytes of dboard EEPROM data.", -                           len(dboard_eeprom_rawdata)) -            if len(override_dboard_pids) > dboard_idx: -                db_pid = override_dboard_pids[dboard_idx] -                self.log.warning("Overriding dboard PID for dboard {} " -                                 "with 0x{:04X}.".format(dboard_idx, db_pid)) -            else: -                db_pid = dboard_eeprom_md.get('pid') -                if db_pid is None: -                    self.log.warning("No dboard PID found in dboard EEPROM!") -                else: -                    self.log.debug("Found dboard PID in EEPROM: 0x{:04X}" -                                   .format(db_pid)) +            db_pid = dboard_info.get('pid')              db_class = get_dboard_class_from_pid(db_pid)              if db_class is None:                  self.log.warning("Could not identify daughterboard class " -                                 "for PID {:04X}!".format(db_pid)) +                                 "for PID {:04X}! Skipping.".format(db_pid))                  continue              if len(self.dboard_spimaster_addrs) > dboard_idx:                  spi_nodes = sorted(get_spidev_nodes( @@ -344,16 +378,13 @@ class PeriphManagerBase(object):              else:                  spi_nodes = []                  self.log.warning("No SPI nodes for dboard %d.", dboard_idx) -            dboard_info = { -                'eeprom_md': dboard_eeprom_md, -                'eeprom_rawdata': dboard_eeprom_rawdata, -                'pid': db_pid, +            dboard_info.update({                  'spi_nodes': spi_nodes,                  'default_args': default_args, -            } +            })              # This will actually instantiate the dboard class:              self.dboards.append(db_class(dboard_idx, **dboard_info)) -        self.log.info("Found %d daughterboard(s).", len(self.dboards)) +        self.log.info("Initialized %d daughterboard(s).", len(self.dboards))      ###########################################################################      # Session (de-)initialization (at UHD startup) | 
