diff options
author | Ashish Chaudhari <ashish@ettus.com> | 2015-07-18 23:33:34 -0700 |
---|---|---|
committer | Ashish Chaudhari <ashish@ettus.com> | 2015-07-19 11:43:13 -0700 |
commit | afaf1e0e0fbb0478790b7d4e4bd3310faf35deba (patch) | |
tree | 7f78a1c4236ba2145dcfabb1284eb382091c5cab /host/lib/usrp | |
parent | 782e20505f0df15d644763738390f7fa11bc464d (diff) | |
download | uhd-afaf1e0e0fbb0478790b7d4e4bd3310faf35deba.tar.gz uhd-afaf1e0e0fbb0478790b7d4e4bd3310faf35deba.tar.bz2 uhd-afaf1e0e0fbb0478790b7d4e4bd3310faf35deba.zip |
x300: Added extended ADC self-test
- New device arg "ext_adc_self_test" triggers the test
- ext_adc_self_test=<time> runs the test for "time" seconds
Diffstat (limited to 'host/lib/usrp')
-rw-r--r-- | host/lib/usrp/x300/x300_impl.cpp | 75 | ||||
-rw-r--r-- | host/lib/usrp/x300/x300_impl.hpp | 2 |
2 files changed, 68 insertions, 9 deletions
diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp index 5d0d5ee16..f466d3bf5 100644 --- a/host/lib/usrp/x300/x300_impl.cpp +++ b/host/lib/usrp/x300/x300_impl.cpp @@ -37,6 +37,7 @@ #include <uhd/transport/nirio_zero_copy.hpp> #include <uhd/transport/nirio/niusrprio_session.h> #include <uhd/utils/platform.hpp> +#include <boost/date_time/posix_time/posix_time_io.hpp> #define NIUSRPRIO_DEFAULT_RPC_PORT "5444" @@ -729,7 +730,11 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr) if (dev_addr.has_key("self_cal_adc_delay")) { self_cal_adc_xfer_delay(mb, true /* Apply ADC delay */); } - self_test_adcs(mb); + if (dev_addr.has_key("ext_adc_self_test")) { + extended_adc_test(mb, dev_addr.cast<double>("ext_adc_self_test", 30)); + } else { + self_test_adcs(mb); + } //////////////////////////////////////////////////////////////////// // front panel gpio @@ -2134,20 +2139,72 @@ void x300_impl::self_test_adcs(mboard_members_t& mb, boost::uint32_t ramp_time_m perif.misc_outs->write(radio_misc_outs_reg::ADC_CHECKER_ENABLED, 1); } boost::this_thread::sleep(boost::posix_time::milliseconds(ramp_time_ms)); + + bool passed = true; + std::string status_str; for (size_t r = 0; r < mboard_members_t::NUM_RADIOS; r++) { radio_perifs_t &perif = mb.radio_perifs[r]; + perif.misc_ins->refresh(); + + std::string i_status, q_status; + if (perif.misc_ins->get(radio_misc_ins_reg::ADC_CHECKER1_I_LOCKED)) + if (perif.misc_ins->get(radio_misc_ins_reg::ADC_CHECKER1_I_ERROR)) + i_status = "Bit Errors!"; + else + i_status = "Good"; + else + i_status = "Not Locked!"; - if (!perif.misc_ins->read(radio_misc_ins_reg::ADC_CHECKER1_I_LOCKED) || - perif.misc_ins->read(radio_misc_ins_reg::ADC_CHECKER1_I_ERROR) || - !perif.misc_ins->read(radio_misc_ins_reg::ADC_CHECKER1_Q_LOCKED) || - perif.misc_ins->read(radio_misc_ins_reg::ADC_CHECKER1_Q_ERROR)) - { - throw uhd::runtime_error( - (boost::format("ADC self-test failed for Radio%d. (Ramp checker failure)")%r).str()); - } + if (perif.misc_ins->get(radio_misc_ins_reg::ADC_CHECKER1_Q_LOCKED)) + if (perif.misc_ins->get(radio_misc_ins_reg::ADC_CHECKER1_Q_ERROR)) + q_status = "Bit Errors!"; + else + q_status = "Good"; + else + q_status = "Not Locked!"; + + passed &= (i_status == "Good") && (q_status == "Good"); + status_str += (boost::format(", ADC%d_I=%s, ADC%d_Q=%s")%r%i_status%r%q_status).str(); //Return to normal mode perif.adc->set_test_word("normal", "normal"); } + + if (not passed) { + throw uhd::runtime_error( + (boost::format("ADC self-test failed! Ramp checker status: {%s}")%status_str.substr(2)).str()); + } } +void x300_impl::extended_adc_test(mboard_members_t& mb, double duration_s) +{ + static const size_t SECS_PER_ITER = 5; + UHD_MSG(status) << boost::format("Running Extended ADC Self-Test (Duration=%.0fs, %ds/iteration)...\n") + % duration_s % SECS_PER_ITER; + + size_t num_iters = static_cast<size_t>(ceil(duration_s/SECS_PER_ITER)); + size_t num_failures = 0; + for (size_t iter = 0; iter < num_iters; iter++) { + //Print date and time + boost::posix_time::time_facet *facet = new boost::posix_time::time_facet("%d-%b-%Y %H:%M:%S"); + std::ostringstream time_strm; + time_strm.imbue(std::locale(std::locale::classic(), facet)); + time_strm << boost::posix_time::second_clock::local_time(); + //Run self-test + UHD_MSG(status) << boost::format("-- [%s] Iteration %06d... ") % time_strm.str() % (iter+1); + try { + self_test_adcs(mb, SECS_PER_ITER*1000); + UHD_MSG(status) << "done" << std::endl; + } catch(std::exception &e) { + num_failures++; + UHD_MSG(status) << e.what() << std::endl; + } + + } + if (num_failures == 0) { + UHD_MSG(status) << "Extended ADC Self-Test PASSED\n"; + } else { + throw uhd::runtime_error( + (boost::format("Extended ADC FAILED!!! (%d/%d failures)\n") % num_failures % num_iters).str()); + } +} diff --git a/host/lib/usrp/x300/x300_impl.hpp b/host/lib/usrp/x300/x300_impl.hpp index 64f14cae6..ad1c802ee 100644 --- a/host/lib/usrp/x300/x300_impl.hpp +++ b/host/lib/usrp/x300/x300_impl.hpp @@ -410,6 +410,8 @@ private: double self_cal_adc_xfer_delay(mboard_members_t& mb, bool apply_delay = false); void self_test_adcs(mboard_members_t& mb, boost::uint32_t ramp_time_ms = 100); + void extended_adc_test(mboard_members_t& mb, double duration_s); + //**PRECONDITION** //This function assumes that all the VITA times in "radios" are synchronized //to a common reference. Currently, this function is called in get_tx_stream |