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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
#
# 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/>.
#
"""
dboard base implementation module
"""
from builtins import object
from six import iteritems
from ..mpmlog import get_logger
class DboardManagerBase(object):
"""
Base class for daughterboard controls
"""
#########################################################################
# Overridables
#
# These values are meant to be overridden by the according subclasses
#########################################################################
# Very important: A list of PIDs that apply to the current device. Must be
# list, even if there's only one entry.
pids = []
# See PeriphManager.mboard_sensor_callback_map for a description.
rx_sensor_callback_map = {}
# See PeriphManager.mboard_sensor_callback_map for a description.
tx_sensor_callback_map = {}
# A dictionary that maps chips or components to chip selects for SPI.
# If this is given, a dictionary called self._spi_nodes is created which
# maps these keys to actual spidev paths. Also throws a warning/error if
# the SPI configuration is invalid.
spi_chipselect = {}
@staticmethod
def list_required_dt_overlays(eeprom_md, sfp_config, device_args):
"""
Lists device tree overlays that need to be applied before this class can
be used. List of strings.
Are applied in order.
eeprom_md -- Dictionary of info read out from the dboard EEPROM
sfp_config -- A string identifying the configuration of the SFP ports.
Example: "XG", "HG", "XA", ...
device_args -- Arbitrary dictionary of info, typically user-defined
"""
return []
### End of overridables #################################################
def __init__(self, slot_idx, **kwargs):
self.log = get_logger('dboardManager')
self.slot_idx = slot_idx
self.device_info = {}
self._init_spi_nodes(kwargs.get('spi_nodes', []))
def _init_spi_nodes(self, spi_devices):
"""
Populates the self._spi_nodes dictionary.
Note that this won't instantiate any spidev objects, it'll just map
keys from self.spi_chipselect to spidev nodes, and do a sanity check
that enough nodes are available.
"""
if len(spi_devices) < len(self.spi_chipselect):
self.log.error("Expected {0} spi devices, found {1} spi devices".format(
len(self.spi_chipselect), len(spi_devices),
))
raise RuntimeError("Not enough SPI devices found.")
self._spi_nodes = {}
for k, v in iteritems(self.spi_chipselect):
self._spi_nodes[k] = spi_devices[v]
self.log.debug("spidev device node map: {}".format(self._spi_nodes))
def init(self, args):
"""
Run the dboard initialization. This typically happens at the beginning
of a UHD session.
Must be overridden. Must return True/False on success/failure.
args -- A dictionary of arbitrary settings that can be used by the
dboard code. Similar to device args for UHD.
"""
raise NotImplementedError("DboardManagerBase::init() not implemented!")
def deinit(self):
"""
Power down the dboard. Does not have be implemented. If it does, it
needs to be safe to call multiple times.
"""
self.log.info("deinit() called, but not implemented.")
def get_serial(self):
"""
Return this daughterboard's serial number as a dictionary.
"""
return self.device_info.get("serial", "")
def update_ref_clock_freq(self, freq):
"""
Call this function if the frequency of the reference clock changes.
"""
self.log.warning("update_ref_clock_freq() called but not implemented")
def get_sensors(self, direction):
"""
Return a list of RX daughterboard sensor names.
direction needs to be either RX or TX.
"""
if direction.lower() == 'rx':
return list(self.rx_sensor_callback_map.keys())
else:
return list(self.tx_sensor_callback_map.keys())
def get_sensor(self, direction, sensor_name):
"""
Return a dictionary that represents the sensor values for a given
sensor. If the requested sensor sensor_name does not exist, throw an
exception. direction is either RX or TX.
See PeriphManager.get_mb_sensor() for a description of the return value
format.
"""
callback_map = \
rx_sensor_callback_map if direction.lower() == 'rx' \
else tx_sensor_callback_map
if sensor_name not in callback_map:
error_msg = "Was asked for non-existent sensor `{}'.".format(
sensor_name
)
self.log.error(error_msg)
raise RuntimeError(error_msg)
return getattr(
self, self.callback_map.get('sensor_name')
)()
|