From b8acf58798018f5fb4d84d470badadce5dd3a08d Mon Sep 17 00:00:00 2001 From: mattprost Date: Thu, 16 Dec 2021 13:48:26 -0600 Subject: n310: Add Filter API to n310 Add the Filter API to n3xx specifically for the AD937x device. The TX filter is limited to 32 taps, and the RX filter is limited to 48 taps. This feature requires MPM version 4.2 or later on the device. Co-authored-by: bpadalino Signed-off-by: mattprost --- .../dboard/magnesium/magnesium_radio_control.cpp | 139 +++++++++++++++++++++ 1 file changed, 139 insertions(+) (limited to 'host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp') diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp index 8e2463721..249833ddf 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp @@ -1174,6 +1174,145 @@ sensor_value_t magnesium_radio_control_impl::get_tx_sensor( _rpc_prefix + "get_sensor", "TX", name, chan)); } +/************************************************************************** + * Filter API + *************************************************************************/ +std::vector magnesium_radio_control_impl::get_rx_filter_names( + const size_t chan) const +{ + UHD_ASSERT_THROW(chan < TOTAL_RADIO_PORTS); + if (chan % 2 == 0) { + return {"RX1_FIR", "RX1RX2_FIR"}; + } else { + return {"RX2_FIR", "RX1RX2_FIR"}; + } +} + +uhd::filter_info_base::sptr magnesium_radio_control_impl::get_rx_filter( + const std::string& name, const size_t) +{ + if (_mpm_compat_num[0] < 4 || (_mpm_compat_num[0] == 4 && _mpm_compat_num[1] < 2)) { + RFNOC_LOG_WARNING("Getting rx filter not supported. Please upgrade MPM to a " + "minimum version of 4.2."); + return std::make_shared>( + uhd::filter_info_base::filter_type::DIGITAL_FIR_I16, + false, + 0, + 1.0, + 1, + 1, + 32767, + AD9371_RX_MAX_FIR_TAPS, + std::vector(AD9371_RX_MAX_FIR_TAPS, 0)); + } + + const auto rv = _ad9371->get_fir(name); + const auto coeffs = rv.second; + // TODO: Put gain in the digital_filter_fir + return std::make_shared>( + uhd::filter_info_base::filter_type::DIGITAL_FIR_I16, + false, + 0, + 1.0, + 1, + 1, + 32767, + AD9371_RX_MAX_FIR_TAPS, + coeffs); +} + +void magnesium_radio_control_impl::set_rx_filter( + const std::string& name, uhd::filter_info_base::sptr filter, const size_t) +{ + std::lock_guard l(_set_lock); + + if (_mpm_compat_num[0] < 4 || (_mpm_compat_num[0] == 4 && _mpm_compat_num[1] < 2)) { + RFNOC_LOG_WARNING("Setting rx filter not supported. Please upgrade MPM to a " + "minimum version of 4.2."); + return; + } + + auto fir = std::dynamic_pointer_cast>(filter); + if (fir == nullptr) { + throw uhd::runtime_error("Invalid Filter Type for RX Filter"); + } + if (fir->get_taps().size() != AD9371_RX_MAX_FIR_TAPS) { + throw uhd::runtime_error("AD937x RX Filter Taps must be " + + std::to_string(AD9371_RX_MAX_FIR_TAPS) + + " taps long!"); + } + // TODO: Use gain in the digital_filter_fir + _ad9371->set_fir(name, 6, fir->get_taps()); +} + +std::vector magnesium_radio_control_impl::get_tx_filter_names( + const size_t chan) const +{ + UHD_ASSERT_THROW(chan < TOTAL_RADIO_PORTS); + if (chan % 2 == 0) { + return {"TX1_FIR", "TX1TX2_FIR"}; + } else { + return {"TX2_FIR", "TX1TX2_FIR"}; + } +} + +uhd::filter_info_base::sptr magnesium_radio_control_impl::get_tx_filter( + const std::string& name, const size_t) +{ + if (_mpm_compat_num[0] < 4 || (_mpm_compat_num[0] == 4 && _mpm_compat_num[1] < 2)) { + RFNOC_LOG_WARNING("Getting tx filter not supported. Please upgrade MPM to a " + "minimum version of 4.2."); + return std::make_shared>( + uhd::filter_info_base::filter_type::DIGITAL_FIR_I16, + false, + 0, + 1.0, + 1, + 1, + 32767, + AD9371_TX_MAX_FIR_TAPS, + std::vector(AD9371_TX_MAX_FIR_TAPS, 0)); + } + + const auto rv = _ad9371->get_fir(name); + const auto taps = rv.second; + // TODO: Use gain in the digital_filter_fir + return std::make_shared>( + uhd::filter_info_base::filter_type::DIGITAL_FIR_I16, + false, + 0, + 1.0, + 1, + 1, + 32767, + AD9371_TX_MAX_FIR_TAPS, + taps); +} + +void magnesium_radio_control_impl::set_tx_filter( + const std::string& name, uhd::filter_info_base::sptr filter, const size_t) +{ + std::lock_guard l(_set_lock); + + if (_mpm_compat_num[0] < 4 || (_mpm_compat_num[0] == 4 && _mpm_compat_num[1] < 2)) { + RFNOC_LOG_WARNING("Setting tx filter not supported. Please upgrade MPM to a " + "minimum version of 4.2."); + return; + } + + auto fir = std::dynamic_pointer_cast>(filter); + if (fir == nullptr) { + throw uhd::runtime_error("Invalid Filter Type for TX Filter"); + } + if (fir->get_taps().size() != AD9371_TX_MAX_FIR_TAPS) { + throw uhd::runtime_error("AD937x TX Filter Taps must be " + + std::to_string(AD9371_TX_MAX_FIR_TAPS) + + " taps long!"); + } + // TODO: Use gain in the digital_filter_fir + _ad9371->set_fir(name, 6, fir->get_taps()); +} + /************************************************************************** * Radio Identification API Calls *************************************************************************/ -- cgit v1.2.3