aboutsummaryrefslogtreecommitdiffstats
path: root/mpm/python/usrp_mpm/dboard_manager/lmk_mg.py
blob: 6c2660521ab453a0fd67b3a3f54e89fb95d64185 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#
# Copyright 2017 Ettus Research (National Instruments)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
"""
LMK04828 driver for use with Magnesium
"""

from time import sleep
from builtins import zip
from builtins import hex
from ..mpmlog import get_logger
from ..chips import LMK04828

class LMK04828Mg(LMK04828):
    def __init__(self, regs_iface, spi_lock, slot=None):
        LMK04828.__init__(self, regs_iface, slot)
        self.spi_lock = spi_lock
        self.log = get_logger("LMK04828")
        assert hasattr(self.spi_lock, 'lock')
        assert hasattr(self.spi_lock, 'unlock')

    def init(self):
        # Reset the LMK
        self.log.trace("lock?")
        self.spi_lock.lock()
        self.log.trace("locked")

        addrs = (0x000, 0x000, 0x002, 0x14A)
        vals  =  (0x90,  0x10,  0x00,  0x33)

        for addr, val in zip(addrs, vals):
            #self.log.trace("send {0}, {1}".format(hex(addr), hex(val),))
            self.regs_iface.poke8(addr, val)

        # Re-verify chip ID
        self.log.trace("check chip id")
        if not self.verify_chip_id():
            raise Exception("Unable to locate LMK04828")

        # Write the configuration (10 MHz reference, 125 MHz outputs)
        addrs = (0x100, 0x101, 0x103, 0x104, 0x105, 0x106, 0x107, 0x108, 0x109, 0x10B, 0x10C, 0x10D, 0x10E, 0x10F, 0x110, 0x111, 0x113, 0x114, 0x115, 0x116, 0x117, 0x118, 0x119, 0x11B, 0x11C, 0x11D, 0x11E, 0x11F, 0x120, 0x121, 0x123, 0x124, 0x125, 0x126, 0x127, 0x128, 0x129, 0x12B, 0x12C, 0x12D, 0x12E, 0x12F, 0x130, 0x131, 0x133, 0x134, 0x135, 0x136, 0x137, 0x138, 0x139, 0x13A, 0x13B, 0x13C, 0x13D, 0x13E, 0x13F, 0x140, 0x141, 0x142, 0x143, 0x144, 0x145, 0x146, 0x147, 0x148, 0x149, 0x14B, 0x14C, 0x14D, 0x14E, 0x14F, 0x150, 0x151, 0x152, 0x153, 0x154, 0x155, 0x156, 0x157, 0x158, 0x159, 0x15A, 0x15B, 0x15C, 0x15D, 0x15E, 0x15F, 0x160, 0x161, 0x162, 0x163, 0x164, 0x165, 0x171, 0x172, 0x17C, 0x17D, 0x166, 0x167, 0x168, 0x169, 0x16A, 0x16B, 0x16C, 0x16D, 0x16E, 0x173)
        vals =   (0x78,  0x55,  0x00,  0x20,  0x00,  0xF2,  0x55,  0x7E,  0x55,  0x00,  0x00,  0x00,  0xF0,  0x55,  0x61,  0x55,  0x00,  0x00,  0x00,  0xF9,  0x00,  0x78,  0x55,  0x00,  0x20,  0x00,  0xF1,  0x00,  0x78,  0x55,  0x00,  0x20,  0x00,  0xF2,  0x55,  0x78,  0x55,  0x00,  0x00,  0x00,  0xF0,  0x50,  0x78,  0x55,  0x00,  0x20,  0x00,  0xF1,  0x05,  0x30,  0x00,  0x01,  0xE0,  0x00,  0x08,  0x00,  0x09,  0x00,  0x00,  0x00,  0xD1,  0x00,  0x7F,  0x10,  0x1A,  0x01,  0x01,  0x01,  0xF6,  0x00,  0x00,  0x7F,  0x03,  0x02,  0x00,  0x00,  0x01,  0x00,  0x0A,  0x00,  0x01,  0x00,  0x7D,  0xCF,  0x03,  0xE8,  0x00,  0x0B,  0x00,  0x04,  0xA4,  0x00,  0x00,  0x19,  0xAA,  0x02,  0x15,  0x33,  0x00,  0x00,  0x19,  0x51,  0x27,  0x10,  0x00,  0x00,  0x13,  0x00)

        self.log.trace("send init sequence")
        for addr, val in zip(addrs, vals):
            self.regs_iface.poke8(addr, val) 

        self.spi_lock.unlock()
        sleep(0.1)
        self.spi_lock.lock()

        # Clear Lock Detect Sticky
        self.log.trace("clear lock sticky")
        addrs = (0x182, 0x182, 0x183, 0x183)
        vals  =  (0x01,  0x00,  0x01,  0x00)
        
        for addr, val in zip(addrs, vals):
            self.regs_iface.poke8(addr, val) 

        self.spi_lock.unlock()
        sleep(0.1)
        self.spi_lock.lock()

        # Check Lock Detects
        self.log.trace("check lock status")
        pll1_lock_status = self.regs_iface.peek8(0x182)
        pll2_lock_status = self.regs_iface.peek8(0x183)

        if not pll1_lock_status == 0x02:
            self.log.error("LMK PLL1 did not lock. Status {0}".format(hex(pll1_lock_status)))

        if not pll2_lock_status == 0x02:
            self.log.error("LMK PLL2 did not lock. Status {0}".format(hex(pll2_lock_status)))

        # Toggle SYNC polarity to trigger SYNC event
        self.regs_iface.poke8(0x143, 0xF1)
        self.regs_iface.poke8(0x143, 0xD1)
        # Enable SYSREF pulses
        self.regs_iface.poke8(0x139, 0x02)
        self.regs_iface.poke8(0x144, 0xFF)
        self.regs_iface.poke8(0x143, 0x52)
        self.spi_lock.unlock()

        self.log.trace("LMK init'd and locked")