// // Copyright 2017 Ettus Research, a National Instruments Company // // SPDX-License-Identifier: GPL-3.0-or-later // #include "magnesium_gain_table.hpp" #include "magnesium_constants.hpp" #include #include #include 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; //! Maps band -> gain_tuple_map_t using gain_tables_t = std::map; // clang-format off /*! RX gain tables */ const gain_tables_t rx_gain_tables = { {RX_LOWBAND, { // Gain, DSA att, Myk att, bypass {0, {30, 30, true}}, {1, {30, 29, true}}, {2, {30, 28, true}}, {3, {30, 27, true}}, {4, {30, 26, true}}, {5, {30, 25, true}}, {6, {29, 25, true}}, {7, {28, 25, true}}, {8, {27, 25, true}}, {9, {26, 25, true}}, {10, {25, 25, true}}, {11, {25, 24, true}}, {12, {25, 23, true}}, {13, {25, 22, true}}, {14, {25, 21, true}}, {15, {25, 20, true}}, {16, {24, 20, true}}, {17, {23, 20, true}}, {18, {22, 20, true}}, {19, {21, 20, true}}, {20, {20, 20, true}}, {21, {20, 19, true}}, {22, {20, 18, true}}, {23, {20, 17, true}}, {24, {20, 16, true}}, {25, {20, 15, true}}, {26, {19, 15, true}}, {27, {18, 15, true}}, {28, {17, 15, true}}, {29, {16, 15, true}}, {30, {15, 15, true}}, {31, {14, 15, true}}, {32, {13, 15, true}}, {33, {12, 15, true}}, {34, {11, 15, true}}, {35, {10, 15, true}}, {36, {10, 14, true}}, {37, {10, 13, true}}, {38, {10, 12, true}}, {39, {10, 11, true}}, {40, {10, 10, true}}, {41, {9, 10, true}}, {42, {8, 10, true}}, {43, {7, 10, true}}, {44, {6, 10, true}}, {45, {5, 10, true}}, {46, {4, 10, true}}, {47, {3, 10, true}}, {48, {2, 10, true}}, {49, {1, 10, true}}, {50, {15, 15, false}}, {51, {14, 15, false}}, {52, {13, 15, false}}, {53, {12, 15, false}}, {54, {11, 15, false}}, {55, {10, 15, false}}, {56, {10, 14, false}}, {57, {10, 13, false}}, {58, {10, 12, false}}, {59, {10, 11, false}}, {60, {10, 10, false}}, {61, {9, 10, false}}, {62, {8, 10, false}}, {63, {7, 10, false}}, {64, {6, 10, false}}, {65, {5, 10, false}}, {66, {4, 10, false}}, {67, {3, 10, false}}, {68, {2, 10, false}}, {69, {1, 10, false}}, {70, {0, 10, false}}, {71, {0, 9, false}}, {72, {0, 8, false}}, {73, {0, 7, false}}, {74, {0, 6, false}}, {75, {0, 5, false}} }}, {RX_MIDBAND, { // Valid for bands 0, 1, 2, 3 {0, {30, 30, true}}, {1, {30, 29, true}}, {2, {30, 28, true}}, {3, {30, 27, true}}, {4, {30, 26, true}}, {5, {30, 25, true}}, {6, {30, 24, true}}, {7, {30, 23, true}}, {8, {30, 22, true}}, {9, {30, 21, true}}, {10, {30, 20, true}}, {11, {30, 19, true}}, {12, {30, 18, true}}, {13, {30, 17, true}}, {14, {30, 16, true}}, {15, {30, 15, true}}, {16, {29, 15, true}}, {17, {28, 15, true}}, {18, {27, 15, true}}, {19, {26, 15, true}}, {20, {25, 15, true}}, {21, {24, 15, true}}, {22, {23, 15, true}}, {23, {22, 15, true}}, {24, {21, 15, true}}, {25, {20, 15, true}}, {26, {19, 15, true}}, {27, {18, 15, true}}, {28, {17, 15, true}}, {29, {16, 15, true}}, {30, {15, 15, true}}, {31, {14, 15, true}}, {32, {13, 15, true}}, {33, {12, 15, true}}, {34, {11, 15, true}}, {35, {10, 15, true}}, {36, {9, 15, true}}, {37, {8, 15, true}}, {38, {7, 15, true}}, {39, {6, 15, true}}, {40, {5, 15, true}}, {41, {5, 14, true}}, {42, {5, 13, true}}, {43, {5, 12, true}}, {44, {5, 11, true}}, {45, {5, 10, true}}, {46, {4, 10, true}}, {47, {3, 10, true}}, {48, {2, 10, true}}, {49, {1, 10, true}}, {50, {15, 15, false}}, {51, {15, 14, false}}, {52, {15, 13, false}}, {53, {15, 12, false}}, {54, {15, 11, false}}, {55, {15, 10, false}}, {56, {15, 9, false}}, {57, {15, 8, false}}, {58, {15, 7, false}}, {59, {15, 6, false}}, {60, {15, 5, false}}, {61, {14, 5, false}}, {62, {13, 5, false}}, {63, {12, 5, false}}, {64, {11, 5, false}}, {65, {10, 5, false}}, {66, {10, 4, false}}, {67, {10, 3, false}}, {68, {10, 2, false}}, {69, {10, 1, false}}, {70, {10, 0, false}}, {71, {9, 0, false}}, {72, {8, 0, false}}, {73, {7, 0, false}}, {74, {6, 0, false}}, {75, {5, 0, false}} }}, {RX_HIGHBAND, { // Valid for bands 4, 5, 6 {0, {30, 30, true}}, {1, {30, 29, true}}, {2, {30, 28, true}}, {3, {30, 27, true}}, {4, {30, 26, true}}, {5, {30, 25, true}}, {6, {30, 24, true}}, {7, {30, 23, true}}, {8, {30, 22, true}}, {9, {30, 21, true}}, {10, {30, 20, true}}, {11, {30, 19, true}}, {12, {30, 18, true}}, {13, {30, 17, true}}, {14, {30, 16, true}}, {15, {30, 15, true}}, {16, {29, 15, true}}, {17, {28, 15, true}}, {18, {27, 15, true}}, {19, {26, 15, true}}, {20, {25, 15, true}}, {21, {24, 15, true}}, {22, {23, 15, true}}, {23, {22, 15, true}}, {24, {21, 15, true}}, {25, {20, 15, true}}, {26, {19, 15, true}}, {27, {18, 15, true}}, {28, {17, 15, true}}, {29, {16, 15, true}}, {30, {15, 15, true}}, {31, {15, 14, true}}, {32, {15, 13, true}}, {33, {15, 12, true}}, {34, {15, 11, true}}, {35, {15, 10, true}}, {36, {14, 10, true}}, {37, {13, 10, true}}, {38, {12, 10, true}}, {39, {11, 10, true}}, {40, {10, 10, true}}, {41, {9, 10, true}}, {42, {8, 10, true}}, {43, {7, 10, true}}, {44, {6, 10, true}}, {45, {5, 10, true}}, {46, {4, 10, true}}, {47, {3, 10, true}}, {48, {2, 10, true}}, {49, {1, 10, true}}, {50, {15, 15, false}}, {51, {15, 14, false}}, {52, {15, 13, false}}, {53, {15, 12, false}}, {54, {15, 11, false}}, {55, {15, 10, false}}, {56, {14, 10, false}}, {57, {13, 10, false}}, {58, {12, 10, false}}, {59, {11, 10, false}}, {60, {10, 10, false}}, {61, {10, 9, false}}, {62, {10, 8, false}}, {63, {10, 7, false}}, {64, {10, 6, false}}, {65, {10, 5, false}}, {66, {9, 5, false}}, {67, {8, 5, false}}, {68, {7, 5, false}}, {69, {6, 5, false}}, {70, {5, 5, false}}, {71, {5, 4, false}}, {72, {5, 3, false}}, {73, {5, 2, false}}, {74, {5, 1, false}}, {75, {5, 0, false}} }, } }; /* rx_gain_tables */ const gain_tables_t tx_gain_tables = { {TX_LOWBAND, { // Gain, DSA att, Myk att, bypass {0, {30, 20, true}}, {1, {29, 20, true}}, {2, {28, 20, true}}, {3, {27, 20, true}}, {4, {26, 20, true}}, {5, {25, 20, true}}, {6, {24, 20, true}}, {7, {23, 20, true}}, {8, {22, 20, true}}, {9, {21, 20, true}}, {10, {20, 20, true}}, {11, {19, 20, true}}, {12, {18, 20, true}}, {13, {17, 20, true}}, {14, {16, 20, true}}, {15, {15, 20, true}}, {16, {14, 20, true}}, {17, {13, 20, true}}, {18, {12, 20, true}}, {19, {11, 20, true}}, {20, {10, 20, true}}, {21, {9, 20, true}}, {22, {8, 20, true}}, {23, {7, 20, true}}, {24, {6, 20, true}}, {25, {5, 20, true}}, {26, {4, 20, true}}, {27, {3, 20, true}}, {28, {2, 20, true}}, {29, {1, 20, true}}, {30, {0, 20, true}}, {31, {0, 19, true}}, {32, {0, 18, true}}, {33, {0, 17, true}}, {34, {0, 16, true}}, {35, {0, 15, true}}, {36, {0, 14, true}}, {37, {0, 13, true}}, {38, {0, 12, true}}, {39, {0, 11, true}}, {40, {10, 15, false}}, {41, {9, 15, false}}, {42, {8, 15, false}}, {43, {7, 15, false}}, {44, {6, 15, false}}, {45, {5, 15, false}}, {46, {4, 15, false}}, {47, {3, 15, false}}, {48, {2, 15, false}}, {49, {1, 15, false}}, {50, {0, 15, false}}, {51, {0, 14, false}}, {52, {0, 13, false}}, {53, {0, 12, false}}, {54, {0, 11, false}}, {55, {0, 10, false}}, {56, {0, 9, false}}, {57, {0, 8, false}}, {58, {0, 7, false}}, {59, {0, 6, false}}, {60, {0, 5, false}}, {61, {0, 4, false}}, {62, {0, 3, false}}, {63, {0, 2, false}}, {64, {0, 1, false}}, {65, {0, 0, false}} }}, {TX_HIGHBAND, { // Valid for bands 1, 2, 3, 4 {0, {30, 20, true}}, {1, {29, 20, true}}, {2, {28, 20, true}}, {3, {27, 20, true}}, {4, {26, 20, true}}, {5, {25, 20, true}}, {6, {24, 20, true}}, {7, {23, 20, true}}, {8, {22, 20, true}}, {9, {21, 20, true}}, {10, {20, 20, true}}, {11, {19, 20, true}}, {12, {18, 20, true}}, {13, {17, 20, true}}, {14, {16, 20, true}}, {15, {15, 20, true}}, {16, {14, 20, true}}, {17, {13, 20, true}}, {18, {12, 20, true}}, {19, {11, 20, true}}, {20, {10, 20, true}}, {21, {9, 20, true}}, {22, {8, 20, true}}, {23, {7, 20, true}}, {24, {6, 20, true}}, {25, {5, 20, true}}, {26, {4, 20, true}}, {27, {3, 20, true}}, {28, {2, 20, true}}, {29, {1, 20, true}}, {30, {0, 20, true}}, {31, {0, 19, true}}, {32, {0, 18, true}}, {33, {0, 17, true}}, {34, {0, 16, true}}, {35, {5, 20, false}}, {36, {4, 20, false}}, {37, {3, 20, false}}, {38, {2, 20, false}}, {39, {1, 20, false}}, {40, {0, 20, false}}, {41, {0, 19, false}}, {42, {0, 18, false}}, {43, {0, 17, false}}, {44, {0, 16, false}}, {45, {0, 15, false}}, {46, {0, 14, false}}, {47, {0, 13, false}}, {48, {0, 12, false}}, {49, {0, 11, false}}, {50, {0, 10, false}}, {51, {0, 9, false}}, {52, {0, 8, false}}, {53, {0, 7, false}}, {54, {0, 6, false}}, {55, {0, 5, false}}, {56, {0, 4, false}}, {57, {0, 3, false}}, {58, {0, 2, false}}, {59, {0, 1, false}}, {60, {0, 0, false}}, // Rest is fake to keep same gain range as low band {61, {0, 0, false}}, {62, {0, 0, false}}, {63, {0, 0, false}}, {64, {0, 0, false}}, {65, {0, 0, false}} }} }; /* tx_gain_tables */ // clang-format on 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 gt2; } return gain_tuple; } } // namespace gain_tuple_t magnesium::get_rx_gain_tuple( const double gain_index, const magnesium_radio_ctrl_impl::rx_band band) { 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); } 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); }