aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/x400/x400_rfdc_control.cpp
blob: b963c0a46cb986cc6741f67f95d7a96b8f0809fc (plain)
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
//
// Copyright 2020 Ettus Research, a National Instruments Brand
//
// SPDX-License-Identifier: GPL-3.0-or-later
//

#include <uhd/utils/log.hpp>
#include <uhdlib/usrp/common/x400_rfdc_control.hpp>
#include <unordered_map>

using namespace uhd::rfnoc::x400;

rfdc_control::rfdc_control(uhd::memmap32_iface_timed&& iface, const std::string& log_id)
    : _iface(std::move(iface)), _log_id(log_id)
{
    // nop
}

void rfdc_control::reset_ncos(
    const std::vector<rfdc_type>& ncos, const uhd::time_spec_t& time)
{
    if (ncos.empty()) {
        UHD_LOG_WARNING(_log_id,
            "reset_ncos() called with empty NCO list! "
            "Not resetting NCOs.");
        return;
    }
    UHD_LOG_TRACE(_log_id, "Resetting " << ncos.size() << " NCOs...");

    const uint32_t reset_word = 1;
    // TODO: When the FPGA supports it, map the list of ncos into bits onto
    // reset_word to set the bit for the specific NCOs that will be reset.

    _iface.poke32(regmap::NCO_RESET, reset_word, time);
}

void rfdc_control::reset_gearboxes(
    const std::vector<rfdc_type>& gearboxes, const uhd::time_spec_t& time)
{
    if (gearboxes.empty()) {
        UHD_LOG_WARNING(_log_id,
            "reset_gearboxes() called with empty gearbox list! "
            "Not resetting gearboxes.");
        return;
    }
    // This is intentionally at INFO: It should typically happen once per session.
    UHD_LOG_INFO(_log_id, "Resetting " << gearboxes.size() << " gearbox(es)...");
    // TODO: Either the FPGA supports resetting gearboxes individually, or we
    // remove this TODO
    static const std::unordered_map<rfdc_type, const uint32_t> gb_map{
        {rfdc_type::TX0, regmap::DAC_RESET_MSB},
        {rfdc_type::TX1, regmap::DAC_RESET_MSB},
        {rfdc_type::RX0, regmap::ADC_RESET_MSB},
        {rfdc_type::RX1, regmap::ADC_RESET_MSB}};

    uint32_t reset_word = 0;
    for (const auto gb : gearboxes) {
        reset_word = reset_word | (1 << gb_map.at(gb));
    }

    _iface.poke32(regmap::GEARBOX_RESET, reset_word, time);
}

bool rfdc_control::get_nco_reset_done()
{
    return bool(_iface.peek32(regmap::NCO_RESET) & (1 << regmap::NCO_RESET_DONE_MSB));
}

double rfdc_control::set_nco_freq(const rfdc_type, const double freq)
{
    UHD_LOG_WARNING(_log_id, "set_nco_freq() called but not yet implemented!");
    return freq;
}