diff options
Diffstat (limited to 'mpm/python/usrp_mpm/dboard_manager/magnesium.py')
-rw-r--r-- | mpm/python/usrp_mpm/dboard_manager/magnesium.py | 50 |
1 files changed, 25 insertions, 25 deletions
diff --git a/mpm/python/usrp_mpm/dboard_manager/magnesium.py b/mpm/python/usrp_mpm/dboard_manager/magnesium.py index 0eaf25ae1..9c36abe89 100644 --- a/mpm/python/usrp_mpm/dboard_manager/magnesium.py +++ b/mpm/python/usrp_mpm/dboard_manager/magnesium.py @@ -157,6 +157,7 @@ class Magnesium(DboardManagerBase): # is at 2^15 = 32768. However, the linearity of the DAC is best just below that # point, so we set it to the (carefully calculated) alternate value instead. INIT_PHASE_DAC_WORD = 31000 # Intentionally decimal + PHASE_DAC_SPI_ADDR = 0x0 default_master_clock_rate = 125e6 default_current_jesd_rate = 2500e6 @@ -316,7 +317,7 @@ class Magnesium(DboardManagerBase): Execute necessary init dance to bring up dboard """ def _init_lmk(lmk_spi, ref_clk_freq, master_clk_rate, - pdac_spi, init_phase_dac_word): + pdac_spi, init_phase_dac_word, phase_dac_spi_addr): """ Sets the phase DAC to initial value, and then brings up the LMK according to the selected ref clock frequency. @@ -325,7 +326,7 @@ class Magnesium(DboardManagerBase): self.log.trace("Initializing Phase DAC to d{}.".format( init_phase_dac_word )) - pdac_spi.poke16(0x0, init_phase_dac_word) + pdac_spi.poke16(phase_dac_spi_addr, init_phase_dac_word) return LMK04828Mg( lmk_spi, self.spi_lock, @@ -333,33 +334,30 @@ class Magnesium(DboardManagerBase): master_clk_rate, self.log ) - def _get_clock_synchronizer(): - " Return a clock synchronizer object " - # Future Work: target_value needs to be tweaked to support - # heterogeneous rate sync. - target_value = { - 122.88e6: 128e-9, - 125e6: 128e-9, - 153.6e6: 122e-9 - }[self.master_clock_rate] - return ClockSynchronizer( + def _sync_db_clock(): + " Synchronizes the DB clock to the common reference " + synchronizer = ClockSynchronizer( dboard_ctrl_regs, self.lmk, self._spi_ifaces['phase_dac'], - 0, # register offset value. future work. + 0, # register offset value. self.master_clock_rate, self.ref_clock_freq, 860E-15, # fine phase shift. TODO don't hardcode. This should live in the EEPROM self.INIT_PHASE_DAC_WORD, - [target_value,], # target_values - 0x0, # spi_addr TODO: make this a constant and replace in _sync_db_clock as well - self.slot_idx - ) - 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) + self.PHASE_DAC_SPI_ADDR, + 5, # External PPS pipeline delay from the PPS captured at the FPGA to TDC input + self.slot_idx) + # The radio clock traces on the motherboard are 69 ps longer for Daughterboard B + # than Daughterboard A. We want both of these clocks to align at the converters + # on each board, so adjust the target value for DB B. This is an N3xx series + # peculiarity and will not apply to other motherboards. + trace_delay_offset = {0: 0.0e-0, + 1: 69.0e-12}[self.slot_idx] + offset = synchronizer.run( + num_meas=[512, 128], + target_offset = trace_delay_offset) + offset_error = abs(offset) if offset_error > 100e-12: self.log.error("Clock synchronizer measured an offset of {:.1f} ps!".format( offset_error*1e12 @@ -368,9 +366,10 @@ class Magnesium(DboardManagerBase): offset_error*1e12 )) else: - self.log.debug("Residual DAC offset error: {:.1f} ps.".format( + self.log.debug("Residual synchronization error: {:.1f} ps.".format( offset_error*1e12 )) + synchronizer = None self.log.debug("Sample Clock Synchronization Complete!") ## Go, go, go! # Sanity checks and input validation: @@ -420,11 +419,12 @@ class Magnesium(DboardManagerBase): self.master_clock_rate, self._spi_ifaces['phase_dac'], self.INIT_PHASE_DAC_WORD, + self.PHASE_DAC_SPI_ADDR, ) db_clk_control.enable_mmcm() - self.log.debug("Sample Clocks and Phase DAC Configured Successfully!") # Synchronize DB Clocks - _sync_db_clock(_get_clock_synchronizer()) + _sync_db_clock() + self.log.debug("Sample Clocks and Phase DAC Configured Successfully!") # Clocks and PPS are now fully active! self.mykonos.set_master_clock_rate(self.master_clock_rate) self.init_jesd(jesdcore, args) |