Hi all,

Related to old questions I have previously asked  in this mail list, I
think I have found two possible bugs (or at least I think so) inside the
UHD code. (IMPORTANT) Following explanations were proved using the uhd
example tx_waveforms.cpp and an ettus B210.

./tx_waveforms --rate 61440000 --freq 2440000000 --wave-type SINE
--wave-freq 100000 --gain 60 --bw 50000000


First, I have realized that once you set a bandwith greater than 40MHz, the
follwing warning appears:

[WARNING] [AD936X] Selected Tx bandwidth (61.44 MHz) exceeds analog
frontend filter bandwidth (56 MHz).

>From this warning, its clear, that somewhere inside the code is
interpreting the sample rate (61.44 MHz) as the bandwith (50MHz). Looking
in the code, I have found the piece of code that produces this warning:

/home/com/uhd/host/lib/usrp/common/ad936x_manager.cpp (line 193)
bool check_bandwidth(double rate, const std::string dir)
    {
        if (rate > _codec_ctrl->get_bw_filter_range(dir).stop()) {
            UHD_LOGGER_WARNING("AD936X")
                << "Selected " << dir << " bandwidth (" << (rate/1e6) << "
MHz) exceeds\n"
                << "analog frontend filter bandwidth (" <<
(_codec_ctrl->get_bw_filter_range(dir).stop()/1e6) << " MHz)."
                ;
            return false;
        }
        return true;
    }

Here, we can see clearly that the code is checking if the sample rate (up
to 61.44MHz) is inside the bandwith range limits (up to 56 MHz). From my
point of view this check has no sense, because instead of the bandwidth of
the signal the function is provided with the sample rate...


Secondly, there is a limit of 40 MHz when the bandwith of the signal is set
(It must be remembered that the maximum bandwith of the B210 is 56 MHz).
This "bug" comes from
/home/com/uhd/host/lib/usrp/common/ad9361_driver/ad9361_device.cpp (line
385).

double ad9361_device_t::_calibrate_baseband_tx_analog_filter(double
req_rfbw)
{
    double bbbw = req_rfbw / 2.0;

    if(bbbw > _baseband_bw / 2.0)
    {
        UHD_LOGGER_DEBUG("AD936X")<< "baseband bandwidth too large for
current sample rate. Setting bandwidth to: "<<_baseband_bw;
        bbbw = _baseband_bw / 2.0;
    }

    /* Baseband BW must be between 20e6 and 0.391e6.
     * Max filter BW is 32 MHz. 32 / 1.6 = 20
     * Min filter BW is 625 kHz. 625 / 1.6 = 391 */
    if (bbbw > 20e6) {
        bbbw = 20e6;
    } else if (bbbw < 0.391e6) {
        bbbw = 0.391e6;
    }

    double txtune_clk = ((1.6 * bbbw * 2 * M_PI) / M_LN2);
    uint16_t txbbfdiv = std::min<uint16_t>(511,
uint16_t(std::ceil(_bbpll_freq / txtune_clk)));
    _regs.bbftune_mode = (_regs.bbftune_mode & 0xFE)
            | ((txbbfdiv >> 8) & 0x0001);

    /* Program the divider values. */
    _io_iface->poke8(0x0d6, (txbbfdiv & 0x00FF));
    _io_iface->poke8(0x0d7, _regs.bbftune_mode);

    /* Enable the filter tuner. */
    _io_iface->poke8(0x0ca, 0x22);

    /* Calibrate! */
    size_t count = 0;
    _io_iface->poke8(0x016, 0x40);
    while (_io_iface->peek8(0x016) & 0x40) {
        if (count > 100) {
            throw uhd::runtime_error("[ad9361_device_t] TX baseband filter
cal FAILURE");
            break;
        }

        count++;
        boost::this_thread::sleep(boost::posix_time::milliseconds(1));
    }

    /* Disable the filter tuner. */
    _io_iface->poke8(0x0ca, 0x26);

    return bbbw;
}

Here, you can see that the function sets to 20MHz (in baseband, 40MHz in
RF), bandwidths greater that 20MHz (in baseband, 40 MHz). That is why the
limit appears. Taking into account that B210 max bandwith is 56 MHz, this
check must be set to 28 MHz (56/2 MHz in baseband).

Please, confirm me if my assumptions are valid.

Thanks in advantage,
Lucas
_______________________________________________
USRP-users mailing list
[email protected]
http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com

Reply via email to