Skip to content

Commit 01e9f28

Browse files
committed
E3xx: Add retry to loopback_self_test
The loopback test sometimes fails. It was found that it would pass on a retry. The root cause of the failure is unknown at this time, but the retry allows the test to pass. This is intended as a temporary patch until the root cause of the failure can be identified. Signed-off-by: michael-west <michael.west@ettus.com>
1 parent 22593f4 commit 01e9f28

File tree

1 file changed

+46
-27
lines changed

1 file changed

+46
-27
lines changed

host/lib/usrp/dboard/e3xx/e3xx_radio_control_impl.cpp

Lines changed: 46 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -433,10 +433,11 @@ void e3xx_radio_control_impl::loopback_self_test(const size_t chan)
433433
_ad9361->set_clock_rate(30.72e6);
434434
// Put AD936x in loopback mode
435435
_ad9361->data_port_loopback(true);
436-
RFNOC_LOG_INFO("Performing CODEC loopback test... ");
436+
RFNOC_LOG_INFO(
437+
"Performing CODEC loopback test on channel " << std::to_string(chan) << " ... ");
437438
size_t hash = size_t(time(NULL));
438439
constexpr size_t loopback_count = 100;
439-
440+
constexpr size_t retries = 3;
440441
// Allow some time for AD936x to enter loopback mode.
441442
// There is no clear statement in the documentation of how long it takes,
442443
// but UG-570 does say to "allow six ADC_CLK/64 clock cycles of flush time"
@@ -445,31 +446,49 @@ void e3xx_radio_control_impl::loopback_self_test(const size_t chan)
445446
// Sleeping 1ms is far more than enough.
446447
std::this_thread::sleep_for(std::chrono::milliseconds(1));
447448

448-
for (size_t i = 0; i < loopback_count; i++) {
449-
// Create test word
450-
boost::hash_combine(hash, i);
451-
const uint32_t word32 = uint32_t(hash) & 0xfff0fff0;
452-
// Write test word to codec_idle idle register (on TX side)
453-
regs().poke32(regmap::RADIO_BASE_ADDR + chan * regmap::REG_CHAN_OFFSET
454-
+ regmap::REG_TX_IDLE_VALUE,
455-
word32);
456-
457-
// Read back values - TX is lower 32-bits and RX is upper 32-bits
458-
const uint32_t rb_tx =
459-
regs().peek32(regmap::RADIO_BASE_ADDR + chan * regmap::REG_CHAN_OFFSET
460-
+ regmap::REG_TX_IDLE_VALUE);
461-
const uint32_t rb_rx =
462-
regs().peek32(regmap::RADIO_BASE_ADDR + chan * regmap::REG_CHAN_OFFSET
463-
+ regmap::REG_RX_DATA);
464-
465-
// Compare TX and RX values to test word
466-
bool test_fail = word32 != rb_tx or word32 != rb_rx;
467-
if (test_fail) {
468-
RFNOC_LOG_WARNING(
469-
"CODEC loopback test failed! "
470-
<< boost::format("Expected: 0x%08X Received (TX/RX): 0x%08X/0x%08X")
471-
% word32 % rb_tx % rb_rx);
472-
throw uhd::runtime_error("CODEC loopback test failed.");
449+
bool test_fail = true;
450+
while (test_fail) {
451+
size_t tries = 0;
452+
for (size_t i = 0; i < loopback_count; i++) {
453+
// Create test word
454+
boost::hash_combine(hash, i);
455+
const uint32_t word32 = uint32_t(hash) & 0xfff0fff0;
456+
// Write test word to codec_idle idle register (on TX side)
457+
regs().poke32(regmap::RADIO_BASE_ADDR + chan * regmap::REG_CHAN_OFFSET
458+
+ regmap::REG_TX_IDLE_VALUE,
459+
word32);
460+
461+
// Read back values - TX is lower 32-bits and RX is upper 32-bits
462+
const uint32_t rb_tx =
463+
regs().peek32(regmap::RADIO_BASE_ADDR + chan * regmap::REG_CHAN_OFFSET
464+
+ regmap::REG_TX_IDLE_VALUE);
465+
const uint32_t rb_rx =
466+
regs().peek32(regmap::RADIO_BASE_ADDR + chan * regmap::REG_CHAN_OFFSET
467+
+ regmap::REG_RX_DATA);
468+
469+
// Compare TX and RX values to test word
470+
test_fail = word32 != rb_tx or word32 != rb_rx;
471+
if (test_fail) {
472+
RFNOC_LOG_DEBUG(
473+
"CODEC loopback test failure: "
474+
<< boost::format("Expected: 0x%08X Received (TX/RX): 0x%08X/0x%08X")
475+
% word32 % rb_tx % rb_rx);
476+
if (tries < retries) {
477+
// TODO: Investigate why loopback test sometimes fails
478+
// Upon failure, setting the streaming mode again makes
479+
// it work for some reason.
480+
this->set_streaming_mode(true, true, true, true);
481+
482+
// Try again
483+
RFNOC_LOG_DEBUG("Retrying CODEC loopback test for channel "
484+
<< std::to_string(chan) << " ... ");
485+
tries++;
486+
break;
487+
} else {
488+
RFNOC_LOG_ERROR("CODEC loopback test failed!");
489+
throw uhd::runtime_error("CODEC loopback test failed.");
490+
}
491+
}
473492
}
474493
}
475494
RFNOC_LOG_INFO("CODEC loopback test passed");

0 commit comments

Comments
 (0)