#!/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 . # """ 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())