aboutsummaryrefslogtreecommitdiffstats
path: root/mpm/python/usrp_mpm
diff options
context:
space:
mode:
authorDaniel Jepson <daniel.jepson@ni.com>2017-05-30 18:10:23 -0700
committerMartin Braun <martin.braun@ettus.com>2017-12-22 15:03:58 -0800
commit273b959fd3af317ddde34a88f845e21a689dc8a0 (patch)
tree89aca49590d09c1a2feedda49ecb153029db654a /mpm/python/usrp_mpm
parentfc89cd3c42e67af5c5f46b880d6da309d4104c48 (diff)
downloaduhd-273b959fd3af317ddde34a88f845e21a689dc8a0.tar.gz
uhd-273b959fd3af317ddde34a88f845e21a689dc8a0.tar.bz2
uhd-273b959fd3af317ddde34a88f845e21a689dc8a0.zip
mpm/eiscat: Updates to LMK04828 driver
Diffstat (limited to 'mpm/python/usrp_mpm')
-rw-r--r--mpm/python/usrp_mpm/chips/lmk04828.py28
-rw-r--r--mpm/python/usrp_mpm/dboard_manager/lmk_eiscat.py87
2 files changed, 77 insertions, 38 deletions
diff --git a/mpm/python/usrp_mpm/chips/lmk04828.py b/mpm/python/usrp_mpm/chips/lmk04828.py
index 3b9a35bae..a67ca05fd 100644
--- a/mpm/python/usrp_mpm/chips/lmk04828.py
+++ b/mpm/python/usrp_mpm/chips/lmk04828.py
@@ -28,7 +28,7 @@ class LMK04828(object):
def __init__(self, regs_iface, postfix=None):
postfix = postfix or ""
- self.log = get_logger("LMK04828"+postfix)
+ self.log = get_logger("LMK04828{}".format(postfix))
self.regs_iface = regs_iface
assert hasattr(self.regs_iface, 'peek8')
assert hasattr(self.regs_iface, 'poke8')
@@ -41,13 +41,13 @@ class LMK04828(object):
pokes8((0,1),(0,2)) is the same as calling poke8(0,1), poke8(0,2).
"""
for addr, val in addr_vals:
- self.regs_iface.poke8(addr, val)
+ self.poke8(addr, val)
def get_chip_id(self):
"""
Read back the chip ID
"""
- chip_id = self.regs_iface.peek8(0x03)
+ chip_id = self.peek8(0x03)
self.log.trace("Read chip ID: {}".format(chip_id))
return chip_id
@@ -61,3 +61,25 @@ class LMK04828(object):
return False
return True
+ def check_plls_locked(self):
+ """
+ Checks both PLLs are locked. Will throw an exception otherwise.
+ Returns True if both PLLs are locked, False otherwise.
+ """
+ self.log.trace("Checking PLL lock bits...")
+ def check_pll_lock(pll_id, addr):
+ """
+
+ pll_id -- A string defining the PLL (e.g. 'PLL1')
+ addr -- The address to peek to see if it's locked
+ """
+ pll_lock_status = self.regs_iface.peek8(addr)
+ if (pll_lock_status & 0x7) != 0x02:
+ self.log.error("LMK {} did not lock. Status: {:x}".format(pll_id, pll_lock_status))
+ return False
+ return True
+ lock_status = \
+ check_pll_lock("PLL1", 0x182) and \
+ check_pll_lock("PLL2", 0x183)
+ return lock_status
+
diff --git a/mpm/python/usrp_mpm/dboard_manager/lmk_eiscat.py b/mpm/python/usrp_mpm/dboard_manager/lmk_eiscat.py
index 1628613df..d6975fea6 100644
--- a/mpm/python/usrp_mpm/dboard_manager/lmk_eiscat.py
+++ b/mpm/python/usrp_mpm/dboard_manager/lmk_eiscat.py
@@ -19,7 +19,6 @@ LMK04828 driver for use with Magnesium
"""
import time
-from ..mpmlog import get_logger
from ..chips import LMK04828
class LMK04828EISCAT(LMK04828):
@@ -38,7 +37,7 @@ class LMK04828EISCAT(LMK04828):
"""
Basic init. Turns it on. Let's us read SPI.
"""
- self.log.info("Init LMK")
+ self.log.info("Reset LMK & Verify")
self.pokes8((
(0x000, 0x90), # Assert reset
(0x000, 0x10), # De-assert reset
@@ -53,39 +52,44 @@ class LMK04828EISCAT(LMK04828):
"""
Write lots of config foo.
"""
- self.log.trace("Setting clkout config...")
- CLKin0_R_divider = {10e6: 0x0A, 20e6: 0x14}[self.ref_clock_freq]
+ self.log.trace("LMK Initialization")
+ clkin0_r_divider = {10e6: 0x0A, 20e6: 0x14}[self.ref_clock_freq]
self.pokes8((
(0x100, 0x6C), # CLKout Config
- (0x101, 0x55), # CLKout Config
+ (0x101, 0x66), # CLKout Config
+ (0x102, 0x66), # CLKout Config
(0x103, 0x00), # CLKout Config
(0x104, 0x20), # CLKout Config
(0x105, 0x00), # CLKout Config
(0x106, 0xF3), # CLKout Config
(0x107, 0x05), # CLKout Config
(0x108, 0x6C), # CLKout Config
- (0x109, 0x55), # CLKout Config
+ (0x109, 0x67), # CLKout Config
+ (0x10A, 0x67), # CLKout Config
(0x10B, 0x00), # CLKout Config
(0x10C, 0x20), # CLKout Config
(0x10D, 0x00), # CLKout Config
- (0x10E, 0xF1), # CLKout Config
+ (0x10E, 0x71), # CLKout Config
(0x10F, 0x05), # CLKout Config
(0x110, 0x6C), # CLKout Config
- (0x111, 0x55), # CLKout Config
+ (0x111, 0x67), # CLKout Config
+ (0x112, 0x67), # CLKout Config
(0x113, 0x00), # CLKout Config
(0x114, 0x20), # CLKout Config
(0x115, 0x00), # CLKout Config
- (0x116, 0xF1), # CLKout Config
+ (0x116, 0x71), # CLKout Config
(0x117, 0x05), # CLKout Config
(0x118, 0x6C), # CLKout Config
- (0x119, 0x55), # CLKout Config
+ (0x119, 0x67), # CLKout Config
+ (0x11A, 0x67), # CLKout Config
(0x11B, 0x00), # CLKout Config
(0x11C, 0x20), # CLKout Config
(0x11D, 0x00), # CLKout Config
- (0x11E, 0xF1), # CLKout Config
+ (0x11E, 0x71), # CLKout Config
(0x11F, 0x05), # CLKout Config
(0x120, 0x78), # CLKout Config
- (0x121, 0x55), # CLKout Config
+ (0x121, 0x66), # CLKout Config
+ (0x122, 0x66), # CLKout Config
(0x123, 0x00), # CLKout Config
(0x124, 0x20), # CLKout Config
(0x125, 0x00), # CLKout Config
@@ -93,18 +97,20 @@ class LMK04828EISCAT(LMK04828):
(0x127, 0x00), # CLKout Config
(0x128, 0x6C), # CLKout Config
(0x129, 0x55), # CLKout Config
+ (0x12A, 0x55), # CLKout Config
(0x12B, 0x00), # CLKout Config
(0x12C, 0x20), # CLKout Config
(0x12D, 0x00), # CLKout Config
(0x12E, 0xF9), # CLKout Config
(0x12F, 0x00), # CLKout Config
(0x130, 0x6C), # CLKout Config
- (0x131, 0x55), # CLKout Config
+ (0x131, 0x67), # CLKout Config
+ (0x132, 0x67), # CLKout Config
(0x133, 0x00), # CLKout Config
(0x134, 0x20), # CLKout Config
(0x135, 0x00), # CLKout Config
- (0x136, 0xF9), # CLKout Config
- (0x137, 0x00), # CLKout Config
+ (0x136, 0x71), # CLKout Config
+ (0x137, 0x01), # CLKout Config
(0x138, 0x10), # VCO_MUX to VCO 1; OSCout off
(0x139, 0x00), # SYSREF Source = MUX; SYSREF MUX = Normal SYNC
(0x13A, 0x01), # SYSREF Divide [12:8]
@@ -114,7 +120,7 @@ class LMK04828EISCAT(LMK04828):
(0x13E, 0x00), # SYSREF Pulse Count = 1 pulse/request
(0x13F, 0x0B), # Feedback Mux: Enabled, DCLKout6, drives PLL1N divider
(0x140, 0x00), # POWERDOWN options
- (0x141, 0x00), # Dynamic digital delay enable
+ (0x141, 0x08), # Dynamic digital delay enable
(0x142, 0x00), # Dynamic digital delay step
(0x143, 0xD1), # SYNC edge sensitive; SYSREF_CLR; SYNC Enabled; SYNC fro
(0x144, 0x00), # Enable SYNC on all outputs including sysref
@@ -133,7 +139,7 @@ class LMK04828EISCAT(LMK04828):
(0x151, 0x02), # Holdover Settings (defaults)
(0x152, 0x00), # Holdover Settings (defaults)
(0x153, 0x00), # CLKin0_R divider [13:8], default = 0
- (0x154, CLKin0_R_divider), # CLKin0_R divider [7:0], default = d120
+ (0x154, clkin0_r_divider), # CLKin0_R divider [7:0], default = d120
(0x155, 0x00), # CLKin1_R divider [13:8], default = 0
(0x156, 0x01), # CLKin1_R divider [7:0], default = d120
(0x157, 0x00), # CLKin2_R divider [13:8], default = 0
@@ -159,13 +165,13 @@ class LMK04828EISCAT(LMK04828):
(0x167, 0x00), # PLL2 N[15:8]
(0x168, 0x0C), # PLL2 N[7:0]
(0x169, 0x51), # PLL2 PFD
- (0x16A, 0x00), # PLL2 DLD Count [13:8] = default d32
+ (0x16A, 0x27), # PLL2 DLD Count [13:8] = default d32
(0x16B, 0x10), # PLL2 DLD Count [7:0] = default d0
(0x16C, 0x00), # PLL2 Loop filter r = 200 ohm
(0x16D, 0x00), # PLL2 loop filter c = 10 pF
(0x173, 0x00), # Do not power down PLL2 or prescaler
))
- time.sleep(0.1)
+ time.sleep(1.0) # Increased time to wait for DAC and VCXO to settle.
self.pokes8((
(0x182, 0x1), # Clear Lock Detect Sticky
(0x182, 0x0), # Clear Lock Detect Sticky
@@ -173,14 +179,8 @@ class LMK04828EISCAT(LMK04828):
(0x183, 0x0), # Clear Lock Detect Sticky
))
time.sleep(0.1)
- self.log.trace("Checking PLL lock bits...")
- def check_pll_lock(pll_id, addr):
- pll_lock_status = self.regs_iface.peek8(addr)
- if (pll_lock_status & 0x7) != 0x02:
- self.log.error("LMK {} did not lock. Status: {:x}".format(pll_id, pll_lock_status))
- raise RuntimeError("LMK {} did not lock.".format(pll_id))
- check_pll_lock("PLL1", 0x182)
- check_pll_lock("PLL2", 0x183)
+ if not self.check_plls_locked():
+ raise RuntimeError("At least one LMK PLL did not lock! Check the logs for details.")
self.log.trace("Setting SYNC and SYSREF config...")
self.pokes8((
(0x143, 0xF1), # toggle SYNC polarity to trigger SYNC event
@@ -191,12 +191,29 @@ class LMK04828EISCAT(LMK04828):
))
self.log.info("LMK init'd and locked!")
+ def lmk_shift(self, num_shifts=0):
+ """
+ Apply time shift
+
+ TODO: See if we can move this up to parent class
+ """
+ ddly_value = 0x67 if num_shifts >= 0 else 0x65
+ self.pokes8((
+ (0x141, 0x4E), # Dynamic digital delay enable
+ (0x143, 0x53), # SYSREF_CLR; SYNC Enabled; SYNC from pulser @ regwrite
+ (0x139, 0x02), # SYSREF_MUX = Pulser
+ (0x109, ddly_value), # Set DDLY values for DCLKout2 +/-1 on low cnt.
+ # To Increment phase, write 0x65. Decrement = 0x67
+ (0x10A, ddly_value), # Hidden register. Write the same as previous based on inc/dec.
+ (0x111, ddly_value), # Set DDLY values for DCLKout4 +/-1 on low cnt
+ (0x112, ddly_value), # Hidden register. Write the same as previous based on inc/dec.
+ (0x119, ddly_value), # Set DDLY values for DCLKout6 +/-1 on low cnt
+ (0x11A, ddly_value), # Hidden register. Write the same as previous based on inc/dec.
+ (0x131, ddly_value), # Set DDLY values for DCLKout12 +/-1 on low cnt
+ (0x132, ddly_value), # Hidden register. Write the same as previous based on inc/dec.
+ (0x144, 0xB1), # Enable SYNC on outputs 2,4,6,12
+ ))
+ for x in xrange(abs(num_shifts)):
+ self.poke8(0x142, 0x1)
+ self.poke8(0x144, 0xFF) # Disable SYNC on all outputs
- # TODO delete this
- # def enable_sysref_pulse(self):
- # """
- # Enable SYSREF pulses
- # """
- # self.poke8(0x139, 0x2)
- # self.poke8(0x144, 0xFF)
- # self.poke8(0x143, 0x52)