diff options
author | Martin Braun <martin.braun@ettus.com> | 2018-05-07 17:27:39 -0700 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2018-06-08 13:27:13 -0700 |
commit | aa0cc703fe9287e4de54c4c5c1a52c5fce9c4402 (patch) | |
tree | 88bb093aa9a7584618d04f3e95549a9895ad0fc9 /mpm | |
parent | ec7144d6466e560b00223fb3bb72d31b38a038da (diff) | |
download | uhd-aa0cc703fe9287e4de54c4c5c1a52c5fce9c4402.tar.gz uhd-aa0cc703fe9287e4de54c4c5c1a52c5fce9c4402.tar.bz2 uhd-aa0cc703fe9287e4de54c4c5c1a52c5fce9c4402.zip |
mpm: Refactor periph manager init; split EEPROM read from rest
The readout of EEPROMs is moved to their own functions. This will allow
us to read out EEPROM values before starting the initialization.
Diffstat (limited to 'mpm')
-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) |