aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrung N Tran <trung.tran@ettus.com>2017-08-31 16:58:57 -0700
committerMartin Braun <martin.braun@ettus.com>2017-12-22 15:04:02 -0800
commit832e9fc79469ec8d95b68a6f752483718707e548 (patch)
treebfd5c0a92583c12b9e0e4408fd49bba1b2f30be2
parent894d1a1a0ae3442ad75b3c20056bd9ea0626309e (diff)
downloaduhd-832e9fc79469ec8d95b68a6f752483718707e548.tar.gz
uhd-832e9fc79469ec8d95b68a6f752483718707e548.tar.bz2
uhd-832e9fc79469ec8d95b68a6f752483718707e548.zip
mpm: mg: Specify I2C parents for GPIO devices
The Magnesium daughterboards have GPIO port expanders, but both have the same udev label. In order to specify which port expander to use, we pass in the parent udev I2c device.
-rw-r--r--mpm/python/usrp_mpm/dboard_manager/magnesium.py80
1 files changed, 77 insertions, 3 deletions
diff --git a/mpm/python/usrp_mpm/dboard_manager/magnesium.py b/mpm/python/usrp_mpm/dboard_manager/magnesium.py
index aba810288..1b87368da 100644
--- a/mpm/python/usrp_mpm/dboard_manager/magnesium.py
+++ b/mpm/python/usrp_mpm/dboard_manager/magnesium.py
@@ -19,6 +19,7 @@ magnesium dboard implementation module
"""
from __future__ import print_function
+import os
import struct
import time
from six import iteritems
@@ -29,7 +30,7 @@ from ..uio import UIO
from ..mpmlog import get_logger
from .lmk_mg import LMK04828Mg
from usrp_mpm.cores import ClockSynchronizer
-
+from ..sysfs_gpio import SysFSGPIO
def create_spidev_iface(dev_node):
"""
Create a regs iface from a spidev node
@@ -84,6 +85,46 @@ def create_spidev_iface_phasedac(dev_node):
0, # Write flag
)
+class TCA6408(object):
+ """
+ Abstraction layer for the port/gpio expander
+ """
+ pins = (
+ 'PWR-GOOD-3.6V', #3.6V
+ 'PWR-EN-3.6V', #3.6V
+ 'PWR-GOOD-1.5V', #1.5V
+ 'PWR-EN-1.5V', #1.5V
+ 'PWR-GOOD-5.5V', #5.5V
+ 'PWR-EN-5.5V', #5.5V
+ '6',
+ 'LED',
+ )
+
+ def __init__(self, i2c_dev):
+ if i2c_dev is None:
+ raise RuntimeError("Need to specify i2c device to use the TCA6408")
+ self._gpios = SysFSGPIO('tca6408', 0xBF, 0xAA, 0xAA, i2c_dev)
+
+ def set(self, name, value=None):
+ """
+ Assert a pin by name
+ """
+ assert name in self.pins
+ self._gpios.set(self.pins.index(name), value=value)
+
+ def reset(self, name):
+ """
+ Deassert a pin by name
+ """
+ self.set(name, value=0)
+
+ def get(self, name):
+ """
+ Read back a pin by name
+ """
+ assert name in self.pins
+ return self._gpios.get(self.pins.index(name))
+
class Magnesium(DboardManagerBase):
"""
Holds all dboard specific information and methods of the magnesium dboard
@@ -94,7 +135,8 @@ class Magnesium(DboardManagerBase):
# See DboardManagerBase for documentation on these fields
#########################################################################
pids = [0x150]
-
+ #file system path to i2c-adapter/mux
+ base_i2c_adapter = '/sys/class/i2c-adapter'
# Maps the chipselects to the corresponding devices:
spi_chipselect = {"cpld": 0, "lmk": 1, "mykonos": 2, "phase_dac": 3}
@staticmethod
@@ -118,6 +160,8 @@ class Magnesium(DboardManagerBase):
"mykonos": create_spidev_iface,
"phase_dac": create_spidev_iface_phasedac,
}
+ # Map I2C channel to slot index
+ i2c_chan_map = {0: 'i2c-9', 1: 'i2c-10'}
# DAC is initialized to midscale automatically on power-on: 16-bit DAC, so midpoint
# is at 2^15 = 32768. However, the linearity of the DAC is best just below that
@@ -131,13 +175,43 @@ class Magnesium(DboardManagerBase):
func.__doc__ = mykfunc.__doc__
return func
+ def _get_i2c_dev(self):
+ " Return the I2C path for this daughterboard "
+ import pyudev
+ context = pyudev.Context()
+ i2c_dev_path = os.path.join(
+ self.base_i2c_adapter,
+ self.i2c_chan_map[self.slot_idx]
+ )
+ return pyudev.Devices.from_sys_path(context, i2c_dev_path)
+
+ def _power_on(self):
+ " Turn on power to daughterboard "
+ self.log.trace("Powering on slot_idx={}...".format(self.slot_idx))
+ i2c_dev = self._get_i2c_dev()
+ self._port_expander = TCA6408(i2c_dev)
+ self._port_expander.set("PWR-EN-3.6V")
+ self._port_expander.set("PWR-EN-1.5V")
+ self._port_expander.set("PWR-EN-5.5V")
+ self._port_expander.set("LED")
+
+ def _power_off(self):
+ " Turn off power to daughterboard "
+ self.log.trace("Powering off slot_idx={}...".format(self.slot_idx))
+ i2c_dev = self._get_i2c_dev()
+ self._port_expander = TCA6408(i2c_dev)
+ self._port_expander.reset("PWR-EN-3.6V")
+ self._port_expander.reset("PWR-EN-1.5V")
+ self._port_expander.reset("PWR-EN-5.5V")
+ self._port_expander.reset("LED")
+
def __init__(self, slot_idx, **kwargs):
super(Magnesium, self).__init__(slot_idx, **kwargs)
self.log = get_logger("Magnesium-{}".format(slot_idx))
self.log.trace("Initializing Magnesium daughterboard, slot index {}".format(self.slot_idx))
self.ref_clock_freq = 10e6 # TODO: make this not fixed
-
+ self._power_on()
self.log.debug("Loading C++ drivers...")
self._device = lib.dboards.magnesium_manager(
self._spi_nodes['mykonos'],