diff options
9 files changed, 339 insertions, 109 deletions
diff --git a/host/lib/usrp/dboard/magnesium/CMakeLists.txt b/host/lib/usrp/dboard/magnesium/CMakeLists.txt index 07d7a0199..eca9e5234 100644 --- a/host/lib/usrp/dboard/magnesium/CMakeLists.txt +++ b/host/lib/usrp/dboard/magnesium/CMakeLists.txt @@ -11,6 +11,7 @@ IF(ENABLE_MPMD) ${CMAKE_CURRENT_SOURCE_DIR}/magnesium_radio_ctrl_cpld.cpp ${CMAKE_CURRENT_SOURCE_DIR}/magnesium_radio_ctrl_gain.cpp ${CMAKE_CURRENT_SOURCE_DIR}/magnesium_ad9371_iface.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/magnesium_bands.cpp ${CMAKE_CURRENT_SOURCE_DIR}/magnesium_cpld_ctrl.cpp ${CMAKE_CURRENT_SOURCE_DIR}/magnesium_gain_table.cpp ) diff --git a/host/lib/usrp/dboard/magnesium/magnesium_bands.cpp b/host/lib/usrp/dboard/magnesium/magnesium_bands.cpp new file mode 100644 index 000000000..22d7502b6 --- /dev/null +++ b/host/lib/usrp/dboard/magnesium/magnesium_bands.cpp @@ -0,0 +1,155 @@ +// +// Copyright 2017 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0 +// + +// The band plan + +#include "magnesium_radio_ctrl_impl.hpp" +#include "magnesium_constants.hpp" +#include <uhd/utils/math.hpp> + +/* + * Magnesium Rev C frequency bands: + * + * RX IF frequency is 2.4418 GHz. Have 80 MHz of bandwidth for loband. + * TX IF frequency is 1.8-2.1 GHz (1.95 GHz is best). + * + * For RX: + * Band SW2-AB SW3-ABC SW4-ABC SW5-ABCD SW6-ABC SW7-AB SW8-AB MIX + * WB RF1 01 OFF 111 NA --- NA ---- RF3 001 RF2 01 RF2 01 0 + * LB RF2 10 RF5 100 NA --- RF3 0010 RF1 100 RF1 10 RF1 10 1 + * 440-530 RF2 10 RF2 001 NA --- RF1 1000 RF1 100 RF2 01 RF2 01 0 + * 650-1000 RF2 10 RF6 101 NA --- RF4 0001 RF1 100 RF2 01 RF2 01 0 + * 1100-1575 RF2 10 RF4 011 NA --- RF2 0100 RF1 100 RF2 01 RF2 01 0 + * 1600-2250 RF2 10 RF3 010 RF2 010 NA ---- RF2 010 RF2 01 RF2 01 0 + * 2100-2850 RF2 10 RF1 000 RF1 100 NA ---- RF2 010 RF2 01 RF2 01 0 + * 2700+ RF3 11 OFF 111 RF3 001 NA ---- RF2 010 RF2 01 RF2 01 0 + * + * For TX: + * Band SW5-AB SW4-AB SW3-X SW2-ABCD SW1-AB SWTRX-AB MIX + * WB RF1 10 RF2 01 RF1 0 NA ---- SHD 00 RF4 11 0 + * LB RF2 01 RF1 10 RF2 1 RF3 0010 RF3 11 RF1 00 1 + * <800 RF1 10 RF2 01 RF2 1 RF3 0010 RF3 11 RF1 00 0 + * 800-1700 RF1 10 RF2 01 RF2 1 RF2 0100 RF2 10 RF1 00 0 + * 1700-3400 RF1 10 RF2 01 RF2 1 RF1 1000 RF1 01 RF1 00 0 + * 3400-6400 RF1 10 RF2 01 RF2 1 RF4 0001 SHD 00 RF2 10 0 + */ + +using namespace uhd; +using namespace uhd::usrp; +using namespace uhd::rfnoc; +using namespace uhd::math::fp_compare; + +namespace { + /* Note on the RX filter bank: + * + * The RX path has 7 bands, which we call BAND0 through BAND7. BAND0 is the + * lowest frequency band (it goes through F44, the 490 MHz low pass filter, + * on the first channel). BAND7 is the highest frequency band, it goes + * through the 2.7 GHz high pass filter (F43 on the first channel). + * + * For all frequencies, there are gain values where we bypass the filter + * bank. In this case, the band setting does not apply (does not have any + * meaning). + * + * The lowband, when not disabling the filter bank, always goes through + * BAND0, but there are non-lowband frequencies which can also go through + * BAND0. + * + * The following constants define lower cutoff frequencies for each band. + * BAND0 does not have a lower cutoff frequency, it is implied by + * MAGNESIUM_MIN_FREQ. MAGNESIUM_RX_BAND1_MIN_FREQ is the cutover frequency + * for switching from BAND0 to BAND1, and so on. + * + * Bands 1-6 have both high- and low-pass filters (effectively band + * passes). Frequencies need to be chosen to allow as much of the full + * bandwidth through unattenuated. + */ + constexpr double MAGNESIUM_RX_BAND1_MIN_FREQ = 430e6; + constexpr double MAGNESIUM_RX_BAND2_MIN_FREQ = 600e6; + constexpr double MAGNESIUM_RX_BAND3_MIN_FREQ = 1050e6; + constexpr double MAGNESIUM_RX_BAND4_MIN_FREQ = 1600e6; + constexpr double MAGNESIUM_RX_BAND5_MIN_FREQ = 2100e6; + constexpr double MAGNESIUM_RX_BAND6_MIN_FREQ = 2700e6; + + /* Note on the TX filter bank: + * + * The TX path has 4 bands, which we call BAND0 through BAND3. + * For all frequencies, there are gain values where we bypass the filter + * bank. In this case, the band setting does not apply (does not have any + * meaning). + * + * The lowband, when not disabling the filter bank, always goes through + * BAND0, but there are non-lowband frequencies which can also go through + * BAND0. + * + * The following constants define lower cutoff frequencies for each band. + * BAND0 does not have a lower cutoff frequency, it is implied by + * MAGNESIUM_MIN_FREQ. MAGNESIUM_TX_BAND1_MIN_FREQ is the cutover frequency + * for switching from BAND0 to BAND1, and so on. + * + * On current Magnesium revisions, all filters on the TX filter bank are + * low pass filters (no high pass filters). + * Frequencies need to be chosen to allow as much of the full bandwidth + * through unattenuated (so don't go all the way up to the cutoff frequency + * of that filter, OK). + */ + constexpr double MAGNESIUM_TX_BAND1_MIN_FREQ = 723.17e6; + constexpr double MAGNESIUM_TX_BAND2_MIN_FREQ = 1623.17e6; + constexpr double MAGNESIUM_TX_BAND3_MIN_FREQ = 3323.17e6; +} + +magnesium_radio_ctrl_impl::rx_band +magnesium_radio_ctrl_impl::_map_freq_to_rx_band(const double freq) { + magnesium_radio_ctrl_impl::rx_band band; + + if (fp_compare_epsilon<double>(freq) < MAGNESIUM_MIN_FREQ) { + band = rx_band::INVALID_BAND; + } else if (fp_compare_epsilon<double>(freq) < MAGNESIUM_LOWBAND_FREQ) { + band = rx_band::LOWBAND; + } else if (fp_compare_epsilon<double>(freq) < MAGNESIUM_RX_BAND1_MIN_FREQ) { + band = rx_band::BAND0; + } else if (fp_compare_epsilon<double>(freq) < MAGNESIUM_RX_BAND2_MIN_FREQ) { + band = rx_band::BAND1; + } else if (fp_compare_epsilon<double>(freq) < MAGNESIUM_RX_BAND3_MIN_FREQ) { + band = rx_band::BAND2; + } else if (fp_compare_epsilon<double>(freq) < MAGNESIUM_RX_BAND4_MIN_FREQ) { + band = rx_band::BAND3; + } else if (fp_compare_epsilon<double>(freq) < MAGNESIUM_RX_BAND5_MIN_FREQ) { + band = rx_band::BAND4; + } else if (fp_compare_epsilon<double>(freq) < MAGNESIUM_RX_BAND6_MIN_FREQ) { + band = rx_band::BAND5; + } else if (fp_compare_epsilon<double>(freq) <= MAGNESIUM_MAX_FREQ) { + band = rx_band::BAND6; + } else { + band = rx_band::INVALID_BAND; + } + + return band; +} + +magnesium_radio_ctrl_impl::tx_band +magnesium_radio_ctrl_impl::_map_freq_to_tx_band(const double freq) { + magnesium_radio_ctrl_impl::tx_band band; + + if (fp_compare_epsilon<double>(freq) < MAGNESIUM_MIN_FREQ) { + band = tx_band::INVALID_BAND; + } else if (fp_compare_epsilon<double>(freq) < MAGNESIUM_LOWBAND_FREQ) { + band = tx_band::LOWBAND; + } else if (fp_compare_epsilon<double>(freq) < MAGNESIUM_TX_BAND1_MIN_FREQ) { + band = tx_band::BAND0; + } else if (fp_compare_epsilon<double>(freq) < MAGNESIUM_TX_BAND2_MIN_FREQ) { + band = tx_band::BAND1; + } else if (fp_compare_epsilon<double>(freq) < MAGNESIUM_TX_BAND3_MIN_FREQ) { + band = tx_band::BAND2; + } else if (fp_compare_epsilon<double>(freq) <= MAGNESIUM_MAX_FREQ) { + band = tx_band::BAND3; + } else { + band = tx_band::INVALID_BAND; + } + + return band; +} + diff --git a/host/lib/usrp/dboard/magnesium/magnesium_constants.hpp b/host/lib/usrp/dboard/magnesium/magnesium_constants.hpp index ba072ad6e..72a708165 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_constants.hpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_constants.hpp @@ -23,19 +23,7 @@ static const double MAGNESIUM_RADIO_RATE = 125e6; // Hz static const double MAGNESIUM_MIN_FREQ = 1e6; // Hz static const double MAGNESIUM_MAX_FREQ = 6e9; // Hz -static const double MAGNESIUM_LOWBAND_FREQ = 300e6; - -static const double MAGNESIUM_RX_BAND1_MIN_FREQ = MAGNESIUM_LOWBAND_FREQ; -static const double MAGNESIUM_RX_BAND2_MIN_FREQ = 600e6; -static const double MAGNESIUM_RX_BAND3_MIN_FREQ = 1050e6; -static const double MAGNESIUM_RX_BAND4_MIN_FREQ = 1600e6; -static const double MAGNESIUM_RX_BAND5_MIN_FREQ = 2100e6; -static const double MAGNESIUM_RX_BAND6_MIN_FREQ = 2700e6; - -static const double MAGNESIUM_TX_BAND1_MIN_FREQ = MAGNESIUM_LOWBAND_FREQ; -static const double MAGNESIUM_TX_BAND2_MIN_FREQ = 800e6; -static const double MAGNESIUM_TX_BAND3_MIN_FREQ = 1700e6; -static const double MAGNESIUM_TX_BAND4_MIN_FREQ = 3400e6; +static constexpr double MAGNESIUM_LOWBAND_FREQ = 300e6; static const double AD9371_MIN_RX_GAIN = 0.0; // dB static const double AD9371_MAX_RX_GAIN = 30.0; // dB diff --git a/host/lib/usrp/dboard/magnesium/magnesium_gain_table.cpp b/host/lib/usrp/dboard/magnesium/magnesium_gain_table.cpp index 8681dc1d5..145501202 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_gain_table.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_gain_table.cpp @@ -11,22 +11,54 @@ #include <map> using namespace uhd; +using namespace uhd::rfnoc; using namespace magnesium; namespace { + typedef magnesium_radio_ctrl_impl::rx_band rx_band; + typedef magnesium_radio_ctrl_impl::tx_band tx_band; + + const size_t TX_LOWBAND = 0; + const size_t TX_HIGHBAND = 1; + const size_t RX_LOWBAND = 0; + const size_t RX_MIDBAND = 1; + const size_t RX_HIGHBAND = 2; + + size_t map_tx_band(const tx_band band) + { + if (band == tx_band::LOWBAND) { + return TX_LOWBAND; + } + return TX_HIGHBAND; + } + + size_t map_rx_band(const rx_band band) + { + if (band == rx_band::LOWBAND) { + return RX_LOWBAND; + } + if (band == rx_band::BAND0 or + band == rx_band::BAND1 or + band == rx_band::BAND2 or + band == rx_band::BAND3) { + return RX_MIDBAND; + } + return RX_HIGHBAND; + } + //! Maps gain index -> gain_tuple_t // // Note: This is an int, for easier lookups. We're basically hardcoding the // knowledge that the gain map has a 1 dB granularity. using gain_tuple_map_t = std::map<int, gain_tuple_t>; - //! Maps max frequency -> gain_tuple_map_t - using gain_tables_t = std::map<double, gain_tuple_map_t>; + //! Maps band -> gain_tuple_map_t + using gain_tables_t = std::map<size_t, gain_tuple_map_t>; /*! RX gain tables */ const gain_tables_t rx_gain_tables = { - {MAGNESIUM_LOWBAND_FREQ, { + {RX_LOWBAND, { // Gain, DSA att, Myk att, bypass {0, {30, 30, true}}, {1, {30, 29, true}}, @@ -105,7 +137,7 @@ namespace { {74, {0, 6, false}}, {75, {0, 5, false}} }}, - {MAGNESIUM_RX_BAND4_MIN_FREQ, { + {RX_MIDBAND, { // Valid for bands 0, 1, 2, 3 {0, {30, 30, true}}, {1, {30, 29, true}}, {2, {30, 28, true}}, @@ -183,7 +215,7 @@ namespace { {74, {6, 0, false}}, {75, {5, 0, false}} }}, - {MAGNESIUM_MAX_FREQ, { + {RX_HIGHBAND, { // Valid for bands 4, 5, 6 {0, {30, 30, true}}, {1, {30, 29, true}}, {2, {30, 28, true}}, @@ -265,7 +297,7 @@ namespace { }; /* rx_gain_tables */ const gain_tables_t tx_gain_tables = { - {MAGNESIUM_LOWBAND_FREQ, { + {TX_LOWBAND, { // Gain, DSA att, Myk att, bypass {0, {30, 20, true}}, {1, {29, 20, true}}, @@ -334,7 +366,7 @@ namespace { {64, {0, 1, false}}, {65, {0, 0, false}} }}, - {6e9, { + {TX_HIGHBAND, { // Valid for bands 1, 2, 3, 4 {0, {30, 20, true}}, {1, {29, 20, true}}, {2, {28, 20, true}}, @@ -404,41 +436,51 @@ namespace { {65, {0, 0, false}} }} }; /* tx_gain_tables */ + + gain_tuple_t fine_tune_ad9371_att( + const gain_tuple_t gain_tuple, + const double gain_index + ) { + // Here, we hardcode the half-dB steps. We soak up all half-dB + // steps by twiddling the AD9371 attenuation, but we need to make + // sure we don't make it negative. + if (gain_index - int(gain_index) >= .5) { + gain_tuple_t gt2 = gain_tuple; + gt2.ad9371_att = std::max(0.0, gain_tuple.ad9371_att - .5); + } + return gain_tuple; + } + } /* namespace ANON */ -gain_tuple_t magnesium::get_gain_tuple( + +gain_tuple_t magnesium::get_rx_gain_tuple( const double gain_index, - const double freq, - const uhd::direction_t dir + const magnesium_radio_ctrl_impl::rx_band band ) { - UHD_ASSERT_THROW(dir == RX_DIRECTION or dir == TX_DIRECTION); - if (dir == RX_DIRECTION) { - UHD_ASSERT_THROW( - gain_index <= ALL_RX_MAX_GAIN and gain_index >= ALL_RX_MIN_GAIN - ); - } else { - UHD_ASSERT_THROW( - gain_index <= ALL_TX_MAX_GAIN and gain_index >= ALL_TX_MIN_GAIN - ); - } - auto &gain_table = (dir == RX_DIRECTION) ? - rx_gain_tables : - tx_gain_tables; + UHD_ASSERT_THROW( + gain_index <= ALL_RX_MAX_GAIN and gain_index >= ALL_RX_MIN_GAIN + ); + auto &gain_table = rx_gain_tables.at(map_rx_band(band)); + const int gain_index_truncd = int(gain_index); + return fine_tune_ad9371_att( + gain_table.at(gain_index_truncd), + gain_index + ); +} - for (const auto &gain_map : gain_table) { - // First, find appropriate gain map for this frequency - if (gain_map.first >= freq) { - int gain_index_truncd = int(gain_index); - // Here, we hardcode the half-dB steps. We soak up all half-dB - // steps by twiddling the AD9371 attenuation, but we need to make - // sure we don't make it negative. - gain_tuple_t gain_tuple = gain_map.second.at(gain_index_truncd); - if (gain_index - double(gain_index_truncd) >= .5) { - gain_tuple.ad9371_att = - std::max(0.0, gain_tuple.ad9371_att - .5); - } - return gain_tuple; - } - } - UHD_THROW_INVALID_CODE_PATH(); +gain_tuple_t magnesium::get_tx_gain_tuple( + const double gain_index, + const magnesium_radio_ctrl_impl::tx_band band +) { + UHD_ASSERT_THROW( + gain_index <= ALL_TX_MAX_GAIN and gain_index >= ALL_TX_MIN_GAIN + ); + auto &gain_table = tx_gain_tables.at(map_tx_band(band)); + const int gain_index_truncd = int(gain_index); + return fine_tune_ad9371_att( + gain_table.at(gain_index_truncd), + gain_index + ); } + diff --git a/host/lib/usrp/dboard/magnesium/magnesium_gain_table.hpp b/host/lib/usrp/dboard/magnesium/magnesium_gain_table.hpp index e3af493b1..28a75ef5b 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_gain_table.hpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_gain_table.hpp @@ -7,6 +7,7 @@ #ifndef INCLUDED_LIBUHD_MAGNESIUM_GAIN_TABLE_HPP #define INCLUDED_LIBUHD_MAGNESIUM_GAIN_TABLE_HPP +#include "magnesium_radio_ctrl_impl.hpp" #include <uhd/types/direction.hpp> namespace magnesium { @@ -27,12 +28,18 @@ struct gain_tuple_t }; -/*! Given a gain index, return a tuple of gain-related settings +/*! Given a gain index, return a tuple of gain-related settings (Rx) */ -gain_tuple_t get_gain_tuple( +gain_tuple_t get_rx_gain_tuple( const double gain_index, - const double freq, - const uhd::direction_t dir + const uhd::rfnoc::magnesium_radio_ctrl_impl::rx_band band_ +); + +/*! Given a gain index, return a tuple of gain-related settings (Tx) + */ +gain_tuple_t get_tx_gain_tuple( + const double gain_index, + const uhd::rfnoc::magnesium_radio_ctrl_impl::tx_band band_ ); } /* namespace magnesium */ diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_cpld.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_cpld.cpp index fd92500b0..8dfca2d6e 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_cpld.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_cpld.cpp @@ -8,38 +8,10 @@ #include "magnesium_cpld_ctrl.hpp" #include "magnesium_constants.hpp" #include <uhd/utils/log.hpp> -#include <uhd/utils/math.hpp> -/* - * Magnesium Rev C frequency bands: - * - * RX IF frequency is 2.4418 GHz. Have 80 MHz of bandwidth for loband. - * TX IF frequency is 1.8-2.1 GHz (1.95 GHz is best). - * - * For RX: - * Band SW2-AB SW3-ABC SW4-ABC SW5-ABCD SW6-ABC SW7-AB SW8-AB MIX - * WB RF1 01 OFF 111 NA --- NA ---- RF3 001 RF2 01 RF2 01 0 - * LB RF2 10 RF5 100 NA --- RF3 0010 RF1 100 RF1 10 RF1 10 1 - * 440-530 RF2 10 RF2 001 NA --- RF1 1000 RF1 100 RF2 01 RF2 01 0 - * 650-1000 RF2 10 RF6 101 NA --- RF4 0001 RF1 100 RF2 01 RF2 01 0 - * 1100-1575 RF2 10 RF4 011 NA --- RF2 0100 RF1 100 RF2 01 RF2 01 0 - * 1600-2250 RF2 10 RF3 010 RF2 010 NA ---- RF2 010 RF2 01 RF2 01 0 - * 2100-2850 RF2 10 RF1 000 RF1 100 NA ---- RF2 010 RF2 01 RF2 01 0 - * 2700+ RF3 11 OFF 111 RF3 001 NA ---- RF2 010 RF2 01 RF2 01 0 - * - * For TX: - * Band SW5-AB SW4-AB SW3-X SW2-ABCD SW1-AB SWTRX-AB MIX - * WB RF1 10 RF2 01 RF1 0 NA ---- SHD 00 RF4 11 0 - * LB RF2 01 RF1 10 RF2 1 RF3 0010 RF3 11 RF1 00 1 - * <800 RF1 10 RF2 01 RF2 1 RF3 0010 RF3 11 RF1 00 0 - * 800-1700 RF1 10 RF2 01 RF2 1 RF2 0100 RF2 10 RF1 00 0 - * 1700-3400 RF1 10 RF2 01 RF2 1 RF1 1000 RF1 01 RF1 00 0 - * 3400-6400 RF1 10 RF2 01 RF2 1 RF4 0001 SHD 00 RF2 10 0 - */ using namespace uhd; using namespace uhd::usrp; using namespace uhd::rfnoc; -using namespace uhd::math::fp_compare; void magnesium_radio_ctrl_impl::_identify_with_leds( const int identify_duration @@ -171,61 +143,79 @@ void magnesium_radio_ctrl_impl::_update_rx_freq_switches( auto rx_sw4 = magnesium_cpld_ctrl::RX_SW4_FILTER2100X2850MHZFROM; auto rx_sw5 = magnesium_cpld_ctrl::RX_SW5_FILTER1100X1575MHZFROM; auto rx_sw6 = magnesium_cpld_ctrl::RX_SW6_BYPASSPATHFROMSWITCH2; - const auto select_lowband_mixer_path = (fp_compare_epsilon<double>(freq) < MAGNESIUM_LOWBAND_FREQ) ? + const auto band = _map_freq_to_rx_band(freq); + const bool is_lowband = (band == rx_band::LOWBAND); + const auto select_lowband_mixer_path = is_lowband ? magnesium_cpld_ctrl::LOWBAND_MIXER_PATH_SEL_LOBAND : magnesium_cpld_ctrl::LOWBAND_MIXER_PATH_SEL_BYPASS; - const bool enable_lowband_mixer = (fp_compare_epsilon<double>(freq) < MAGNESIUM_LOWBAND_FREQ); - const bool rx_lna2_enable = - not bypass_lnas and (fp_compare_epsilon<double>(freq) < MAGNESIUM_RX_BAND4_MIN_FREQ); + const bool enable_lowband_mixer = is_lowband; const bool rx_lna1_enable = - not bypass_lnas and not rx_lna2_enable; + not bypass_lnas and ( + band == rx_band::BAND4 or + band == rx_band::BAND5 or + band == rx_band::BAND6); + const bool rx_lna2_enable = not bypass_lnas and not rx_lna1_enable; UHD_LOG_TRACE(unique_id(), " Enabling LNA1: " << (rx_lna1_enable ? "Yes" : "No") << " Enabling LNA2: " << (rx_lna2_enable ? "Yes" : "No")); // All the defaults are OK when using the bypass path. if (not bypass_lnas) { - if (fp_compare_epsilon<double>(freq) < MAGNESIUM_LOWBAND_FREQ) { + switch(band) { + case rx_band::BAND0: rx_sw2 = magnesium_cpld_ctrl::RX_SW2_LOWERFILTERBANKTOSWITCH3; rx_sw3 = magnesium_cpld_ctrl::RX_SW3_FILTER0490LPMHZ; rx_sw4 = magnesium_cpld_ctrl::RX_SW4_FILTER2700HPMHZ; rx_sw5 = magnesium_cpld_ctrl::RX_SW5_FILTER0490LPMHZFROM; rx_sw6 = magnesium_cpld_ctrl::RX_SW6_LOWERFILTERBANKFROMSWITCH5; - } else if (fp_compare_epsilon<double>(freq) < MAGNESIUM_RX_BAND2_MIN_FREQ) { + break; + case rx_band::BAND1: rx_sw2 = magnesium_cpld_ctrl::RX_SW2_LOWERFILTERBANKTOSWITCH3; rx_sw3 = magnesium_cpld_ctrl::RX_SW3_FILTER0440X0530MHZ; rx_sw4 = magnesium_cpld_ctrl::RX_SW4_FILTER2700HPMHZ; rx_sw5 = magnesium_cpld_ctrl::RX_SW5_FILTER0440X0530MHZFROM; rx_sw6 = magnesium_cpld_ctrl::RX_SW6_LOWERFILTERBANKFROMSWITCH5; - } else if (fp_compare_epsilon<double>(freq) < MAGNESIUM_RX_BAND3_MIN_FREQ) { + break; + case rx_band::BAND2: rx_sw2 = magnesium_cpld_ctrl::RX_SW2_LOWERFILTERBANKTOSWITCH3; rx_sw3 = magnesium_cpld_ctrl::RX_SW3_FILTER0650X1000MHZ; rx_sw4 = magnesium_cpld_ctrl::RX_SW4_FILTER2700HPMHZ; rx_sw5 = magnesium_cpld_ctrl::RX_SW5_FILTER0650X1000MHZFROM; rx_sw6 = magnesium_cpld_ctrl::RX_SW6_LOWERFILTERBANKFROMSWITCH5; - } else if (fp_compare_epsilon<double>(freq) < MAGNESIUM_RX_BAND4_MIN_FREQ) { + break; + case rx_band::BAND3: rx_sw2 = magnesium_cpld_ctrl::RX_SW2_LOWERFILTERBANKTOSWITCH3; rx_sw3 = magnesium_cpld_ctrl::RX_SW3_FILTER1100X1575MHZ; rx_sw4 = magnesium_cpld_ctrl::RX_SW4_FILTER2700HPMHZ; rx_sw5 = magnesium_cpld_ctrl::RX_SW5_FILTER1100X1575MHZFROM; rx_sw6 = magnesium_cpld_ctrl::RX_SW6_LOWERFILTERBANKFROMSWITCH5; - } else if (fp_compare_epsilon<double>(freq) < MAGNESIUM_RX_BAND5_MIN_FREQ) { + break; + case rx_band::BAND4: rx_sw2 = magnesium_cpld_ctrl::RX_SW2_LOWERFILTERBANKTOSWITCH3; rx_sw3 = magnesium_cpld_ctrl::RX_SW3_FILTER1600X2250MHZ; rx_sw4 = magnesium_cpld_ctrl::RX_SW4_FILTER1600X2250MHZFROM; rx_sw5 = magnesium_cpld_ctrl::RX_SW5_FILTER0440X0530MHZFROM; rx_sw6 = magnesium_cpld_ctrl::RX_SW6_UPPERFILTERBANKFROMSWITCH4; - } else if (fp_compare_epsilon<double>(freq) < MAGNESIUM_RX_BAND6_MIN_FREQ) { + break; + case rx_band::BAND5: rx_sw2 = magnesium_cpld_ctrl::RX_SW2_LOWERFILTERBANKTOSWITCH3; rx_sw3 = magnesium_cpld_ctrl::RX_SW3_FILTER2100X2850MHZ; rx_sw4 = magnesium_cpld_ctrl::RX_SW4_FILTER2100X2850MHZFROM; rx_sw5 = magnesium_cpld_ctrl::RX_SW5_FILTER0440X0530MHZFROM; rx_sw6 = magnesium_cpld_ctrl::RX_SW6_UPPERFILTERBANKFROMSWITCH4; - } else { + break; + case rx_band::BAND6: rx_sw2 = magnesium_cpld_ctrl::RX_SW2_UPPERFILTERBANKTOSWITCH4; rx_sw3 = magnesium_cpld_ctrl::RX_SW3_SHUTDOWNSW3; rx_sw4 = magnesium_cpld_ctrl::RX_SW4_FILTER2700HPMHZ; rx_sw5 = magnesium_cpld_ctrl::RX_SW5_FILTER0440X0530MHZFROM; rx_sw6 = magnesium_cpld_ctrl::RX_SW6_UPPERFILTERBANKFROMSWITCH4; + break; + case rx_band::INVALID_BAND: + UHD_LOG_ERROR(unique_id(), + "Cannot map RX frequency to band: " << freq); + break; + default: + UHD_THROW_INVALID_CODE_PATH(); } } @@ -260,45 +250,59 @@ void magnesium_radio_ctrl_impl::_update_tx_freq_switches( auto tx_sw1 = magnesium_cpld_ctrl::TX_SW1_SHUTDOWNTXSW1; auto tx_sw2 = magnesium_cpld_ctrl::TX_SW2_TOTXFILTERLP6400MHZ; auto tx_sw3 = magnesium_cpld_ctrl::TX_SW3_BYPASSPATHTOTRXSW; - const auto select_lowband_mixer_path = (fp_compare_epsilon<double>(freq) < MAGNESIUM_LOWBAND_FREQ) ? + const auto band = _map_freq_to_tx_band(freq); + const bool is_lowband = (band == tx_band::LOWBAND); + const auto select_lowband_mixer_path = is_lowband ? magnesium_cpld_ctrl::LOWBAND_MIXER_PATH_SEL_LOBAND : magnesium_cpld_ctrl::LOWBAND_MIXER_PATH_SEL_BYPASS; - const bool enable_lowband_mixer = (fp_compare_epsilon<double>(freq) < MAGNESIUM_LOWBAND_FREQ); + const bool enable_lowband_mixer = is_lowband; // Defaults are fine for bypassing the amp stage if (bypass_amp) { _sw_trx[chan_sel] = magnesium_cpld_ctrl::SW_TRX_BYPASSPATHTOTXSW3; } else { // Set filters based on frequency - if (fp_compare_epsilon<double>(freq) < MAGNESIUM_TX_BAND1_MIN_FREQ) { + switch(band) { + case tx_band::LOWBAND: _sw_trx[chan_sel] = magnesium_cpld_ctrl::SW_TRX_FROMLOWERFILTERBANKTXSW1; tx_sw1 = magnesium_cpld_ctrl::TX_SW1_FROMTXFILTERLP0800MHZ; tx_sw2 = magnesium_cpld_ctrl::TX_SW2_TOTXFILTERLP0800MHZ; tx_sw3 = magnesium_cpld_ctrl::TX_SW3_TOTXFILTERBANKS; - } else if (fp_compare_epsilon<double>(freq) < MAGNESIUM_TX_BAND2_MIN_FREQ) { + break; + case tx_band::BAND0: _sw_trx[chan_sel] = magnesium_cpld_ctrl::SW_TRX_FROMLOWERFILTERBANKTXSW1; tx_sw1 = magnesium_cpld_ctrl::TX_SW1_FROMTXFILTERLP0800MHZ; tx_sw2 = magnesium_cpld_ctrl::TX_SW2_TOTXFILTERLP0800MHZ; tx_sw3 = magnesium_cpld_ctrl::TX_SW3_TOTXFILTERBANKS; - } else if (fp_compare_epsilon<double>(freq) < MAGNESIUM_TX_BAND3_MIN_FREQ) { + break; + case tx_band::BAND1: _sw_trx[chan_sel] = magnesium_cpld_ctrl::SW_TRX_FROMLOWERFILTERBANKTXSW1; tx_sw1 = magnesium_cpld_ctrl::TX_SW1_FROMTXFILTERLP1700MHZ; tx_sw2 = magnesium_cpld_ctrl::TX_SW2_TOTXFILTERLP1700MHZ; tx_sw3 = magnesium_cpld_ctrl::TX_SW3_TOTXFILTERBANKS; - } else if (fp_compare_epsilon<double>(freq) < MAGNESIUM_TX_BAND4_MIN_FREQ) { + break; + case tx_band::BAND2: _sw_trx[chan_sel] = magnesium_cpld_ctrl::SW_TRX_FROMLOWERFILTERBANKTXSW1; tx_sw1 = magnesium_cpld_ctrl::TX_SW1_FROMTXFILTERLP3400MHZ; tx_sw2 = magnesium_cpld_ctrl::TX_SW2_TOTXFILTERLP3400MHZ; tx_sw3 = magnesium_cpld_ctrl::TX_SW3_TOTXFILTERBANKS; - } else { + break; + case tx_band::BAND3: _sw_trx[chan_sel] = magnesium_cpld_ctrl::SW_TRX_FROMTXUPPERFILTERBANKLP6400MHZ; tx_sw1 = magnesium_cpld_ctrl::TX_SW1_SHUTDOWNTXSW1; tx_sw2 = magnesium_cpld_ctrl::TX_SW2_TOTXFILTERLP6400MHZ; tx_sw3 = magnesium_cpld_ctrl::TX_SW3_TOTXFILTERBANKS; + break; + case tx_band::INVALID_BAND: + UHD_LOG_ERROR(unique_id(), + "Cannot map TX frequency to band: " << freq); + break; + default: + UHD_THROW_INVALID_CODE_PATH(); } } diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_gain.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_gain.cpp index d7869a24a..449b772b3 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_gain.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_gain.cpp @@ -26,9 +26,11 @@ double magnesium_radio_ctrl_impl::_set_all_gain( "chan=" << chan << ", " "dir=" << dir); const size_t ad9371_chan = _master ? 0 : 1; ;// FIXME: use chan when 2 radios - magnesium_cpld_ctrl::chan_sel_t chan_sel = + const magnesium_cpld_ctrl::chan_sel_t chan_sel = _master ? magnesium_cpld_ctrl::CHAN1 : magnesium_cpld_ctrl::CHAN2; - const auto gain_tuple = get_gain_tuple(gain, freq, dir); + const auto gain_tuple = (dir == RX_DIRECTION) ? + get_rx_gain_tuple(gain, _map_freq_to_rx_band(freq)) : + get_tx_gain_tuple(gain, _map_freq_to_tx_band(freq)); const double ad9371_gain = ((dir == RX_DIRECTION) ? AD9371_MAX_RX_GAIN : AD9371_MAX_TX_GAIN) - gain_tuple.ad9371_att; diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp index f54112ac8..09b6dd710 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp @@ -25,6 +25,7 @@ using namespace uhd; using namespace uhd::usrp; using namespace uhd::rfnoc; using namespace uhd::math::fp_compare; + namespace { /************************************************************************** * ADF4351 Controls @@ -227,7 +228,7 @@ double magnesium_radio_ctrl_impl::set_tx_frequency( UHD_ASSERT_THROW(adf4351_source == "internal"); double coerced_if_freq = freq; - if (fp_compare_epsilon<double>(freq) < MAGNESIUM_LOWBAND_FREQ) { // Low band + if (_map_freq_to_tx_band(freq) == tx_band::LOWBAND) { _is_low_band[TX_DIRECTION] = true; const double desired_low_freq = MAGNESIUM_TX_IF_FREQ - freq; coerced_if_freq = @@ -273,7 +274,7 @@ void magnesium_radio_ctrl_impl::_update_freq( this->get_tx_lo_source(MAGNESIUM_LO1, chan) : this->get_rx_lo_source(MAGNESIUM_LO1, chan) ; - + const double ad9371_freq = ad9371_source == "external" ? _ad9371_freq[dir]/2 : _ad9371_freq[dir] @@ -325,7 +326,7 @@ double magnesium_radio_ctrl_impl::set_rx_frequency( UHD_ASSERT_THROW(adf4351_source == "internal"); double coerced_if_freq = freq; - if (fp_compare_epsilon<double>(freq) < MAGNESIUM_LOWBAND_FREQ) { // Low band + if (_map_freq_to_rx_band(freq) == rx_band::LOWBAND) { _is_low_band[RX_DIRECTION] = true; const double desired_low_freq = MAGNESIUM_RX_IF_FREQ - freq; coerced_if_freq = @@ -828,7 +829,7 @@ bool magnesium_radio_ctrl_impl::get_lo_lock_status( _rpc_prefix + "get_ad9371_lo_lock", trx); UHD_LOG_TRACE(unique_id(), "AD9371 " << trx << " LO reports lock: " << (lo_lock ? "Yes" : "No")); - if (lo_lock && fp_compare_epsilon<double>(freq) < MAGNESIUM_LOWBAND_FREQ) { + if (lo_lock and _map_freq_to_rx_band(freq) == rx_band::LOWBAND) { lo_lock = lo_lock && _rpcc->request_with_token<bool>( _rpc_prefix + "get_lowband_lo_lock", trx); UHD_LOG_TRACE(unique_id(), diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp index 0659dad14..49affaa6f 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp @@ -29,6 +29,29 @@ class magnesium_radio_ctrl_impl : public radio_ctrl_impl, public rpc_block_ctrl public: typedef boost::shared_ptr<magnesium_radio_ctrl_impl> sptr; + //! Frequency bands for RX. Bands are a function of the analog filter banks + enum class rx_band { + INVALID_BAND, + LOWBAND, + BAND0, + BAND1, + BAND2, + BAND3, + BAND4, + BAND5, + BAND6 + }; + + //! Frequency bands for TX. Bands are a function of the analog filter banks + enum class tx_band { + INVALID_BAND, + LOWBAND, + BAND0, + BAND1, + BAND2, + BAND3 + }; + /************************************************************************ * Structors ***********************************************************************/ @@ -144,6 +167,13 @@ private: const size_t chan_idx ); + //! Map a frequency in Hz to an rx_band value. Will return + // rx_band::INVALID_BAND if the frequency is out of range. + rx_band _map_freq_to_rx_band(const double freq); + //! Map a frequency in Hz to an tx_band value. Will return + // tx_band::INVALID_BAND if the frequency is out of range. + tx_band _map_freq_to_tx_band(const double freq); + /************************************************************************** * Sensors *************************************************************************/ |