aboutsummaryrefslogtreecommitdiffstats
path: root/mpm/python
diff options
context:
space:
mode:
authordjepson1 <daniel.jepson@ni.com>2018-01-12 10:18:14 -0600
committerMartin Braun <martin.braun@ettus.com>2018-01-12 13:14:05 -0800
commitebfd551c355cd28f720b6b77a9d0470353b2e21c (patch)
treefee91fca68254e88f54a5cc5bbbb15c3a6d2b2c1 /mpm/python
parentec4caf86f236a0e5a0cdbc75fd9028e568da9723 (diff)
downloaduhd-ebfd551c355cd28f720b6b77a9d0470353b2e21c.tar.gz
uhd-ebfd551c355cd28f720b6b77a9d0470353b2e21c.tar.bz2
uhd-ebfd551c355cd28f720b6b77a9d0470353b2e21c.zip
mpm: tdc: add signature/revision checks and master reset routine
Reviewed-by: Martin Braun <martin.braun@ettus.com>
Diffstat (limited to 'mpm/python')
-rw-r--r--mpm/python/usrp_mpm/cores/tdc_sync.py62
-rw-r--r--mpm/python/usrp_mpm/dboard_manager/magnesium.py1
2 files changed, 62 insertions, 1 deletions
diff --git a/mpm/python/usrp_mpm/cores/tdc_sync.py b/mpm/python/usrp_mpm/cores/tdc_sync.py
index c37600e80..f58234e2d 100644
--- a/mpm/python/usrp_mpm/cores/tdc_sync.py
+++ b/mpm/python/usrp_mpm/cores/tdc_sync.py
@@ -72,7 +72,6 @@ class ClockSynchronizer(object):
The actual synchronization is run in run_sync().
"""
# TDC Control Register address constants
- # TODO see if we want to factor in an offset
TDC_CONTROL = 0x200
TDC_STATUS = 0x208
RSP_OFFSET_0 = 0x20C
@@ -81,6 +80,11 @@ class ClockSynchronizer(object):
RTC_OFFSET_1 = 0x218
RSP_PERIOD_CONTROL = 0x220
RTC_PERIOD_CONTROL = 0x224
+ TDC_MASTER_RESET = 0x230
+ SYNC_SIGNATURE = 0x300
+ SYNC_REVISION = 0x304
+ SYNC_OLDESTCOMPAT = 0x308
+ SYNC_SCRATCH = 0x30C
def __init__(
self,
@@ -111,6 +115,62 @@ class ClockSynchronizer(object):
self.target_values = target_values
self.dac_spi_addr_val = dac_spi_addr_val
self.meas_clk_freq = 170.542641116e6
+ # Bump this whenever we stop supporting older FPGA images or boards.
+ # YYMMDDHH
+ self.oldest_compat_version = 0x17060111
+ # Bump this whenever changes are made to this MPM host code.
+ self.current_version = 0x18011210
+
+
+ def check_core(self):
+ """
+ Verify TDC core returns correct ID and passes revision tests.
+ """
+ self.log.trace("Checking TDC Core...")
+ if self.peek32(self.SYNC_SIGNATURE) != 0x73796e63:
+ raise RuntimeError('TDC Core signature mismatch! Check that core is mapped correctly')
+ # Two revision checks are needed:
+ # FPGA Current Rev >= Host Oldest Compatible Rev
+ # Host Current Rev >= FPGA Oldest Compatible Rev
+ fpga_current_revision = self.peek32(self.SYNC_REVISION) & 0xFFFFFFFF
+ fpga_old_compat_revision = self.peek32(self.SYNC_OLDESTCOMPAT) & 0xFFFFFFFF
+ if fpga_current_revision < self.oldest_compat_version:
+ self.log.error("Revision check failed! MPM oldest supported revision "
+ "(0x{:08X}) is too new for this FPGA revision (0x{:08X})."
+ .format(self.oldest_compat_version, fpga_current_revision))
+ raise RuntimeError('This MPM version does not support the loaded FPGA image. Please update images!')
+ if self.current_version < fpga_old_compat_revision:
+ self.log.error("Revision check failed! FPGA oldest compatible revision "
+ "(0x{:08X}) is too new for this MPM version (0x{:08X})."
+ .format(fpga_current_revision, self.current_version))
+ raise RuntimeError('The loaded FPGA version is too new for MPM. Please update MPM!')
+ self.log.trace("TDC Core current revision: 0x{:08X}".format(fpga_current_revision))
+ self.log.trace("TDC Core oldest compatible revision: 0x{:08X}".format(fpga_old_compat_revision))
+ return True
+
+
+ def reset_tdc(self):
+ """
+ Toggles the master reset for the registers as well as all other portions of
+ the TDC. Confirms registers are cleared by writing and reading from the
+ scratch register.
+ """
+ # Write the scratch register with known data. This will be used to tell if the
+ # register data is cleared.
+ self.poke32(self.SYNC_SCRATCH, 0xDEADBEEF)
+ assert self.peek32(self.SYNC_SCRATCH) == 0xDEADBEEF
+
+ # Reset the register space first, then check to confirm it has been cleared.
+ self.poke32(self.TDC_MASTER_RESET, 0x01) # self-clearing bit
+ if self.peek32(self.SYNC_SCRATCH) != 0:
+ self.log.error("TDC Failed to Clear Registers!")
+ raise RuntimeError("TDC Master Reset Failed")
+
+ # Toggle the master reset for the TDC module. This is not self-clearing.
+ self.poke32(self.TDC_MASTER_RESET, 0x10)
+ time.sleep(0.001)
+ self.poke32(self.TDC_MASTER_RESET, 0x00)
+
def run_sync(self, measurement_only=False):
"""
diff --git a/mpm/python/usrp_mpm/dboard_manager/magnesium.py b/mpm/python/usrp_mpm/dboard_manager/magnesium.py
index 6b5491f99..1c46d134b 100644
--- a/mpm/python/usrp_mpm/dboard_manager/magnesium.py
+++ b/mpm/python/usrp_mpm/dboard_manager/magnesium.py
@@ -498,6 +498,7 @@ class Magnesium(DboardManagerBase):
)
def _sync_db_clock(synchronizer):
" Synchronizes the DB clock to the common reference "
+ synchronizer.check_core()
synchronizer.run_sync(measurement_only=False)
offset_error = synchronizer.run_sync(measurement_only=True)
if offset_error > 100e-12: