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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
|
#!/usr/bin/env python
#
# 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/>.
#
"""
N310 Built-In Self Test (BIST)
"""
from __future__ import print_function
import sys
import argparse
class N310BIST(object):
"""
BIST Tool for the USRP N3xx series
"""
# This defines special tests that are really collections of other tests.
collections = {
'standard': ["ddr3", "gpsdo", "rtc", "temp", "clock_int", "tpm"],
'extended': "*",
}
@staticmethod
def make_arg_parser():
"""
Return arg parser
"""
parser = argparse.ArgumentParser(
description="N3xx BIST Tool",
)
parser.add_argument(
'tests',
help="List the tests that should be run",
nargs='+', # There has to be at least one
)
return parser
def __init__(self):
self.args = N310BIST.make_arg_parser().parse_args()
self.tests_to_run = set()
for test in self.args.tests:
if test in self.collections:
for test in self.expand_collection(test):
self.tests_to_run.add(test)
else:
self.tests_to_run.add(test)
def expand_collection(self, coll):
"""
Return names of tests in a collection
"""
tests = self.collections[coll]
if tests == "*":
tests = {x.replace('bist_', '')
for x in dir(self)
if x.find('bist_') == 0
}
else:
tests = set(tests)
return tests
def run(self):
"""
Execute tests.
Returns True on Success.
"""
def execute_test(testname):
"""
Actually run a test.
"""
testmethod_name = "bist_{0}".format(testname)
sys.stderr.write("Executing test method: {0}\n\n".format(testmethod_name))
return getattr(self, testmethod_name)()
tests_successful = True
for test in self.tests_to_run:
tests_successful = tests_successful and execute_test(test)
return tests_successful
#############################################################################
# BISTS
# All bist_* methods must return True/False success values!
#############################################################################
def bist_rtc(self):
"""
BIST for RTC (real time clock)
Description:!!! I don't know how this will be tested !!!
External Equipment: None
JSON{
'status': Return TRUE if no errors occurred, else FALSE
'idk': Returns some stuff??
}
"""
assert 'rtc' in self.tests_to_run
sys.stderr.write("Test not implemented.\n")
return True
def bist_ddr3(self):
"""
BIST for PL DDR3 DRAM
Description: Calls a test to examine the speed of the DDR3
External Equipment: None
JSON{
'status': Return TRUE if no errors occurred, else FALSE
'speed': Return numeric value of speed in MB/s
}
"""
assert 'ddr3' in self.tests_to_run
sys.stderr.write("Test not implemented.\n")
return True
def bist_gpsdo(self):
"""
BIST for GPSDO
Description: Returns the time of GPSDO
External Equipment: None; Recommend attaching an antenna
JSON{
'status': Return TRUE if no errors occurred, else FALSE
'time': Return GPSDO time, in seconds since January 1, 1970
}
"""
assert 'gpsdo' in self.tests_to_run
sys.stderr.write("Test not implemented.\n")
return True
def bist_tpm(self):
"""
BIST for TPM (Trusted Platform Module)
Description:!!! I don't know how this will be tested !!!
External Equipment: None
JSON{
'status': Return TRUE if no errors occurred, else FALSE
'idk': Returns some stuff??
}
"""
assert 'gpsdo' in self.tests_to_run
sys.stderr.write("Test not implemented.\n")
return True
def bist_clock_int(self):
"""
BIST for clock lock from internal source
Description: Checks to see if the N3xx can lock to the internal reference clock
External Equipment: None
JSON{
'status': Return TRUE if no errors occurred, else FALSE
'locked': Return TRUE if able to lock to internal reference, else FALSE
}
"""
assert 'clock_int' in self.tests_to_run
sys.stderr.write("Test not implemented.\n")
return True
def bist_clock_ext(self):
"""
BIST for clock lock from external source
Description: Checks to see if the N3xx can lock to the external reference clock
External Equipment: Reference Source outputted into the "Ref In"
JSON{
'status': Return TRUE if no errors occurred, else FALSE
'locked': Return TRUE if able to lock to external reference, else FALSE
}
"""
assert 'clock_ext' in self.tests_to_run
sys.stderr.write("Test not implemented.\n")
return True
def bist_usbhost(self):
"""
BIST for USB host functionality
Description:!!! I'm considering removing this test !!!
External Equipment: USB device attached to USB hOST
JSON{
'status': Return TRUE if no errors occurred, else FALSE
'devices': [] Returns all devices seen on USB hub
}
"""
assert 'usbhost' in self.tests_to_run
sys.stderr.write("Test not implemented.\n")
return True
def bist_sfp(self):
"""
BIST for SFP+ ports:
Description: Uses one SFP+ port to test the other. Returns the speeds
External Equipment: External loopback cable between SFP+ port 0 and 1 is required
JSON{
'status': Return TRUE if no errors occurred, else FALSE
'speed01': Returns speed in Gbit/s from port 0 to port 1
'speed10': Returns speed in Gbit/s from port 1 to port 0
}
"""
assert 'sfp' in self.tests_to_run
sys.stderr.write("Test not implemented.\n")
return True
def bist_gpio(self):
"""
BIST for GPIO
Description: Writes and reads the values to the GPIO
Needed Equipment: External loopback as follows
GPIO
0<->6
1<->7
2<->8
3<->9
4<->10
5<->11
JSON{
'status': Return TRUE if no errors occurred, else FALSE
'expected': Return expected read values
'returned': Return read values
}
"""
assert 'gpio' in self.tests_to_run
sys.stderr.write("Test not implemented.\n")
return True
def bist_temp(self):
"""
BIST for temperature sensors
Description: Reads the temperature sensors on the motherboards and returns their values
External Equipment: None
JSON{
'status': Return TRUE if no errors occurred, else FALSE
'temperature_ec_hwmon': Return numeric value of read temperature in milliCelsius
'temperature_iio_hwmon': Return numeric value of read temperature in milliCelsius
'temperature_XXX': Return numeric value of read temperature in milliCelsius
}
"""
assert 'temp' in self.tests_to_run
sys.stderr.write("Test not implemented.\n")
return True
def bist_fan(self):
"""
BIST for temperature sensors
Description: Reads the RPM and temperature sensor values of the fans on the motherboard
External Equipment: None
JSON{
'status': Return TRUE if no errors occurred, else FALSE
'fan0_rpm': Return numeric value of revolutions per minute (RPM) of fan0
'fan0_temperature': Return numeric value of read temperature in milliCelsius of fan0
'fan1_rpm': Return numeric value of revolutions per minute (RPM) of fan1
'fan1_temperature': Return numeric value of read temperature in milliCelsius of fan1
}
"""
assert 'fan' in self.tests_to_run
sys.stderr.write("Test not implemented.\n")
return True
def main():
" Go, go, go! "
return N310BIST().run()
if __name__ == '__main__':
exit(not main())
|